Commit 39ecc018 by Jan Hubicka Committed by Jan Hubicka

re PR tree-optimization/37315 (gcc.c-torture/execute/931018-1.c int-compare.c…

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
parent cafea0e4
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> 2008-09-03 Jakub Jelinek <jakub@redhat.com>
PR c++/37346 PR c++/37346
......
...@@ -645,7 +645,7 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee, ...@@ -645,7 +645,7 @@ cgraph_create_edge (struct cgraph_node *caller, struct cgraph_node *callee,
gcc_assert (is_gimple_call (call_stmt)); gcc_assert (is_gimple_call (call_stmt));
if (!gimple_body (callee->decl)) if (!callee->analyzed)
edge->inline_failed = N_("function body not available"); edge->inline_failed = N_("function body not available");
else if (callee->local.redefined_extern_inline) else if (callee->local.redefined_extern_inline)
edge->inline_failed = N_("redefined extern inline functions are not " edge->inline_failed = N_("redefined extern inline functions are not "
...@@ -1073,7 +1073,7 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) ...@@ -1073,7 +1073,7 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
fprintf (f, " needed"); fprintf (f, " needed");
else if (node->reachable) else if (node->reachable)
fprintf (f, " reachable"); fprintf (f, " reachable");
if (gimple_body (node->decl)) if (gimple_has_body_p (node->decl))
fprintf (f, " body"); fprintf (f, " body");
if (node->output) if (node->output)
fprintf (f, " output"); fprintf (f, " output");
......
...@@ -639,7 +639,6 @@ verify_cgraph_node (struct cgraph_node *node) ...@@ -639,7 +639,6 @@ verify_cgraph_node (struct cgraph_node *node)
} }
if (node->analyzed if (node->analyzed
&& gimple_body (node->decl)
&& !TREE_ASM_WRITTEN (node->decl) && !TREE_ASM_WRITTEN (node->decl)
&& (!DECL_EXTERNAL (node->decl) || node->global.inlined_to)) && (!DECL_EXTERNAL (node->decl) || node->global.inlined_to))
{ {
...@@ -860,7 +859,7 @@ cgraph_analyze_functions (void) ...@@ -860,7 +859,7 @@ cgraph_analyze_functions (void)
{ {
fprintf (cgraph_dump_file, "Initial entry points:"); fprintf (cgraph_dump_file, "Initial entry points:");
for (node = cgraph_nodes; node != first_analyzed; node = node->next) 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, " %s", cgraph_node_name (node));
fprintf (cgraph_dump_file, "\n"); fprintf (cgraph_dump_file, "\n");
} }
...@@ -912,7 +911,7 @@ cgraph_analyze_functions (void) ...@@ -912,7 +911,7 @@ cgraph_analyze_functions (void)
{ {
fprintf (cgraph_dump_file, "Unit entry points:"); fprintf (cgraph_dump_file, "Unit entry points:");
for (node = cgraph_nodes; node != first_analyzed; node = node->next) 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, " %s", cgraph_node_name (node));
fprintf (cgraph_dump_file, "\n\nInitial "); fprintf (cgraph_dump_file, "\n\nInitial ");
dump_cgraph (cgraph_dump_file); dump_cgraph (cgraph_dump_file);
...@@ -926,10 +925,10 @@ cgraph_analyze_functions (void) ...@@ -926,10 +925,10 @@ cgraph_analyze_functions (void)
tree decl = node->decl; tree decl = node->decl;
next = node->next; next = node->next;
if (node->local.finalized && !gimple_body (decl)) if (node->local.finalized && !gimple_has_body_p (decl))
cgraph_reset_node (node); cgraph_reset_node (node);
if (!node->reachable && gimple_body (decl)) if (!node->reachable && gimple_has_body_p (decl))
{ {
if (cgraph_dump_file) if (cgraph_dump_file)
fprintf (cgraph_dump_file, " %s", cgraph_node_name (node)); fprintf (cgraph_dump_file, " %s", cgraph_node_name (node));
...@@ -938,7 +937,7 @@ cgraph_analyze_functions (void) ...@@ -938,7 +937,7 @@ cgraph_analyze_functions (void)
} }
else else
node->next_needed = NULL; 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); gcc_assert (node->analyzed == node->local.finalized);
} }
if (cgraph_dump_file) if (cgraph_dump_file)
...@@ -991,7 +990,7 @@ cgraph_mark_functions_to_output (void) ...@@ -991,7 +990,7 @@ cgraph_mark_functions_to_output (void)
/* We need to output all local functions that are used and not /* We need to output all local functions that are used and not
always inlined, as well as those that are reachable from always inlined, as well as those that are reachable from
outside the current compilation unit. */ outside the current compilation unit. */
if (gimple_body (decl) if (node->analyzed
&& !node->global.inlined_to && !node->global.inlined_to
&& (node->needed && (node->needed
|| (e && node->reachable)) || (e && node->reachable))
...@@ -1003,7 +1002,7 @@ cgraph_mark_functions_to_output (void) ...@@ -1003,7 +1002,7 @@ cgraph_mark_functions_to_output (void)
/* We should've reclaimed all functions that are not needed. */ /* We should've reclaimed all functions that are not needed. */
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
if (!node->global.inlined_to if (!node->global.inlined_to
&& gimple_body (decl) && gimple_has_body_p (decl)
&& !DECL_EXTERNAL (decl)) && !DECL_EXTERNAL (decl))
{ {
dump_cgraph_node (stderr, node); dump_cgraph_node (stderr, node);
...@@ -1011,7 +1010,7 @@ cgraph_mark_functions_to_output (void) ...@@ -1011,7 +1010,7 @@ cgraph_mark_functions_to_output (void)
} }
#endif #endif
gcc_assert (node->global.inlined_to gcc_assert (node->global.inlined_to
|| !gimple_body (decl) || !gimple_has_body_p (decl)
|| DECL_EXTERNAL (decl)); || DECL_EXTERNAL (decl));
} }
...@@ -1039,16 +1038,13 @@ cgraph_expand_function (struct cgraph_node *node) ...@@ -1039,16 +1038,13 @@ cgraph_expand_function (struct cgraph_node *node)
tree_rest_of_compilation (decl); tree_rest_of_compilation (decl);
/* Make sure that BE didn't give up on compiling. */ /* Make sure that BE didn't give up on compiling. */
/* ??? Can happen with nested function of extern inline. */
gcc_assert (TREE_ASM_WRITTEN (decl)); gcc_assert (TREE_ASM_WRITTEN (decl));
current_function_decl = NULL; current_function_decl = NULL;
if (!cgraph_preserve_function_body_p (decl)) gcc_assert (!cgraph_preserve_function_body_p (decl));
{ cgraph_release_function_body (node);
cgraph_release_function_body (node); /* Eliminate all call edges. This is important so the GIMPLE_CALL no longer
/* Eliminate all call edges. This is important so the call_expr no longer points to the dead function body. */
points to the dead function body. */ cgraph_node_remove_callees (node);
cgraph_node_remove_callees (node);
}
cgraph_function_flags_ready = true; cgraph_function_flags_ready = true;
} }
...@@ -1329,7 +1325,7 @@ cgraph_optimize (void) ...@@ -1329,7 +1325,7 @@ cgraph_optimize (void)
for (node = cgraph_nodes; node; node = node->next) for (node = cgraph_nodes; node; node = node->next)
if (node->analyzed if (node->analyzed
&& (node->global.inlined_to && (node->global.inlined_to
|| gimple_body (node->decl))) || gimple_has_body_p (node->decl)))
{ {
error_found = true; error_found = true;
dump_cgraph_node (stderr, node); dump_cgraph_node (stderr, node);
......
...@@ -1816,6 +1816,14 @@ gimple_body (tree fndecl) ...@@ -1816,6 +1816,14 @@ gimple_body (tree fndecl)
return fn ? fn->gimple_body : NULL; 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 /* Detect flags from a GIMPLE_CALL. This is just like
call_expr_flags, but for gimple tuples. */ call_expr_flags, but for gimple tuples. */
......
...@@ -822,6 +822,7 @@ enum gimple_statement_structure_enum gss_for_assign (enum tree_code); ...@@ -822,6 +822,7 @@ enum gimple_statement_structure_enum gss_for_assign (enum tree_code);
void sort_case_labels (VEC(tree,heap) *); void sort_case_labels (VEC(tree,heap) *);
void gimple_set_body (tree, gimple_seq); void gimple_set_body (tree, gimple_seq);
gimple_seq gimple_body (tree); gimple_seq gimple_body (tree);
bool gimple_has_body_p (tree);
gimple_seq gimple_seq_alloc (void); gimple_seq gimple_seq_alloc (void);
void gimple_seq_free (gimple_seq); void gimple_seq_free (gimple_seq);
void gimple_seq_add_seq (gimple_seq *, 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, ...@@ -212,7 +212,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
&& !cgraph_new_nodes) && !cgraph_new_nodes)
{ {
gcc_assert (!e->callee->global.inlined_to); 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++; overall_insns -= e->callee->global.insns, nfunctions_inlined++;
duplicate = false; duplicate = false;
} }
...@@ -1388,7 +1388,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, ...@@ -1388,7 +1388,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
} }
continue; continue;
} }
if (!gimple_body (e->callee->decl) && !e->callee->inline_decl) if (!e->callee->analyzed && !e->callee->inline_decl)
{ {
if (dump_file) if (dump_file)
{ {
...@@ -1463,7 +1463,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node, ...@@ -1463,7 +1463,7 @@ cgraph_decide_inlining_incrementally (struct cgraph_node *node,
} }
continue; continue;
} }
if (!gimple_body (e->callee->decl) && !e->callee->inline_decl) if (!e->callee->analyzed && !e->callee->inline_decl)
{ {
if (dump_file) if (dump_file)
{ {
...@@ -1706,7 +1706,7 @@ inline_transform (struct cgraph_node *node) ...@@ -1706,7 +1706,7 @@ inline_transform (struct cgraph_node *node)
/* We might need the body of this function so that we can expand /* We might need the body of this function so that we can expand
it inline somewhere else. */ 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); save_inline_function_body (node);
for (e = node->callees; e; e = e->next_callee) for (e = node->callees; e; e = e->next_callee)
......
...@@ -217,7 +217,10 @@ build_gimple_cfg (gimple_seq seq) ...@@ -217,7 +217,10 @@ build_gimple_cfg (gimple_seq seq)
static unsigned int static unsigned int
execute_build_cfg (void) 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; return 0;
} }
...@@ -5898,7 +5901,7 @@ dump_function_to_file (tree fn, FILE *file, int flags) ...@@ -5898,7 +5901,7 @@ dump_function_to_file (tree fn, FILE *file, int flags)
if (dsf && (flags & TDF_DETAILS)) if (dsf && (flags & TDF_DETAILS))
dump_eh_tree (file, dsf); 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); dump_node (fn, TDF_SLIM | flags, file);
return; return;
......
...@@ -1692,8 +1692,6 @@ static void ...@@ -1692,8 +1692,6 @@ static void
initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count, initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count,
int frequency) int frequency)
{ {
struct function *new_cfun
= (struct function *) ggc_alloc_cleared (sizeof (struct function));
struct function *src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl); struct function *src_cfun = DECL_STRUCT_FUNCTION (callee_fndecl);
gcov_type count_scale, frequency_scale; gcov_type count_scale, frequency_scale;
...@@ -1712,14 +1710,40 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count, ...@@ -1712,14 +1710,40 @@ initialize_cfun (tree new_fndecl, tree callee_fndecl, gcov_type count,
/* Register specific tree functions. */ /* Register specific tree functions. */
gimple_register_cfg_hooks (); gimple_register_cfg_hooks ();
*new_cfun = *DECL_STRUCT_FUNCTION (callee_fndecl);
new_cfun->funcdef_no = get_next_funcdef_no (); /* Get clean struct function. */
VALUE_HISTOGRAMS (new_cfun) = NULL; push_struct_function (new_fndecl);
new_cfun->local_decls = NULL;
new_cfun->cfg = NULL; /* We will rebuild these, so just sanity check that they are empty. */
new_cfun->decl = new_fndecl /*= copy_node (callee_fndecl)*/; gcc_assert (VALUE_HISTOGRAMS (cfun) == NULL);
DECL_STRUCT_FUNCTION (new_fndecl) = new_cfun; gcc_assert (cfun->local_decls == NULL);
push_cfun (new_cfun); 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 (); init_empty_tree_cfg ();
ENTRY_BLOCK_PTR->count = ENTRY_BLOCK_PTR->count =
...@@ -2581,12 +2605,6 @@ inlinable_function_p (tree fn) ...@@ -2581,12 +2605,6 @@ inlinable_function_p (tree fn)
inlinable = false; 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)) else if (inline_forbidden_p (fn))
{ {
/* See if we should warn about uninlinable functions. Previously, /* 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) ...@@ -3089,7 +3107,7 @@ expand_call_inline (basic_block bb, gimple stmt, copy_body_data *id)
gimple_body. */ gimple_body. */
if (!DECL_INITIAL (fn) if (!DECL_INITIAL (fn)
&& DECL_ABSTRACT_ORIGIN (fn) && DECL_ABSTRACT_ORIGIN (fn)
&& gimple_body (DECL_ABSTRACT_ORIGIN (fn))) && gimple_has_body_p (DECL_ABSTRACT_ORIGIN (fn)))
fn = DECL_ABSTRACT_ORIGIN (fn); fn = DECL_ABSTRACT_ORIGIN (fn);
/* Objective C and fortran still calls tree_rest_of_compilation directly. /* Objective C and fortran still calls tree_rest_of_compilation directly.
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment