Commit 3fddb2ef by Jan Hubicka Committed by Jan Hubicka

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
parent f36932a2
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> 2015-12-15 Ilya Verbin <ilya.verbin@intel.com>
* lto.c: Include stringpool.h and fold-const.h. * lto.c: Include stringpool.h and fold-const.h.
......
...@@ -517,6 +517,8 @@ lto_symtab_merge_p (tree prevailing, tree decl) ...@@ -517,6 +517,8 @@ lto_symtab_merge_p (tree prevailing, tree decl)
"TREE_CODE mismatch\n"); "TREE_CODE mismatch\n");
return false; return false;
} }
gcc_checking_assert (TREE_CHAIN (prevailing) == TREE_CHAIN (decl));
if (TREE_CODE (prevailing) == FUNCTION_DECL) if (TREE_CODE (prevailing) == FUNCTION_DECL)
{ {
if (DECL_BUILT_IN (prevailing) != DECL_BUILT_IN (decl)) if (DECL_BUILT_IN (prevailing) != DECL_BUILT_IN (decl))
...@@ -883,6 +885,11 @@ lto_symtab_merge_symbols_1 (symtab_node *prevailing) ...@@ -883,6 +885,11 @@ lto_symtab_merge_symbols_1 (symtab_node *prevailing)
else else
{ {
DECL_INITIAL (e->decl) = error_mark_node; 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)); symtab->call_varpool_removal_hooks (dyn_cast<varpool_node *> (e));
} }
e->remove_all_references (); e->remove_all_references ();
...@@ -968,3 +975,33 @@ lto_symtab_merge_symbols (void) ...@@ -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;
}
...@@ -20,6 +20,7 @@ along with GCC; see the file COPYING3. If not see ...@@ -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_decls (void);
extern void lto_symtab_merge_symbols (void); extern void lto_symtab_merge_symbols (void);
extern tree lto_symtab_prevailing_decl (tree decl); extern tree lto_symtab_prevailing_decl (tree decl);
extern tree lto_symtab_prevailing_virtual_decl (tree decl);
/* Mark DECL to be previailed by PREVAILING. /* Mark DECL to be previailed by PREVAILING.
Use DECL_ABSTRACT_ORIGIN and DECL_CHAIN as special markers; those do not Use DECL_ABSTRACT_ORIGIN and DECL_CHAIN as special markers; those do not
...@@ -31,6 +32,7 @@ inline void ...@@ -31,6 +32,7 @@ inline void
lto_symtab_prevail_decl (tree prevailing, tree decl) lto_symtab_prevail_decl (tree prevailing, tree decl)
{ {
gcc_checking_assert (DECL_ABSTRACT_ORIGIN (decl) != error_mark_node); gcc_checking_assert (DECL_ABSTRACT_ORIGIN (decl) != error_mark_node);
gcc_assert (TREE_PUBLIC (decl) || DECL_EXTERNAL (decl));
DECL_CHAIN (decl) = prevailing; DECL_CHAIN (decl) = prevailing;
DECL_ABSTRACT_ORIGIN (decl) = error_mark_node; DECL_ABSTRACT_ORIGIN (decl) = error_mark_node;
} }
...@@ -43,5 +45,12 @@ lto_symtab_prevailing_decl (tree decl) ...@@ -43,5 +45,12 @@ lto_symtab_prevailing_decl (tree decl)
if (DECL_ABSTRACT_ORIGIN (decl) == error_mark_node) if (DECL_ABSTRACT_ORIGIN (decl) == error_mark_node)
return DECL_CHAIN (decl); return DECL_CHAIN (decl);
else 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;
}
} }
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment