re PR tree-optimization/37315 (gcc.c-torture/execute/931018-1.c int-compare.c ieee/inf-2.c mzero6.c)
PR tree-optimization/37315 * cgraph.c (cgraph_create_edge): Use gimple_has_body_p. * cgraphunit.c (verify_cgraph_node): drop gimple_body check. (cgraph_analyze_functions): Use node->analyzed (cgraph_mark_functions_to_output): Likewise. (cgraph_expand_function): All functions can be released after expanding. (cgraph_optimize): Use gimple_has_body_p. * ipa-inline.c (cgraph_clone_inlined_nodes): Use analyzed flag. (cgraph_decide_inlining_incrementally): Likewise. (inline_transform): Inline transform. * tree-inline.c (initialize_cfun): Do now shallow copy structure; copy fields needed. (inlinable_function_p): Drop gimple_body check. (expand_call_inline): Use gimple_has_body_p. * gimple.c (gimple_has_body_p): New. * gimple.h (gimple_has_body_p): Add prototype. * tree-cfg.c (execute_build_cfg): Remove gimple_body. (dump_function_to_file): Use gimple_has_body_p check. From-SVN: r139945
This commit is contained in:
parent
cafea0e436
commit
39ecc01879
8 changed files with 91 additions and 43 deletions
|
@ -1,3 +1,25 @@
|
|||
2008-09-03 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
PR tree-optimization/37315
|
||||
* cgraph.c (cgraph_create_edge): Use gimple_has_body_p.
|
||||
* cgraphunit.c (verify_cgraph_node): drop gimple_body check.
|
||||
(cgraph_analyze_functions): Use node->analyzed
|
||||
(cgraph_mark_functions_to_output): Likewise.
|
||||
(cgraph_expand_function): All functions can be released after
|
||||
expanding.
|
||||
(cgraph_optimize): Use gimple_has_body_p.
|
||||
* ipa-inline.c (cgraph_clone_inlined_nodes): Use analyzed flag.
|
||||
(cgraph_decide_inlining_incrementally): Likewise.
|
||||
(inline_transform): Inline transform.
|
||||
* tree-inline.c (initialize_cfun): Do now shallow copy structure;
|
||||
copy fields needed.
|
||||
(inlinable_function_p): Drop gimple_body check.
|
||||
(expand_call_inline): Use gimple_has_body_p.
|
||||
* gimple.c (gimple_has_body_p): New.
|
||||
* gimple.h (gimple_has_body_p): Add prototype.
|
||||
* tree-cfg.c (execute_build_cfg): Remove gimple_body.
|
||||
(dump_function_to_file): Use gimple_has_body_p check.
|
||||
|
||||
2008-09-03 Jakub Jelinek <jakub@redhat.com>
|
||||
|
||||
PR c++/37346
|
||||
|
|
|
@ -645,7 +645,7 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
|
|||
|
||||
gcc_assert (is_gimple_call (call_stmt));
|
||||
|
||||
if (!gimple_body (callee->decl))
|
||||
if (!callee->analyzed)
|
||||
edge->inline_failed = N_("function body not available");
|
||||
else if (callee->local.redefined_extern_inline)
|
||||
edge->inline_failed = N_("redefined extern inline functions are not "
|
||||
|
@ -1073,7 +1073,7 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
|
|||
fprintf (f, " needed");
|
||||
else if (node->reachable)
|
||||
fprintf (f, " reachable");
|
||||
if (gimple_body (node->decl))
|
||||
if (gimple_has_body_p (node->decl))
|
||||
fprintf (f, " body");
|
||||
if (node->output)
|
||||
fprintf (f, " output");
|
||||
|
|
|
@ -639,7 +639,6 @@ verify_cgraph_node (struct cgraph_node *node)
|
|||
}
|
||||
|
||||
if (node->analyzed
|
||||
&& gimple_body (node->decl)
|
||||
&& !TREE_ASM_WRITTEN (node->decl)
|
||||
&& (!DECL_EXTERNAL (node->decl) || node->global.inlined_to))
|
||||
{
|
||||
|
@ -860,7 +859,7 @@ cgraph_analyze_functions (void)
|
|||
{
|
||||
fprintf (cgraph_dump_file, "Initial entry points:");
|
||||
for (node = cgraph_nodes; node != first_analyzed; node = node->next)
|
||||
if (node->needed && gimple_body (node->decl))
|
||||
if (node->needed)
|
||||
fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
|
||||
fprintf (cgraph_dump_file, "\n");
|
||||
}
|
||||
|
@ -912,7 +911,7 @@ cgraph_analyze_functions (void)
|
|||
{
|
||||
fprintf (cgraph_dump_file, "Unit entry points:");
|
||||
for (node = cgraph_nodes; node != first_analyzed; node = node->next)
|
||||
if (node->needed && gimple_body (node->decl))
|
||||
if (node->needed)
|
||||
fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
|
||||
fprintf (cgraph_dump_file, "\n\nInitial ");
|
||||
dump_cgraph (cgraph_dump_file);
|
||||
|
@ -926,10 +925,10 @@ cgraph_analyze_functions (void)
|
|||
tree decl = node->decl;
|
||||
next = node->next;
|
||||
|
||||
if (node->local.finalized && !gimple_body (decl))
|
||||
if (node->local.finalized && !gimple_has_body_p (decl))
|
||||
cgraph_reset_node (node);
|
||||
|
||||
if (!node->reachable && gimple_body (decl))
|
||||
if (!node->reachable && gimple_has_body_p (decl))
|
||||
{
|
||||
if (cgraph_dump_file)
|
||||
fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
|
||||
|
@ -938,7 +937,7 @@ cgraph_analyze_functions (void)
|
|||
}
|
||||
else
|
||||
node->next_needed = NULL;
|
||||
gcc_assert (!node->local.finalized || gimple_body (decl));
|
||||
gcc_assert (!node->local.finalized || gimple_has_body_p (decl));
|
||||
gcc_assert (node->analyzed == node->local.finalized);
|
||||
}
|
||||
if (cgraph_dump_file)
|
||||
|
@ -991,7 +990,7 @@ cgraph_mark_functions_to_output (void)
|
|||
/* We need to output all local functions that are used and not
|
||||
always inlined, as well as those that are reachable from
|
||||
outside the current compilation unit. */
|
||||
if (gimple_body (decl)
|
||||
if (node->analyzed
|
||||
&& !node->global.inlined_to
|
||||
&& (node->needed
|
||||
|| (e && node->reachable))
|
||||
|
@ -1003,7 +1002,7 @@ cgraph_mark_functions_to_output (void)
|
|||
/* We should've reclaimed all functions that are not needed. */
|
||||
#ifdef ENABLE_CHECKING
|
||||
if (!node->global.inlined_to
|
||||
&& gimple_body (decl)
|
||||
&& gimple_has_body_p (decl)
|
||||
&& !DECL_EXTERNAL (decl))
|
||||
{
|
||||
dump_cgraph_node (stderr, node);
|
||||
|
@ -1011,7 +1010,7 @@ cgraph_mark_functions_to_output (void)
|
|||
}
|
||||
#endif
|
||||
gcc_assert (node->global.inlined_to
|
||||
|| !gimple_body (decl)
|
||||
|| !gimple_has_body_p (decl)
|
||||
|| DECL_EXTERNAL (decl));
|
||||
|
||||
}
|
||||
|
@ -1039,16 +1038,13 @@ cgraph_expand_function (struct cgraph_node *node)
|
|||
tree_rest_of_compilation (decl);
|
||||
|
||||
/* Make sure that BE didn't give up on compiling. */
|
||||
/* ??? Can happen with nested function of extern inline. */
|
||||
gcc_assert (TREE_ASM_WRITTEN (decl));
|
||||
current_function_decl = NULL;
|
||||
if (!cgraph_preserve_function_body_p (decl))
|
||||
{
|
||||
cgraph_release_function_body (node);
|
||||
/* Eliminate all call edges. This is important so the call_expr no longer
|
||||
points to the dead function body. */
|
||||
cgraph_node_remove_callees (node);
|
||||
}
|
||||
gcc_assert (!cgraph_preserve_function_body_p (decl));
|
||||
cgraph_release_function_body (node);
|
||||
/* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
|
||||
points to the dead function body. */
|
||||
cgraph_node_remove_callees (node);
|
||||
|
||||
cgraph_function_flags_ready = true;
|
||||
}
|
||||
|
@ -1329,7 +1325,7 @@ cgraph_optimize (void)
|
|||
for (node = cgraph_nodes; node; node = node->next)
|
||||
if (node->analyzed
|
||||
&& (node->global.inlined_to
|
||||
|| gimple_body (node->decl)))
|
||||
|| gimple_has_body_p (node->decl)))
|
||||
{
|
||||
error_found = true;
|
||||
dump_cgraph_node (stderr, node);
|
||||
|
|
|
@ -1816,6 +1816,14 @@ gimple_body (tree fndecl)
|
|||
return fn ? fn->gimple_body : NULL;
|
||||
}
|
||||
|
||||
/* Return true when FNDECL has Gimple body either in unlowered
|
||||
or CFG form. */
|
||||
bool
|
||||
gimple_has_body_p (tree fndecl)
|
||||
{
|
||||
struct function *fn = DECL_STRUCT_FUNCTION (fndecl);
|
||||
return (gimple_body (fndecl) || (fn && fn->cfg));
|
||||
}
|
||||
|
||||
/* Detect flags from a GIMPLE_CALL. This is just like
|
||||
call_expr_flags, but for gimple tuples. */
|
||||
|
|
|
@ -822,6 +822,7 @@ enum gimple_statement_structure_enum gss_for_assign (enum tree_code);
|
|||
void sort_case_labels (VEC(tree,heap) *);
|
||||
void gimple_set_body (tree, gimple_seq);
|
||||
gimple_seq gimple_body (tree);
|
||||
bool gimple_has_body_p (tree);
|
||||
gimple_seq gimple_seq_alloc (void);
|
||||
void gimple_seq_free (gimple_seq);
|
||||
void gimple_seq_add_seq (gimple_seq *, gimple_seq);
|
||||
|
|
|
@ -212,7 +212,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
|
|||
&& !cgraph_new_nodes)
|
||||
{
|
||||
gcc_assert (!e->callee->global.inlined_to);
|
||||
if (gimple_body (e->callee->decl))
|
||||
if (e->callee->analyzed)
|
||||
overall_insns -= e->callee->global.insns, nfunctions_inlined++;
|
||||
duplicate = false;
|
||||
}
|
||||
|
@ -1388,7 +1388,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if (!gimple_body (e->callee->decl) && !e->callee->inline_decl)
|
||||
if (!e->callee->analyzed && !e->callee->inline_decl)
|
||||
{
|
||||
if (dump_file)
|
||||
{
|
||||
|
@ -1463,7 +1463,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
|
|||
}
|
||||
continue;
|
||||
}
|
||||
if (!gimple_body (e->callee->decl) && !e->callee->inline_decl)
|
||||
if (!e->callee->analyzed && !e->callee->inline_decl)
|
||||
{
|
||||
if (dump_file)
|
||||
{
|
||||
|
@ -1706,7 +1706,7 @@ inline_transform (struct cgraph_node *node)
|
|||
|
||||
/* We might need the body of this function so that we can expand
|
||||
it inline somewhere else. */
|
||||
if (cgraph_preserve_function_body_p (current_function_decl))
|
||||
if (cgraph_preserve_function_body_p (node->decl))
|
||||
save_inline_function_body (node);
|
||||
|
||||
for (e = node->callees; e; e = e->next_callee)
|
||||
|
|
|
@ -217,7 +217,10 @@ build_gimple_cfg (gimple_seq seq)
|
|||
static unsigned int
|
||||
execute_build_cfg (void)
|
||||
{
|
||||
build_gimple_cfg (gimple_body (current_function_decl));
|
||||
gimple_seq body = gimple_body (current_function_decl);
|
||||
|
||||
build_gimple_cfg (body);
|
||||
gimple_set_body (current_function_decl, NULL);
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
@ -5898,7 +5901,7 @@ dump_function_to_file (tree fn, FILE *file, int flags)
|
|||
if (dsf && (flags & TDF_DETAILS))
|
||||
dump_eh_tree (file, dsf);
|
||||
|
||||
if (flags & TDF_RAW && !gimple_body (fn))
|
||||
if (flags & TDF_RAW && !gimple_has_body_p (fn))
|
||||
{
|
||||
dump_node (fn, TDF_SLIM | flags, file);
|
||||
return;
|
||||
|
|
|
@ -1692,8 +1692,6 @@ static void
|
|||
initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count,
|
||||
int frequency)
|
||||
{
|
||||
struct function *new_cfun
|
||||
= (struct function *) ggc_alloc_cleared (sizeof (struct function));
|
||||
struct function *src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl);
|
||||
gcov_type count_scale, frequency_scale;
|
||||
|
||||
|
@ -1712,14 +1710,40 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count,
|
|||
|
||||
/* Register specific tree functions. */
|
||||
gimple_register_cfg_hooks ();
|
||||
*new_cfun = *DECL_STRUCT_FUNCTION (callee_fndecl);
|
||||
new_cfun->funcdef_no = get_next_funcdef_no ();
|
||||
VALUE_HISTOGRAMS (new_cfun) = NULL;
|
||||
new_cfun->local_decls = NULL;
|
||||
new_cfun->cfg = NULL;
|
||||
new_cfun->decl = new_fndecl /*= copy_node (callee_fndecl)*/;
|
||||
DECL_STRUCT_FUNCTION (new_fndecl) = new_cfun;
|
||||
push_cfun (new_cfun);
|
||||
|
||||
/* Get clean struct function. */
|
||||
push_struct_function (new_fndecl);
|
||||
|
||||
/* We will rebuild these, so just sanity check that they are empty. */
|
||||
gcc_assert (VALUE_HISTOGRAMS (cfun) == NULL);
|
||||
gcc_assert (cfun->local_decls == NULL);
|
||||
gcc_assert (cfun->cfg == NULL);
|
||||
gcc_assert (cfun->decl == new_fndecl);
|
||||
|
||||
/* No need to copy; this is initialized later in compilation. */
|
||||
gcc_assert (!src_cfun->calls_setjmp);
|
||||
gcc_assert (!src_cfun->calls_alloca);
|
||||
|
||||
/* Copy items we preserve during clonning. */
|
||||
cfun->static_chain_decl = src_cfun->static_chain_decl;
|
||||
cfun->nonlocal_goto_save_area = src_cfun->nonlocal_goto_save_area;
|
||||
cfun->function_end_locus = src_cfun->function_end_locus;
|
||||
cfun->curr_properties = src_cfun->curr_properties;
|
||||
cfun->last_verified = src_cfun->last_verified;
|
||||
if (src_cfun->ipa_transforms_to_apply)
|
||||
cfun->ipa_transforms_to_apply = VEC_copy (ipa_opt_pass, heap,
|
||||
src_cfun->ipa_transforms_to_apply);
|
||||
cfun->va_list_gpr_size = src_cfun->va_list_gpr_size;
|
||||
cfun->va_list_fpr_size = src_cfun->va_list_fpr_size;
|
||||
cfun->function_frequency = src_cfun->function_frequency;
|
||||
cfun->has_nonlocal_label = src_cfun->has_nonlocal_label;
|
||||
cfun->stdarg = src_cfun->stdarg;
|
||||
cfun->dont_save_pending_sizes_p = src_cfun->dont_save_pending_sizes_p;
|
||||
cfun->after_inlining = src_cfun->after_inlining;
|
||||
cfun->returns_struct = src_cfun->returns_struct;
|
||||
cfun->returns_pcc_struct = src_cfun->returns_pcc_struct;
|
||||
cfun->after_tree_profile = src_cfun->after_tree_profile;
|
||||
|
||||
init_empty_tree_cfg ();
|
||||
|
||||
ENTRY_BLOCK_PTR->count =
|
||||
|
@ -2581,12 +2605,6 @@ inlinable_function_p (tree fn)
|
|||
inlinable = false;
|
||||
}
|
||||
|
||||
/* If we don't have the function body available, we can't inline it.
|
||||
However, this should not be recorded since we also get here for
|
||||
forward declared inline functions. Therefore, return at once. */
|
||||
if (!gimple_body (fn))
|
||||
return false;
|
||||
|
||||
else if (inline_forbidden_p (fn))
|
||||
{
|
||||
/* See if we should warn about uninlinable functions. Previously,
|
||||
|
@ -3089,7 +3107,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
|
|||
gimple_body. */
|
||||
if (!DECL_INITIAL (fn)
|
||||
&& DECL_ABSTRACT_ORIGIN (fn)
|
||||
&& gimple_body (DECL_ABSTRACT_ORIGIN (fn)))
|
||||
&& gimple_has_body_p (DECL_ABSTRACT_ORIGIN (fn)))
|
||||
fn = DECL_ABSTRACT_ORIGIN (fn);
|
||||
|
||||
/* Objective C and fortran still calls tree_rest_of_compilation directly.
|
||||
|
|
Loading…
Add table
Reference in a new issue