From 41710b76736db179e72878dd39a32ef0d4f2677e Mon Sep 17 00:00:00 2001 From: hubicka Date: Thu, 22 Mar 2012 14:33:27 +0000 Subject: [PATCH] PR middle-end/51737 * cgraph.c (cgraph_remove_node_and_inline_clones): Add FORBIDDEN_NODE parameter. * cgraph.h (cgraph_remove_node_and_inline_clones): Update prototype. * ipa-inline-transform.c (save_inline_function_body): Remove copied clone if needed. * tree-inline.c (delete_unreachable_blocks_update_callgraph): Update. PR middle-end/51737 * g++.dg/torture/pr51737.C: New testcase git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@185694 138bc75d-0d04-0410-961f-82ee72b054a4 --- gcc/ChangeLog | 10 ++++++++++ gcc/cgraph.c | 16 ++++++++++++---- gcc/cgraph.h | 2 +- gcc/ipa-inline-transform.c | 13 ++++++++++++- gcc/testsuite/ChangeLog | 5 +++++ gcc/tree-inline.c | 4 ++-- 6 files changed, 42 insertions(+), 8 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 86f7e06..a3e966f 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2012-03-22 Jan Hubicka + + PR middle-end/51737 + * cgraph.c (cgraph_remove_node_and_inline_clones): Add FORBIDDEN_NODE + parameter. + * cgraph.h (cgraph_remove_node_and_inline_clones): Update prototype. + * ipa-inline-transform.c (save_inline_function_body): Remove copied clone + if needed. + * tree-inline.c (delete_unreachable_blocks_update_callgraph): Update. + 2012-03-22 Richard Guenther PR middle-end/52666 diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 9cc3690..7c44c05 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -1639,19 +1639,27 @@ cgraph_add_to_same_comdat_group (struct cgraph_node *new_, } } -/* Remove the node from cgraph. */ +/* Remove the node from cgraph and all inline clones inlined into it. + Skip however removal of FORBIDDEN_NODE and return true if it needs to be + removed. This allows to call the function from outer loop walking clone + tree. */ -void -cgraph_remove_node_and_inline_clones (struct cgraph_node *node) +bool +cgraph_remove_node_and_inline_clones (struct cgraph_node *node, struct cgraph_node *forbidden_node) { struct cgraph_edge *e, *next; + bool found = false; + + if (node == forbidden_node) + return true; for (e = node->callees; e; e = next) { next = e->next_callee; if (!e->inline_failed) - cgraph_remove_node_and_inline_clones (e->callee); + found |= cgraph_remove_node_and_inline_clones (e->callee, forbidden_node); } cgraph_remove_node (node); + return found; } /* Notify finalize_compilation_unit that given node is reachable. */ diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 191364c..db4bcea 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -478,7 +478,7 @@ void cgraph_insert_node_to_hashtable (struct cgraph_node *node); void cgraph_remove_edge (struct cgraph_edge *); void cgraph_remove_node (struct cgraph_node *); void cgraph_add_to_same_comdat_group (struct cgraph_node *, struct cgraph_node *); -void cgraph_remove_node_and_inline_clones (struct cgraph_node *); +bool cgraph_remove_node_and_inline_clones (struct cgraph_node *, struct cgraph_node *); void cgraph_release_function_body (struct cgraph_node *); void cgraph_node_remove_callees (struct cgraph_node *node); struct cgraph_edge *cgraph_create_edge (struct cgraph_node *, diff --git a/gcc/ipa-inline-transform.c b/gcc/ipa-inline-transform.c index 75b8e9d..32d8c16 100644 --- a/gcc/ipa-inline-transform.c +++ b/gcc/ipa-inline-transform.c @@ -336,8 +336,19 @@ save_inline_function_body (struct cgraph_node *node) first_clone->ipa_transforms_to_apply); first_clone->ipa_transforms_to_apply = NULL; + /* When doing recursive inlining, the clone may become unnecessary. + This is possible i.e. in the case when the recursive function is proved to be + non-throwing and the recursion happens only in the EH landing pad. + We can not remove the clone until we are done with saving the body. + Remove it now. */ + if (!first_clone->callers) + { + cgraph_remove_node_and_inline_clones (first_clone, NULL); + first_clone = NULL; + } #ifdef ENABLE_CHECKING - verify_cgraph_node (first_clone); + else + verify_cgraph_node (first_clone); #endif return first_clone; } diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index 5bdb9a3..0e66883 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,8 @@ +2012-03-22 Jan Hubicka + + PR middle-end/51737 + * g++.dg/torture/pr51737.C: New testcase + 2012-03-22 Richard Guenther PR tree-optimization/52548 diff --git a/gcc/tree-inline.c b/gcc/tree-inline.c index ae773f6..5d58c51 100644 --- a/gcc/tree-inline.c +++ b/gcc/tree-inline.c @@ -4955,7 +4955,7 @@ delete_unreachable_blocks_update_callgraph (copy_body_data *id) if ((e = cgraph_edge (id->dst_node, gsi_stmt (bsi))) != NULL) { if (!e->inline_failed) - cgraph_remove_node_and_inline_clones (e->callee); + cgraph_remove_node_and_inline_clones (e->callee, id->dst_node); else cgraph_remove_edge (e); } @@ -4966,7 +4966,7 @@ delete_unreachable_blocks_update_callgraph (copy_body_data *id) if ((e = cgraph_edge (node, gsi_stmt (bsi))) != NULL) { if (!e->inline_failed) - cgraph_remove_node_and_inline_clones (e->callee); + cgraph_remove_node_and_inline_clones (e->callee, id->dst_node); else cgraph_remove_edge (e); } -- 2.7.4