Fix copying of clone_info while reshaping clone tree.
authorJan Hubicka <jh@suse.cz>
Tue, 3 Nov 2020 23:19:59 +0000 (00:19 +0100)
committerJan Hubicka <jh@suse.cz>
Tue, 3 Nov 2020 23:19:59 +0000 (00:19 +0100)
2020-11-04  Jan Hubicka  <hubicka@ucw.cz>

PR ipa/97695
* cgraph.c (cgraph_edge::redirect_call_stmt_to_callee): Fix ICE with
in dumping code.
(cgraph_node::remove): Save clone info before releasing it and pass it
to unregister.
* cgraph.h (symtab_node::unregister): Add clone_info parameter.
(cgraph_clone::unregister): Likewise.
* cgraphclones.c (cgraph_node::find_replacement): Copy clone info
* symtab-clones.cc (clone_infos_t::duplicate): Remove.
(clone_info::get_create): Simplify.
* symtab.c (symtab_node::unregister): Pass around clone info.
* varpool.c (varpool_node::remove): Update.

gcc/cgraph.c
gcc/cgraph.h
gcc/cgraphclones.c
gcc/symtab-clones.cc
gcc/symtab.c
gcc/varpool.c

index 36bdb009bf85c20fe6173de76703d070cb7d8d5e..19dfe2be23b1a6d6dfbf93c1a8a88278004527a1 100644 (file)
@@ -1503,14 +1503,13 @@ cgraph_edge::redirect_call_stmt_to_callee (cgraph_edge *e)
 
   if (symtab->dump_file)
     {
-
       fprintf (symtab->dump_file, "updating call of %s -> %s: ",
               e->caller->dump_name (), e->callee->dump_name ());
       print_gimple_stmt (symtab->dump_file, e->call_stmt, 0, dump_flags);
       if (callee_info && callee_info->param_adjustments)
        callee_info->param_adjustments->dump (symtab->dump_file);
       unsigned performed_len
-       = vec_safe_length (caller_info->performed_splits);
+       = caller_info ? vec_safe_length (caller_info->performed_splits) : 0;
       if (performed_len > 0)
        fprintf (symtab->dump_file, "Performed splits records:\n");
       for (unsigned i = 0; i < performed_len; i++)
@@ -1861,12 +1860,19 @@ cgraph_node::release_body (bool keep_arguments)
 void
 cgraph_node::remove (void)
 {
+  bool clone_info_set = false;
+  clone_info *info, saved_info;
   if (symtab->ipa_clones_dump_file && symtab->cloned_nodes.contains (this))
     fprintf (symtab->ipa_clones_dump_file,
             "Callgraph removal;%s;%d;%s;%d;%d\n", asm_name (), order,
             DECL_SOURCE_FILE (decl), DECL_SOURCE_LINE (decl),
             DECL_SOURCE_COLUMN (decl));
 
+  if ((info = clone_info::get (this)) != NULL)
+    {
+      saved_info = *info;
+      clone_info_set = true;
+    }
   symtab->call_cgraph_removal_hooks (this);
   remove_callers ();
   remove_callees ();
@@ -1878,7 +1884,7 @@ cgraph_node::remove (void)
   force_output = false;
   forced_by_abi = false;
 
-  unregister ();
+  unregister (clone_info_set ? &saved_info : NULL);
   if (prev_sibling_clone)
     prev_sibling_clone->next_sibling_clone = next_sibling_clone;
   else if (clone_of)
index cd22676ff9ed20de510ea45d025096f4279b3c05..c87180f1e96870f30ebc7421c1bca70c3a709b67 100644 (file)
@@ -631,7 +631,7 @@ protected:
 
   /* Remove node from symbol table.  This function is not used directly, but via
      cgraph/varpool node removal routines.  */
-  void unregister (void);
+  void unregister (struct clone_info *);
 
   /* Return the initialization and finalization priority information for
      DECL.  If there is no previous priority information, a freshly
@@ -949,7 +949,7 @@ struct GTY((tag ("SYMTAB_FUNCTION"))) cgraph_node : public symtab_node
 
   /* cgraph node being removed from symbol table; see if its entry can be
    replaced by other inline clone.  */
-  cgraph_node *find_replacement (void);
+  cgraph_node *find_replacement (struct clone_info *);
 
   /* Create a new cgraph node which is the new version of
      callgraph node.  REDIRECT_CALLERS holds the callers
index 36ca6477139881eb0ff2fffe5f2d229fea4467a5..bc590819f78599e079dabcf3fa45c4efe6ad5acc 100644 (file)
@@ -648,9 +648,10 @@ cgraph_node::create_virtual_clone (vec<cgraph_edge *> redirect_callers,
 }
 
 /* callgraph node being removed from symbol table; see if its entry can be
-   replaced by other inline clone.  */
+   replaced by other inline clone. 
+   INFO is clone info to attach to the new root.  */
 cgraph_node *
-cgraph_node::find_replacement (void)
+cgraph_node::find_replacement (clone_info *info)
 {
   cgraph_node *next_inline_clone, *replacement;
 
@@ -690,7 +691,6 @@ cgraph_node::find_replacement (void)
       clones = NULL;
 
       /* Copy clone info.  */
-      clone_info *info = clone_info::get (this);
       if (info)
        *clone_info::get_create (next_inline_clone) = *info;
 
index 76b86c6496f6e05a42c5ae460463928890c74c8c..ad154f6522d6ef17a78e6e3b16bb588d5dc68b7e 100644 (file)
@@ -42,22 +42,8 @@ class GTY((user)) clone_infos_t: public function_summary <clone_info *>
 public:
   clone_infos_t (symbol_table *table, bool ggc):
     function_summary<clone_info *> (table, ggc) { }
-
-  /* Hook that is called by summary when a node is duplicated.  */
-  virtual void duplicate (cgraph_node *node,
-                         cgraph_node *node2,
-                         clone_info *data,
-                         clone_info *data2);
 };
 
-/* Duplication hook.  */
-void
-clone_infos_t::duplicate (cgraph_node *, cgraph_node *,
-                         clone_info *src, clone_info *dst)
-{
-  *dst = *src;
-}
-
 }  /* anon namespace  */
 
 /* Return thunk_info possibly creating new one.  */
@@ -67,8 +53,8 @@ clone_info::get_create (cgraph_node *node)
   if (!symtab->m_clones)
     {
       symtab->m_clones
-        = new (ggc_alloc_no_dtor <clone_infos_t> ())
-            clone_infos_t (symtab, true);
+        = new (ggc_alloc_no_dtor <function_summary <clone_info *>> ())
+            function_summary <clone_info *> (symtab, true);
       symtab->m_clones->disable_insertion_hook ();
       symtab->m_clones->disable_duplication_hook ();
     }
index 9db88fa8531d4946cf17f5c2cb07ebd8ddb64865..8ce1c0635664b0167c9feb7f56522046caaf0125 100644 (file)
@@ -408,10 +408,11 @@ symtab_node::remove_from_same_comdat_group (void)
 }
 
 /* Remove node from symbol table.  This function is not used directly, but via
-   cgraph/varpool node removal routines.  */
+   cgraph/varpool node removal routines.
+   INFO is a clone info to attach to new root of clone tree (if any).  */
 
 void
-symtab_node::unregister (void)
+symtab_node::unregister (clone_info *info)
 {
   remove_all_references ();
   remove_all_referring ();
@@ -430,7 +431,7 @@ symtab_node::unregister (void)
     {
       symtab_node *replacement_node = NULL;
       if (cgraph_node *cnode = dyn_cast <cgraph_node *> (this))
-       replacement_node = cnode->find_replacement ();
+       replacement_node = cnode->find_replacement (info);
       decl->decl_with_vis.symtab_node = replacement_node;
     }
   if (!is_a <varpool_node *> (this) || !DECL_HARD_REGISTER (decl))
index 31ea2132331b2f9695e0b7f85efa0ec1ce04a04e..dc04d10cd422e37620c63be19c3083bdd92e96c8 100644 (file)
@@ -186,7 +186,7 @@ varpool_node::remove (void)
           && !ctor_useable_for_folding_p ())
     remove_initializer ();
 
-  unregister ();
+  unregister (NULL);
   ggc_free (this);
 }