From d0b1b67aabc2b88b58a7485f79d16f9a6d4dd11c Mon Sep 17 00:00:00 2001 From: Martin Jambor Date: Mon, 25 Nov 2019 11:13:08 +0100 Subject: [PATCH] ipa: Prevent materialization of clones with removed bodies (PR 92109) 2019-11-25 Martin Jambor 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 | 10 ++++++++++ gcc/cgraph.h | 4 ++++ gcc/cgraphclones.c | 35 ++++++++++++++++++++++------------- gcc/ipa.c | 11 ++++++++--- 4 files changed, 44 insertions(+), 16 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index a15cc758e54..5364edc92f6 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,13 @@ +2019-11-25 Martin Jambor + + 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 PR ipa/91956 diff --git a/gcc/cgraph.h b/gcc/cgraph.h index a4f14743f00..0d2442c997c 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -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); diff --git a/gcc/cgraphclones.c b/gcc/cgraphclones.c index bfcebb20495..ac5c57a47aa 100644 --- a/gcc/cgraphclones.c +++ b/gcc/cgraphclones.c @@ -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); } diff --git a/gcc/ipa.c b/gcc/ipa.c index 0c92980db46..2404024d722 100644 --- 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) -- 2.30.2