diff options
author | Jan Hubicka <jh@suse.cz> | 2009-10-02 01:20:15 +0200 |
---|---|---|
committer | Jan Hubicka <hubicka@gcc.gnu.org> | 2009-10-01 23:20:15 +0000 |
commit | 03ec7d01e07f3477397874f01ee7da39fc93d023 (patch) | |
tree | 851bbe5f7a341f0badf18bf5a177dfbf5e290e5c | |
parent | 0ecdd2aae98b931eb50dff3c8013a1b7adcfaa95 (diff) | |
download | gcc-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/ChangeLog | 11 | ||||
-rw-r--r-- | gcc/cgraph.c | 25 | ||||
-rw-r--r-- | gcc/cgraph.h | 2 | ||||
-rw-r--r-- | gcc/ipa-inline.c | 5 | ||||
-rw-r--r-- | gcc/ipa-pure-const.c | 14 | ||||
-rw-r--r-- | gcc/testsuite/ChangeLog | 4 | ||||
-rw-r--r-- | gcc/testsuite/gcc.dg/tree-ssa/ipa-cp-1.c | 42 |
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" } } */ |