ipa: Prevent materialization of clones with removed bodies (PR 92109)
authorMartin Jambor <mjambor@suse.cz>
Mon, 25 Nov 2019 10:13:08 +0000 (11:13 +0100)
committerMartin Jambor <jamborm@gcc.gnu.org>
Mon, 25 Nov 2019 10:13:08 +0000 (11:13 +0100)
2019-11-25  Martin Jambor  <mjambor@suse.cz>

PR ipa/92109
* cgraph.h (cgraph_node::remove_from_clone_tree): Declare.
* cgraphclones.c (cgraph_node::remove_from_clone_tree): New method.
(cgraph_materialize_clone): Move removel from clone tree to the
the new method and use it instead.
* ipa.c (symbol_table::remove_unreachable_nodes): When removing
bodies of clones, also remove it from the clone tree.

From-SVN: r278670

gcc/ChangeLog
gcc/cgraph.h
gcc/cgraphclones.c
gcc/ipa.c

index a15cc758e541c771daad8e9a78a30481a3b2418f..5364edc92f666a746f73faeaaf6bce8e9d7b6adc 100644 (file)
@@ -1,3 +1,13 @@
+2019-11-25  Martin Jambor  <mjambor@suse.cz>
+
+       PR ipa/92109
+       * cgraph.h (cgraph_node::remove_from_clone_tree): Declare.
+       * cgraphclones.c (cgraph_node::remove_from_clone_tree): New method.
+       (cgraph_materialize_clone): Move removel from clone tree to the
+       the new method and use it instead.
+       * ipa.c (symbol_table::remove_unreachable_nodes): When removing
+       bodies of clones, also remove it from the clone tree.
+
 2019-11-25  Martin Jambor  <mjambor@suse.cz>
 
        PR ipa/91956
index a4f14743f00882d921672ba6542d8e0338bc61ad..0d2442c997ca298dfb6814aee414e2c8dd2dc433 100644 (file)
@@ -967,6 +967,10 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
                                     ipa_param_adjustments *param_adjustments,
                                     const char * suffix, unsigned num_suffix);
 
+  /* Remove the node from the tree of virtual and inline clones and make it a
+     standalone node - not a clone any more.  */
+  void remove_from_clone_tree ();
+
   /* cgraph node being removed from symbol table; see if its entry can be
    replaced by other inline clone.  */
   cgraph_node *find_replacement (void);
index bfcebb20495b6918e58af5f6abd12f9fbff5bf79..ac5c57a47aa64109631320f30ed6f7b0c4a0557e 100644 (file)
@@ -1013,6 +1013,22 @@ cgraph_node::create_version_clone_with_body
   return new_version_node;
 }
 
+/* Remove the node from the tree of virtual and inline clones and make it a
+   standalone node - not a clone any more.  */
+
+void cgraph_node::remove_from_clone_tree ()
+{
+  if (next_sibling_clone)
+    next_sibling_clone->prev_sibling_clone = prev_sibling_clone;
+  if (prev_sibling_clone)
+    prev_sibling_clone->next_sibling_clone = next_sibling_clone;
+  else
+    clone_of->clones = next_sibling_clone;
+  next_sibling_clone = NULL;
+  prev_sibling_clone = NULL;
+  clone_of = NULL;
+}
+
 /* Given virtual clone, turn it into actual clone.  */
 
 static void
@@ -1033,22 +1049,15 @@ cgraph_materialize_clone (cgraph_node *node)
       dump_function_to_file (node->decl, symtab->dump_file, dump_flags);
     }
 
+  cgraph_node *clone_of = node->clone_of;
   /* Function is no longer clone.  */
-  if (node->next_sibling_clone)
-    node->next_sibling_clone->prev_sibling_clone = node->prev_sibling_clone;
-  if (node->prev_sibling_clone)
-    node->prev_sibling_clone->next_sibling_clone = node->next_sibling_clone;
-  else
-    node->clone_of->clones = node->next_sibling_clone;
-  node->next_sibling_clone = NULL;
-  node->prev_sibling_clone = NULL;
-  if (!node->clone_of->analyzed && !node->clone_of->clones)
+  node->remove_from_clone_tree ();
+  if (!clone_of->analyzed && !clone_of->clones)
     {
-      node->clone_of->release_body ();
-      node->clone_of->remove_callees ();
-      node->clone_of->remove_all_references ();
+      clone_of->release_body ();
+      clone_of->remove_callees ();
+      clone_of->remove_all_references ();
     }
-  node->clone_of = NULL;
   bitmap_obstack_release (NULL);
 }
 
index 0c92980db462c9d152ee493fd57322b55d4302c5..2404024d722e29d58725f590668694faf7fb3fab 100644 (file)
--- a/gcc/ipa.c
+++ b/gcc/ipa.c
@@ -520,9 +520,14 @@ symbol_table::remove_unreachable_nodes (FILE *file)
             reliably.  */
          if (node->alias || node->thunk.thunk_p)
            ;
-         else if (!body_needed_for_clonning.contains (node->decl)
-             && !node->alias && !node->thunk.thunk_p)
-           node->release_body ();
+         else if (!body_needed_for_clonning.contains (node->decl))
+           {
+             /* Make the node a non-clone so that we do not attempt to
+                materialize it later.  */
+             if (node->clone_of)
+               node->remove_from_clone_tree ();
+             node->release_body ();
+           }
          else if (!node->clone_of)
            gcc_assert (in_lto_p || DECL_RESULT (node->decl));
          if (node->definition && !node->alias && !node->thunk.thunk_p)