PR middle-end/51737
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 22 Mar 2012 14:33:27 +0000 (14:33 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 22 Mar 2012 14:33:27 +0000 (14:33 +0000)
* 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
gcc/cgraph.c
gcc/cgraph.h
gcc/ipa-inline-transform.c
gcc/testsuite/ChangeLog
gcc/tree-inline.c

index 86f7e06..a3e966f 100644 (file)
@@ -1,3 +1,13 @@
+2012-03-22  Jan Hubicka  <jh@suse.cz>
+
+       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  <rguenther@suse.de>
 
        PR middle-end/52666
index 9cc3690..7c44c05 100644 (file)
@@ -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.  */
index 191364c..db4bcea 100644 (file)
@@ -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 *,
index 75b8e9d..32d8c16 100644 (file)
@@ -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;
 }
index 5bdb9a3..0e66883 100644 (file)
@@ -1,3 +1,8 @@
+2012-03-22  Jan Hubicka  <jh@suse.cz>
+
+       PR middle-end/51737
+       * g++.dg/torture/pr51737.C: New testcase
+
 2012-03-22  Richard Guenther  <rguenther@suse.de>
 
        PR tree-optimization/52548
index ae773f6..5d58c51 100644 (file)
@@ -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);
                        }