Hi,
On Tue, Sep 18, 2012 at 03:35:45PM +0200, Jan Hubicka wrote:
> Hi,
> this patch reorganize lto-symtab to work across symtab's symbol table instead
> of building its own. This simplifies things a bit and with the previous
> changes it is rather straighforward - i.e. replace all uses of
> lto_symtab_entry_t by symtab_node.
>
> There are few differences in between the symtab as built by lto-symtab and
> our symbol table. In one direction the declarations that are not going to be
> output to final assembly (i.e. are used by debug info and such) are not in
> symbol table and consequentely they no longer get merged. I think this is
> fine.
>
> Other difference is that symbol table contains some symbols that are not
> really
> symbols in classical definition - such as inline clones or functions held in
> table only for purposes of materialization. I added symtab_real_symbol_p
> predicate for this. It would make more sense to exclude those from the
> assembler name hash and drop checks I added to lto-symtab.c. I plan to work
> on
> this incrementally - it is not completely trivial. The symbol can become
> non-real in several ways and it will need bit of work to get this consistent.
>
> Bootstrapped/regtested x86_64-linux, tested by building Mozilla, Qt and other
> stuff with LTO. OK?
>
> Honza
>
> * symtab.c (insert_to_assembler_name_hash): Do not insert
> register vars.
> (unlink_from_assembler_name_hash): NULL out pointers of unlinked
> var.
> (symtab_prevail_in_asm_name_hash): New.
> (symtab_initialize_asm_name_hash): Break out from ...
> (symtab_node_for_asm): ... here.
> (dump_symtab_base): Dump LTO file data.
> (verify_symtab_base): Register vars are not in symtab.
> * cgraph.h (symtab_initialize_asm_name_hash,
> symtab_prevail_in_asm_name_hash): New functions.
> (symtab_real_symbol_p): New inline.
> * lto-symtab.c: Do not include gt-lto-symtab.h.
> (lto_symtab_entry_def): Remove.
> (lto_symtab_entry_t): Remove.
> (lto_symtab_identifiers): Remove.
> (lto_symtab_free): Remove.
> (lto_symtab_entry_hash): Remove.
> (lto_symtab_entry_eq): Remove.
> (lto_symtab_entry_marked_p): Remove.
> (lto_symtab_maybe_init_hash_table): Remove.
> (resolution_guessed_p, set_resolution_guessed): New functions.
> (lto_symtab_register_decl): Only set resolution info.
> (lto_symtab_get, lto_symtab_get_resolution): Remove.
> (lto_symtab_merge): Reorg to work across symtab; do nothing if decls
> are same.
> (lto_symtab_resolve_replaceable_p): Reorg to work on symtab.
> (lto_symtab_resolve_can_prevail_p): Likewise; only real symbols can
> prevail.
> (lto_symtab_resolve_symbols): Reorg to work on symtab.
> (lto_symtab_merge_decls_2): Likewise.
> (lto_symtab_merge_decls_1): Likewise; add debug dumps.
> (lto_symtab_merge_decls): Likewise; do not merge at ltrans stage.
> (lto_symtab_merge_cgraph_nodes_1): Reorg to work on symtab.
> (lto_symtab_merge_cgraph_nodes): Likewise; do not merge at ltrans stage.
> (lto_symtab_prevailing_decl): Rewrite to lookup into symtab.
> * lto-streaer.h (lto_symtab_free): Remove.
> * lto-cgraph.c (add_references): Cleanup.
> * varpool.c (varpool_assemble_decl): Skip hard regs.
>
> * lto.c (lto_materialize_function): Update confused comment.
> (read_cgraph_and_symbols): Do not free symtab.
Unfortunately, this patch breaks SPEC2006 povray LTO build for me.
I'm getting:
In file included from :168:0:
lighting.cpp: In function 'InitMallocPools':
lighting.cpp:5971:13: error: address taken, but ADDRESSABLE bit not set
static void InitMallocPools(void)
^
PHI argument
&Frame.Number_Of_Light_Sources;
for PHI node
_191 = PHI <&Frame.Number_Of_Light_Sources(100), &D.7040(101)>
lighting.cpp:5971:13: internal compiler error: verify_ssa failed
I'm currently a bit too busy to try to reduce this, I hope you'll be
able to reproduce the issue yourself easily though. If not, ping me
on IRC.
Thanks,
Martin
> Index: symtab.c
> ===================================================================
> *** symtab.c (revision 191418)
> --- symtab.c (working copy)
> *************** eq_assembler_name (const void *p1, const
> *** 104,109 ****
> --- 104,111 ----
> static void
> insert_to_assembler_name_hash (symtab_node node)
> {
> + if (symtab_variable_p (node) && DECL_HARD_REGISTER (node->symbol.decl))
> + return;
> gcc_checking_assert (!node->symbol.previous_sharing_asm_name
> && !node->symbol.next_sharing_asm_name);
> if (assembler_name_hash)
> *************** unlink_from_assembler_name_hash (symtab_
> *** 151,159 ****
> --- 153,172 ----
> else
> *slot = node->symbol.next_sharing_asm_name;
> }
> + node->symbol.next_sharing_asm_name = NULL;
> + node->symbol.previous_sharing_asm_name = NULL;
> }
> }
>
> + /* Arrange node to be first in its entry of assembler_name_hash. */
> +
> + void
> + symtab_prevail_in_asm_name_hash (symtab_node node)
> + {
> + unlink_from_assembler_name_hash (node);
> + insert_to_assembler_name_hash (node);
> + }
> +
>
> /* Add node into symbol table. This function is not used directly, but via
> cgraph/varpool node creation routines. */
> *************** symtab_remove_node (symtab_node node)
> *** 287,301 ****
> varpool_remove_node (varpool (node));
> }
>
> ! /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
> ! Return NULL if there's no such node. */
>
> ! symtab_node
> ! symtab_node_for_asm (const_tree asmname)
> {
> symtab_node node;
> - void **slot;
> -
> if (!assembler_name_hash)
> {
> assembler_name_hash =
> --- 300,311 ----
> varpool_remove_node (varpool (node));
> }
>
> ! /* Initalize asm name hash unless. */
>
> ! void
> ! symtab_initialize_asm_name_hash (void)
> {
> symtab_node node;
> if (!assembler_name_hash)
> {
> assembler_name_hash =
> *************** symtab_node_for_asm (const_tree asmname)
> *** 304,310 ****
> --- 314,331 ----
> FOR_EACH_SYMBOL (node)
> insert_to_assembler_name_hash (node);
> }
> + }
>
> + /* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
> + Return NULL if there's no such node. */
> +
> + symtab_node
> + symtab_node_for_asm (const_tree asmname)
> + {
> + symtab_node node;
> + void **slot;
> +
> + symtab_initialize_asm_name_hash ();
> slot = htab_find_slot_with_hash (assembler_name_hash, asmname,
> decl_assembler_name_hash (asmname),
> NO_INSERT);
> *************** dump_symtab_base (FILE *f, symtab_node n
> *** 507,512 ****
> --- 528,536 ----
> ipa_dump_references (f, &node->symbol.ref_list);
> fprintf (f, " Referring: ");
> ipa_dump_referring (f, &node->symbol.ref_list);
> + if (node->symbol.lto_file_data)
> + fprintf (f, " Read from file: %s\n",
> + node->symbol.lto_file_data->file_name);
> }
>
> /* Dump symtab node. */
> *************** verify_symtab_base (symtab_node node)
> *** 597,603 ****
> break;
> hashed_node = hashed_node->symbol.next_sharing_asm_name;
> }
> ! if (!hashed_node)
> {
> error ("node not found in symtab assembler name hash");
> error_found = true;
> --- 621,628 ----
> break;
> hashed_node = hashed_node->symbol.next_sharing_asm_name;
> }
> ! if (!hashed_node
> ! && !(symtab_variable_p (node) || DECL_HARD_REGISTER
> (node->symbol.decl)))
> {
> error ("node not found in symtab assembler name hash");
> error_found = true;
> *************** symtab_make_decl_local (tree decl)
> *** 733,738 ****
> --- 758,765 ----
> DECL_COMDAT_GROUP (decl) = 0;
> DECL_WEAK (decl) = 0;
> DECL_EXTERNAL (decl) = 0;
> + DECL_VISIBILITY_SPECIFIED (decl) = 0;
> + DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
> TREE_PUBLIC (decl) = 0;
> DECL_VISIBILITY_SPECIFIED (decl) = 0;
> DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
> Index: cgraph.h
> ===================================================================
> *** cgraph.h (revision 191418)
> --- cgraph.h (working copy)
> *************** bool varpool_for_node_and_aliases (struc
> *** 704,709 ****
> --- 704,711 ----
> bool (*) (struct varpool_node *, void *),
> void *, bool);
> void varpool_add_new_variable (tree);
> + void symtab_initialize_asm_name_hash (void);
> + void symtab_prevail_in_asm_name_hash (symtab_node node);
>
> /* Return true when NODE is function. */
> static inline bool
> *************** cgraph_mark_force_output_node (struct cg
> *** 1309,1312 ****
> --- 1311,1337 ----
> gcc_checking_assert (!node->global.inlined_to);
> }
>
> + /* Return true when the symbol is real symbol, i.e. it is not inline clone
> + or extern function kept around just for inlining. */
> +
> + static inline bool
> + symtab_real_symbol_p (symtab_node node)
> + {
> + struct cgraph_node *cnode;
> + struct ipa_ref *ref;
> +
> + if (!symtab_function_p (node))
> + return true;
> + cnode = cgraph (node);
> + if (cnode->global.inlined_to)
> + return false;
> + if (cnode->abstract_and_needed)
> + return false;
> + /* We keep virtual clones in symtab. */
> + if (!cnode->analyzed
> + || DECL_EXTERNAL (cnode->symbol.decl))
> + return (cnode->callers
> + || ipa_ref_list_referring_iterate (&cnode->symbol.ref_list, 0,
> ref));
> + return true;
> + }
> #endif /* GCC_CGRAPH_H */
> Index: lto-symtab.c
> ===================================================================
> *** lto-symtab.c (revision 191418)
> --- lto-symtab.c (working copy)
> *************** along with GCC; see the file COPYING3.
> *** 32,129 ****
> /* Vector to keep track of external variables we've seen so far. */
> VEC(tree,gc) *lto_global_var_decls;
>
> ! /* Symbol table entry. */
> !
> ! struct GTY(()) lto_symtab_entry_def
> ! {
> ! /* The symbol table entry key, an IDENTIFIER. */
> ! tree id;
> ! /* The symbol table entry, a DECL. */
> ! tree decl;
> ! /* The cgraph node if decl is a function decl. Filled in during the
> ! merging process. */
> ! struct cgraph_node *node;
> ! /* The varpool node if decl is a variable decl. Filled in during the
> ! merging process. */
> ! struct varpool_node *vnode;
> ! /* LTO file-data and symbol resolution for this decl. */
> ! struct lto_file_decl_data * GTY((skip (""))) file_data;
> ! enum ld_plugin_symbol_resolution resolution;
> ! /* True when resolution was guessed and not read from the file. */
> ! bool guessed;
> ! /* Pointer to the next entry with the same key. Before decl merging
> ! this links all symbols from the different TUs. After decl merging
> ! this links merged but incompatible decls, thus all prevailing ones
> ! remaining. */
> ! struct lto_symtab_entry_def *next;
> ! };
> ! typedef struct lto_symtab_entry_def *lto_symtab_entry_t;
> !
> ! /* A poor man's symbol table. This hashes identifier to prevailing DECL
> ! if there is one. */
> !
> ! static GTY ((if_marked ("lto_symtab_entry_marked_p"),
> ! param_is (struct lto_symtab_entry_def)))
> ! htab_t lto_symtab_identifiers;
> !
> ! /* Free symtab hashtable. */
> !
> ! void
> ! lto_symtab_free (void)
> ! {
> ! htab_delete (lto_symtab_identifiers);
> ! lto_symtab_identifiers = NULL;
> ! }
> !
> ! /* Return the hash value of an lto_symtab_entry_t object pointed to by P.
> */
> !
> ! static hashval_t
> ! lto_symtab_entry_hash (const void *p)
> {
> ! const struct lto_symtab_entry_def *base =
> ! (const struct lto_symtab_entry_def *) p;
> ! return IDENTIFIER_HASH_VALUE (base->id);
> }
>
> ! /* Return non-zero if P1 and P2 points to lto_symtab_entry_def structs
> ! corresponding to the same symbol. */
> !
> ! static int
> ! lto_symtab_entry_eq (const void *p1, const void *p2)
> ! {
> ! const struct lto_symtab_entry_def *base1 =
> ! (const struct lto_symtab_entry_def *) p1;
> ! const struct lto_symtab_entry_def *base2 =
> ! (const struct lto_symtab_entry_def *) p2;
> ! return (base1->id == base2->id);
> ! }
> !
> ! /* Returns non-zero if P points to an lto_symtab_entry_def struct that needs
> ! to be marked for GC. */
> !
> ! static int
> ! lto_symtab_entry_marked_p (const void *p)
> {
> ! const struct lto_symtab_entry_def *base =
> ! (const struct lto_symtab_entry_def *) p;
> !
> ! /* Keep this only if the common IDENTIFIER_NODE of the symtab chain
> ! is marked which it will be if at least one of the DECLs in the
> ! chain is marked. */
> ! return ggc_marked_p (base->id);
> ! }
> !
> ! /* Lazily initialize resolution hash tables. */
> !
> ! static void
> ! lto_symtab_maybe_init_hash_table (void)
> ! {
> ! if (lto_symtab_identifiers)
> ! return;
> !
> ! lto_symtab_identifiers =
> ! htab_create_ggc (1021, lto_symtab_entry_hash,
> ! lto_symtab_entry_eq, NULL);
> }
>
> /* Registers DECL with the LTO symbol table as having resolution RESOLUTION
> --- 32,50 ----
> /* Vector to keep track of external variables we've seen so far. */
> VEC(tree,gc) *lto_global_var_decls;
>
> ! /* Return true if the resolution was guessed and not obtained from
> ! the file. */
> ! static inline bool
> ! resolution_guessed_p (symtab_node node)
> {
> ! return node->symbol.aux != NULL;
> }
>
> ! /* Set guessed flag for NODE. */
> ! static inline void
> ! set_resolution_guessed (symtab_node node, bool value)
> {
> ! node->symbol.aux = (void *)(size_t)value;
> }
>
> /* Registers DECL with the LTO symbol table as having resolution RESOLUTION
> *************** lto_symtab_register_decl (tree decl,
> *** 134,141 ****
> ld_plugin_symbol_resolution_t resolution,
> struct lto_file_decl_data *file_data)
> {
> ! lto_symtab_entry_t new_entry;
> ! void **slot;
>
> /* Check that declarations reaching this function do not have
> properties inconsistent with having external linkage. If any of
> --- 55,61 ----
> ld_plugin_symbol_resolution_t resolution,
> struct lto_file_decl_data *file_data)
> {
> ! symtab_node node;
>
> /* Check that declarations reaching this function do not have
> properties inconsistent with having external linkage. If any of
> *************** lto_symtab_register_decl (tree decl,
> *** 153,206 ****
> if (TREE_CODE (decl) == FUNCTION_DECL)
> gcc_assert (!DECL_ABSTRACT (decl));
>
> ! new_entry = ggc_alloc_cleared_lto_symtab_entry_def ();
> ! new_entry->id = (*targetm.asm_out.mangle_assembler_name)
> ! (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
> ! new_entry->decl = decl;
> ! new_entry->resolution = resolution;
> ! new_entry->file_data = file_data;
> !
> ! lto_symtab_maybe_init_hash_table ();
> ! slot = htab_find_slot (lto_symtab_identifiers, new_entry, INSERT);
> ! new_entry->next = (lto_symtab_entry_t) *slot;
> ! *slot = new_entry;
> ! }
> !
> ! /* Get the lto_symtab_entry_def struct associated with ID
> ! if there is one. */
> !
> ! static lto_symtab_entry_t
> ! lto_symtab_get (tree id)
> ! {
> ! struct lto_symtab_entry_def temp;
> ! void **slot;
> !
> ! lto_symtab_maybe_init_hash_table ();
> ! temp.id = id;
> ! slot = htab_find_slot (lto_symtab_identifiers, &temp, NO_INSERT);
> ! return slot ? (lto_symtab_entry_t) *slot : NULL;
> ! }
> !
> ! /* Get the linker resolution for DECL. */
> !
> ! enum ld_plugin_symbol_resolution
> ! lto_symtab_get_resolution (tree decl)
> ! {
> ! lto_symtab_entry_t e;
> !
> ! gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
> !
> ! e = lto_symtab_get ((*targetm.asm_out.mangle_assembler_name)
> ! (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
> ! while (e && e->decl != decl)
> ! e = e->next;
> ! if (!e)
> ! return LDPR_UNKNOWN;
> !
> ! return e->resolution;
> }
>
> -
> /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
> all edges and removing the old node. */
>
> --- 73,87 ----
> if (TREE_CODE (decl) == FUNCTION_DECL)
> gcc_assert (!DECL_ABSTRACT (decl));
>
> ! node = symtab_get_node (decl);
> ! if (node)
> ! {
> ! node->symbol.resolution = resolution;
> ! gcc_assert (node->symbol.lto_file_data == file_data);
> ! gcc_assert (!resolution_guessed_p (node));
> ! }
> }
>
> /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
> all edges and removing the old node. */
>
> *************** lto_varpool_replace_node (struct varpool
> *** 277,288 ****
> should be emitted. */
>
> static bool
> ! lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
> {
> ! tree prevailing_decl = prevailing->decl;
> ! tree decl = entry->decl;
> tree prevailing_type, type;
>
> /* Merge decl state in both directions, we may still end up using
> the new decl. */
> TREE_ADDRESSABLE (prevailing_decl) |= TREE_ADDRESSABLE (decl);
> --- 158,172 ----
> should be emitted. */
>
> static bool
> ! lto_symtab_merge (symtab_node prevailing, symtab_node entry)
> {
> ! tree prevailing_decl = prevailing->symbol.decl;
> ! tree decl = entry->symbol.decl;
> tree prevailing_type, type;
>
> + if (prevailing_decl == decl)
> + return true;
> +
> /* Merge decl state in both directions, we may still end up using
> the new decl. */
> TREE_ADDRESSABLE (prevailing_decl) |= TREE_ADDRESSABLE (decl);
> *************** lto_symtab_merge (lto_symtab_entry_t pre
> *** 377,393 ****
> entry. */
>
> static bool
> ! lto_symtab_resolve_replaceable_p (lto_symtab_entry_t e)
> {
> ! if (DECL_EXTERNAL (e->decl)
> ! || DECL_COMDAT (e->decl)
> ! || DECL_ONE_ONLY (e->decl)
> ! || DECL_WEAK (e->decl))
> return true;
>
> ! if (TREE_CODE (e->decl) == VAR_DECL)
> ! return (DECL_COMMON (e->decl)
> ! || (!flag_no_common && !DECL_INITIAL (e->decl)));
>
> return false;
> }
> --- 261,277 ----
> entry. */
>
> static bool
> ! lto_symtab_resolve_replaceable_p (symtab_node e)
> {
> ! if (DECL_EXTERNAL (e->symbol.decl)
> ! || DECL_COMDAT (e->symbol.decl)
> ! || DECL_ONE_ONLY (e->symbol.decl)
> ! || DECL_WEAK (e->symbol.decl))
> return true;
>
> ! if (TREE_CODE (e->symbol.decl) == VAR_DECL)
> ! return (DECL_COMMON (e->symbol.decl)
> ! || (!flag_no_common && !DECL_INITIAL (e->symbol.decl)));
>
> return false;
> }
> *************** lto_symtab_resolve_replaceable_p (lto_sy
> *** 395,418 ****
> /* Return true if the symtab entry E can be the prevailing one. */
>
> static bool
> ! lto_symtab_resolve_can_prevail_p (lto_symtab_entry_t e)
> {
> /* The C++ frontend ends up neither setting TREE_STATIC nor
> DECL_EXTERNAL on virtual methods but only TREE_PUBLIC.
> So do not reject !TREE_STATIC here but only DECL_EXTERNAL. */
> ! if (DECL_EXTERNAL (e->decl))
> return false;
>
> /* For functions we need a non-discarded body. */
> ! if (TREE_CODE (e->decl) == FUNCTION_DECL)
> ! return (e->node && e->node->analyzed);
>
> ! else if (TREE_CODE (e->decl) == VAR_DECL)
> ! {
> ! if (!e->vnode)
> ! return false;
> ! return e->vnode->finalized;
> ! }
>
> gcc_unreachable ();
> }
> --- 279,301 ----
> /* Return true if the symtab entry E can be the prevailing one. */
>
> static bool
> ! lto_symtab_resolve_can_prevail_p (symtab_node e)
> {
> + if (!symtab_real_symbol_p (e))
> + return false;
> +
> /* The C++ frontend ends up neither setting TREE_STATIC nor
> DECL_EXTERNAL on virtual methods but only TREE_PUBLIC.
> So do not reject !TREE_STATIC here but only DECL_EXTERNAL. */
> ! if (DECL_EXTERNAL (e->symbol.decl))
> return false;
>
> /* For functions we need a non-discarded body. */
> ! if (TREE_CODE (e->symbol.decl) == FUNCTION_DECL)
> ! return (cgraph (e)->analyzed);
>
> ! else if (TREE_CODE (e->symbol.decl) == VAR_DECL)
> ! return varpool (e)->finalized;
>
> gcc_unreachable ();
> }
> *************** lto_symtab_resolve_can_prevail_p (lto_sy
> *** 421,443 ****
> their resolutions. */
>
> static void
> ! lto_symtab_resolve_symbols (void **slot)
> {
> ! lto_symtab_entry_t e;
> ! lto_symtab_entry_t prevailing = NULL;
>
> /* Always set e->node so that edges are updated to reflect decl merging.
> */
> ! 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);
> ! else if (TREE_CODE (e->decl) == VAR_DECL)
> ! e->vnode = varpool_get_node (e->decl);
> ! if (e->resolution == LDPR_PREVAILING_DEF_IRONLY
> ! || e->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
> ! || e->resolution == LDPR_PREVAILING_DEF)
> ! prevailing = e;
> ! }
>
> /* If the chain is already resolved there is nothing else to do. */
> if (prevailing)
> --- 304,321 ----
> their resolutions. */
>
> static void
> ! lto_symtab_resolve_symbols (symtab_node first)
> {
> ! symtab_node e;
> ! symtab_node prevailing = NULL;
>
> /* Always set e->node so that edges are updated to reflect decl merging.
> */
> ! for (e = first; e; e = e->symbol.next_sharing_asm_name)
> ! if (symtab_real_symbol_p (e)
> ! && (e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
> ! || e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
> ! || e->symbol.resolution == LDPR_PREVAILING_DEF))
> ! prevailing = e;
>
> /* If the chain is already resolved there is nothing else to do. */
> if (prevailing)
> *************** lto_symtab_resolve_symbols (void **slot)
> *** 445,470 ****
>
> /* Find the single non-replaceable prevailing symbol and
> diagnose ODR violations. */
> ! for (e = (lto_symtab_entry_t) *slot; e; e = e->next)
> {
> if (!lto_symtab_resolve_can_prevail_p (e))
> {
> ! e->resolution = LDPR_RESOLVED_IR;
> ! e->guessed = true;
> continue;
> }
>
> /* Set a default resolution - the final prevailing one will get
> adjusted later. */
> ! e->resolution = LDPR_PREEMPTED_IR;
> ! e->guessed = true;
> if (!lto_symtab_resolve_replaceable_p (e))
> {
> if (prevailing)
> {
> ! error_at (DECL_SOURCE_LOCATION (e->decl),
> ! "%qD has already been defined", e->decl);
> ! inform (DECL_SOURCE_LOCATION (prevailing->decl),
> "previously defined here");
> }
> prevailing = e;
> --- 323,348 ----
>
> /* Find the single non-replaceable prevailing symbol and
> diagnose ODR violations. */
> ! for (e = first; e; e = e->symbol.next_sharing_asm_name)
> {
> if (!lto_symtab_resolve_can_prevail_p (e))
> {
> ! e->symbol.resolution = LDPR_RESOLVED_IR;
> ! set_resolution_guessed (e, true);
> continue;
> }
>
> /* Set a default resolution - the final prevailing one will get
> adjusted later. */
> ! e->symbol.resolution = LDPR_PREEMPTED_IR;
> ! set_resolution_guessed (e, true);
> if (!lto_symtab_resolve_replaceable_p (e))
> {
> if (prevailing)
> {
> ! error_at (DECL_SOURCE_LOCATION (e->symbol.decl),
> ! "%qD has already been defined", e->symbol.decl);
> ! inform (DECL_SOURCE_LOCATION (prevailing->symbol.decl),
> "previously defined here");
> }
> prevailing = e;
> *************** lto_symtab_resolve_symbols (void **slot)
> *** 474,486 ****
> goto found;
>
> /* Do a second round choosing one from the replaceable prevailing decls.
> */
> ! for (e = (lto_symtab_entry_t) *slot; e; e = e->next)
> {
> ! if (e->resolution != LDPR_PREEMPTED_IR)
> continue;
>
> /* Choose the first function that can prevail as prevailing. */
> ! if (TREE_CODE (e->decl) == FUNCTION_DECL)
> {
> prevailing = e;
> break;
> --- 352,365 ----
> goto found;
>
> /* Do a second round choosing one from the replaceable prevailing decls.
> */
> ! for (e = first; e; e = e->symbol.next_sharing_asm_name)
> {
> ! if (e->symbol.resolution != LDPR_PREEMPTED_IR
> ! || !symtab_real_symbol_p (e))
> continue;
>
> /* Choose the first function that can prevail as prevailing. */
> ! if (TREE_CODE (e->symbol.decl) == FUNCTION_DECL)
> {
> prevailing = e;
> break;
> *************** lto_symtab_resolve_symbols (void **slot)
> *** 488,495 ****
>
> /* From variables that can prevail choose the largest one. */
> if (!prevailing
> ! || tree_int_cst_lt (DECL_SIZE (prevailing->decl),
> ! DECL_SIZE (e->decl))
> /* When variables are equivalent try to chose one that has useful
> DECL_INITIAL. This makes sense for keyed vtables that are
> DECL_EXTERNAL but initialized. In units that do not need them
> --- 367,374 ----
>
> /* From variables that can prevail choose the largest one. */
> if (!prevailing
> ! || tree_int_cst_lt (DECL_SIZE (prevailing->symbol.decl),
> ! DECL_SIZE (e->symbol.decl))
> /* When variables are equivalent try to chose one that has useful
> DECL_INITIAL. This makes sense for keyed vtables that are
> DECL_EXTERNAL but initialized. In units that do not need them
> *************** lto_symtab_resolve_symbols (void **slot)
> *** 499,509 ****
> We know that the vtable is keyed outside the LTO unit - otherwise
> the keyed instance would prevail. We still can preserve useful
> info in the initializer. */
> ! || (DECL_SIZE (prevailing->decl) == DECL_SIZE (e->decl)
> ! && (DECL_INITIAL (e->decl)
> ! && DECL_INITIAL (e->decl) != error_mark_node)
> ! && (!DECL_INITIAL (prevailing->decl)
> ! || DECL_INITIAL (prevailing->decl) == error_mark_node)))
> prevailing = e;
> }
>
> --- 378,388 ----
> We know that the vtable is keyed outside the LTO unit - otherwise
> the keyed instance would prevail. We still can preserve useful
> info in the initializer. */
> ! || (DECL_SIZE (prevailing->symbol.decl) == DECL_SIZE (e->symbol.decl)
> ! && (DECL_INITIAL (e->symbol.decl)
> ! && DECL_INITIAL (e->symbol.decl) != error_mark_node)
> ! && (!DECL_INITIAL (prevailing->symbol.decl)
> ! || DECL_INITIAL (prevailing->symbol.decl) ==
> error_mark_node)))
> prevailing = e;
> }
>
> *************** found:
> *** 524,531 ****
> variables IRONLY, which are indeed PREVAILING_DEF in
> resolution file. These variables still need manual
> externally_visible attribute. */
> ! prevailing->resolution = LDPR_PREVAILING_DEF_IRONLY;
> ! prevailing->guessed = true;
> }
>
> /* Merge all decls in the symbol table chain to the prevailing decl and
> --- 403,410 ----
> variables IRONLY, which are indeed PREVAILING_DEF in
> resolution file. These variables still need manual
> externally_visible attribute. */
> ! prevailing->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
> ! set_resolution_guessed (prevailing, true);
> }
>
> /* Merge all decls in the symbol table chain to the prevailing decl and
> *************** found:
> *** 533,556 ****
> do not issue further diagnostics.*/
>
> static void
> ! 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;
>
> /* Nothing to do for a single entry. */
> ! prevailing = (lto_symtab_entry_t) *slot;
> ! if (!prevailing->next)
> return;
>
> /* Try to merge each entry with the prevailing one. */
> ! for (e = prevailing->next; e; e = e->next)
> {
> if (!lto_symtab_merge (prevailing, e)
> && !diagnosed_p)
> ! VEC_safe_push (tree, heap, mismatches, e->decl);
> }
> if (VEC_empty (tree, mismatches))
> return;
> --- 412,436 ----
> do not issue further diagnostics.*/
>
> static void
> ! lto_symtab_merge_decls_2 (symtab_node first, bool diagnosed_p)
> {
> ! symtab_node prevailing, e;
> VEC(tree, heap) *mismatches = NULL;
> unsigned i;
> tree decl;
>
> /* Nothing to do for a single entry. */
> ! prevailing = first;
> ! if (!prevailing->symbol.next_sharing_asm_name)
> return;
>
> /* Try to merge each entry with the prevailing one. */
> ! for (e = prevailing->symbol.next_sharing_asm_name;
> ! e; e = e->symbol.next_sharing_asm_name)
> {
> if (!lto_symtab_merge (prevailing, e)
> && !diagnosed_p)
> ! VEC_safe_push (tree, heap, mismatches, e->symbol.decl);
> }
> if (VEC_empty (tree, mismatches))
> return;
> *************** lto_symtab_merge_decls_2 (void **slot, b
> *** 558,570 ****
> /* Diagnose all mismatched re-declarations. */
> FOR_EACH_VEC_ELT (tree, mismatches, i, decl)
> {
> ! 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);
>
> ! else if ((DECL_USER_ALIGN (prevailing->decl) && DECL_USER_ALIGN
> (decl))
> ! && DECL_ALIGN (prevailing->decl) < DECL_ALIGN (decl))
> {
> diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
> "alignment of %qD is bigger than "
> --- 438,452 ----
> /* Diagnose all mismatched re-declarations. */
> FOR_EACH_VEC_ELT (tree, mismatches, i, decl)
> {
> ! if (!types_compatible_p (TREE_TYPE (prevailing->symbol.decl),
> ! TREE_TYPE (decl)))
> diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
> "type of %qD does not match original "
> "declaration", decl);
>
> ! else if ((DECL_USER_ALIGN (prevailing->symbol.decl)
> ! && DECL_USER_ALIGN (decl))
> ! && DECL_ALIGN (prevailing->symbol.decl) < DECL_ALIGN (decl))
> {
> diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
> "alignment of %qD is bigger than "
> *************** lto_symtab_merge_decls_2 (void **slot, b
> *** 572,578 ****
> }
> }
> if (diagnosed_p)
> ! inform (DECL_SOURCE_LOCATION (prevailing->decl),
> "previously declared here");
>
> VEC_free (tree, heap, mismatches);
> --- 454,460 ----
> }
> }
> if (diagnosed_p)
> ! inform (DECL_SOURCE_LOCATION (prevailing->symbol.decl),
> "previously declared here");
>
> VEC_free (tree, heap, mismatches);
> *************** lto_symtab_merge_decls_2 (void **slot, b
> *** 580,626 ****
>
> /* Helper to process the decl chain for the symbol table entry *SLOT. */
>
> ! static int
> ! lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
> {
> ! lto_symtab_entry_t e, prevailing;
> bool diagnosed_p = false;
>
> /* Compute the symbol resolutions. This is a no-op when using the
> ! linker plugin. */
> ! lto_symtab_resolve_symbols (slot);
>
> /* Find the prevailing decl. */
> ! for (prevailing = (lto_symtab_entry_t) *slot;
> prevailing
> ! && prevailing->resolution != LDPR_PREVAILING_DEF_IRONLY
> ! && prevailing->resolution != LDPR_PREVAILING_DEF_IRONLY_EXP
> ! && prevailing->resolution != LDPR_PREVAILING_DEF;
> ! prevailing = prevailing->next)
> ;
>
> /* Assert it's the only one. */
> if (prevailing)
> ! for (e = prevailing->next; e; e = e->next)
> ! {
> ! if (e->resolution == LDPR_PREVAILING_DEF_IRONLY
> ! || e->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
> ! || e->resolution == LDPR_PREVAILING_DEF)
> ! fatal_error ("multiple prevailing defs for %qE",
> ! DECL_NAME (prevailing->decl));
> ! }
>
> /* If there's not a prevailing symbol yet it's an external reference.
> Happens a lot during ltrans. Choose the first symbol with a
> cgraph or a varpool node. */
> if (!prevailing)
> {
> ! prevailing = (lto_symtab_entry_t) *slot;
> ! /* For functions choose one with a cgraph node. */
> ! if (TREE_CODE (prevailing->decl) == FUNCTION_DECL)
> ! while (!prevailing->node
> ! && prevailing->next)
> ! prevailing = prevailing->next;
> /* For variables chose with a priority variant with vnode
> attached (i.e. from unit where external declaration of
> variable is actually used).
> --- 462,511 ----
>
> /* Helper to process the decl chain for the symbol table entry *SLOT. */
>
> ! static void
> ! lto_symtab_merge_decls_1 (symtab_node first)
> {
> ! symtab_node e, prevailing;
> bool diagnosed_p = false;
>
> + if (cgraph_dump_file)
> + {
> + fprintf (cgraph_dump_file, "Merging nodes for %s. Candidates:\n",
> + symtab_node_asm_name (first));
> + for (e = first; e; e = e->symbol.next_sharing_asm_name)
> + dump_symtab_node (cgraph_dump_file, e);
> + }
> +
> /* Compute the symbol resolutions. This is a no-op when using the
> ! linker plugin and resolution was decided by the linker. */
> ! lto_symtab_resolve_symbols (first);
>
> /* Find the prevailing decl. */
> ! for (prevailing = first;
> prevailing
> ! && (!symtab_real_symbol_p (prevailing)
> ! || (prevailing->symbol.resolution != LDPR_PREVAILING_DEF_IRONLY
> ! && prevailing->symbol.resolution !=
> LDPR_PREVAILING_DEF_IRONLY_EXP
> ! && prevailing->symbol.resolution != LDPR_PREVAILING_DEF));
> ! prevailing = prevailing->symbol.next_sharing_asm_name)
> ;
>
> /* Assert it's the only one. */
> if (prevailing)
> ! for (e = prevailing->symbol.next_sharing_asm_name; e; e =
> e->symbol.next_sharing_asm_name)
> ! if (symtab_real_symbol_p (e)
> ! && (e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
> ! || e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
> ! || e->symbol.resolution == LDPR_PREVAILING_DEF))
> ! fatal_error ("multiple prevailing defs for %qE",
> ! DECL_NAME (prevailing->symbol.decl));
>
> /* If there's not a prevailing symbol yet it's an external reference.
> Happens a lot during ltrans. Choose the first symbol with a
> cgraph or a varpool node. */
> if (!prevailing)
> {
> ! prevailing = first;
> /* For variables chose with a priority variant with vnode
> attached (i.e. from unit where external declaration of
> variable is actually used).
> *************** lto_symtab_merge_decls_1 (void **slot, v
> *** 628,676 ****
> This is needed for C++ typeinfos, for example in
> lto/20081204-1 there are typeifos in both units, just
> one of them do have size. */
> ! if (TREE_CODE (prevailing->decl) == VAR_DECL)
> {
> ! for (e = prevailing->next; e; e = e->next)
> ! if ((!prevailing->vnode && e->vnode)
> ! || ((prevailing->vnode != NULL) == (e->vnode != NULL)
> ! && !COMPLETE_TYPE_P (TREE_TYPE (prevailing->decl))
> ! && COMPLETE_TYPE_P (TREE_TYPE (e->decl))))
> prevailing = e;
> }
> }
>
> ! /* Move it first in the list. */
> ! if ((lto_symtab_entry_t) *slot != prevailing)
> ! {
> ! for (e = (lto_symtab_entry_t) *slot; e->next != prevailing; e =
> e->next)
> ! ;
> ! e->next = prevailing->next;
> ! prevailing->next = (lto_symtab_entry_t) *slot;
> ! *slot = (void *) prevailing;
> ! }
>
> /* Record the prevailing variable. */
> ! if (TREE_CODE (prevailing->decl) == VAR_DECL)
> ! VEC_safe_push (tree, gc, lto_global_var_decls, prevailing->decl);
>
> /* Diagnose mismatched objects. */
> ! for (e = prevailing->next; e; e = e->next)
> {
> ! if (TREE_CODE (prevailing->decl) == TREE_CODE (e->decl))
> continue;
>
> ! switch (TREE_CODE (prevailing->decl))
> {
> case VAR_DECL:
> ! gcc_assert (TREE_CODE (e->decl) == FUNCTION_DECL);
> ! error_at (DECL_SOURCE_LOCATION (e->decl),
> ! "variable %qD redeclared as function", prevailing->decl);
> break;
>
> case FUNCTION_DECL:
> ! gcc_assert (TREE_CODE (e->decl) == VAR_DECL);
> ! error_at (DECL_SOURCE_LOCATION (e->decl),
> ! "function %qD redeclared as variable", prevailing->decl);
> break;
>
> default:
> --- 513,557 ----
> This is needed for C++ typeinfos, for example in
> lto/20081204-1 there are typeifos in both units, just
> one of them do have size. */
> ! if (TREE_CODE (prevailing->symbol.decl) == VAR_DECL)
> {
> ! for (e = prevailing->symbol.next_sharing_asm_name;
> ! e; e = e->symbol.next_sharing_asm_name)
> ! if (!COMPLETE_TYPE_P (TREE_TYPE (prevailing->symbol.decl))
> ! && COMPLETE_TYPE_P (TREE_TYPE (e->symbol.decl)))
> prevailing = e;
> }
> }
>
> ! symtab_prevail_in_asm_name_hash (prevailing);
>
> /* Record the prevailing variable. */
> ! if (TREE_CODE (prevailing->symbol.decl) == VAR_DECL)
> ! VEC_safe_push (tree, gc, lto_global_var_decls,
> ! prevailing->symbol.decl);
>
> /* Diagnose mismatched objects. */
> ! for (e = prevailing->symbol.next_sharing_asm_name;
> ! e; e = e->symbol.next_sharing_asm_name)
> {
> ! if (TREE_CODE (prevailing->symbol.decl)
> ! == TREE_CODE (e->symbol.decl))
> continue;
>
> ! switch (TREE_CODE (prevailing->symbol.decl))
> {
> case VAR_DECL:
> ! gcc_assert (TREE_CODE (e->symbol.decl) == FUNCTION_DECL);
> ! error_at (DECL_SOURCE_LOCATION (e->symbol.decl),
> ! "variable %qD redeclared as function",
> ! prevailing->symbol.decl);
> break;
>
> case FUNCTION_DECL:
> ! gcc_assert (TREE_CODE (e->symbol.decl) == VAR_DECL);
> ! error_at (DECL_SOURCE_LOCATION (e->symbol.decl),
> ! "function %qD redeclared as variable",
> ! prevailing->symbol.decl);
> break;
>
> default:
> *************** lto_symtab_merge_decls_1 (void **slot, v
> *** 680,691 ****
> diagnosed_p = true;
> }
> if (diagnosed_p)
> ! inform (DECL_SOURCE_LOCATION (prevailing->decl),
> "previously declared here");
>
> /* Merge the chain to the single prevailing decl and diagnose
> mismatches. */
> ! 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
> --- 561,579 ----
> diagnosed_p = true;
> }
> if (diagnosed_p)
> ! inform (DECL_SOURCE_LOCATION (prevailing->symbol.decl),
> "previously declared here");
>
> /* Merge the chain to the single prevailing decl and diagnose
> mismatches. */
> ! lto_symtab_merge_decls_2 (first, diagnosed_p);
> !
> ! if (cgraph_dump_file)
> ! {
> ! fprintf (cgraph_dump_file, "After resolution:\n");
> ! for (e = first; e; e = e->symbol.next_sharing_asm_name)
> ! dump_symtab_node (cgraph_dump_file, e);
> ! }
>
> /* Store resolution decision into the callgraph.
> In LTRANS don't overwrite information we stored into callgraph at
> *************** lto_symtab_merge_decls_1 (void **slot, v
> *** 698,708 ****
> PREVAILING_DEF, PREVAILING_DEF_IRONLY, PREVAILING_DEF_IRONLY_EXP.
> First one would disable some whole program optimizations, while
> ther second would imply to many whole program assumptions. */
> ! if (prevailing->node && !flag_ltrans && !prevailing->guessed)
> ! prevailing->node->symbol.resolution = prevailing->resolution;
> ! else if (prevailing->vnode && !flag_ltrans && !prevailing->guessed)
> ! prevailing->vnode->symbol.resolution = prevailing->resolution;
> ! return 1;
> }
>
> /* Resolve and merge all symbol table chains to a prevailing decl. */
> --- 586,594 ----
> PREVAILING_DEF, PREVAILING_DEF_IRONLY, PREVAILING_DEF_IRONLY_EXP.
> First one would disable some whole program optimizations, while
> ther second would imply to many whole program assumptions. */
> ! if (resolution_guessed_p (prevailing))
> ! prevailing->symbol.resolution = LDPR_UNKNOWN;
> ! return;
> }
>
> /* Resolve and merge all symbol table chains to a prevailing decl. */
> *************** lto_symtab_merge_decls_1 (void **slot, v
> *** 710,759 ****
> void
> lto_symtab_merge_decls (void)
> {
> ! lto_symtab_maybe_init_hash_table ();
> ! htab_traverse (lto_symtab_identifiers, lto_symtab_merge_decls_1, NULL);
> }
>
> /* Helper to process the decl chain for the symbol table entry *SLOT. */
>
> ! static int
> ! lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED)
> {
> ! lto_symtab_entry_t e, prevailing = (lto_symtab_entry_t) *slot;
> !
> ! if (!prevailing->next)
> ! return 1;
>
> /* Replace the cgraph node of each entry with the prevailing one. */
> ! for (e = prevailing->next; e; e = e->next)
> {
> ! if (e->node != NULL)
> ! {
> ! /* 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)
> ! {
> ! 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. */
> ! prevailing->next = NULL;
>
> ! return 1;
> }
>
> /* Merge cgraph nodes according to the symbol merging done by
> --- 596,641 ----
> void
> lto_symtab_merge_decls (void)
> {
> ! symtab_node node;
> !
> ! /* In ltrans mode we read merged cgraph, we do not really need to care
> ! about resolving symbols again, we only need to replace duplicated
> declarations
> ! read from the callgraph and from function sections. */
> ! if (flag_ltrans)
> ! return;
> !
> ! /* Populate assembler name hash. */
> ! symtab_initialize_asm_name_hash ();
> !
> ! FOR_EACH_SYMBOL (node)
> ! if (TREE_PUBLIC (node->symbol.decl)
> ! && node->symbol.next_sharing_asm_name
> ! && !node->symbol.previous_sharing_asm_name)
> ! lto_symtab_merge_decls_1 (node);
> }
>
> /* Helper to process the decl chain for the symbol table entry *SLOT. */
>
> ! static void
> ! lto_symtab_merge_cgraph_nodes_1 (symtab_node prevailing)
> {
> ! symtab_node e, next;
>
> /* Replace the cgraph node of each entry with the prevailing one. */
> ! for (e = prevailing->symbol.next_sharing_asm_name; e;
> ! e = next)
> {
> ! next = e->symbol.next_sharing_asm_name;
>
> ! if (!symtab_real_symbol_p (e))
> ! continue;
> ! if (symtab_function_p (e))
> ! lto_cgraph_replace_node (cgraph (e), cgraph (prevailing));
> ! if (symtab_variable_p (e))
> ! lto_varpool_replace_node (varpool (e), varpool (prevailing));
> ! }
>
> ! return;
> }
>
> /* Merge cgraph nodes according to the symbol merging done by
> *************** lto_symtab_merge_cgraph_nodes_1 (void **
> *** 762,779 ****
> 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_EACH_FUNCTION (node)
> ! if ((node->thunk.thunk_p || node->alias)
> ! && node->thunk.alias)
> ! node->thunk.alias = lto_symtab_prevailing_decl (node->thunk.alias);
> FOR_EACH_VARIABLE (vnode)
> ! 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. */
> --- 644,676 ----
> void
> lto_symtab_merge_cgraph_nodes (void)
> {
> ! struct cgraph_node *cnode;
> struct varpool_node *vnode;
> ! symtab_node node;
> !
> ! /* Populate assembler name hash. */
> ! symtab_initialize_asm_name_hash ();
>
> ! if (!flag_ltrans)
> ! FOR_EACH_SYMBOL (node)
> ! if (TREE_PUBLIC (node->symbol.decl)
> ! && node->symbol.next_sharing_asm_name
> ! && !node->symbol.previous_sharing_asm_name)
> ! lto_symtab_merge_cgraph_nodes_1 (node);
> !
> ! FOR_EACH_FUNCTION (cnode)
> ! {
> ! if ((cnode->thunk.thunk_p || cnode->alias)
> ! && cnode->thunk.alias)
> ! cnode->thunk.alias = lto_symtab_prevailing_decl
> (cnode->thunk.alias);
> ! cnode->symbol.aux = NULL;
> ! }
> FOR_EACH_VARIABLE (vnode)
> ! {
> ! if (vnode->alias_of)
> ! vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of);
> ! vnode->symbol.aux = NULL;
> ! }
> }
>
> /* Given the decl DECL, return the prevailing decl with the same name. */
> *************** lto_symtab_merge_cgraph_nodes (void)
> *** 781,787 ****
> tree
> lto_symtab_prevailing_decl (tree decl)
> {
> ! lto_symtab_entry_t ret;
>
> /* Builtins and local symbols are their own prevailing decl. */
> if (!TREE_PUBLIC (decl) || is_builtin_fn (decl))
> --- 678,684 ----
> tree
> lto_symtab_prevailing_decl (tree decl)
> {
> ! symtab_node ret;
>
> /* Builtins and local symbols are their own prevailing decl. */
> if (!TREE_PUBLIC (decl) || is_builtin_fn (decl))
> *************** lto_symtab_prevailing_decl (tree decl)
> *** 795,806 ****
> gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
>
> /* Walk through the list of candidates and return the one we merged to.
> */
> ! ret = lto_symtab_get ((*targetm.asm_out.mangle_assembler_name)
> ! (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
> if (!ret)
> ! return NULL_TREE;
>
> ! return ret->decl;
> }
> -
> - #include "gt-lto-symtab.h"
> --- 692,700 ----
> gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
>
> /* Walk through the list of candidates and return the one we merged to.
> */
> ! ret = symtab_node_for_asm (DECL_ASSEMBLER_NAME (decl));
> if (!ret)
> ! return decl;
>
> ! return ret->symbol.decl;
> }
> Index: lto/lto.c
> ===================================================================
> *** lto/lto.c (revision 191418)
> --- lto/lto.c (working copy)
> *************** lto_materialize_function (struct cgraph_
> *** 198,204 ****
> and also functions that are needed to produce virtual clones. */
> if (cgraph_function_with_gimple_body_p (node) || has_analyzed_clone_p
> (node))
> {
> ! /* Clones and thunks don't need to be read. */
> if (node->clone_of)
> return;
>
> --- 198,204 ----
> and also functions that are needed to produce virtual clones. */
> if (cgraph_function_with_gimple_body_p (node) || has_analyzed_clone_p
> (node))
> {
> ! /* Clones don't need to be read. */
> if (node->clone_of)
> return;
>
> *************** read_cgraph_and_symbols (unsigned nfiles
> *** 3006,3012 ****
> VEC_safe_push (ipa_opt_pass, heap,
> node->ipa_transforms_to_apply,
> (ipa_opt_pass)&pass_ipa_inline);
> - lto_symtab_free ();
>
> timevar_pop (TV_IPA_LTO_CGRAPH_MERGE);
>
> --- 3006,3011 ----
> *************** materialize_cgraph (void)
> *** 3035,3041 ****
> fprintf (stderr,
> flag_wpa ? "Materializing decls:" : "Reading function bodies:");
>
> -
> /* Now that we have input the cgraph, we need to clear all of the aux
> nodes and read the functions if we are not running in WPA mode. */
> timevar_push (TV_IPA_LTO_GIMPLE_IN);
> --- 3034,3039 ----
> Index: lto-streamer.h
> ===================================================================
> *** lto-streamer.h (revision 191418)
> --- lto-streamer.h (working copy)
> *************** extern void lto_symtab_merge_decls (void
> *** 866,872 ****
> extern void lto_symtab_merge_cgraph_nodes (void);
> extern tree lto_symtab_prevailing_decl (tree decl);
> extern enum ld_plugin_symbol_resolution lto_symtab_get_resolution (tree
> decl);
> - extern void lto_symtab_free (void);
> extern GTY(()) VEC(tree,gc) *lto_global_var_decls;
>
>
> --- 866,871 ----
> Index: lto-cgraph.c
> ===================================================================
> *** lto-cgraph.c (revision 191418)
> --- lto-cgraph.c (working copy)
> *************** add_references (lto_symtab_encoder_t enc
> *** 668,677 ****
> if (symtab_function_p (ref->referred))
> add_node_to (encoder, ipa_ref_node (ref), false);
> else
> ! {
> ! struct varpool_node *vnode = ipa_ref_varpool_node (ref);
> ! lto_symtab_encoder_encode (encoder, (symtab_node)vnode);
> ! }
> }
>
> /* Find all symbols we want to stream into given partition and insert them
> --- 668,674 ----
> if (symtab_function_p (ref->referred))
> add_node_to (encoder, ipa_ref_node (ref), false);
> else
> ! lto_symtab_encoder_encode (encoder, ref->referred);
> }
>
> /* Find all symbols we want to stream into given partition and insert them
> Index: varpool.c
> ===================================================================
> *** varpool.c (revision 191418)
> --- varpool.c (working copy)
> *************** varpool_assemble_decl (struct varpool_no
> *** 301,306 ****
> --- 301,310 ----
> && !targetm.have_tls)
> return false;
>
> + /* Hard register vars do not need to be output. */
> + if (DECL_HARD_REGISTER (decl))
> + return false;
> +
> gcc_checking_assert (!TREE_ASM_WRITTEN (decl)
> && TREE_CODE (decl) == VAR_DECL
> && !DECL_HAS_VALUE_EXPR_P (decl));