From patchwork Tue Nov 3 23:23:19 2020 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 1393505 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Authentication-Results: ozlabs.org; spf=pass (sender SPF authorized) smtp.mailfrom=gcc.gnu.org (client-ip=8.43.85.97; helo=sourceware.org; envelope-from=gcc-patches-bounces@gcc.gnu.org; receiver=) Authentication-Results: ozlabs.org; dmarc=none (p=none dis=none) header.from=ucw.cz Received: from sourceware.org (server2.sourceware.org [8.43.85.97]) (using TLSv1.3 with cipher TLS_AES_256_GCM_SHA384 (256/256 bits) key-exchange X25519 server-signature RSA-PSS (4096 bits) server-digest SHA256) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 4CQm742Nqnz9sT6 for ; Wed, 4 Nov 2020 10:23:28 +1100 (AEDT) Received: from server2.sourceware.org (localhost [IPv6:::1]) by sourceware.org (Postfix) with ESMTP id 82AFB3987848; Tue, 3 Nov 2020 23:23:26 +0000 (GMT) X-Original-To: gcc-patches@gcc.gnu.org Delivered-To: gcc-patches@gcc.gnu.org Received: from nikam.ms.mff.cuni.cz (nikam.ms.mff.cuni.cz [195.113.20.16]) by sourceware.org (Postfix) with ESMTPS id 1CDB9386EC33 for ; Tue, 3 Nov 2020 23:23:23 +0000 (GMT) DMARC-Filter: OpenDMARC Filter v1.3.2 sourceware.org 1CDB9386EC33 Authentication-Results: sourceware.org; dmarc=none (p=none dis=none) header.from=ucw.cz Authentication-Results: sourceware.org; spf=none smtp.mailfrom=hubicka@kam.mff.cuni.cz Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id C8B6B282598; Wed, 4 Nov 2020 00:23:19 +0100 (CET) Date: Wed, 4 Nov 2020 00:23:19 +0100 From: Jan Hubicka To: gcc-patches@gcc.gnu.org Subject: Fix copying of clone_info while reshaping clone tree Message-ID: <20201103232319.GA76943@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.10.1 (2018-07-13) X-Spam-Status: No, score=-15.6 required=5.0 tests=BAYES_00, GIT_PATCH_0, HEADER_FROM_DIFFERENT_DOMAINS, KAM_DMARC_STATUS, KAM_LAZY_DOMAIN_SECURITY, RCVD_IN_MSPIKE_H3, RCVD_IN_MSPIKE_WL, SPF_HELO_NONE, SPF_NONE, TXREP autolearn=ham autolearn_force=no version=3.4.2 X-Spam-Checker-Version: SpamAssassin 3.4.2 (2018-09-13) on server2.sourceware.org X-BeenThere: gcc-patches@gcc.gnu.org X-Mailman-Version: 2.1.29 Precedence: list List-Id: Gcc-patches mailing list List-Unsubscribe: , List-Archive: List-Post: List-Help: List-Subscribe: , Errors-To: gcc-patches-bounces@gcc.gnu.org Sender: "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 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 * 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 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 public: clone_infos_t (symbol_table *table, bool ggc): function_summary (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 (symtab, true); + = new (ggc_alloc_no_dtor > ()) + function_summary (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 (this)) - replacement_node = cnode->find_replacement (); + replacement_node = cnode->find_replacement (info); decl->decl_with_vis.symtab_node = replacement_node; } if (!is_a (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); }