From patchwork Mon Jun 30 21:17:27 2014 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: =?utf-8?q?Martin_Li=C5=A1ka?= X-Patchwork-Id: 365744 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 D85651400B5 for ; Tue, 1 Jul 2014 07:17:45 +1000 (EST) DomainKey-Signature: a=rsa-sha1; c=nofws; d=gcc.gnu.org; h=list-id :list-unsubscribe:list-archive:list-post:list-help:sender :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; q=dns; s=default; b=JrGyYHhnMRYU+Q8T3 RKGM7SyMUdxKZtePw6ijvOUIYk7F09sg5uaGlAhUmkwxYCc4Nk7AZVMpgtlO+rIY EPkZPN3azC9lSPEYarmHeq1cVIt7IQljeMEvtO2XsfCAuyoeMOukv5ipXAWiY8gT 9rKAgIJaN3isUFi4ZgLKagyU+c= 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 :message-id:date:from:mime-version:to:cc:subject:references :in-reply-to:content-type; s=default; bh=Fgrdt/AnTIJyRBK4AunUZe7 AtPo=; b=fo7yGCJPMCnSBvNQX74ilhspANASHArhRJ/wWI6zwgCDp+Ba5HTWfkr LjnVd6X+qbhwUd6qJPpD7djUGxnFvBIvlDWPa4D3i+1wlJiV78yczRkw5qXAcAww qa9dk5yj5lkXvMYNafpfhzOct2JfxlKAhAdiENkNGwtM8/zRr7r8= Received: (qmail 27585 invoked by alias); 30 Jun 2014 21:17:38 -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 27562 invoked by uid 89); 30 Jun 2014 21:17:37 -0000 Authentication-Results: sourceware.org; auth=none X-Virus-Found: No X-Spam-SWARE-Status: No, score=-0.8 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; Mon, 30 Jun 2014 21:17:31 +0000 Received: from relay2.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 4AA0DACC1; Mon, 30 Jun 2014 21:17:28 +0000 (UTC) Message-ID: <53B1D3E7.30508@suse.cz> Date: Mon, 30 Jun 2014 23:17:27 +0200 From: =?windows-1252?Q?Martin_Li=9Aka?= User-Agent: Mozilla/5.0 (X11; Linux x86_64; rv:24.0) Gecko/20100101 Thunderbird/24.5.0 MIME-Version: 1.0 To: Jan Hubicka CC: GCC Patches Subject: Re: [PATCH] IPA REF: alias refactoring References: <53AD41FB.3040409@suse.cz> <20140628064954.GB20144@atrey.karlin.mff.cuni.cz> In-Reply-To: <20140628064954.GB20144@atrey.karlin.mff.cuni.cz> X-IsSubscribed: yes On 06/28/2014 08:49 AM, Jan Hubicka wrote: >> Hi, >> this patch enhances alias manipulation for symtab_node. Honza suggested following changes. >> >> Patch is pre approved, will be committed if no comments and regressions. >> Bootstrapped on x86_64-pc-linux-gnu, regression tests have been running. >> >> Thanks, >> Martin >> >> gcc/ChangeLog: >> >> * cgraph.h (iterate_direct_aliases): New function. >> (FOR_EACH_ALIAS): New macro iterates all direct aliases for a node. >> * cgraph.c (cgraph_for_node_thunks_and_aliases): Usage of >> FOR_EACH_ALIAS added. >> (cgraph_for_node_and_aliases): Likewise. >> * cgraphunit.c (assemble_thunks_and_aliases): Likewise. >> * ipa-inline.c (reset_edge_caches): Likewise. >> (update_caller_keys): Likewise. >> * trans-mem.c (ipa_tm_execute): Likewise. >> *varpool.c (varpool_analyze_node): Likewise. >> (varpool_for_node_and_aliases): Likewise. >> * ipa-ref.h (first_referring_alias): New function. >> (last_referring_alias): Likewise. > I missed it last time around, I think first_alias/last_alias are better names. > first_alias is unused. If you added it I guess FOR_EACH_ALIAS should use it. Hello, I renamed these functions as you suggested and has_aliases_p predication was also added. Previous patch has an error in ipa_ref::remove_refence, this patch has been regtested and the problem is removed. > > We probably also can bring has_aliases_p inline and implement it using > first_referring_alias. > >> + /* If deleted item is IPA_REF_ALIAS, we have to move last >> + item of IPA_REF_LIST type to the deleted position. After that >> + we replace last node with deletion slot. */ >> + struct ipa_ref *last_alias = list->last_referring_alias (); > You can avoid walking to last alias when the removed item is not IPA_REF_ALIAS. > >> + >> + /* IPA_REF_ALIAS is always put at the beginning of the list. */ > inserted? Type fixed. If no other comments will come, I consider the patch as preapproved. Thanks, Martin gcc/ChangeLog: * cgraph.h (iterate_direct_aliases): New function. (FOR_EACH_ALIAS): New macro iterates all direct aliases for a node. * cgraph.c (cgraph_for_node_thunks_and_aliases): Usage of FOR_EACH_ALIAS added. (cgraph_for_node_and_aliases): Likewise. * cgraphunit.c (assemble_thunks_and_aliases): Likewise. * ipa-inline.c (reset_edge_caches): Likewise. (update_caller_keys): Likewise. * trans-mem.c (ipa_tm_execute): Likewise. *varpool.c (varpool_analyze_node): Likewise. (varpool_for_node_and_aliases): Likewise. * ipa-ref.h (first_alias): New function. (last_alias): Likewise. (has_aliases_p): Likewise. * ipa-ref.c (ipa_ref::remove_reference): Removal function is sensitive to IPA_REF_ALIASes. * symtab.c (symtab_node::add_reference): Node of IPA_REF_ALIAS type are put at the beginning of the list. (symtab_node::iterate_direct_aliases): New function. gcc/lto/ChangeLog: * lto-partition.c (add_symbol_to_partition_1): Usage of FOR_EACH_ALIAS added. > > OK with these changes (or if you already comitted, just do them incrementally) > > Honza diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 43428be..41dcaf9 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -2198,8 +2198,7 @@ cgraph_for_node_thunks_and_aliases (struct cgraph_node *node, bool include_overwritable) { struct cgraph_edge *e; - int i; - struct ipa_ref *ref = NULL; + struct ipa_ref *ref; if (callback (node, data)) return true; @@ -2210,16 +2209,16 @@ cgraph_for_node_thunks_and_aliases (struct cgraph_node *node, if (cgraph_for_node_thunks_and_aliases (e->caller, callback, data, include_overwritable)) return true; - for (i = 0; node->iterate_referring (i, ref); i++) - if (ref->use == IPA_REF_ALIAS) - { - struct cgraph_node *alias = dyn_cast (ref->referring); - if (include_overwritable - || cgraph_function_body_availability (alias) > AVAIL_OVERWRITABLE) - if (cgraph_for_node_thunks_and_aliases (alias, callback, data, - include_overwritable)) - return true; - } + + FOR_EACH_ALIAS (node, ref) + { + struct cgraph_node *alias = dyn_cast (ref->referring); + if (include_overwritable + || cgraph_function_body_availability (alias) > AVAIL_OVERWRITABLE) + if (cgraph_for_node_thunks_and_aliases (alias, callback, data, + include_overwritable)) + return true; + } return false; } @@ -2233,21 +2232,20 @@ cgraph_for_node_and_aliases (struct cgraph_node *node, void *data, bool include_overwritable) { - int i; - struct ipa_ref *ref = NULL; + struct ipa_ref *ref; if (callback (node, data)) return true; - for (i = 0; node->iterate_referring (i, ref); i++) - if (ref->use == IPA_REF_ALIAS) - { - struct cgraph_node *alias = dyn_cast (ref->referring); - if (include_overwritable - || cgraph_function_body_availability (alias) > AVAIL_OVERWRITABLE) - if (cgraph_for_node_and_aliases (alias, callback, data, - include_overwritable)) - return true; - } + + FOR_EACH_ALIAS (node, ref) + { + struct cgraph_node *alias = dyn_cast (ref->referring); + if (include_overwritable + || cgraph_function_body_availability (alias) > AVAIL_OVERWRITABLE) + if (cgraph_for_node_and_aliases (alias, callback, data, + include_overwritable)) + return true; + } return false; } diff --git a/gcc/cgraph.h b/gcc/cgraph.h index 0761e26..3ab0516 100644 --- a/gcc/cgraph.h +++ b/gcc/cgraph.h @@ -254,6 +254,9 @@ public: /* Iterates I-th referring item in the list, REF is also set. */ struct ipa_ref *iterate_referring (unsigned i, struct ipa_ref *&ref); + /* Iterates I-th referring alias item in the list, REF is also set. */ + struct ipa_ref *iterate_direct_aliases (unsigned i, struct ipa_ref *&ref); + /* Vectors of referring and referenced entities. */ struct ipa_ref_list ref_list; @@ -281,6 +284,10 @@ public: priority_type get_init_priority (); }; +/* Walk all aliases for NODE. */ +#define FOR_EACH_ALIAS(node, alias) \ + for (unsigned x_i = 0; node->iterate_direct_aliases (x_i, alias); x_i++) + enum availability { /* Not yet set by cgraph_function_body_availability. */ diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c index d7e8038..f7980ed 100644 --- a/gcc/cgraphunit.c +++ b/gcc/cgraphunit.c @@ -1711,8 +1711,7 @@ static void assemble_thunks_and_aliases (struct cgraph_node *node) { struct cgraph_edge *e; - int i; - struct ipa_ref *ref = NULL; + struct ipa_ref *ref; for (e = node->callers; e;) if (e->caller->thunk.thunk_p) @@ -1725,20 +1724,20 @@ assemble_thunks_and_aliases (struct cgraph_node *node) } else e = e->next_caller; - for (i = 0; node->iterate_referring (i, ref); i++) - if (ref->use == IPA_REF_ALIAS) - { - struct cgraph_node *alias = dyn_cast (ref->referring); - bool saved_written = TREE_ASM_WRITTEN (node->decl); - - /* Force assemble_alias to really output the alias this time instead - of buffering it in same alias pairs. */ - TREE_ASM_WRITTEN (node->decl) = 1; - do_assemble_alias (alias->decl, - DECL_ASSEMBLER_NAME (node->decl)); - assemble_thunks_and_aliases (alias); - TREE_ASM_WRITTEN (node->decl) = saved_written; - } + + FOR_EACH_ALIAS (node, ref) + { + struct cgraph_node *alias = dyn_cast (ref->referring); + bool saved_written = TREE_ASM_WRITTEN (node->decl); + + /* Force assemble_alias to really output the alias this time instead + of buffering it in same alias pairs. */ + TREE_ASM_WRITTEN (node->decl) = 1; + do_assemble_alias (alias->decl, + DECL_ASSEMBLER_NAME (node->decl)); + assemble_thunks_and_aliases (alias); + TREE_ASM_WRITTEN (node->decl) = saved_written; + } } /* Expand function specified by NODE. */ diff --git a/gcc/ipa-inline.c b/gcc/ipa-inline.c index 81030f3..c4095ec 100644 --- a/gcc/ipa-inline.c +++ b/gcc/ipa-inline.c @@ -1119,8 +1119,7 @@ reset_edge_caches (struct cgraph_node *node) struct cgraph_edge *edge; struct cgraph_edge *e = node->callees; struct cgraph_node *where = node; - int i; - struct ipa_ref *ref = NULL; + struct ipa_ref *ref; if (where->global.inlined_to) where = where->global.inlined_to; @@ -1131,9 +1130,9 @@ reset_edge_caches (struct cgraph_node *node) for (edge = where->callers; edge; edge = edge->next_caller) if (edge->inline_failed) reset_edge_growth_cache (edge); - for (i = 0; where->iterate_referring (i, ref); i++) - if (ref->use == IPA_REF_ALIAS) - reset_edge_caches (dyn_cast (ref->referring)); + + FOR_EACH_ALIAS (where, ref) + reset_edge_caches (dyn_cast (ref->referring)); if (!e) return; @@ -1172,8 +1171,7 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, struct cgraph_edge *check_inlinablity_for) { struct cgraph_edge *edge; - int i; - struct ipa_ref *ref = NULL; + struct ipa_ref *ref; if ((!node->alias && !inline_summary (node)->inlinable) || node->global.inlined_to) @@ -1181,12 +1179,11 @@ update_caller_keys (fibheap_t heap, struct cgraph_node *node, if (!bitmap_set_bit (updated_nodes, node->uid)) return; - for (i = 0; node->iterate_referring (i, ref); i++) - if (ref->use == IPA_REF_ALIAS) - { - struct cgraph_node *alias = dyn_cast (ref->referring); - update_caller_keys (heap, alias, updated_nodes, check_inlinablity_for); - } + FOR_EACH_ALIAS (node, ref) + { + struct cgraph_node *alias = dyn_cast (ref->referring); + update_caller_keys (heap, alias, updated_nodes, check_inlinablity_for); + } for (edge = node->callers; edge; edge = edge->next_caller) if (edge->inline_failed) diff --git a/gcc/ipa-ref.c b/gcc/ipa-ref.c index 1be173a..3c10011 100644 --- a/gcc/ipa-ref.c +++ b/gcc/ipa-ref.c @@ -38,12 +38,33 @@ ipa_ref::remove_reference () struct ipa_ref *last; gcc_assert (list->referring[referred_index] == this); + last = list->referring.last (); if (this != last) { + if (use == IPA_REF_ALIAS) + { + /* If deleted item is IPA_REF_ALIAS, we have to move last + item of IPA_REF_LIST type to the deleted position. After that + we replace last node with deletion slot. */ + struct ipa_ref *last_alias = list->last_alias (); + + if (last_alias && referred_index < last_alias->referred_index + && last_alias != last) + { + unsigned last_alias_index = last_alias->referred_index; + + list->referring[referred_index] = last_alias; + list->referring[referred_index]->referred_index = referred_index; + + /* New position for replacement is previous index + of the last_alias. */ + referred_index = last_alias_index; + } + } + list->referring[referred_index] = list->referring.last (); - list->referring[referred_index]->referred_index - = referred_index; + list->referring[referred_index]->referred_index= referred_index; } list->referring.pop (); @@ -54,7 +75,7 @@ ipa_ref::remove_reference () if (ref != last) { *ref = *last; - referred_ref_list ()->referring[referred_index] = ref; + ref->referred_ref_list ()->referring[referred_index] = ref; } list2->references->pop (); gcc_assert (list2->references == old_references); diff --git a/gcc/ipa-ref.h b/gcc/ipa-ref.h index d2de006..b8b1f9e 100644 --- a/gcc/ipa-ref.h +++ b/gcc/ipa-ref.h @@ -82,6 +82,32 @@ public: return referring[0]; } + /* Return first referring alias. */ + struct ipa_ref *first_alias (void) + { + struct ipa_ref *r = first_referring (); + + return r && r->use == IPA_REF_ALIAS ? r : NULL; + } + + /* Return last referring alias. */ + struct ipa_ref *last_alias (void) + { + unsigned int i = 0; + + for(i = 0; i < referring.length (); i++) + if (referring[i]->use != IPA_REF_ALIAS) + break; + + return i == 0 ? NULL : referring[i - 1]; + } + + /* Return true if the symbol has an alias. */ + bool inline has_aliases_p (void) + { + return first_alias (); + } + /* Clear reference list. */ void clear (void) { diff --git a/gcc/lto/lto-partition.c b/gcc/lto/lto-partition.c index 4d19ef6..944943c 100644 --- a/gcc/lto/lto-partition.c +++ b/gcc/lto/lto-partition.c @@ -113,8 +113,7 @@ static bool add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node) { enum symbol_partitioning_class c = symtab_get_symbol_partitioning_class (node); - int i; - struct ipa_ref *ref = NULL; + struct ipa_ref *ref; symtab_node *node1; /* If NODE is already there, we have nothing to do. */ @@ -168,8 +167,9 @@ add_symbol_to_partition_1 (ltrans_partition part, symtab_node *node) add_references_to_partition (part, node); /* Add all aliases associated with the symbol. */ - for (i = 0; node->iterate_referring (i, ref); i++) - if (ref->use == IPA_REF_ALIAS && !node->weakref) + + FOR_EACH_ALIAS (node, ref) + if (!node->weakref) add_symbol_to_partition_1 (part, ref->referring); /* Ensure that SAME_COMDAT_GROUP lists all allways added in a group. */ diff --git a/gcc/symtab.c b/gcc/symtab.c index 89591ee..80ea94a 100644 --- a/gcc/symtab.c +++ b/gcc/symtab.c @@ -558,8 +558,22 @@ symtab_node::add_reference (symtab_node *referred_node, ref = &list->references->last (); list2 = &referred_node->ref_list; - list2->referring.safe_push (ref); - ref->referred_index = list2->referring.length () - 1; + + /* IPA_REF_ALIAS is always inserted at the beginning of the list. */ + if(use_type == IPA_REF_ALIAS) + { + list2->referring.safe_insert (0, ref); + ref->referred_index = 0; + + for (unsigned int i = 1; i < list2->referring.length (); i++) + list2->referring[i]->referred_index = i; + } + else + { + list2->referring.safe_push (ref); + ref->referred_index = list2->referring.length () - 1; + } + ref->referring = this; ref->referred = referred_node; ref->stmt = stmt; @@ -796,6 +810,20 @@ symtab_node::iterate_referring (unsigned i, struct ipa_ref *&ref) return ref; } +/* Iterates I-th referring alias item in the list, REF is also set. */ + +struct ipa_ref * +symtab_node::iterate_direct_aliases (unsigned i, struct ipa_ref *&ref) +{ + ref_list.referring.iterate (i, &ref); + + if (ref && ref->use != IPA_REF_ALIAS) + return NULL; + + return ref; +} + + static const char * const symtab_type_names[] = {"symbol", "function", "variable"}; /* Dump base fields of symtab nodes. Not to be used directly. */ diff --git a/gcc/trans-mem.c b/gcc/trans-mem.c index af8bc09..12c0b35 100644 --- a/gcc/trans-mem.c +++ b/gcc/trans-mem.c @@ -5439,8 +5439,7 @@ ipa_tm_execute (void) { struct cgraph_node *caller; struct cgraph_edge *e; - struct ipa_ref *ref = NULL; - unsigned j; + struct ipa_ref *ref; if (i > 256 && i == irr_worklist.length () / 8) { @@ -5466,11 +5465,10 @@ ipa_tm_execute (void) } /* Propagate back to referring aliases as well. */ - for (j = 0; node->iterate_referring (j, ref); j++) + FOR_EACH_ALIAS (node, ref) { caller = cgraph (ref->referring); - if (ref->use == IPA_REF_ALIAS - && !caller->local.tm_may_enter_irr) + if (!caller->local.tm_may_enter_irr) { /* ?? Do not traverse aliases here. */ d = get_cg_data (&caller, false); diff --git a/gcc/varpool.c b/gcc/varpool.c index 04ac870..79f07bf 100644 --- a/gcc/varpool.c +++ b/gcc/varpool.c @@ -424,17 +424,15 @@ varpool_analyze_node (varpool_node *node) static void assemble_aliases (varpool_node *node) { - int i; - struct ipa_ref *ref = NULL; + struct ipa_ref *ref; - for (i = 0; node->iterate_referring (i, ref); i++) - if (ref->use == IPA_REF_ALIAS) - { - varpool_node *alias = dyn_cast (ref->referring); - do_assemble_alias (alias->decl, - DECL_ASSEMBLER_NAME (node->decl)); - assemble_aliases (alias); - } + FOR_EACH_ALIAS (node, ref) + { + varpool_node *alias = dyn_cast (ref->referring); + do_assemble_alias (alias->decl, + DECL_ASSEMBLER_NAME (node->decl)); + assemble_aliases (alias); + } } /* Output one variable, if necessary. Return whether we output it. */ @@ -694,20 +692,19 @@ varpool_for_node_and_aliases (varpool_node *node, void *data, bool include_overwritable) { - int i; - struct ipa_ref *ref = NULL; + struct ipa_ref *ref; if (callback (node, data)) return true; - for (i = 0; node->iterate_referring (i, ref); i++) - if (ref->use == IPA_REF_ALIAS) - { - varpool_node *alias = dyn_cast (ref->referring); - if (include_overwritable - || cgraph_variable_initializer_availability (alias) > AVAIL_OVERWRITABLE) - if (varpool_for_node_and_aliases (alias, callback, data, - include_overwritable)) - return true; - } + + FOR_EACH_ALIAS (node, ref) + { + varpool_node *alias = dyn_cast (ref->referring); + if (include_overwritable + || cgraph_variable_initializer_availability (alias) > AVAIL_OVERWRITABLE) + if (varpool_for_node_and_aliases (alias, callback, data, + include_overwritable)) + return true; + } return false; }