* Fix copying of clone_info while reshaping clone tree
@ 2020-11-03 23:23 Jan Hubicka
0 siblings, 0 replies; only message in thread
From: Jan Hubicka @ 2020-11-03 23:23 UTC (permalink / raw)
To: gcc-patches
Hi,
this patch fixes somewhat ugly issue with clone info getting lost when
root of clone tree is removed. That code is quite old and probably
should go away - i will look on that incrementally.
Honza
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/testsuite/ChangeLog:
2020-11-04 Jan Hubicka <hubicka@ucw.cz>
* gcc.c-torture/execute/pr97695.c: New test.
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index 36bdb009bf8..19dfe2be23b 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -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)
diff --git a/gcc/cgraph.h b/gcc/cgraph.h
index cd22676ff9e..c87180f1e96 100644
--- a/gcc/cgraph.h
+++ b/gcc/cgraph.h
@@ -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
diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c
index 36ca6477139..bc590819f78 100644
--- a/gcc/cgraphclones.c
+++ b/gcc/cgraphclones.c
@@ -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;
diff --git a/gcc/symtab-clones.cc b/gcc/symtab-clones.cc
index 76b86c6496f..ad154f6522d 100644
--- a/gcc/symtab-clones.cc
+++ b/gcc/symtab-clones.cc
@@ -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 ();
}
diff --git a/gcc/symtab.c b/gcc/symtab.c
index 9db88fa8531..8ce1c063566 100644
--- a/gcc/symtab.c
+++ b/gcc/symtab.c
@@ -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))
diff --git a/gcc/testsuite/gcc.c-torture/execute/pr97695.c b/gcc/testsuite/gcc.c-torture/execute/pr97695.c
new file mode 100644
index 00000000000..36f48b4140c
--- /dev/null
+++ b/gcc/testsuite/gcc.c-torture/execute/pr97695.c
@@ -0,0 +1,20 @@
+int *a, b, **c = &a, d, e;
+
+int f(int g, int h) { return !h || (g && h == 1) ? 0 : g / h; }
+
+static void *i(int g) {
+ while (e < 2)
+ if (!f(g, 9)) {
+ while (b)
+ ;
+ return 0;
+ }
+ return 0;
+}
+
+void j() {
+ i(1);
+ *c = i(d);
+}
+
+int main() { j(); return 0; }
diff --git a/gcc/varpool.c b/gcc/varpool.c
index 31ea2132331..dc04d10cd42 100644
--- a/gcc/varpool.c
+++ b/gcc/varpool.c
@@ -186,7 +186,7 @@ varpool_node::remove (void)
&& !ctor_useable_for_folding_p ())
remove_initializer ();
- unregister ();
+ unregister (NULL);
ggc_free (this);
}
^ permalink raw reply [flat|nested] only message in thread
only message in thread, other threads:[~2020-11-03 23:23 UTC | newest]
Thread overview: (only message) (download: mbox.gz / follow: Atom feed)
-- links below jump to the message on this page --
2020-11-03 23:23 Fix copying of clone_info while reshaping clone tree Jan Hubicka
This is a public inbox, see mirroring instructions
for how to clone and mirror all data and code used for this inbox;
as well as URLs for read-only IMAP folder(s) and NNTP newsgroup(s).