Commit 87e7b310 by Jan Hubicka Committed by Jan Hubicka

re PR lto/47497 (SPEC CPU 2006 failed to link with LTO -fuse-linker-plugin -fwhole-program)

	PR lto/47497
	* lto-symtab.c (lto_cgraph_replace_node): Do not set thunk.alias.
	(lto_symtab_merge_cgraph_nodes_1): Update thunk.alias pointers here.
	* cgraph.h (cgraph_same_body_alias, cgraph_add_thunk): Add node pointers.
	* cgraph.c (cgraph_same_body_alias_1, cgraph_same_body_alias,
	cgraph_add_thunk): Add node pointers.
	* lto-cgraph.c (lto_output_node): Verify that thunks&aliases are
	associated to right node.
	(input_node): Update use of cgraph_same_body_alias
	and cgraph_add_thunk.

	* optimize.c (maybe_clone_body): Update call of cgraph_same_body_alias
	and cgraph_add_thunk.
	* method.c (make_alias_for_thunk, use_thunk): Likewise.
	* mangle.c (mangle_decl): Likewise.

From-SVN: r170682
parent d9c64246
2011-03-04 Jan Hubicka <jh@suse.cz>
PR lto/47497
* lto-symtab.c (lto_cgraph_replace_node): Do not set thunk.alias.
(lto_symtab_merge_cgraph_nodes_1): Update thunk.alias pointers here.
* cgraph.h (cgraph_same_body_alias, cgraph_add_thunk): Add node pointers.
* cgraph.c (cgraph_same_body_alias_1, cgraph_same_body_alias,
cgraph_add_thunk): Add node pointers.
* lto-cgraph.c (lto_output_node): Verify that thunks&aliases are
associated to right node.
(input_node): Update use of cgraph_same_body_alias
and cgraph_add_thunk.
2011-03-04 Changpeng Fang <changpeng.fang@amd.com> 2011-03-04 Changpeng Fang <changpeng.fang@amd.com>
* config/i386/i386.opt (mprefer-avx128): New flag. * config/i386/i386.opt (mprefer-avx128): New flag.
......
...@@ -536,16 +536,16 @@ cgraph_node (tree decl) ...@@ -536,16 +536,16 @@ cgraph_node (tree decl)
return node; return node;
} }
/* Mark ALIAS as an alias to DECL. */ /* Mark ALIAS as an alias to DECL. DECL_NODE is cgraph node representing
the function body is associated with (not neccesarily cgraph_node (DECL). */
static struct cgraph_node * static struct cgraph_node *
cgraph_same_body_alias_1 (tree alias, tree decl) cgraph_same_body_alias_1 (struct cgraph_node *decl_node, tree alias, tree decl)
{ {
struct cgraph_node key, *alias_node, *decl_node, **slot; struct cgraph_node key, *alias_node, **slot;
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
gcc_assert (TREE_CODE (alias) == FUNCTION_DECL); gcc_assert (TREE_CODE (alias) == FUNCTION_DECL);
decl_node = cgraph_node (decl);
key.decl = alias; key.decl = alias;
...@@ -575,7 +575,7 @@ cgraph_same_body_alias_1 (tree alias, tree decl) ...@@ -575,7 +575,7 @@ cgraph_same_body_alias_1 (tree alias, tree decl)
and cgraph_node (ALIAS) transparently returns cgraph_node (DECL). */ and cgraph_node (ALIAS) transparently returns cgraph_node (DECL). */
struct cgraph_node * struct cgraph_node *
cgraph_same_body_alias (tree alias, tree decl) cgraph_same_body_alias (struct cgraph_node *decl_node, tree alias, tree decl)
{ {
#ifndef ASM_OUTPUT_DEF #ifndef ASM_OUTPUT_DEF
/* If aliases aren't supported by the assembler, fail. */ /* If aliases aren't supported by the assembler, fail. */
...@@ -584,7 +584,7 @@ cgraph_same_body_alias (tree alias, tree decl) ...@@ -584,7 +584,7 @@ cgraph_same_body_alias (tree alias, tree decl)
/*gcc_assert (!assembler_name_hash);*/ /*gcc_assert (!assembler_name_hash);*/
return cgraph_same_body_alias_1 (alias, decl); return cgraph_same_body_alias_1 (decl_node, alias, decl);
} }
/* Add thunk alias into callgraph. The alias declaration is ALIAS and it /* Add thunk alias into callgraph. The alias declaration is ALIAS and it
...@@ -592,7 +592,8 @@ cgraph_same_body_alias (tree alias, tree decl) ...@@ -592,7 +592,8 @@ cgraph_same_body_alias (tree alias, tree decl)
See comments in thunk_adjust for detail on the parameters. */ See comments in thunk_adjust for detail on the parameters. */
struct cgraph_node * struct cgraph_node *
cgraph_add_thunk (tree alias, tree decl, bool this_adjusting, cgraph_add_thunk (struct cgraph_node *decl_node, tree alias, tree decl,
bool this_adjusting,
HOST_WIDE_INT fixed_offset, HOST_WIDE_INT virtual_value, HOST_WIDE_INT fixed_offset, HOST_WIDE_INT virtual_value,
tree virtual_offset, tree virtual_offset,
tree real_alias) tree real_alias)
...@@ -606,7 +607,7 @@ cgraph_add_thunk (tree alias, tree decl, bool this_adjusting, ...@@ -606,7 +607,7 @@ cgraph_add_thunk (tree alias, tree decl, bool this_adjusting,
cgraph_remove_node (node); cgraph_remove_node (node);
} }
node = cgraph_same_body_alias_1 (alias, decl); node = cgraph_same_body_alias_1 (decl_node, alias, decl);
gcc_assert (node); gcc_assert (node);
gcc_checking_assert (!virtual_offset gcc_checking_assert (!virtual_offset
|| tree_int_cst_equal (virtual_offset, || tree_int_cst_equal (virtual_offset,
...@@ -2722,7 +2723,7 @@ cgraph_propagate_frequency (struct cgraph_node *node) ...@@ -2722,7 +2723,7 @@ cgraph_propagate_frequency (struct cgraph_node *node)
case NODE_FREQUENCY_EXECUTED_ONCE: case NODE_FREQUENCY_EXECUTED_ONCE:
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Called by %s that is executed once\n", fprintf (dump_file, " Called by %s that is executed once\n",
cgraph_node_name (node)); cgraph_node_name (edge->caller));
maybe_unlikely_executed = false; maybe_unlikely_executed = false;
if (edge->loop_nest) if (edge->loop_nest)
{ {
...@@ -2735,7 +2736,7 @@ cgraph_propagate_frequency (struct cgraph_node *node) ...@@ -2735,7 +2736,7 @@ cgraph_propagate_frequency (struct cgraph_node *node)
case NODE_FREQUENCY_NORMAL: case NODE_FREQUENCY_NORMAL:
if (dump_file && (dump_flags & TDF_DETAILS)) if (dump_file && (dump_flags & TDF_DETAILS))
fprintf (dump_file, " Called by %s that is normal or hot\n", fprintf (dump_file, " Called by %s that is normal or hot\n",
cgraph_node_name (node)); cgraph_node_name (edge->caller));
maybe_unlikely_executed = false; maybe_unlikely_executed = false;
maybe_executed_once = false; maybe_executed_once = false;
break; break;
......
...@@ -559,8 +559,8 @@ struct cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void); ...@@ -559,8 +559,8 @@ struct cgraph_indirect_call_info *cgraph_allocate_init_indirect_info (void);
struct cgraph_node * cgraph_get_node (const_tree); struct cgraph_node * cgraph_get_node (const_tree);
struct cgraph_node * cgraph_get_node_or_alias (const_tree); struct cgraph_node * cgraph_get_node_or_alias (const_tree);
struct cgraph_node * cgraph_node (tree); struct cgraph_node * cgraph_node (tree);
struct cgraph_node * cgraph_same_body_alias (tree, tree); struct cgraph_node * cgraph_same_body_alias (struct cgraph_node *, tree, tree);
struct cgraph_node * cgraph_add_thunk (tree, tree, bool, HOST_WIDE_INT, struct cgraph_node * cgraph_add_thunk (struct cgraph_node *, tree, tree, bool, HOST_WIDE_INT,
HOST_WIDE_INT, tree, tree); HOST_WIDE_INT, tree, tree);
void cgraph_remove_same_body_alias (struct cgraph_node *); void cgraph_remove_same_body_alias (struct cgraph_node *);
struct cgraph_node *cgraph_node_for_asm (tree); struct cgraph_node *cgraph_node_for_asm (tree);
......
2011-03-04 Jan Hubicka <jh@suse.cz>
PR lto/47497
* optimize.c (maybe_clone_body): Update call of cgraph_same_body_alias
and cgraph_add_thunk.
* method.c (make_alias_for_thunk, use_thunk): Likewise.
* mangle.c (mangle_decl): Likewise.
2011-03-04 Jason Merrill <jason@redhat.com> 2011-03-04 Jason Merrill <jason@redhat.com>
PR c++/47971 PR c++/47971
......
...@@ -3163,7 +3163,7 @@ mangle_decl (const tree decl) ...@@ -3163,7 +3163,7 @@ mangle_decl (const tree decl)
if (vague_linkage_p (decl)) if (vague_linkage_p (decl))
DECL_WEAK (alias) = 1; DECL_WEAK (alias) = 1;
if (TREE_CODE (decl) == FUNCTION_DECL) if (TREE_CODE (decl) == FUNCTION_DECL)
cgraph_same_body_alias (alias, decl); cgraph_same_body_alias (cgraph_node (decl), alias, decl);
else else
varpool_extra_name_alias (alias, decl); varpool_extra_name_alias (alias, decl);
#endif #endif
......
...@@ -259,7 +259,8 @@ make_alias_for_thunk (tree function) ...@@ -259,7 +259,8 @@ make_alias_for_thunk (tree function)
if (!flag_syntax_only) if (!flag_syntax_only)
{ {
struct cgraph_node *aliasn = cgraph_same_body_alias (alias, function); struct cgraph_node *aliasn = cgraph_same_body_alias (cgraph_node (function),
alias, function);
DECL_ASSEMBLER_NAME (function); DECL_ASSEMBLER_NAME (function);
gcc_assert (aliasn != NULL); gcc_assert (aliasn != NULL);
} }
...@@ -376,7 +377,7 @@ use_thunk (tree thunk_fndecl, bool emit_p) ...@@ -376,7 +377,7 @@ use_thunk (tree thunk_fndecl, bool emit_p)
a = nreverse (t); a = nreverse (t);
DECL_ARGUMENTS (thunk_fndecl) = a; DECL_ARGUMENTS (thunk_fndecl) = a;
TREE_ASM_WRITTEN (thunk_fndecl) = 1; TREE_ASM_WRITTEN (thunk_fndecl) = 1;
cgraph_add_thunk (thunk_fndecl, function, cgraph_add_thunk (cgraph_node (function), thunk_fndecl, function,
this_adjusting, fixed_offset, virtual_value, this_adjusting, fixed_offset, virtual_value,
virtual_offset, alias); virtual_offset, alias);
......
...@@ -309,7 +309,7 @@ maybe_clone_body (tree fn) ...@@ -309,7 +309,7 @@ maybe_clone_body (tree fn)
&& (!DECL_ONE_ONLY (fns[0]) && (!DECL_ONE_ONLY (fns[0])
|| (HAVE_COMDAT_GROUP || (HAVE_COMDAT_GROUP
&& DECL_WEAK (fns[0]))) && DECL_WEAK (fns[0])))
&& cgraph_same_body_alias (clone, fns[0])) && cgraph_same_body_alias (cgraph_node (fns[0]), clone, fns[0]))
{ {
alias = true; alias = true;
if (DECL_ONE_ONLY (fns[0])) if (DECL_ONE_ONLY (fns[0]))
......
...@@ -551,6 +551,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, ...@@ -551,6 +551,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
lto_output_fn_decl_index (ob->decl_state, ob->main_stream, lto_output_fn_decl_index (ob->decl_state, ob->main_stream,
alias->thunk.alias); alias->thunk.alias);
} }
gcc_assert (cgraph_get_node (alias->thunk.alias) == node);
lto_output_uleb128_stream (ob->main_stream, alias->resolution); lto_output_uleb128_stream (ob->main_stream, alias->resolution);
alias = alias->previous; alias = alias->previous;
} }
...@@ -1094,7 +1095,7 @@ input_node (struct lto_file_decl_data *file_data, ...@@ -1094,7 +1095,7 @@ input_node (struct lto_file_decl_data *file_data,
tree real_alias; tree real_alias;
decl_index = lto_input_uleb128 (ib); decl_index = lto_input_uleb128 (ib);
real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index); real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index);
alias = cgraph_same_body_alias (alias_decl, real_alias); alias = cgraph_same_body_alias (node, alias_decl, real_alias);
} }
else else
{ {
...@@ -1103,12 +1104,13 @@ input_node (struct lto_file_decl_data *file_data, ...@@ -1103,12 +1104,13 @@ input_node (struct lto_file_decl_data *file_data,
tree real_alias; tree real_alias;
decl_index = lto_input_uleb128 (ib); decl_index = lto_input_uleb128 (ib);
real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index); real_alias = lto_file_decl_data_get_fn_decl (file_data, decl_index);
alias = cgraph_add_thunk (alias_decl, fn_decl, type & 2, fixed_offset, alias = cgraph_add_thunk (node, alias_decl, fn_decl, type & 2, fixed_offset,
virtual_value, virtual_value,
(type & 4) ? size_int (virtual_value) : NULL_TREE, (type & 4) ? size_int (virtual_value) : NULL_TREE,
real_alias); real_alias);
} }
alias->resolution = (enum ld_plugin_symbol_resolution)lto_input_uleb128 (ib); gcc_assert (alias);
alias->resolution = (enum ld_plugin_symbol_resolution)lto_input_uleb128 (ib);
} }
return node; return node;
} }
......
...@@ -273,7 +273,6 @@ lto_cgraph_replace_node (struct cgraph_node *node, ...@@ -273,7 +273,6 @@ lto_cgraph_replace_node (struct cgraph_node *node,
last = alias; last = alias;
gcc_assert (alias->same_body_alias); gcc_assert (alias->same_body_alias);
alias->same_body = prevailing_node; alias->same_body = prevailing_node;
alias->thunk.alias = prevailing_node->decl;
} }
last->next = prevailing_node->same_body; last->next = prevailing_node->same_body;
/* Node with aliases is prevailed by alias. /* Node with aliases is prevailed by alias.
...@@ -828,8 +827,16 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED) ...@@ -828,8 +827,16 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED)
void void
lto_symtab_merge_cgraph_nodes (void) lto_symtab_merge_cgraph_nodes (void)
{ {
struct cgraph_node *node, *alias, *next;
lto_symtab_maybe_init_hash_table (); lto_symtab_maybe_init_hash_table ();
htab_traverse (lto_symtab_identifiers, lto_symtab_merge_cgraph_nodes_1, NULL); htab_traverse (lto_symtab_identifiers, lto_symtab_merge_cgraph_nodes_1, NULL);
for (node = cgraph_nodes; node; node = node->next)
for (alias = node->same_body; alias; alias = next)
{
next = alias->next;
alias->thunk.alias = lto_symtab_prevailing_decl (alias->thunk.alias);
}
} }
/* Given the decl DECL, return the prevailing decl with the same name. */ /* Given the decl DECL, return the prevailing decl with the same name. */
......
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