aboutsummaryrefslogtreecommitdiff
path: root/gcc/lto-symtab.c
diff options
context:
space:
mode:
authorRichard Guenther <rguenther@suse.de>2012-09-27 09:11:18 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2012-09-27 09:11:18 +0000
commite649d346e789ca15524872c11a40288113c27d50 (patch)
treeff86bf776914366000628c9bf9dc4c0d6d38f8c8 /gcc/lto-symtab.c
parenta80f7a710e9bb7f5873b197d127aa30630ce6e4f (diff)
downloadgcc-e649d346e789ca15524872c11a40288113c27d50.zip
gcc-e649d346e789ca15524872c11a40288113c27d50.tar.gz
gcc-e649d346e789ca15524872c11a40288113c27d50.tar.bz2
re PR lto/54709 (r191713 breaks Firefox build)
2012-09-27 Richard Guenther <rguenther@suse.de> PR lto/54709 * lto-symtab.c (resolution_guessed_p): Remove. (set_resolution_guessed): Likewise. (lto_symtab_register_decl): Remove assert. (lto_symtab_resolve_symbols): Do not alter symbol resolutions and return the prevailing symbol, checking for multiple prevailing symbols here. (lto_symtab_merge_decls_1): Use the result from lto_symtab_resolve_symbols. Do not alter symbol resolutions. * gcc.dg/lto/pr54709_0.c: New testcase. * gcc.dg/lto/pr54709_1.c: Likewise. From-SVN: r191798
Diffstat (limited to 'gcc/lto-symtab.c')
-rw-r--r--gcc/lto-symtab.c107
1 files changed, 22 insertions, 85 deletions
diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c
index a8a4657..cd8ca67 100644
--- a/gcc/lto-symtab.c
+++ b/gcc/lto-symtab.c
@@ -32,21 +32,6 @@ 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;
-/* 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
and read from FILE_DATA. */
@@ -78,7 +63,6 @@ lto_symtab_register_decl (tree decl,
{
node->symbol.resolution = resolution;
gcc_assert (node->symbol.lto_file_data == file_data);
- gcc_assert (!resolution_guessed_p (node));
}
}
@@ -303,7 +287,7 @@ lto_symtab_resolve_can_prevail_p (symtab_node e)
/* Resolve the symbol with the candidates in the chain *SLOT and store
their resolutions. */
-static void
+static symtab_node
lto_symtab_resolve_symbols (symtab_node first)
{
symtab_node e;
@@ -315,27 +299,33 @@ lto_symtab_resolve_symbols (symtab_node first)
&& (e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
|| e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
|| e->symbol.resolution == LDPR_PREVAILING_DEF))
- prevailing = e;
+ {
+ prevailing = e;
+ break;
+ }
/* If the chain is already resolved there is nothing else to do. */
if (prevailing)
- return;
+ {
+ /* Assert it's the only one. */
+ 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));
+ return prevailing;
+ }
/* 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;
- }
+ 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 we have a non-replaceable definition it prevails. */
if (!lto_symtab_resolve_replaceable_p (e))
{
if (prevailing)
@@ -349,12 +339,12 @@ lto_symtab_resolve_symbols (symtab_node first)
}
}
if (prevailing)
- goto found;
+ return prevailing;
/* 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
+ if (!lto_symtab_resolve_can_prevail_p (e)
|| !symtab_real_symbol_p (e))
continue;
@@ -386,25 +376,7 @@ lto_symtab_resolve_symbols (symtab_node first)
prevailing = e;
}
- if (!prevailing)
- return;
-
-found:
- /* If current lto files represent the whole program,
- it is correct to use LDPR_PREVALING_DEF_IRONLY.
- If current lto files are part of whole program, internal
- resolver doesn't know if it is LDPR_PREVAILING_DEF
- or LDPR_PREVAILING_DEF_IRONLY. Use IRONLY conforms to
- using -fwhole-program. Otherwise, it doesn't
- matter using either LDPR_PREVAILING_DEF or
- LDPR_PREVAILING_DEF_IRONLY
-
- FIXME: above workaround due to gold plugin makes some
- 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);
+ return prevailing;
}
/* Merge all decls in the symbol table chain to the prevailing decl and
@@ -478,27 +450,7 @@ lto_symtab_merge_decls_1 (symtab_node first)
/* 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));
+ prevailing = lto_symtab_resolve_symbols (first);
/* If there's not a prevailing symbol yet it's an external reference.
Happens a lot during ltrans. Choose the first symbol with a
@@ -574,21 +526,6 @@ lto_symtab_merge_decls_1 (symtab_node first)
for (e = prevailing; 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
- WPA stage.
-
- Do not bother to store guessed decisions. Generic code knows how
- to handle UNKNOWN relocation well.
-
- The problem with storing guessed decision is whether to use
- 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. */