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
This commit is contained in:
Jan Hubicka 2015-12-16 05:58:13 +01:00 committed by Jan Hubicka
parent f36932a2c7
commit 3fddb2efc2
3 changed files with 54 additions and 1 deletions

View file

@ -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.

View file

@ -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;
}

View file

@ -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;
}
}