From a1e880328b19d607aeef6885338b2d5df8fe86bb Mon Sep 17 00:00:00 2001 From: hubicka Date: Thu, 1 Oct 2009 23:20:15 +0000 Subject: [PATCH] * 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@152388 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 11 +++++++++ gcc/cgraph.c | 25 ++++++++++--------- gcc/cgraph.h | 2 +- gcc/ipa-inline.c | 5 ++-- gcc/ipa-pure-const.c | 14 +++++++++++ gcc/testsuite/ChangeLog | 4 +++ gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c | 42 ++++++++++++++++++++++++++++++++ 7 files changed, 89 insertions(+), 14 deletions(-) create mode 100644 gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index cdaee936e62..aebdbffcdb9 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,14 @@ +2009-10-01 Jan Hubicka + + * 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 * gcc/config/mips/mips.c (mips_process_sync_loop) Emit syncw diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 75447be839e..15dd60a7ee4 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 67670ef4b77..292eccd0284 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 662e13f2512..8851d605372 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 e5ff3a77253..04d4e112ed3 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 1d34fb7213c..a981836180e 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-10-01 Jan Hubicka + + * gcc.dg/tree-ssa/ipa-cp-1.c: New testcase. + 2009-10-01 Loren J. Rittle * 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 00000000000..bd24446e162 --- /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" } } */ -- 2.11.0