re PR tree-optimization/51737 (g++ crashes (internal compiler error: Segmentation...
authorJan Hubicka <jh@suse.cz>
Thu, 22 Mar 2012 14:33:27 +0000 (15:33 +0100)
committerJan Hubicka <hubicka@gcc.gnu.org>
Thu, 22 Mar 2012 14:33:27 +0000 (14:33 +0000)
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

From-SVN: r185694

gcc/ChangeLog
gcc/cgraph.c
gcc/cgraph.h
gcc/ipa-inline-transform.c
gcc/testsuite/ChangeLog
gcc/tree-inline.c

index 86f7e069dd5d267161195b7ef62a627504a71072..a3e966fa5ea29a450c9cc1cbf0816ef05b6d569f 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 9cc36903a8c5c6b982d08dd7798f960c620e3c45..7c44c0592457f49eabfd8f79d340a23478a06c6f 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 191364ca37728c0ed6ff2d672d67243efcee04be..db4bcea1fc437c754af02aa9404918b37e9f5131 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 75b8e9daf11f9d2dcf5908424e581c7372e9235b..32d8c167be17c493bd9e08a36394b6c89c3b9869 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 5bdb9a3d1a697d9a08dec41124fa4e57e916e8c7..0e668832be3d7abd67a4e60889d98773de88953d 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 ae773f63b58eb67a17ab4b45e92562dcb756eb26..5d58c5169bb5aa53c0e03dd6db7331df1b722279 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);
                        }