From patchwork Fri Jan 17 17:19:03 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Martin Jambor X-Patchwork-Id: 312156 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) (using TLSv1.2 with cipher ECDHE-RSA-AES256-GCM-SHA384 (256/256 bits)) (No client certificate requested) by ozlabs.org (Postfix) with ESMTPS id 327B52C0098 for ; Sat, 18 Jan 2014 04:19:14 +1100 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; q=dns; s=default; b=LfUTlqmHomc6jgbod5rwDcSlbhGsdLKwXWj5LvAm6a6xs2cpHj iWJ5Zn9JvZF2pSeZu0+2T0cGLuk3P85WaKxiat5pwR7aHVprgc6lDyVAt+MEFTjS UqazXcQGgylSgedv0VfpdObTUpcY2MI1QSloh6rwLyPKWLt4Yh2W1RRdA= DKIM-Signature: v=1; a=rsa-sha1; c=relaxed; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender:date :from:to:cc:subject:message-id:mime-version:content-type; s= default; bh=8IyCLxgKKiFBNW+RBJRsPMADBcY=; b=pZe6FYPhK0hCSY/gzuWs DlxZ0O6HiSidrGd+FwZQLW/ZB6vyR1BZ4t//wC6VFJFzRVF5eLE+U+4GEm2TKjMF 58wm5JzsxCzitcQ1k5xfLFxBp/IUzEF9leo0NrUduOpVPwk4UkImrk8uAx4F60zC qlK9wVUX2yTm3Q/VF2cNZLs= Received: (qmail 10744 invoked by alias); 17 Jan 2014 17:19:07 -0000 Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org Received: (qmail 10733 invoked by uid 89); 17 Jan 2014 17:19:07 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-3.2 required=5.0 tests=AWL, BAYES_00 autolearn=ham version=3.3.2 X-HELO: mx2.suse.de Received: from cantor2.suse.de (HELO mx2.suse.de) (195.135.220.15) by sourceware.org (qpsmtpd/0.93/v0.84-503-g423c35a) with (CAMELLIA256-SHA encrypted) ESMTPS; Fri, 17 Jan 2014 17:19:06 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 92077AC64; Fri, 17 Jan 2014 17:19:03 +0000 (UTC) Date: Fri, 17 Jan 2014 18:19:03 +0100 From: Martin Jambor To: GCC Patches Cc: Jan Hubicka Subject: [PATCH, PR 59736] Fix an IPA-CP issue with de-speculation Message-ID: <20140117171902.GJ23848@virgil.suse> Mail-Followup-To: GCC Patches , Jan Hubicka MIME-Version: 1.0 Content-Disposition: inline User-Agent: Mutt/1.5.21 (2010-09-15) X-IsSubscribed: yes Hi, in PR 59736, IPA-CP stumples on an already removed call graph edge. The reason is that it keeps an internal linked list of edge clones which can however now be corrupted by cgraph de-speculation machinery which can decide to remove an edge. In order to fix this, I made the linked-list bi-directional and added a remove hook that fixes it up if need be. Bootstrapped and tedted on x86_64-linux. Unfortunately, I don't have a simple testcase (the smallest I have is a 8.3K multidetla reduced mess). OK for trunk anyway? Thanks, Martin 2014-01-17 Martin Jambor PR ipa/59736 * ipa-cp.c (prev_edge_clone): New variable. (grow_next_edge_clone_vector): Renamed to grow_edge_clone_vectors. Also resize prev_edge_clone vector. (ipcp_edge_duplication_hook): Also update prev_edge_clone. (ipcp_edge_removal_hook): New function. (ipcp_driver): Register ipcp_edge_removal_hook. diff --git a/gcc/ipa-cp.c b/gcc/ipa-cp.c index a6a44e6..10fa4b6 100644 --- a/gcc/ipa-cp.c +++ b/gcc/ipa-cp.c @@ -2321,13 +2321,17 @@ ipcp_discover_new_direct_edges (struct cgraph_node *node, edge. */ static vec next_edge_clone; +static vec prev_edge_clone; static inline void -grow_next_edge_clone_vector (void) +grow_edge_clone_vectors (void) { if (next_edge_clone.length () <= (unsigned) cgraph_edge_max_uid) next_edge_clone.safe_grow_cleared (cgraph_edge_max_uid + 1); + if (prev_edge_clone.length () + <= (unsigned) cgraph_edge_max_uid) + prev_edge_clone.safe_grow_cleared (cgraph_edge_max_uid + 1); } /* Edge duplication hook to grow the appropriate linked list in @@ -2335,13 +2339,34 @@ grow_next_edge_clone_vector (void) static void ipcp_edge_duplication_hook (struct cgraph_edge *src, struct cgraph_edge *dst, - __attribute__((unused)) void *data) + void *) { - grow_next_edge_clone_vector (); - next_edge_clone[dst->uid] = next_edge_clone[src->uid]; + grow_edge_clone_vectors (); + + struct cgraph_edge *old_next = next_edge_clone[src->uid]; + if (old_next) + prev_edge_clone[old_next->uid] = dst; + prev_edge_clone[dst->uid] = src; + + next_edge_clone[dst->uid] = old_next; next_edge_clone[src->uid] = dst; } +/* Hook that is called by cgraph.c when an edge is removed. */ + +static void +ipcp_edge_removal_hook (struct cgraph_edge *cs, void *) +{ + grow_edge_clone_vectors (); + + struct cgraph_edge *prev = prev_edge_clone[cs->uid]; + struct cgraph_edge *next = next_edge_clone[cs->uid]; + if (prev) + next_edge_clone[prev->uid] = next; + if (next) + prev_edge_clone[next->uid] = prev; +} + /* See if NODE is a clone with a known aggregate value at a given OFFSET of a parameter with the given INDEX. */ @@ -3568,13 +3593,17 @@ static unsigned int ipcp_driver (void) { struct cgraph_2edge_hook_list *edge_duplication_hook_holder; + struct cgraph_edge_hook_list *edge_removal_hook_holder; struct topo_info topo; ipa_check_create_node_params (); ipa_check_create_edge_args (); - grow_next_edge_clone_vector (); + grow_edge_clone_vectors (); edge_duplication_hook_holder = cgraph_add_edge_duplication_hook (&ipcp_edge_duplication_hook, NULL); + edge_removal_hook_holder = + cgraph_add_edge_removal_hook (&ipcp_edge_removal_hook, NULL); + ipcp_values_pool = create_alloc_pool ("IPA-CP values", sizeof (struct ipcp_value), 32); ipcp_sources_pool = create_alloc_pool ("IPA-CP value sources", @@ -3600,6 +3629,7 @@ ipcp_driver (void) /* Free all IPCP structures. */ free_toporder_info (&topo); next_edge_clone.release (); + cgraph_remove_edge_removal_hook (edge_removal_hook_holder); cgraph_remove_edge_duplication_hook (edge_duplication_hook_holder); ipa_free_all_structures_after_ipa_cp (); if (dump_file)