symtab.c (insert_to_assembler_name_hash): Do not insert register vars.
* 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. From-SVN: r191466
This commit is contained in:
parent
9745abfd1c
commit
b5493fb2fa
9 changed files with 317 additions and 326 deletions
|
@ -1,3 +1,45 @@
|
|||
2012-09-19 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* 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.
|
||||
|
||||
2012-09-19 Richard Guenther <rguenther@suse.de>
|
||||
|
||||
PR other/53316
|
||||
|
|
25
gcc/cgraph.h
25
gcc/cgraph.h
|
@ -704,6 +704,8 @@ bool varpool_for_node_and_aliases (struct varpool_node *,
|
|||
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
|
||||
|
@ -1309,4 +1311,27 @@ cgraph_mark_force_output_node (struct cgraph_node *node)
|
|||
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 */
|
||||
|
|
|
@ -668,10 +668,7 @@ add_references (lto_symtab_encoder_t encoder,
|
|||
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);
|
||||
}
|
||||
lto_symtab_encoder_encode (encoder, ref->referred);
|
||||
}
|
||||
|
||||
/* Find all symbols we want to stream into given partition and insert them
|
||||
|
|
|
@ -866,7 +866,6 @@ extern void lto_symtab_merge_decls (void);
|
|||
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;
|
||||
|
||||
|
||||
|
|
510
gcc/lto-symtab.c
510
gcc/lto-symtab.c
|
@ -32,98 +32,19 @@ along with GCC; see the file COPYING3. If not see
|
|||
/* 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
|
||||
/* Return true if the resolution was guessed and not obtained from
|
||||
the file. */
|
||||
static inline bool
|
||||
resolution_guessed_p (symtab_node node)
|
||||
{
|
||||
/* 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 node->symbol.aux != 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)
|
||||
/* Set guessed flag for NODE. */
|
||||
static inline void
|
||||
set_resolution_guessed (symtab_node node, bool value)
|
||||
{
|
||||
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);
|
||||
node->symbol.aux = (void *)(size_t)value;
|
||||
}
|
||||
|
||||
/* Registers DECL with the LTO symbol table as having resolution RESOLUTION
|
||||
|
@ -134,8 +55,7 @@ lto_symtab_register_decl (tree decl,
|
|||
ld_plugin_symbol_resolution_t resolution,
|
||||
struct lto_file_decl_data *file_data)
|
||||
{
|
||||
lto_symtab_entry_t new_entry;
|
||||
void **slot;
|
||||
symtab_node node;
|
||||
|
||||
/* Check that declarations reaching this function do not have
|
||||
properties inconsistent with having external linkage. If any of
|
||||
|
@ -153,54 +73,15 @@ lto_symtab_register_decl (tree decl,
|
|||
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;
|
||||
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));
|
||||
}
|
||||
}
|
||||
|
||||
/* 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. */
|
||||
|
||||
|
@ -277,12 +158,15 @@ lto_varpool_replace_node (struct varpool_node *vnode,
|
|||
should be emitted. */
|
||||
|
||||
static bool
|
||||
lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
|
||||
lto_symtab_merge (symtab_node prevailing, symtab_node entry)
|
||||
{
|
||||
tree prevailing_decl = prevailing->decl;
|
||||
tree decl = entry->decl;
|
||||
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);
|
||||
|
@ -377,17 +261,17 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
|
|||
entry. */
|
||||
|
||||
static bool
|
||||
lto_symtab_resolve_replaceable_p (lto_symtab_entry_t e)
|
||||
lto_symtab_resolve_replaceable_p (symtab_node e)
|
||||
{
|
||||
if (DECL_EXTERNAL (e->decl)
|
||||
|| DECL_COMDAT (e->decl)
|
||||
|| DECL_ONE_ONLY (e->decl)
|
||||
|| DECL_WEAK (e->decl))
|
||||
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->decl) == VAR_DECL)
|
||||
return (DECL_COMMON (e->decl)
|
||||
|| (!flag_no_common && !DECL_INITIAL (e->decl)));
|
||||
if (TREE_CODE (e->symbol.decl) == VAR_DECL)
|
||||
return (DECL_COMMON (e->symbol.decl)
|
||||
|| (!flag_no_common && !DECL_INITIAL (e->symbol.decl)));
|
||||
|
||||
return false;
|
||||
}
|
||||
|
@ -395,24 +279,23 @@ lto_symtab_resolve_replaceable_p (lto_symtab_entry_t e)
|
|||
/* 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)
|
||||
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->decl))
|
||||
if (DECL_EXTERNAL (e->symbol.decl))
|
||||
return false;
|
||||
|
||||
/* For functions we need a non-discarded body. */
|
||||
if (TREE_CODE (e->decl) == FUNCTION_DECL)
|
||||
return (e->node && e->node->analyzed);
|
||||
if (TREE_CODE (e->symbol.decl) == FUNCTION_DECL)
|
||||
return (cgraph (e)->analyzed);
|
||||
|
||||
else if (TREE_CODE (e->decl) == VAR_DECL)
|
||||
{
|
||||
if (!e->vnode)
|
||||
return false;
|
||||
return e->vnode->finalized;
|
||||
}
|
||||
else if (TREE_CODE (e->symbol.decl) == VAR_DECL)
|
||||
return varpool (e)->finalized;
|
||||
|
||||
gcc_unreachable ();
|
||||
}
|
||||
|
@ -421,23 +304,18 @@ lto_symtab_resolve_can_prevail_p (lto_symtab_entry_t e)
|
|||
their resolutions. */
|
||||
|
||||
static void
|
||||
lto_symtab_resolve_symbols (void **slot)
|
||||
lto_symtab_resolve_symbols (symtab_node first)
|
||||
{
|
||||
lto_symtab_entry_t e;
|
||||
lto_symtab_entry_t prevailing = NULL;
|
||||
symtab_node e;
|
||||
symtab_node 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;
|
||||
}
|
||||
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)
|
||||
|
@ -445,26 +323,26 @@ lto_symtab_resolve_symbols (void **slot)
|
|||
|
||||
/* Find the single non-replaceable prevailing symbol and
|
||||
diagnose ODR violations. */
|
||||
for (e = (lto_symtab_entry_t) *slot; e; e = e->next)
|
||||
for (e = first; e; e = e->symbol.next_sharing_asm_name)
|
||||
{
|
||||
if (!lto_symtab_resolve_can_prevail_p (e))
|
||||
{
|
||||
e->resolution = LDPR_RESOLVED_IR;
|
||||
e->guessed = true;
|
||||
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->resolution = LDPR_PREEMPTED_IR;
|
||||
e->guessed = true;
|
||||
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->decl),
|
||||
"%qD has already been defined", e->decl);
|
||||
inform (DECL_SOURCE_LOCATION (prevailing->decl),
|
||||
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;
|
||||
|
@ -474,13 +352,14 @@ lto_symtab_resolve_symbols (void **slot)
|
|||
goto found;
|
||||
|
||||
/* Do a second round choosing one from the replaceable prevailing decls. */
|
||||
for (e = (lto_symtab_entry_t) *slot; e; e = e->next)
|
||||
for (e = first; e; e = e->symbol.next_sharing_asm_name)
|
||||
{
|
||||
if (e->resolution != LDPR_PREEMPTED_IR)
|
||||
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->decl) == FUNCTION_DECL)
|
||||
if (TREE_CODE (e->symbol.decl) == FUNCTION_DECL)
|
||||
{
|
||||
prevailing = e;
|
||||
break;
|
||||
|
@ -488,8 +367,8 @@ lto_symtab_resolve_symbols (void **slot)
|
|||
|
||||
/* From variables that can prevail choose the largest one. */
|
||||
if (!prevailing
|
||||
|| tree_int_cst_lt (DECL_SIZE (prevailing->decl),
|
||||
DECL_SIZE (e->decl))
|
||||
|| 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
|
||||
|
@ -499,11 +378,11 @@ lto_symtab_resolve_symbols (void **slot)
|
|||
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)))
|
||||
|| (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;
|
||||
}
|
||||
|
||||
|
@ -524,8 +403,8 @@ found:
|
|||
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;
|
||||
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
|
||||
|
@ -533,24 +412,25 @@ found:
|
|||
do not issue further diagnostics.*/
|
||||
|
||||
static void
|
||||
lto_symtab_merge_decls_2 (void **slot, bool diagnosed_p)
|
||||
lto_symtab_merge_decls_2 (symtab_node first, bool diagnosed_p)
|
||||
{
|
||||
lto_symtab_entry_t prevailing, e;
|
||||
symtab_node 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)
|
||||
prevailing = first;
|
||||
if (!prevailing->symbol.next_sharing_asm_name)
|
||||
return;
|
||||
|
||||
/* Try to merge each entry with the prevailing one. */
|
||||
for (e = prevailing->next; e; e = e->next)
|
||||
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->decl);
|
||||
VEC_safe_push (tree, heap, mismatches, e->symbol.decl);
|
||||
}
|
||||
if (VEC_empty (tree, mismatches))
|
||||
return;
|
||||
|
@ -558,13 +438,15 @@ lto_symtab_merge_decls_2 (void **slot, bool diagnosed_p)
|
|||
/* Diagnose all mismatched re-declarations. */
|
||||
FOR_EACH_VEC_ELT (tree, mismatches, i, decl)
|
||||
{
|
||||
if (!types_compatible_p (TREE_TYPE (prevailing->decl), TREE_TYPE (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->decl) && DECL_USER_ALIGN (decl))
|
||||
&& DECL_ALIGN (prevailing->decl) < DECL_ALIGN (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 "
|
||||
|
@ -572,7 +454,7 @@ lto_symtab_merge_decls_2 (void **slot, bool diagnosed_p)
|
|||
}
|
||||
}
|
||||
if (diagnosed_p)
|
||||
inform (DECL_SOURCE_LOCATION (prevailing->decl),
|
||||
inform (DECL_SOURCE_LOCATION (prevailing->symbol.decl),
|
||||
"previously declared here");
|
||||
|
||||
VEC_free (tree, heap, mismatches);
|
||||
|
@ -580,47 +462,50 @@ lto_symtab_merge_decls_2 (void **slot, bool diagnosed_p)
|
|||
|
||||
/* 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)
|
||||
static void
|
||||
lto_symtab_merge_decls_1 (symtab_node first)
|
||||
{
|
||||
lto_symtab_entry_t e, prevailing;
|
||||
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. */
|
||||
lto_symtab_resolve_symbols (slot);
|
||||
linker plugin and resolution was decided by the linker. */
|
||||
lto_symtab_resolve_symbols (first);
|
||||
|
||||
/* Find the prevailing decl. */
|
||||
for (prevailing = (lto_symtab_entry_t) *slot;
|
||||
for (prevailing = first;
|
||||
prevailing
|
||||
&& prevailing->resolution != LDPR_PREVAILING_DEF_IRONLY
|
||||
&& prevailing->resolution != LDPR_PREVAILING_DEF_IRONLY_EXP
|
||||
&& prevailing->resolution != LDPR_PREVAILING_DEF;
|
||||
prevailing = prevailing->next)
|
||||
&& (!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->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));
|
||||
}
|
||||
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 = (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;
|
||||
prevailing = first;
|
||||
/* For variables chose with a priority variant with vnode
|
||||
attached (i.e. from unit where external declaration of
|
||||
variable is actually used).
|
||||
|
@ -628,49 +513,45 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
|
|||
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)
|
||||
if (TREE_CODE (prevailing->symbol.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))))
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
/* 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;
|
||||
}
|
||||
symtab_prevail_in_asm_name_hash (prevailing);
|
||||
|
||||
/* Record the prevailing variable. */
|
||||
if (TREE_CODE (prevailing->decl) == VAR_DECL)
|
||||
VEC_safe_push (tree, gc, lto_global_var_decls, prevailing->decl);
|
||||
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->next; e; e = e->next)
|
||||
for (e = prevailing->symbol.next_sharing_asm_name;
|
||||
e; e = e->symbol.next_sharing_asm_name)
|
||||
{
|
||||
if (TREE_CODE (prevailing->decl) == TREE_CODE (e->decl))
|
||||
if (TREE_CODE (prevailing->symbol.decl)
|
||||
== TREE_CODE (e->symbol.decl))
|
||||
continue;
|
||||
|
||||
switch (TREE_CODE (prevailing->decl))
|
||||
switch (TREE_CODE (prevailing->symbol.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);
|
||||
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->decl) == VAR_DECL);
|
||||
error_at (DECL_SOURCE_LOCATION (e->decl),
|
||||
"function %qD redeclared as variable", prevailing->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:
|
||||
|
@ -680,12 +561,19 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
|
|||
diagnosed_p = true;
|
||||
}
|
||||
if (diagnosed_p)
|
||||
inform (DECL_SOURCE_LOCATION (prevailing->decl),
|
||||
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 (slot, diagnosed_p);
|
||||
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
|
||||
|
@ -698,11 +586,9 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
|
|||
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;
|
||||
if (resolution_guessed_p (prevailing))
|
||||
prevailing->symbol.resolution = LDPR_UNKNOWN;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Resolve and merge all symbol table chains to a prevailing decl. */
|
||||
|
@ -710,50 +596,46 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
|
|||
void
|
||||
lto_symtab_merge_decls (void)
|
||||
{
|
||||
lto_symtab_maybe_init_hash_table ();
|
||||
htab_traverse (lto_symtab_identifiers, lto_symtab_merge_decls_1, NULL);
|
||||
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 int
|
||||
lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED)
|
||||
static void
|
||||
lto_symtab_merge_cgraph_nodes_1 (symtab_node prevailing)
|
||||
{
|
||||
lto_symtab_entry_t e, prevailing = (lto_symtab_entry_t) *slot;
|
||||
|
||||
if (!prevailing->next)
|
||||
return 1;
|
||||
symtab_node e, next;
|
||||
|
||||
/* Replace the cgraph node of each entry with the prevailing one. */
|
||||
for (e = prevailing->next; e; e = e->next)
|
||||
for (e = prevailing->symbol.next_sharing_asm_name; 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);
|
||||
}
|
||||
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));
|
||||
}
|
||||
|
||||
/* Drop all but the prevailing decl from the symtab. */
|
||||
prevailing->next = NULL;
|
||||
|
||||
return 1;
|
||||
return;
|
||||
}
|
||||
|
||||
/* Merge cgraph nodes according to the symbol merging done by
|
||||
|
@ -762,18 +644,33 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED)
|
|||
void
|
||||
lto_symtab_merge_cgraph_nodes (void)
|
||||
{
|
||||
struct cgraph_node *node;
|
||||
struct cgraph_node *cnode;
|
||||
struct varpool_node *vnode;
|
||||
lto_symtab_maybe_init_hash_table ();
|
||||
htab_traverse (lto_symtab_identifiers, lto_symtab_merge_cgraph_nodes_1, NULL);
|
||||
symtab_node node;
|
||||
|
||||
FOR_EACH_FUNCTION (node)
|
||||
if ((node->thunk.thunk_p || node->alias)
|
||||
&& node->thunk.alias)
|
||||
node->thunk.alias = lto_symtab_prevailing_decl (node->thunk.alias);
|
||||
/* 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);
|
||||
{
|
||||
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. */
|
||||
|
@ -781,7 +678,7 @@ lto_symtab_merge_cgraph_nodes (void)
|
|||
tree
|
||||
lto_symtab_prevailing_decl (tree decl)
|
||||
{
|
||||
lto_symtab_entry_t ret;
|
||||
symtab_node ret;
|
||||
|
||||
/* Builtins and local symbols are their own prevailing decl. */
|
||||
if (!TREE_PUBLIC (decl) || is_builtin_fn (decl))
|
||||
|
@ -795,12 +692,9 @@ lto_symtab_prevailing_decl (tree decl)
|
|||
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))));
|
||||
ret = symtab_node_for_asm (DECL_ASSEMBLER_NAME (decl));
|
||||
if (!ret)
|
||||
return NULL_TREE;
|
||||
return decl;
|
||||
|
||||
return ret->decl;
|
||||
return ret->symbol.decl;
|
||||
}
|
||||
|
||||
#include "gt-lto-symtab.h"
|
||||
|
|
|
@ -1,3 +1,8 @@
|
|||
2012-09-19 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* lto.c (lto_materialize_function): Update confused comment.
|
||||
(read_cgraph_and_symbols): Do not free symtab.
|
||||
|
||||
2012-09-12 Jan Hubicka <jh@suse.cz>
|
||||
|
||||
* lto.c (do_whole_program_analysis): Care timevars, statistics and
|
||||
|
|
|
@ -198,7 +198,7 @@ lto_materialize_function (struct cgraph_node *node)
|
|||
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. */
|
||||
/* Clones don't need to be read. */
|
||||
if (node->clone_of)
|
||||
return;
|
||||
|
||||
|
@ -3006,7 +3006,6 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
|
|||
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);
|
||||
|
||||
|
@ -3035,7 +3034,6 @@ materialize_cgraph (void)
|
|||
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);
|
||||
|
|
47
gcc/symtab.c
47
gcc/symtab.c
|
@ -104,6 +104,8 @@ eq_assembler_name (const void *p1, const void *p2)
|
|||
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)
|
||||
|
@ -151,9 +153,20 @@ unlink_from_assembler_name_hash (symtab_node node)
|
|||
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. */
|
||||
|
@ -287,6 +300,22 @@ symtab_remove_node (symtab_node node)
|
|||
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 =
|
||||
htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name,
|
||||
NULL);
|
||||
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. */
|
||||
|
||||
|
@ -296,15 +325,7 @@ symtab_node_for_asm (const_tree asmname)
|
|||
symtab_node node;
|
||||
void **slot;
|
||||
|
||||
if (!assembler_name_hash)
|
||||
{
|
||||
assembler_name_hash =
|
||||
htab_create_ggc (10, hash_node_by_assembler_name, eq_assembler_name,
|
||||
NULL);
|
||||
FOR_EACH_SYMBOL (node)
|
||||
insert_to_assembler_name_hash (node);
|
||||
}
|
||||
|
||||
symtab_initialize_asm_name_hash ();
|
||||
slot = htab_find_slot_with_hash (assembler_name_hash, asmname,
|
||||
decl_assembler_name_hash (asmname),
|
||||
NO_INSERT);
|
||||
|
@ -507,6 +528,9 @@ dump_symtab_base (FILE *f, symtab_node node)
|
|||
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. */
|
||||
|
@ -597,7 +621,8 @@ verify_symtab_base (symtab_node node)
|
|||
break;
|
||||
hashed_node = hashed_node->symbol.next_sharing_asm_name;
|
||||
}
|
||||
if (!hashed_node)
|
||||
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;
|
||||
|
@ -733,6 +758,8 @@ symtab_make_decl_local (tree decl)
|
|||
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;
|
||||
|
|
|
@ -301,6 +301,10 @@ varpool_assemble_decl (struct varpool_node *node)
|
|||
&& !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));
|
||||
|
|
Loading…
Add table
Reference in a new issue