X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Flto-symtab.c;h=3a7c783f770efb3da8aa9facfd9c4ffe3b70f9fb;hb=5d25efc0fd72fef10dbc606561fade95f2c99a88;hp=c86bbcc8a5a20e0a664dcdeaa2ea70029e2fa2d2;hpb=d86d364d2d6e1cb56a043f57dd46d3e076048314;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c index c86bbcc8a5a..3a7c783f770 100644 --- a/gcc/lto-symtab.c +++ b/gcc/lto-symtab.c @@ -25,7 +25,6 @@ along with GCC; see the file COPYING3. If not see #include "tree.h" #include "gimple.h" #include "ggc.h" -#include "lambda.h" /* gcd */ #include "hashtab.h" #include "plugin-api.h" #include "lto-streamer.h" @@ -210,7 +209,6 @@ lto_cgraph_replace_node (struct cgraph_node *node, struct cgraph_node *prevailing_node) { struct cgraph_edge *e, *next; - bool no_aliases_please = false; bool compatible_p; if (cgraph_dump_file) @@ -224,13 +222,6 @@ lto_cgraph_replace_node (struct cgraph_node *node, (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) cgraph_mark_needed_node (prevailing_node); @@ -244,8 +235,8 @@ lto_cgraph_replace_node (struct cgraph_node *node, /* Redirect all incoming edges. */ compatible_p - = gimple_types_compatible_p (TREE_TYPE (TREE_TYPE (prevailing_node->decl)), - TREE_TYPE (TREE_TYPE (node->decl)), GTC_DIAG); + = types_compatible_p (TREE_TYPE (TREE_TYPE (prevailing_node->decl)), + TREE_TYPE (TREE_TYPE (node->decl))); for (e = node->callers; e; e = next) { next = e->next_caller; @@ -260,37 +251,8 @@ lto_cgraph_replace_node (struct cgraph_node *node, /* Redirect incomming references. */ ipa_clone_refering (prevailing_node, NULL, &node->ref_list); - /* If we have aliases, redirect them to the prevailing node. */ - if (!node->same_body_alias && node->same_body) - { - 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) - { - 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. */ - if (node->same_body_alias) - cgraph_remove_same_body_alias (node); - else - cgraph_remove_node (node); + cgraph_remove_node (node); } /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging @@ -306,32 +268,9 @@ lto_varpool_replace_node (struct varpool_node *vnode, gcc_assert (!vnode->analyzed || prevailing_node->analyzed); varpool_mark_needed_node (prevailing_node); } - /* Relink aliases. */ - if (vnode->extra_name && !vnode->alias) - { - struct varpool_node *alias, *last; - for (alias = vnode->extra_name; - alias; alias = alias->next) - { - last = alias; - alias->extra_name = prevailing_node; - } - - if (prevailing_node->extra_name) - { - last->next = prevailing_node->extra_name; - prevailing_node->extra_name->prev = last; - } - prevailing_node->extra_name = vnode->extra_name; - vnode->extra_name = NULL; - } gcc_assert (!vnode->finalized || prevailing_node->finalized); gcc_assert (!vnode->analyzed || prevailing_node->analyzed); - /* When replacing by an alias, the references goes to the original - variable. */ - if (prevailing_node->alias && prevailing_node->extra_name) - prevailing_node = prevailing_node->extra_name; ipa_clone_refering (NULL, prevailing_node, &vnode->ref_list); /* Be sure we can garbage collect the initializer. */ @@ -362,8 +301,8 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry) if (TREE_CODE (decl) == FUNCTION_DECL) { - if (!gimple_types_compatible_p (TREE_TYPE (prevailing_decl), - TREE_TYPE (decl), GTC_DIAG)) + if (!types_compatible_p (TREE_TYPE (prevailing_decl), + TREE_TYPE (decl))) /* If we don't have a merged type yet...sigh. The linker wouldn't complain if the types were mismatched, so we probably shouldn't either. Just use the type from @@ -392,11 +331,7 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry) prevailing_type = TYPE_MAIN_VARIANT (TREE_TYPE (prevailing_decl)); type = TYPE_MAIN_VARIANT (TREE_TYPE (decl)); - /* We have to register and fetch canonical types here as the global - fixup process didn't yet run. */ - prevailing_type = gimple_register_type (prevailing_type); - type = gimple_register_type (type); - if (!gimple_types_compatible_p (prevailing_type, type, GTC_DIAG)) + if (!types_compatible_p (prevailing_type, type)) { if (COMPLETE_TYPE_P (type)) return false; @@ -421,9 +356,7 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry) if (TREE_CODE (tem1) != TREE_CODE (tem2)) return false; - if (!gimple_types_compatible_p (gimple_register_type (tem1), - gimple_register_type (tem2), - GTC_DIAG)) + if (!types_compatible_p (tem1, tem2)) return false; } @@ -480,18 +413,13 @@ lto_symtab_resolve_can_prevail_p (lto_symtab_entry_t e) /* For functions we need a non-discarded body. */ if (TREE_CODE (e->decl) == FUNCTION_DECL) - return (e->node - && (e->node->analyzed - || (e->node->same_body_alias && e->node->same_body->analyzed))); + return (e->node && e->node->analyzed); - /* A variable should have a size. */ else if (TREE_CODE (e->decl) == VAR_DECL) { if (!e->vnode) return false; - if (e->vnode->finalized) - return true; - return e->vnode->alias && e->vnode->extra_name->finalized; + return e->vnode->finalized; } gcc_unreachable (); @@ -510,7 +438,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_or_alias (e->decl); + e->node = cgraph_get_node (e->decl); else if (TREE_CODE (e->decl) == VAR_DECL) e->vnode = varpool_get_node (e->decl); } @@ -593,16 +521,16 @@ found: } /* Merge all decls in the symbol table chain to the prevailing decl and - issue diagnostics about type mismatches. */ + issue diagnostics about type mismatches. If DIAGNOSED_P is true + do not issue further diagnostics.*/ static void -lto_symtab_merge_decls_2 (void **slot) +lto_symtab_merge_decls_2 (void **slot, bool diagnosed_p) { lto_symtab_entry_t prevailing, e; VEC(tree, heap) *mismatches = NULL; unsigned i; tree decl; - bool diagnosed_p = false; /* Nothing to do for a single entry. */ prevailing = (lto_symtab_entry_t) *slot; @@ -612,7 +540,8 @@ lto_symtab_merge_decls_2 (void **slot) /* Try to merge each entry with the prevailing one. */ for (e = prevailing->next; e; e = e->next) { - if (!lto_symtab_merge (prevailing, e)) + if (!lto_symtab_merge (prevailing, e) + && !diagnosed_p) VEC_safe_push (tree, heap, mismatches, e->decl); } if (VEC_empty (tree, mismatches)) @@ -621,8 +550,7 @@ lto_symtab_merge_decls_2 (void **slot) /* Diagnose all mismatched re-declarations. */ FOR_EACH_VEC_ELT (tree, mismatches, i, decl) { - if (!gimple_types_compatible_p (TREE_TYPE (prevailing->decl), - TREE_TYPE (decl), GTC_DIAG)) + if (!types_compatible_p (TREE_TYPE (prevailing->decl), TREE_TYPE (decl))) diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0, "type of %qD does not match original " "declaration", decl); @@ -745,18 +673,9 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED) inform (DECL_SOURCE_LOCATION (prevailing->decl), "previously declared here"); - /* Register and adjust types of the entries. */ - for (e = (lto_symtab_entry_t) *slot; e; e = e->next) - TREE_TYPE (e->decl) = gimple_register_type (TREE_TYPE (e->decl)); - /* Merge the chain to the single prevailing decl and diagnose mismatches. */ - lto_symtab_merge_decls_2 (slot); - - /* Drop all but the prevailing decl from the symtab. */ - if (TREE_CODE (prevailing->decl) != FUNCTION_DECL - && TREE_CODE (prevailing->decl) != VAR_DECL) - prevailing->next = NULL; + lto_symtab_merge_decls_2 (slot, diagnosed_p); /* Store resolution decision into the callgraph. In LTRANS don't overwrite information we stored into callgraph at @@ -799,9 +718,26 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED) for (e = prevailing->next; e; e = e->next) { if (e->node != NULL) - lto_cgraph_replace_node (e->node, prevailing->node); + { + /* In case we prevail funcion by an alias, we can run into case + that the alias has no cgraph node attached, since it was + previously unused. Create the node. */ + if (!prevailing->node) + { + prevailing->node = cgraph_create_node (prevailing->decl); + prevailing->node->alias = true; + } + lto_cgraph_replace_node (e->node, prevailing->node); + } if (e->vnode != NULL) - lto_varpool_replace_node (e->vnode, prevailing->vnode); + { + if (!prevailing->vnode) + { + prevailing->vnode = varpool_node (prevailing->decl); + prevailing->vnode->alias = true; + } + lto_varpool_replace_node (e->vnode, prevailing->vnode); + } } /* Drop all but the prevailing decl from the symtab. */ @@ -816,8 +752,18 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED) void lto_symtab_merge_cgraph_nodes (void) { + struct cgraph_node *node; + struct varpool_node *vnode; lto_symtab_maybe_init_hash_table (); htab_traverse (lto_symtab_identifiers, lto_symtab_merge_cgraph_nodes_1, NULL); + + for (node = cgraph_nodes; node; node = node->next) + if ((node->thunk.thunk_p || node->alias) + && node->thunk.alias) + node->thunk.alias = lto_symtab_prevailing_decl (node->thunk.alias); + for (vnode = varpool_nodes; vnode; vnode = vnode->next) + if (vnode->alias_of) + vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of); } /* Given the decl DECL, return the prevailing decl with the same name. */