aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2009-10-02 01:20:15 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2009-10-01 23:20:15 +0000
commit03ec7d01e07f3477397874f01ee7da39fc93d023 (patch)
tree851bbe5f7a341f0badf18bf5a177dfbf5e290e5c
parent0ecdd2aae98b931eb50dff3c8013a1b7adcfaa95 (diff)
downloadgcc-03ec7d01e07f3477397874f01ee7da39fc93d023.zip
gcc-03ec7d01e07f3477397874f01ee7da39fc93d023.tar.gz
gcc-03ec7d01e07f3477397874f01ee7da39fc93d023.tar.bz2
cgraph.c (cgraph_clone_node): Add redirect_callers parameter.
* cgraph.c (cgraph_clone_node): Add redirect_callers parameter. (cgraph_create_virtual_clone): Just pass redirect_callers around. * cgraph.h (cgraph_clone_node): Update prototype. * ipa-pure-const.c (self_recursive_p): New function. (propagate): Use it. * ipa-inline.c (cgraph_clone_inlined_nodes, * cgraph_decide_recursive_inlining): Update. * gcc.dg/tree-ssa/ipa-cp-1.c: New testcase. From-SVN: r152388
-rw-r--r--gcc/ChangeLog11
-rw-r--r--gcc/cgraph.c25
-rw-r--r--gcc/cgraph.h2
-rw-r--r--gcc/ipa-inline.c5
-rw-r--r--gcc/ipa-pure-const.c14
-rw-r--r--gcc/testsuite/ChangeLog4
-rw-r--r--gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c42
7 files changed, 89 insertions, 14 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index cdaee93..aebdbff 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,14 @@
+2009-10-01 Jan Hubicka <jh@suse.cz>
+
+ * cgraph.c (cgraph_clone_node): Add redirect_callers parameter.
+ (cgraph_create_virtual_clone): Just pass redirect_callers
+ around.
+ * cgraph.h (cgraph_clone_node): Update prototype.
+ * ipa-pure-const.c (self_recursive_p): New function.
+ (propagate): Use it.
+ * ipa-inline.c (cgraph_clone_inlined_nodes,
+ cgraph_decide_recursive_inlining): Update.
+
2009-10-01 David Daney <ddaney@caviumnetworks.com>
* gcc/config/mips/mips.c (mips_process_sync_loop) Emit syncw
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 75447be..15dd60a 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -1656,11 +1656,13 @@ cgraph_clone_edge (struct cgraph_edge *e, struct cgraph_node *n,
by node. */
struct cgraph_node *
cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq,
- int loop_nest, bool update_original)
+ int loop_nest, bool update_original,
+ VEC(cgraph_edge_p,heap) *redirect_callers)
{
struct cgraph_node *new_node = cgraph_create_node ();
struct cgraph_edge *e;
gcov_type count_scale;
+ unsigned i;
new_node->decl = n->decl;
new_node->origin = n->origin;
@@ -1691,6 +1693,14 @@ cgraph_clone_node (struct cgraph_node *n, gcov_type count, int freq,
n->count = 0;
}
+ for (i = 0; VEC_iterate (cgraph_edge_p, redirect_callers, i, e); i++)
+ {
+ /* Redirect calls to the old version node to point to its new
+ version. */
+ cgraph_redirect_edge_callee (e, new_node);
+ }
+
+
for (e = n->callees;e; e=e->next_callee)
cgraph_clone_edge (e, new_node, e->call_stmt, count_scale, freq, loop_nest,
update_original);
@@ -1744,8 +1754,6 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
struct cgraph_node *new_node = NULL;
tree new_decl;
struct cgraph_node key, **slot;
- unsigned i;
- struct cgraph_edge *e;
gcc_assert (tree_versionable_function_p (old_decl));
@@ -1762,7 +1770,8 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
SET_DECL_RTL (new_decl, NULL);
new_node = cgraph_clone_node (old_node, old_node->count,
- CGRAPH_FREQ_BASE, 0, false);
+ CGRAPH_FREQ_BASE, 0, false,
+ redirect_callers);
new_node->decl = new_decl;
/* Update the properties.
Make clone visible only within this translation unit. Make sure
@@ -1821,13 +1830,7 @@ cgraph_create_virtual_clone (struct cgraph_node *old_node,
gcc_assert (!*aslot);
*aslot = new_node;
}
- for (i = 0; VEC_iterate (cgraph_edge_p, redirect_callers, i, e); i++)
- {
- /* Redirect calls to the old version node to point to its new
- version. */
- cgraph_redirect_edge_callee (e, new_node);
- }
-
+
return new_node;
}
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index 67670ef..292eccd 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -409,7 +409,7 @@ struct cgraph_edge * cgraph_clone_edge (struct cgraph_edge *,
struct cgraph_node *,
gimple, gcov_type, int, int, bool);
struct cgraph_node * cgraph_clone_node (struct cgraph_node *, gcov_type, int,
- int, bool);
+ int, bool, VEC(cgraph_edge_p,heap) *);
void cgraph_redirect_edge_callee (struct cgraph_edge *, struct cgraph_node *);
diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c
index 662e13f..8851d60 100644
--- a/gcc/ipa-inline.c
+++ b/gcc/ipa-inline.c
@@ -238,7 +238,7 @@ cgraph_clone_inlined_nodes (struct cgraph_edge *e, bool duplicate,
{
struct cgraph_node *n;
n = cgraph_clone_node (e->callee, e->count, e->frequency, e->loop_nest,
- update_original);
+ update_original, NULL);
cgraph_redirect_edge_callee (e, n);
}
}
@@ -723,7 +723,8 @@ cgraph_decide_recursive_inlining (struct cgraph_node *node,
cgraph_node_name (node));
/* We need original clone to copy around. */
- master_clone = cgraph_clone_node (node, node->count, CGRAPH_FREQ_BASE, 1, false);
+ master_clone = cgraph_clone_node (node, node->count, CGRAPH_FREQ_BASE, 1,
+ false, NULL);
master_clone->needed = true;
for (e = master_clone->callees; e; e = e->next_callee)
if (!e->inline_failed)
diff --git a/gcc/ipa-pure-const.c b/gcc/ipa-pure-const.c
index e5ff3a7..04d4e11 100644
--- a/gcc/ipa-pure-const.c
+++ b/gcc/ipa-pure-const.c
@@ -688,6 +688,18 @@ ignore_edge (struct cgraph_edge *e)
return (!e->can_throw_external);
}
+/* Return true if NODE is self recursive function. */
+
+static bool
+self_recursive_p (struct cgraph_node *node)
+{
+ struct cgraph_edge *e;
+ for (e = node->callees; e; e = e->next_callee)
+ if (e->callee == node)
+ return true;
+ return false;
+}
+
/* Produce the global information by preforming a transitive closure
on the local information that was produced by generate_summary.
Note that there is no function_transform pass since this only
@@ -776,6 +788,8 @@ propagate (void)
if (w_l->state_previously_known != IPA_NEITHER
&& this_state > w_l->state_previously_known)
this_state = w_l->state_previously_known;
+ if (!this_looping && self_recursive_p (w))
+ this_looping = true;
if (!w_l->looping_previously_known)
this_looping = false;
diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog
index 1d34fb7..a981836 100644
--- a/gcc/testsuite/ChangeLog
+++ b/gcc/testsuite/ChangeLog
@@ -1,3 +1,7 @@
+2009-10-01 Jan Hubicka <jh@suse.cz>
+
+ * gcc.dg/tree-ssa/ipa-cp-1.c: New testcase.
+
2009-10-01 Loren J. Rittle <ljrittle@acm.org>
* gcc.dg/20021014-1.c (*-*-freebsd*): Use dg-message.
diff --git a/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c b/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c
new file mode 100644
index 0000000..bd24446
--- /dev/null
+++ b/gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c
@@ -0,0 +1,42 @@
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized -fno-inline" } */
+int
+very_long_function(int a)
+{
+ return very_long_function (a)/4;
+}
+main()
+{
+ very_long_function (1);
+}
+/* One appereance for dump, one self recursive call and one call from main. */
+/* { dg-final { scan-tree-dump-times "very_long_function.clone.0 \\(\\)" 3 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized -fno-inline" } */
+int
+very_long_function(int a)
+{
+ return very_long_function (a)/4;
+}
+main()
+{
+ very_long_function (1);
+}
+/* One appereance for dump, one self recursive call and one call from main. */
+/* { dg-final { scan-tree-dump-times "very_long_function.clone.0 \\(\\)" 3 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */
+/* { dg-do compile } */
+/* { dg-options "-O3 -fdump-tree-optimized -fno-inline" } */
+int
+very_long_function(int a)
+{
+ return very_long_function (a)/4;
+}
+main()
+{
+ very_long_function (1);
+}
+/* One appereance for dump, one self recursive call and one call from main. */
+/* { dg-final { scan-tree-dump-times "very_long_function.clone.0 \\(\\)" 3 "optimized"} } */
+/* { dg-final { cleanup-tree-dump "optimized" } } */