From patchwork Fri Jun 27 10:05:47 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: 364857 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 4358C1400D2 for ; Fri, 27 Jun 2014 20:06:01 +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:subject:content-type; q= dns; s=default; b=J9QMArGT633+D8bKB604nW5ODX+dhuytgE7lg5GeXuDXQP u+aGd/gxZEEnc9d+zXRnhRQdJo4W43G015X3ppGcUph2b1nbyx5F/DML9iSh7OUW K10T00JqJRSGuPzBBLaMnuYc8c7GeTG4p0Fq7pM1kuUEYDKUyYMC1tZgK+G4c= 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:subject:content-type; s= default; bh=RAwoUXIVHLqFjdRT2LbVnRu+Fqs=; b=bbzabZXm8TovHEvfAvhW e69VvONtRTJB3uZc3TjPeW4FhXbvkjx5noG14cYKklFm0XyCJi0GFtJLWzNqDj/S +3kR0dpz7Hoy33B1hoVEU8IKZ2gjbtILaVCvIXMMDakZBOSQYgUZoHoLpwx59CSl bUdRLY6IqNBOK0evXVF5Pgs= Received: (qmail 12749 invoked by alias); 27 Jun 2014 10:05:54 -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 12740 invoked by uid 89); 27 Jun 2014 10:05:53 -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; Fri, 27 Jun 2014 10:05:51 +0000 Received: from relay1.suse.de (charybdis-ext.suse.de [195.135.220.254]) by mx2.suse.de (Postfix) with ESMTP id 8C000AC93 for ; Fri, 27 Jun 2014 10:05:48 +0000 (UTC) Message-ID: <53AD41FB.3040409@suse.cz> Date: Fri, 27 Jun 2014 12:05:47 +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: GCC Patches Subject: [PATCH] IPA REF: alias refactoring X-IsSubscribed: yes 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. * 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. diff --git a/gcc/cgraph.c b/gcc/cgraph.c index 7360f77..568eb45 100644 --- a/gcc/cgraph.c +++ b/gcc/cgraph.c @@ -2194,8 +2194,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; @@ -2206,16 +2205,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; } @@ -2229,21 +2228,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 76b2fda1..b0478cb 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..8df6b81 100644 --- a/gcc/ipa-ref.c +++ b/gcc/ipa-ref.c @@ -38,12 +38,23 @@ ipa_ref::remove_reference () struct ipa_ref *last; gcc_assert (list->referring[referred_index] == this); + last = list->referring.last (); if (this != last) { + /* 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 (); + + if (last_alias && referred_index < last_alias->referred_index) + { + list->referring[referred_index] = last_alias; + list->referring[referred_index]->referred_index = referred_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 (); diff --git a/gcc/ipa-ref.h b/gcc/ipa-ref.h index d2de006..65f1f30 100644 --- a/gcc/ipa-ref.h +++ b/gcc/ipa-ref.h @@ -82,6 +82,26 @@ public: return referring[0]; } + /* Return first referring alias. */ + struct ipa_ref *first_referring_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_referring_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]; + } + /* 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..fd83604 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 put 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; }