aboutsummaryrefslogtreecommitdiff
path: root/gcc/lto
diff options
context:
space:
mode:
authorJan Hubicka <hubicka@ucw.cz>2015-12-16 05:58:13 +0100
committerJan Hubicka <hubicka@gcc.gnu.org>2015-12-16 04:58:13 +0000
commit3fddb2efc21a7724a7de2cca9bc277bb2bff473e (patch)
tree50380b892bb7c1e747b43a8008d0ed35b5021ef3 /gcc/lto
parentf36932a2c7418a5a2f1f62f4a968147e054d45d4 (diff)
downloadgcc-3fddb2efc21a7724a7de2cca9bc277bb2bff473e.zip
gcc-3fddb2efc21a7724a7de2cca9bc277bb2bff473e.tar.gz
gcc-3fddb2efc21a7724a7de2cca9bc277bb2bff473e.tar.bz2
re PR middle-end/68878 (471.omnetpp in SPEC CPU 2006 is miscompiled with LTO)
PR lto/68878 * lto-symtab.c (lto_symtab_prevailing_virtual_decl): New function. * lto-symtab.h (lto_symtab_prevailing_virtual_decl): Declare. (lto_symtab_prevailing_decl): Use it. From-SVN: r231671
Diffstat (limited to 'gcc/lto')
-rw-r--r--gcc/lto/ChangeLog7
-rw-r--r--gcc/lto/lto-symtab.c37
-rw-r--r--gcc/lto/lto-symtab.h11
3 files changed, 54 insertions, 1 deletions
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index ac20a3f..1e509b1 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,10 @@
+2015-12-10 Jan Hubicka <hubicka@ucw.cz>
+
+ PR lto/68878
+ * lto-symtab.c (lto_symtab_prevailing_virtual_decl): New function.
+ * lto-symtab.h (lto_symtab_prevailing_virtual_decl): Declare.
+ (lto_symtab_prevailing_decl): Use it.
+
2015-12-15 Ilya Verbin <ilya.verbin@intel.com>
* lto.c: Include stringpool.h and fold-const.h.
diff --git a/gcc/lto/lto-symtab.c b/gcc/lto/lto-symtab.c
index 35c690a..957fbf6 100644
--- a/gcc/lto/lto-symtab.c
+++ b/gcc/lto/lto-symtab.c
@@ -517,6 +517,8 @@ lto_symtab_merge_p (tree prevailing, tree decl)
"TREE_CODE mismatch\n");
return false;
}
+ gcc_checking_assert (TREE_CHAIN (prevailing) == TREE_CHAIN (decl));
+
if (TREE_CODE (prevailing) == FUNCTION_DECL)
{
if (DECL_BUILT_IN (prevailing) != DECL_BUILT_IN (decl))
@@ -883,6 +885,11 @@ lto_symtab_merge_symbols_1 (symtab_node *prevailing)
else
{
DECL_INITIAL (e->decl) = error_mark_node;
+ if (e->lto_file_data)
+ {
+ lto_free_function_in_decl_state_for_node (e);
+ e->lto_file_data = NULL;
+ }
symtab->call_varpool_removal_hooks (dyn_cast<varpool_node *> (e));
}
e->remove_all_references ();
@@ -968,3 +975,33 @@ lto_symtab_merge_symbols (void)
}
}
}
+
+/* Virtual tables may matter for code generation even if they are not
+ directly refernced by the code because they may be used for devirtualizaiton.
+ For this reason it is important to merge even virtual tables that have no
+ associated symbol table entries. Without doing so we lose optimization
+ oppurtunities by losing track of the vtable constructor.
+ FIXME: we probably ought to introduce explicit symbol table entries for
+ those before streaming. */
+
+tree
+lto_symtab_prevailing_virtual_decl (tree decl)
+{
+ gcc_checking_assert (!type_in_anonymous_namespace_p (DECL_CONTEXT (decl))
+ && DECL_ASSEMBLER_NAME_SET_P (decl));
+
+ symtab_node *n = symtab_node::get_for_asmname
+ (DECL_ASSEMBLER_NAME (decl));
+ while (n && ((!DECL_EXTERNAL (n->decl) && !TREE_PUBLIC (n->decl))
+ || !DECL_VIRTUAL_P (n->decl)))
+ n = n->next_sharing_asm_name;
+ if (n)
+ {
+ lto_symtab_prevail_decl (n->decl, decl);
+ decl = n->decl;
+ }
+ else
+ symtab_node::get_create (decl);
+
+ return decl;
+}
diff --git a/gcc/lto/lto-symtab.h b/gcc/lto/lto-symtab.h
index c6b68b6..4c44631 100644
--- a/gcc/lto/lto-symtab.h
+++ b/gcc/lto/lto-symtab.h
@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see
extern void lto_symtab_merge_decls (void);
extern void lto_symtab_merge_symbols (void);
extern tree lto_symtab_prevailing_decl (tree decl);
+extern tree lto_symtab_prevailing_virtual_decl (tree decl);
/* Mark DECL to be previailed by PREVAILING.
Use DECL_ABSTRACT_ORIGIN and DECL_CHAIN as special markers; those do not
@@ -31,6 +32,7 @@ inline void
lto_symtab_prevail_decl (tree prevailing, tree decl)
{
gcc_checking_assert (DECL_ABSTRACT_ORIGIN (decl) != error_mark_node);
+ gcc_assert (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl));
DECL_CHAIN (decl) = prevailing;
DECL_ABSTRACT_ORIGIN (decl) = error_mark_node;
}
@@ -43,5 +45,12 @@ lto_symtab_prevailing_decl (tree decl)
if (DECL_ABSTRACT_ORIGIN (decl) == error_mark_node)
return DECL_CHAIN (decl);
else
- return decl;
+ {
+ if ((TREE_CODE (decl) == VAR_DECL || TREE_CODE (decl) == FUNCTION_DECL)
+ && DECL_VIRTUAL_P (decl)
+ && (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl))
+ && !symtab_node::get (decl))
+ return lto_symtab_prevailing_virtual_decl (decl);
+ return decl;
+ }
}