aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2008-09-03 20:16:26 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2008-09-03 18:16:26 +0000
commit39ecc018798bc85d22bfc3c3155986ab5b35f5ac (patch)
tree2ec6cd14c2fd416d7473c8942ba129ded5f4824b /gcc
parentcafea0e43647f764861b625232460c584fe11086 (diff)
downloadgcc-39ecc018798bc85d22bfc3c3155986ab5b35f5ac.zip
gcc-39ecc018798bc85d22bfc3c3155986ab5b35f5ac.tar.gz
gcc-39ecc018798bc85d22bfc3c3155986ab5b35f5ac.tar.bz2
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
Diffstat (limited to 'gcc')
-rw-r--r--gcc/ChangeLog22
-rw-r--r--gcc/cgraph.c4
-rw-r--r--gcc/cgraphunit.c32
-rw-r--r--gcc/gimple.c8
-rw-r--r--gcc/gimple.h1
-rw-r--r--gcc/ipa-inline.c8
-rw-r--r--gcc/tree-cfg.c7
-rw-r--r--gcc/tree-inline.c52
8 files changed, 91 insertions, 43 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 0b1b999..b3bad2f 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -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
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 54d5fad..a12ed15 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -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");
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 43cdfda..d011041 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -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);
diff --git a/gcc/gimple.c b/gcc/gimple.c
index 6e203b7..7419d85 100644
--- a/gcc/gimple.c
+++ b/gcc/gimple.c
@@ -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. */
diff --git a/gcc/gimple.h b/gcc/gimple.h
index f8af057..03b6217 100644
--- a/gcc/gimple.h
+++ b/gcc/gimple.h
@@ -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);
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 4c8096a..66b9bac 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -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)
diff --git a/gcc/tree-cfg.c b/gcc/tree-cfg.c
index 6bd8a06..ce0649d 100644
--- a/gcc/tree-cfg.c
+++ b/gcc/tree-cfg.c
@@ -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;
diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c
index 3b77c0e..8b603f0 100644
--- a/gcc/tree-inline.c
+++ b/gcc/tree-inline.c
@@ -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.