From patchwork Tue Jul 6 11:55:49 2010 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Jan Hubicka X-Patchwork-Id: 58000 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]) by ozlabs.org (Postfix) with SMTP id 578E5B6EE9 for ; Tue, 6 Jul 2010 21:56:04 +1000 (EST) Received: (qmail 24605 invoked by alias); 6 Jul 2010 11:56:00 -0000 Received: (qmail 24589 invoked by uid 22791); 6 Jul 2010 11:55:58 -0000 X-SWARE-Spam-Status: No, hits=-1.8 required=5.0 tests=AWL, BAYES_00, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from nikam-dmz.ms.mff.cuni.cz (HELO nikam.ms.mff.cuni.cz) (195.113.20.16) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Tue, 06 Jul 2010 11:55:51 +0000 Received: by nikam.ms.mff.cuni.cz (Postfix, from userid 16202) id 731D49AC7C7; Tue, 6 Jul 2010 13:55:49 +0200 (CEST) Date: Tue, 6 Jul 2010 13:55:49 +0200 From: Jan Hubicka To: Richard Guenther Cc: Jan Hubicka , gcc-patches@gcc.gnu.org Subject: Re: lto-symtab and cgraph aliases Message-ID: <20100706115549.GA12425@kam.mff.cuni.cz> References: <20100705195535.GB12132@kam.mff.cuni.cz> MIME-Version: 1.0 Content-Disposition: inline In-Reply-To: User-Agent: Mutt/1.5.18 (2008-05-17) 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 > Changelog is incomplete (missing cgraph.h change). > > Otherwise it makes sense. > > Thanks, > Richard. Must've got incomplette file somehow. This is full version I am re-testing now. OK if it passes? * lto-symtab.c (lto_cgraph_replace_node): Handle aliases. (lto_symtab_resolve_can_prevail_p): Also alias of cgraph node with body can prevail. (lto_symtab_resolve_symbols): Use cgraph_get_node_or_alias. (lto_symtab_merge_cgraph_nodes_1): Do not remove nodes from aliases. * cgraph.c (cgraph_get_node_or_alias): New function. * cgraph.h (cgraph_get_node_or_alias): Declare. Index: lto-symtab.c =================================================================== --- lto-symtab.c (revision 161847) +++ lto-symtab.c (working copy) @@ -206,6 +206,24 @@ lto_cgraph_replace_node (struct cgraph_n struct cgraph_node *prevailing_node) { struct cgraph_edge *e, *next; + bool no_aliases_please = false; + + if (cgraph_dump_file) + { + fprintf (cgraph_dump_file, "Replacing cgraph node %s/%i by %s/%i" + " for symbol %s\n", + cgraph_node_name (node), node->uid, + cgraph_node_name (prevailing_node), + prevailing_node->uid, + IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl))); + } + + if (prevailing_node->same_body_alias) + { + if (prevailing_node->thunk.thunk_p) + no_aliases_please = true; + prevailing_node = prevailing_node->same_body; + } /* Merge node flags. */ if (node->needed) @@ -227,27 +244,37 @@ lto_cgraph_replace_node (struct cgraph_n /* Redirect incomming references. */ ipa_clone_refering (prevailing_node, NULL, &node->ref_list); - if (node->same_body) + /* If we have aliases, redirect them to the prevailing node. */ + if (!node->same_body_alias && node->same_body) { - struct cgraph_node *alias; + struct cgraph_node *alias, *last; + /* We prevail aliases/tunks by a thunk. This is doable but + would need thunk combination. Hopefully no ABI changes will + every be crazy enough. */ + gcc_assert (!no_aliases_please); for (alias = node->same_body; alias; alias = alias->next) - if (DECL_ASSEMBLER_NAME_SET_P (alias->decl)) - { - lto_symtab_entry_t se - = lto_symtab_get (DECL_ASSEMBLER_NAME (alias->decl)); - - for (; se; se = se->next) - if (se->node == node) - { - se->node = NULL; - break; - } - } + { + last = alias; + gcc_assert (alias->same_body_alias); + alias->same_body = prevailing_node; + alias->thunk.alias = prevailing_node->decl; + } + last->next = prevailing_node->same_body; + /* Node with aliases is prevailed by alias. + We could handle this, but combining thunks together will be tricky. + Hopefully this does not happen. */ + if (prevailing_node->same_body) + prevailing_node->same_body->previous = last; + prevailing_node->same_body = node->same_body; + node->same_body = NULL; } /* Finally remove the replaced node. */ - cgraph_remove_node (node); + if (node->same_body_alias) + cgraph_remove_same_body_alias (node); + else + cgraph_remove_node (node); } /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging @@ -433,7 +460,9 @@ lto_symtab_resolve_can_prevail_p (lto_sy /* For functions we need a non-discarded body. */ if (TREE_CODE (e->decl) == FUNCTION_DECL) - return (e->node && e->node->analyzed); + return (e->node + && (e->node->analyzed + || (e->node->same_body_alias && e->node->same_body->analyzed))); /* A variable should have a size. */ else if (TREE_CODE (e->decl) == VAR_DECL) @@ -461,7 +490,7 @@ lto_symtab_resolve_symbols (void **slot) for (e = (lto_symtab_entry_t) *slot; e; e = e->next) { if (TREE_CODE (e->decl) == FUNCTION_DECL) - e->node = cgraph_get_node (e->decl); + e->node = cgraph_get_node_or_alias (e->decl); else if (TREE_CODE (e->decl) == VAR_DECL) { e->vnode = varpool_get_node (e->decl); @@ -751,22 +780,7 @@ lto_symtab_merge_cgraph_nodes_1 (void ** for (e = prevailing->next; e; e = e->next) { if (e->node != NULL) - { - if (e->node->decl != e->decl && e->node->same_body) - { - struct cgraph_node *alias; - - for (alias = e->node->same_body; alias; alias = alias->next) - if (alias->decl == e->decl) - break; - if (alias) - { - cgraph_remove_same_body_alias (alias); - continue; - } - } - lto_cgraph_replace_node (e->node, prevailing->node); - } + lto_cgraph_replace_node (e->node, prevailing->node); if (e->vnode != NULL) lto_varpool_replace_node (e->vnode, prevailing->vnode); } Index: cgraph.c =================================================================== --- cgraph.c (revision 161847) +++ cgraph.c (working copy) @@ -604,6 +604,29 @@ cgraph_add_thunk (tree alias, tree decl, is assigned. */ +/* Returns the cgraph or alias node assigned to DECL or NULL if no cgraph node + is assigned. */ + struct cgraph_node * +cgraph_get_node_or_alias (tree decl) +{ + struct cgraph_node key, *node = NULL, **slot; + + gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); + + if (!cgraph_hash) + return NULL; + + key.decl = decl; + + slot = (struct cgraph_node **) htab_find_slot (cgraph_hash, &key, + NO_INSERT); + + if (slot && *slot) + node = *slot; + return node; +} + +/* Returns the cgraph node assigned to DECL or NULL if no cgraph node + is assigned. */ + +struct cgraph_node * cgraph_get_node (tree decl) { struct cgraph_node key, *node = NULL, **slot; Index: cgraph.h =================================================================== --- cgraph.h (revision 161866) +++ cgraph.h (working copy) @@ -556,6 +560,7 @@ struct cgraph_edge *cgraph_create_edge ( struct cgraph_edge *cgraph_create_indirect_edge (struct cgraph_node *, gimple, int, gcov_type, int, int); struct cgraph_node * cgraph_get_node (tree); +struct cgraph_node * cgraph_get_node_or_alias (tree); struct cgraph_node *cgraph_node (tree); bool cgraph_same_body_alias (tree, tree); void cgraph_add_thunk (tree, tree, bool, HOST_WIDE_INT, HOST_WIDE_INT, tree, tree);