Commit 40a7fe1e by Jan Hubicka Committed by Jan Hubicka

lto-symtab.c (lto_symtab_merge_cgraph_nodes_1): Rename to ...

	* lto-symtab.c (lto_symtab_merge_cgraph_nodes_1): Rename to ...
	(lto_symtab_merge_symbols_1): ... this one.
	(lto_symtab_merge_cgraph_nodes): Rename to ...
	(lto_symtab_merge_symbols): ... this one; simplify.
	* cgraph.c (same_body_aliases_done): Rename to ...
	(cpp_implicit_aliases_done): ... this one.
	(cgraph_create_function_alias): Update.
	(cgraph_same_body_alias): Update.
	(dump_cgraph_node): Remove alias dumping; simplify
	thunk dumping.
	(verify_edge_corresponds_to_fndecl): Simplify.
	* cgraph.h (symtab_node_base): Add cpp_implicit_alias,
	alias_target.
	(cgraph_node): Remove same_body_alias.
	(varpool_node): Remove alias_of and extra_name_alias.
	(same_body_aliases_done): Rename to ..
	(cpp_implicit_aliases_done): ... this one.
	(symtab_alias_ultimate_target): Add default parameter.
	(symtab_resolve_alias): New function.
	(fixup_same_cpp_alias_visibility): Declare.
	(cgraph_function_node): Add default parameter.
	(cgraph_node_asm_name): Likewise.
	(cgraph_function_or_thunk_node): Add default parameter; do
	not ICE when it is NULL.
	(varpool_variable_node): Likewise.
	* tree-emutls.c (create_emultls_var): Update.
	(ipa_lower_emutls): Update.
	* cgraphunit.c (cgraph_decide_is_function_needed): Update.
	(cgraph_reset_node): Reset alias info.
	(cgraph_finalize_function): Update.
	(fixup_same_cpp_alias_visibility): Move to symtab.c.
	(analyze_function): Simplify.
	(cgraph_process_same_body_aliases): Simplify.
	(analyze_functions): Fixup same body aliases.
	(handle_alias_pairs): Simplify.
	(assemble_thunk): Update.
	(assemble_thunks_and_aliases): Update.
	(output_weakrefs): Rewrite.
	* lto-cgraph.c (lto_output_node): Rewrite alias handling.
	(lto_output_varpool_node): Likewise.
	(compute_ltrans_boundary): Remve assert.
	(get_alias_symbol): New functoin.
	(input_node): Rewrite alias handling.
	(input_varpool_node): Likewise.
	* ipa-pure-const.c (propagate_pure_const): Fix formating.
	* ipa.c (process_references): Handle weakrefs correctly.
	(symtab_remove_unreachable_nodes): Likewise.
	* trans-mem.c (get_cg_data): Update.
	(ipa_tm_create_version_alias): Update.
	(ipa_tm_execute): Update.
	* symtab.c (dump_symtab_base): Dump aliases.
	(verify_symtab_base): Verify aliases.
	(symtab_node_availability): New function.
	(symtab_alias_ultimate_target): Simplify.
	(fixup_same_cpp_alias_visibility): Move here from cgraphunit.c;
	handle all the fixup cases.
	(symtab_resolve_alias): New function.
	* passes.c (ipa_write_summaries): Handle weakrefs.
	* varpool.c (varpool_analyze_node): Simplify.
	(assemble_aliases): Update.
	(varpool_create_variable_alias): Simplify.
	(varpool_extra_name_alias): Simplify.
	* lto-streamer.h (lto_symtab_merge_cgraph_nodes): Rename to...
	(lto_symtab_merge_symbols): ... this one.

	* decl2.c (cp_write_global_declarations): Replace same_body_alias
	by symbol.cpp_implicit_alias.

	* lto.c (read_cgraph_and_symbols): Simplify dumping; Replace
	lto_symtab_merge_cgraph_nodes by lto_symtab_merge_symbols.
	(do_whole_program_analysis): Update dumping.

From-SVN: r199577
parent 21759881
2013-06-01 Jan Hubicka <jh@suse.cz>
* lto-symtab.c (lto_symtab_merge_cgraph_nodes_1): Rename to ...
(lto_symtab_merge_symbols_1): ... this one.
(lto_symtab_merge_cgraph_nodes): Rename to ...
(lto_symtab_merge_symbols): ... this one; simplify.
* cgraph.c (same_body_aliases_done): Rename to ...
(cpp_implicit_aliases_done): ... this one.
(cgraph_create_function_alias): Update.
(cgraph_same_body_alias): Update.
(dump_cgraph_node): Remove alias dumping; simplify
thunk dumping.
(verify_edge_corresponds_to_fndecl): Simplify.
* cgraph.h (symtab_node_base): Add cpp_implicit_alias,
alias_target.
(cgraph_node): Remove same_body_alias.
(varpool_node): Remove alias_of and extra_name_alias.
(same_body_aliases_done): Rename to ..
(cpp_implicit_aliases_done): ... this one.
(symtab_alias_ultimate_target): Add default parameter.
(symtab_resolve_alias): New function.
(fixup_same_cpp_alias_visibility): Declare.
(cgraph_function_node): Add default parameter.
(cgraph_node_asm_name): Likewise.
(cgraph_function_or_thunk_node): Add default parameter; do
not ICE when it is NULL.
(varpool_variable_node): Likewise.
* tree-emutls.c (create_emultls_var): Update.
(ipa_lower_emutls): Update.
* cgraphunit.c (cgraph_decide_is_function_needed): Update.
(cgraph_reset_node): Reset alias info.
(cgraph_finalize_function): Update.
(fixup_same_cpp_alias_visibility): Move to symtab.c.
(analyze_function): Simplify.
(cgraph_process_same_body_aliases): Simplify.
(analyze_functions): Fixup same body aliases.
(handle_alias_pairs): Simplify.
(assemble_thunk): Update.
(assemble_thunks_and_aliases): Update.
(output_weakrefs): Rewrite.
* lto-cgraph.c (lto_output_node): Rewrite alias handling.
(lto_output_varpool_node): Likewise.
(compute_ltrans_boundary): Remve assert.
(get_alias_symbol): New functoin.
(input_node): Rewrite alias handling.
(input_varpool_node): Likewise.
* ipa-pure-const.c (propagate_pure_const): Fix formating.
* ipa.c (process_references): Handle weakrefs correctly.
(symtab_remove_unreachable_nodes): Likewise.
* trans-mem.c (get_cg_data): Update.
(ipa_tm_create_version_alias): Update.
(ipa_tm_execute): Update.
* symtab.c (dump_symtab_base): Dump aliases.
(verify_symtab_base): Verify aliases.
(symtab_node_availability): New function.
(symtab_alias_ultimate_target): Simplify.
(fixup_same_cpp_alias_visibility): Move here from cgraphunit.c;
handle all the fixup cases.
(symtab_resolve_alias): New function.
* passes.c (ipa_write_summaries): Handle weakrefs.
* varpool.c (varpool_analyze_node): Simplify.
(assemble_aliases): Update.
(varpool_create_variable_alias): Simplify.
(varpool_extra_name_alias): Simplify.
* lto-streamer.h (lto_symtab_merge_cgraph_nodes): Rename to...
(lto_symtab_merge_symbols): ... this one.
2013-06-01 Dinar Temirbulatov <dinar@kugelworks.com> 2013-06-01 Dinar Temirbulatov <dinar@kugelworks.com>
Revert Revert
......
...@@ -129,7 +129,7 @@ static GTY(()) struct cgraph_node *free_nodes; ...@@ -129,7 +129,7 @@ static GTY(()) struct cgraph_node *free_nodes;
static GTY(()) struct cgraph_edge *free_edges; static GTY(()) struct cgraph_edge *free_edges;
/* Did procss_same_body_aliases run? */ /* Did procss_same_body_aliases run? */
bool same_body_aliases_done; bool cpp_implicit_aliases_done;
/* Map a cgraph_node to cgraph_function_version_info using this htab. /* Map a cgraph_node to cgraph_function_version_info using this htab.
The cgraph_function_version_info has a THIS_NODE field that is the The cgraph_function_version_info has a THIS_NODE field that is the
...@@ -556,15 +556,16 @@ cgraph_get_create_node (tree decl) ...@@ -556,15 +556,16 @@ cgraph_get_create_node (tree decl)
the function body is associated with (not necessarily cgraph_node (DECL). */ the function body is associated with (not necessarily cgraph_node (DECL). */
struct cgraph_node * struct cgraph_node *
cgraph_create_function_alias (tree alias, tree decl) cgraph_create_function_alias (tree alias, tree target)
{ {
struct cgraph_node *alias_node; struct cgraph_node *alias_node;
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL); gcc_assert (TREE_CODE (target) == FUNCTION_DECL
|| TREE_CODE (target) == IDENTIFIER_NODE);
gcc_assert (TREE_CODE (alias) == FUNCTION_DECL); gcc_assert (TREE_CODE (alias) == FUNCTION_DECL);
alias_node = cgraph_get_create_node (alias); alias_node = cgraph_get_create_node (alias);
gcc_assert (!alias_node->symbol.definition); gcc_assert (!alias_node->symbol.definition);
alias_node->thunk.alias = decl; alias_node->symbol.alias_target = target;
alias_node->symbol.definition = true; alias_node->symbol.definition = true;
alias_node->symbol.alias = true; alias_node->symbol.alias = true;
return alias_node; return alias_node;
...@@ -589,10 +590,10 @@ cgraph_same_body_alias (struct cgraph_node *decl_node ATTRIBUTE_UNUSED, tree ali ...@@ -589,10 +590,10 @@ cgraph_same_body_alias (struct cgraph_node *decl_node ATTRIBUTE_UNUSED, tree ali
return NULL; return NULL;
n = cgraph_create_function_alias (alias, decl); n = cgraph_create_function_alias (alias, decl);
n->same_body_alias = true; n->symbol.cpp_implicit_alias = true;
if (same_body_aliases_done) if (cpp_implicit_aliases_done)
ipa_record_reference ((symtab_node)n, (symtab_node)cgraph_get_node (decl), symtab_resolve_alias ((symtab_node)n,
IPA_REF_ALIAS, NULL); (symtab_node)cgraph_get_node (decl));
return n; return n;
} }
...@@ -1545,10 +1546,13 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) ...@@ -1545,10 +1546,13 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
if (node->thunk.thunk_p) if (node->thunk.thunk_p)
{ {
fprintf (f, " Thunk of %s (asm: %s) fixed offset %i virtual value %i has " fprintf (f, " Thunk");
"virtual offset %i)\n", if (node->thunk.alias)
fprintf (f, " of %s (asm: %s)",
lang_hooks.decl_printable_name (node->thunk.alias, 2), lang_hooks.decl_printable_name (node->thunk.alias, 2),
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->thunk.alias)), IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->thunk.alias)));
fprintf (f, " fixed offset %i virtual value %i has "
"virtual offset %i)\n",
(int)node->thunk.fixed_offset, (int)node->thunk.fixed_offset,
(int)node->thunk.virtual_value, (int)node->thunk.virtual_value,
(int)node->thunk.virtual_offset_p); (int)node->thunk.virtual_offset_p);
...@@ -2288,17 +2292,11 @@ verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl) ...@@ -2288,17 +2292,11 @@ verify_edge_corresponds_to_fndecl (struct cgraph_edge *e, tree decl)
return false; return false;
node = cgraph_function_or_thunk_node (node, NULL); node = cgraph_function_or_thunk_node (node, NULL);
if ((e->callee->former_clone_of != node->symbol.decl if (e->callee->former_clone_of != node->symbol.decl
&& (!node->same_body_alias
|| e->callee->former_clone_of != node->thunk.alias))
/* IPA-CP sometimes redirect edge to clone and then back to the former /* IPA-CP sometimes redirect edge to clone and then back to the former
function. This ping-pong has to go, eventually. */ function. This ping-pong has to go, eventually. */
&& (node != cgraph_function_or_thunk_node (e->callee, NULL)) && (node != cgraph_function_or_thunk_node (e->callee, NULL))
&& !clone_of_p (node, e->callee) && !clone_of_p (cgraph_function_or_thunk_node (node, NULL), e->callee))
/* If decl is a same body alias of some other decl, allow e->callee to be
a clone of a clone of that other decl too. */
&& (!node->same_body_alias
|| !clone_of_p (cgraph_get_node (node->thunk.alias), e->callee)))
return true; return true;
else else
return false; return false;
......
...@@ -56,6 +56,13 @@ struct GTY(()) symtab_node_base ...@@ -56,6 +56,13 @@ struct GTY(()) symtab_node_base
/* True when symbol is an alias. /* True when symbol is an alias.
Set by assemble_alias. */ Set by assemble_alias. */
unsigned alias : 1; unsigned alias : 1;
/* C++ frontend produce same body aliases and extra name aliases for
virutal functions and vtables that are obviously equivalent.
Those aliases are bit special, especially because C++ frontend
visibility code is so ugly it can not get them right at first time
and their visibility needs to be copied from their "masters" at
the end of parsing. */
unsigned cpp_implicit_alias : 1;
/* Set once the definition was analyzed. The list of references and /* Set once the definition was analyzed. The list of references and
other properties are built during analysis. */ other properties are built during analysis. */
unsigned analyzed : 1; unsigned analyzed : 1;
...@@ -119,6 +126,11 @@ struct GTY(()) symtab_node_base ...@@ -119,6 +126,11 @@ struct GTY(()) symtab_node_base
/* Vectors of referring and referenced entities. */ /* Vectors of referring and referenced entities. */
struct ipa_ref_list ref_list; struct ipa_ref_list ref_list;
/* Alias target. May be either DECL pointer or ASSEMBLER_NAME pointer
depending to what was known to frontend on the creation time.
Once alias is resolved, this pointer become NULL. */
tree alias_target;
/* File stream where this node is being written to. */ /* File stream where this node is being written to. */
struct lto_file_decl_data * lto_file_data; struct lto_file_decl_data * lto_file_data;
...@@ -291,8 +303,6 @@ struct GTY(()) cgraph_node { ...@@ -291,8 +303,6 @@ struct GTY(()) cgraph_node {
/* Set once the function has been instantiated and its callee /* Set once the function has been instantiated and its callee
lists created. */ lists created. */
unsigned process : 1; unsigned process : 1;
/* Set for aliases created as C++ same body aliases. */
unsigned same_body_alias : 1;
/* How commonly executed the node is. Initialized during branch /* How commonly executed the node is. Initialized during branch
probabilities pass. */ probabilities pass. */
ENUM_BITFIELD (node_frequency) frequency : 2; ENUM_BITFIELD (node_frequency) frequency : 2;
...@@ -478,12 +488,9 @@ typedef struct cgraph_edge *cgraph_edge_p; ...@@ -478,12 +488,9 @@ typedef struct cgraph_edge *cgraph_edge_p;
struct GTY(()) varpool_node { struct GTY(()) varpool_node {
struct symtab_node_base symbol; struct symtab_node_base symbol;
/* For aliases points to declaration DECL is alias of. */
tree alias_of;
/* Set when variable is scheduled to be assembled. */ /* Set when variable is scheduled to be assembled. */
unsigned output : 1; unsigned output : 1;
unsigned extra_name_alias : 1;
}; };
/* Every top level asm statement is put into a asm_node. */ /* Every top level asm statement is put into a asm_node. */
...@@ -553,7 +560,7 @@ extern cgraph_node_set cgraph_new_nodes; ...@@ -553,7 +560,7 @@ extern cgraph_node_set cgraph_new_nodes;
extern GTY(()) struct asm_node *asm_nodes; extern GTY(()) struct asm_node *asm_nodes;
extern GTY(()) int symtab_order; extern GTY(()) int symtab_order;
extern bool same_body_aliases_done; extern bool cpp_implicit_aliases_done;
/* In symtab.c */ /* In symtab.c */
void symtab_register_node (symtab_node); void symtab_register_node (symtab_node);
...@@ -576,7 +583,10 @@ void verify_symtab_node (symtab_node); ...@@ -576,7 +583,10 @@ void verify_symtab_node (symtab_node);
bool verify_symtab_base (symtab_node); bool verify_symtab_base (symtab_node);
bool symtab_used_from_object_file_p (symtab_node); bool symtab_used_from_object_file_p (symtab_node);
void symtab_make_decl_local (tree); void symtab_make_decl_local (tree);
symtab_node symtab_alias_ultimate_target (symtab_node, enum availability *); symtab_node symtab_alias_ultimate_target (symtab_node,
enum availability *avail = NULL);
bool symtab_resolve_alias (symtab_node node, symtab_node target);
void fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target);
/* In cgraph.c */ /* In cgraph.c */
void dump_cgraph (FILE *); void dump_cgraph (FILE *);
...@@ -672,7 +682,8 @@ struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_ho ...@@ -672,7 +682,8 @@ struct cgraph_2node_hook_list *cgraph_add_node_duplication_hook (cgraph_2node_ho
void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *); void cgraph_remove_node_duplication_hook (struct cgraph_2node_hook_list *);
gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *); gimple cgraph_redirect_edge_call_stmt_to_callee (struct cgraph_edge *);
bool cgraph_propagate_frequency (struct cgraph_node *node); bool cgraph_propagate_frequency (struct cgraph_node *node);
struct cgraph_node * cgraph_function_node (struct cgraph_node *, enum availability *); struct cgraph_node * cgraph_function_node (struct cgraph_node *,
enum availability *avail = NULL);
/* In cgraphunit.c */ /* In cgraphunit.c */
struct asm_node *add_asm_node (tree); struct asm_node *add_asm_node (tree);
...@@ -822,7 +833,7 @@ varpool_get_node (const_tree decl) ...@@ -822,7 +833,7 @@ varpool_get_node (const_tree decl)
/* Return asm name of cgraph node. */ /* Return asm name of cgraph node. */
static inline const char * static inline const char *
cgraph_node_asm_name(struct cgraph_node *node) cgraph_node_asm_name (struct cgraph_node *node)
{ {
return symtab_node_asm_name ((symtab_node)node); return symtab_node_asm_name ((symtab_node)node);
} }
...@@ -1258,12 +1269,14 @@ varpool_alias_target (struct varpool_node *n) ...@@ -1258,12 +1269,14 @@ varpool_alias_target (struct varpool_node *n)
When AVAILABILITY is non-NULL, get minimal availability in the chain. */ When AVAILABILITY is non-NULL, get minimal availability in the chain. */
static inline struct cgraph_node * static inline struct cgraph_node *
cgraph_function_or_thunk_node (struct cgraph_node *node, enum availability *availability) cgraph_function_or_thunk_node (struct cgraph_node *node,
enum availability *availability = NULL)
{ {
struct cgraph_node *n; struct cgraph_node *n;
n = dyn_cast <cgraph_node> (symtab_alias_ultimate_target ((symtab_node)node, availability)); n = dyn_cast <cgraph_node> (symtab_alias_ultimate_target ((symtab_node)node,
if (!n) availability));
if (!n && availability)
*availability = AVAIL_NOT_AVAILABLE; *availability = AVAIL_NOT_AVAILABLE;
return n; return n;
} }
...@@ -1272,12 +1285,14 @@ cgraph_function_or_thunk_node (struct cgraph_node *node, enum availability *avai ...@@ -1272,12 +1285,14 @@ cgraph_function_or_thunk_node (struct cgraph_node *node, enum availability *avai
When AVAILABILITY is non-NULL, get minimal availability in the chain. */ When AVAILABILITY is non-NULL, get minimal availability in the chain. */
static inline struct varpool_node * static inline struct varpool_node *
varpool_variable_node (struct varpool_node *node, enum availability *availability) varpool_variable_node (struct varpool_node *node,
enum availability *availability = NULL)
{ {
struct varpool_node *n; struct varpool_node *n;
n = dyn_cast <varpool_node> (symtab_alias_ultimate_target ((symtab_node)node, availability)); n = dyn_cast <varpool_node> (symtab_alias_ultimate_target ((symtab_node)node,
if (!n) availability));
if (!n && availability)
*availability = AVAIL_NOT_AVAILABLE; *availability = AVAIL_NOT_AVAILABLE;
return n; return n;
} }
......
...@@ -231,7 +231,6 @@ cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl) ...@@ -231,7 +231,6 @@ cgraph_decide_is_function_needed (struct cgraph_node *node, tree decl)
/* Double check that no one output the function into assembly file /* Double check that no one output the function into assembly file
early. */ early. */
gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl) gcc_checking_assert (!DECL_ASSEMBLER_NAME_SET_P (decl)
|| (node->thunk.thunk_p || node->same_body_alias)
|| !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl))); || !TREE_SYMBOL_REFERENCED (DECL_ASSEMBLER_NAME (decl)));
...@@ -370,6 +369,8 @@ cgraph_reset_node (struct cgraph_node *node) ...@@ -370,6 +369,8 @@ cgraph_reset_node (struct cgraph_node *node)
memset (&node->rtl, 0, sizeof (node->rtl)); memset (&node->rtl, 0, sizeof (node->rtl));
node->symbol.analyzed = false; node->symbol.analyzed = false;
node->symbol.definition = false; node->symbol.definition = false;
node->symbol.alias = false;
node->symbol.cpp_implicit_alias = false;
cgraph_node_remove_callees (node); cgraph_node_remove_callees (node);
ipa_remove_all_references (&node->symbol.ref_list); ipa_remove_all_references (&node->symbol.ref_list);
...@@ -426,7 +427,7 @@ cgraph_finalize_function (tree decl, bool nested) ...@@ -426,7 +427,7 @@ cgraph_finalize_function (tree decl, bool nested)
in the original implementation and it is unclear whether we want in the original implementation and it is unclear whether we want
to change the behavior here. */ to change the behavior here. */
if ((!optimize if ((!optimize
&& !node->same_body_alias && !node->symbol.cpp_implicit_alias
&& !DECL_DISREGARD_INLINE_LIMITS (decl) && !DECL_DISREGARD_INLINE_LIMITS (decl)
&& !DECL_DECLARED_INLINE_P (decl) && !DECL_DECLARED_INLINE_P (decl)
&& !(DECL_CONTEXT (decl) && !(DECL_CONTEXT (decl)
...@@ -573,22 +574,6 @@ output_asm_statements (void) ...@@ -573,22 +574,6 @@ output_asm_statements (void)
asm_nodes = NULL; asm_nodes = NULL;
} }
/* C++ FE sometimes change linkage flags after producing same body aliases. */
void
fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target, tree alias)
{
DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (alias);
if (TREE_PUBLIC (node->symbol.decl))
{
DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (alias);
DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (alias);
DECL_COMDAT_GROUP (node->symbol.decl) = DECL_COMDAT_GROUP (alias);
if (DECL_ONE_ONLY (alias)
&& !node->symbol.same_comdat_group)
symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target);
}
}
/* Analyze the function scheduled to be output. */ /* Analyze the function scheduled to be output. */
static void static void
analyze_function (struct cgraph_node *node) analyze_function (struct cgraph_node *node)
...@@ -597,39 +582,14 @@ analyze_function (struct cgraph_node *node) ...@@ -597,39 +582,14 @@ analyze_function (struct cgraph_node *node)
location_t saved_loc = input_location; location_t saved_loc = input_location;
input_location = DECL_SOURCE_LOCATION (decl); input_location = DECL_SOURCE_LOCATION (decl);
if (node->symbol.alias && node->thunk.alias) if (node->symbol.alias)
{ symtab_resolve_alias
struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias); ((symtab_node) node, (symtab_node) cgraph_get_node (node->symbol.alias_target));
struct cgraph_node *n;
for (n = tgt; n && n->symbol.alias;
n = n->symbol.analyzed ? cgraph_alias_target (n) : NULL)
if (n == node)
{
error ("function %q+D part of alias cycle", node->symbol.decl);
node->symbol.alias = false;
input_location = saved_loc;
return;
}
if (!vec_safe_length (node->symbol.ref_list.references))
ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
IPA_REF_ALIAS, NULL);
if (node->same_body_alias)
{
DECL_DECLARED_INLINE_P (node->symbol.decl)
= DECL_DECLARED_INLINE_P (node->thunk.alias);
DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
= DECL_DISREGARD_INLINE_LIMITS (node->thunk.alias);
fixup_same_cpp_alias_visibility ((symtab_node) node, (symtab_node) tgt, node->thunk.alias);
}
if (node->symbol.address_taken)
cgraph_mark_address_taken_node (cgraph_alias_target (node));
}
else if (node->thunk.thunk_p) else if (node->thunk.thunk_p)
{ {
cgraph_create_edge (node, cgraph_get_node (node->thunk.alias), cgraph_create_edge (node, cgraph_get_node (node->thunk.alias),
NULL, 0, CGRAPH_FREQ_BASE); NULL, 0, CGRAPH_FREQ_BASE);
node->thunk.alias = NULL;
} }
else if (node->dispatcher_function) else if (node->dispatcher_function)
{ {
...@@ -693,16 +653,12 @@ analyze_function (struct cgraph_node *node) ...@@ -693,16 +653,12 @@ analyze_function (struct cgraph_node *node)
void void
cgraph_process_same_body_aliases (void) cgraph_process_same_body_aliases (void)
{ {
struct cgraph_node *node; symtab_node node;
FOR_EACH_FUNCTION (node) FOR_EACH_SYMBOL (node)
if (node->same_body_alias if (node->symbol.cpp_implicit_alias && !node->symbol.analyzed)
&& !vec_safe_length (node->symbol.ref_list.references)) symtab_resolve_alias (node,
{ symtab_get_node (node->symbol.alias_target));
struct cgraph_node *tgt = cgraph_get_node (node->thunk.alias); cpp_implicit_aliases_done = true;
ipa_record_reference ((symtab_node)node, (symtab_node)tgt,
IPA_REF_ALIAS, NULL);
}
same_body_aliases_done = true;
} }
/* Process attributes common for vars and functions. */ /* Process attributes common for vars and functions. */
...@@ -890,6 +846,13 @@ analyze_functions (void) ...@@ -890,6 +846,13 @@ analyze_functions (void)
bitmap_obstack_initialize (NULL); bitmap_obstack_initialize (NULL);
cgraph_state = CGRAPH_STATE_CONSTRUCTION; cgraph_state = CGRAPH_STATE_CONSTRUCTION;
/* Ugly, but the fixup can not happen at a time same body alias is created;
C++ FE is confused about the COMDAT groups being right. */
if (cpp_implicit_aliases_done)
FOR_EACH_SYMBOL (node)
if (node->symbol.cpp_implicit_alias)
fixup_same_cpp_alias_visibility (node, symtab_alias_target (node));
/* Analysis adds static variables that in turn adds references to new functions. /* Analysis adds static variables that in turn adds references to new functions.
So we need to iterate the process until it stabilize. */ So we need to iterate the process until it stabilize. */
while (changed) while (changed)
...@@ -940,7 +903,7 @@ analyze_functions (void) ...@@ -940,7 +903,7 @@ analyze_functions (void)
and later using weak alias attribute to kill its body. and later using weak alias attribute to kill its body.
See gcc.c-torture/compile/20011119-1.c */ See gcc.c-torture/compile/20011119-1.c */
if (!DECL_STRUCT_FUNCTION (decl) if (!DECL_STRUCT_FUNCTION (decl)
&& (!cnode->symbol.alias || !cnode->thunk.alias) && !cnode->symbol.alias
&& !cnode->thunk.thunk_p && !cnode->thunk.thunk_p
&& !cnode->dispatcher_function) && !cnode->dispatcher_function)
{ {
...@@ -970,7 +933,7 @@ analyze_functions (void) ...@@ -970,7 +933,7 @@ analyze_functions (void)
else else
{ {
varpool_node *vnode = dyn_cast <varpool_node> (node); varpool_node *vnode = dyn_cast <varpool_node> (node);
if (vnode && vnode->symbol.definition) if (vnode && vnode->symbol.definition && !vnode->symbol.analyzed)
varpool_analyze_node (vnode); varpool_analyze_node (vnode);
} }
...@@ -1016,7 +979,7 @@ analyze_functions (void) ...@@ -1016,7 +979,7 @@ analyze_functions (void)
tree decl = node->symbol.decl; tree decl = node->symbol.decl;
if (cnode->symbol.definition && !gimple_has_body_p (decl) if (cnode->symbol.definition && !gimple_has_body_p (decl)
&& (!cnode->symbol.alias || !cnode->thunk.alias) && !cnode->symbol.alias
&& !cnode->thunk.thunk_p) && !cnode->thunk.thunk_p)
cgraph_reset_node (cnode); cgraph_reset_node (cnode);
...@@ -1057,17 +1020,11 @@ handle_alias_pairs (void) ...@@ -1057,17 +1020,11 @@ handle_alias_pairs (void)
to later output the weakref pseudo op into asm file. */ to later output the weakref pseudo op into asm file. */
if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL) if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
{ {
if (TREE_CODE (p->decl) == FUNCTION_DECL) symtab_node node = symtab_get_node (p->decl);
if (node)
{ {
struct cgraph_node *anode = cgraph_get_create_node (p->decl); node->symbol.alias_target = p->target;
anode->symbol.alias = true; node->symbol.alias = true;
anode->thunk.alias = p->target;
}
else
{
struct varpool_node *anode = varpool_get_node (p->decl);
anode->symbol.alias = true;
anode->alias_of = p->target;
} }
DECL_EXTERNAL (p->decl) = 1; DECL_EXTERNAL (p->decl) = 1;
alias_pairs->unordered_remove (i); alias_pairs->unordered_remove (i);
...@@ -1380,7 +1337,7 @@ assemble_thunk (struct cgraph_node *node) ...@@ -1380,7 +1337,7 @@ assemble_thunk (struct cgraph_node *node)
HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset; HOST_WIDE_INT fixed_offset = node->thunk.fixed_offset;
HOST_WIDE_INT virtual_value = node->thunk.virtual_value; HOST_WIDE_INT virtual_value = node->thunk.virtual_value;
tree virtual_offset = NULL; tree virtual_offset = NULL;
tree alias = node->thunk.alias; tree alias = node->callees->callee->symbol.decl;
tree thunk_fndecl = node->symbol.decl; tree thunk_fndecl = node->symbol.decl;
tree a = DECL_ARGUMENTS (thunk_fndecl); tree a = DECL_ARGUMENTS (thunk_fndecl);
...@@ -1581,15 +1538,15 @@ assemble_thunks_and_aliases (struct cgraph_node *node) ...@@ -1581,15 +1538,15 @@ assemble_thunks_and_aliases (struct cgraph_node *node)
if (ref->use == IPA_REF_ALIAS) if (ref->use == IPA_REF_ALIAS)
{ {
struct cgraph_node *alias = ipa_ref_referring_node (ref); struct cgraph_node *alias = ipa_ref_referring_node (ref);
bool saved_written = TREE_ASM_WRITTEN (alias->thunk.alias); bool saved_written = TREE_ASM_WRITTEN (node->symbol.decl);
/* Force assemble_alias to really output the alias this time instead /* Force assemble_alias to really output the alias this time instead
of buffering it in same alias pairs. */ of buffering it in same alias pairs. */
TREE_ASM_WRITTEN (alias->thunk.alias) = 1; TREE_ASM_WRITTEN (node->symbol.decl) = 1;
do_assemble_alias (alias->symbol.decl, do_assemble_alias (alias->symbol.decl,
DECL_ASSEMBLER_NAME (alias->thunk.alias)); DECL_ASSEMBLER_NAME (node->symbol.decl));
assemble_thunks_and_aliases (alias); assemble_thunks_and_aliases (alias);
TREE_ASM_WRITTEN (alias->thunk.alias) = saved_written; TREE_ASM_WRITTEN (node->symbol.decl) = saved_written;
} }
} }
...@@ -1929,22 +1886,32 @@ get_alias_symbol (tree decl) ...@@ -1929,22 +1886,32 @@ get_alias_symbol (tree decl)
static void static void
output_weakrefs (void) output_weakrefs (void)
{ {
struct cgraph_node *node; symtab_node node;
struct varpool_node *vnode; FOR_EACH_SYMBOL (node)
FOR_EACH_FUNCTION (node)
if (node->symbol.alias && DECL_EXTERNAL (node->symbol.decl) if (node->symbol.alias && DECL_EXTERNAL (node->symbol.decl)
&& !TREE_ASM_WRITTEN (node->symbol.decl) && !TREE_ASM_WRITTEN (node->symbol.decl)
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl))) && lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
do_assemble_alias (node->symbol.decl, {
node->thunk.alias && DECL_P (node->thunk.alias) ? DECL_ASSEMBLER_NAME (node->thunk.alias) tree target;
: get_alias_symbol (node->symbol.decl));
FOR_EACH_VARIABLE (vnode) /* Weakrefs are special by not requiring target definition in current
if (vnode->symbol.alias && DECL_EXTERNAL (vnode->symbol.decl) compilation unit. It is thus bit hard to work out what we want to
&& !TREE_ASM_WRITTEN (vnode->symbol.decl) alias.
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl))) When alias target is defined, we need to fetch it from symtab reference,
do_assemble_alias (vnode->symbol.decl, otherwise it is pointed to by alias_target. */
vnode->alias_of && DECL_P (vnode->alias_of) ? DECL_ASSEMBLER_NAME (vnode->alias_of) if (node->symbol.alias_target)
: get_alias_symbol (vnode->symbol.decl)); target = (DECL_P (node->symbol.alias_target)
? DECL_ASSEMBLER_NAME (node->symbol.alias_target)
: node->symbol.alias_target);
else if (node->symbol.analyzed)
target = DECL_ASSEMBLER_NAME (symtab_alias_target (node)->symbol.decl);
else
{
gcc_unreachable ();
target = get_alias_symbol (node->symbol.decl);
}
do_assemble_alias (node->symbol.decl, target);
}
} }
/* Initialize callgraph dump file. */ /* Initialize callgraph dump file. */
......
2013-06-01 Jan Hubicka <jh@suse.cz>
* decl2.c (cp_write_global_declarations): Replace same_body_alias
by symbol.cpp_implicit_alias.
2013-05-30 Jason Merrill <jason@redhat.com> 2013-05-30 Jason Merrill <jason@redhat.com>
PR c++/57404 PR c++/57404
......
...@@ -4201,7 +4201,7 @@ cp_write_global_declarations (void) ...@@ -4201,7 +4201,7 @@ cp_write_global_declarations (void)
struct cgraph_node *node, *next; struct cgraph_node *node, *next;
node = cgraph_get_node (decl); node = cgraph_get_node (decl);
if (node->same_body_alias) if (node->symbol.cpp_implicit_alias)
node = cgraph_alias_target (node); node = cgraph_alias_target (node);
cgraph_for_node_and_aliases (node, clear_decl_external, cgraph_for_node_and_aliases (node, clear_decl_external,
......
...@@ -1110,7 +1110,7 @@ propagate_pure_const (void) ...@@ -1110,7 +1110,7 @@ propagate_pure_const (void)
if (dump_file) if (dump_file)
{ {
dump_cgraph (dump_file); dump_cgraph (dump_file);
ipa_print_order(dump_file, "reduced", order, order_pos); ipa_print_order (dump_file, "reduced", order, order_pos);
} }
/* Propagate the local information through the call graph to produce /* Propagate the local information through the call graph to produce
......
...@@ -139,8 +139,7 @@ process_references (struct ipa_ref_list *list, ...@@ -139,8 +139,7 @@ process_references (struct ipa_ref_list *list,
symtab_node node = ref->referred; symtab_node node = ref->referred;
if (node->symbol.definition if (node->symbol.definition
&& (!DECL_EXTERNAL (node->symbol.decl) && ((!DECL_EXTERNAL (node->symbol.decl) || node->symbol.alias)
|| node->symbol.alias
|| (before_inlining_p || (before_inlining_p
/* We use variable constructors during late complation for /* We use variable constructors during late complation for
constant folding. Keep references alive so partitioning constant folding. Keep references alive so partitioning
...@@ -297,7 +296,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file) ...@@ -297,7 +296,7 @@ symtab_remove_unreachable_nodes (bool before_inlining_p, FILE *file)
if (e->callee->symbol.definition if (e->callee->symbol.definition
&& (!e->inline_failed && (!e->inline_failed
|| !DECL_EXTERNAL (e->callee->symbol.decl) || !DECL_EXTERNAL (e->callee->symbol.decl)
|| cnode->symbol.alias || e->callee->symbol.alias
|| before_inlining_p)) || before_inlining_p))
pointer_set_insert (reachable, e->callee); pointer_set_insert (reachable, e->callee);
enqueue_node ((symtab_node) e->callee, &first, reachable); enqueue_node ((symtab_node) e->callee, &first, reachable);
......
...@@ -377,6 +377,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, ...@@ -377,6 +377,7 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
struct cgraph_node *clone_of; struct cgraph_node *clone_of;
struct ipa_opt_pass_d *pass; struct ipa_opt_pass_d *pass;
int i; int i;
bool alias_p;
boundary_p = !lto_symtab_encoder_in_partition_p (encoder, (symtab_node)node); boundary_p = !lto_symtab_encoder_in_partition_p (encoder, (symtab_node)node);
...@@ -485,7 +486,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, ...@@ -485,7 +486,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
defined in other unit, we may use the info on aliases to resolve defined in other unit, we may use the info on aliases to resolve
symbol1 != symbol2 type tests that we can do only for locally defined objects symbol1 != symbol2 type tests that we can do only for locally defined objects
otherwise. */ otherwise. */
bp_pack_value (&bp, node->symbol.alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl)), 1); alias_p = node->symbol.alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl));
bp_pack_value (&bp, alias_p, 1);
bp_pack_value (&bp, node->frequency, 2); bp_pack_value (&bp, node->frequency, 2);
bp_pack_value (&bp, node->only_called_at_startup, 1); bp_pack_value (&bp, node->only_called_at_startup, 1);
bp_pack_value (&bp, node->only_called_at_exit, 1); bp_pack_value (&bp, node->only_called_at_exit, 1);
...@@ -504,15 +506,6 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, ...@@ -504,15 +506,6 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
streamer_write_uhwi_stream (ob->main_stream, node->thunk.fixed_offset); streamer_write_uhwi_stream (ob->main_stream, node->thunk.fixed_offset);
streamer_write_uhwi_stream (ob->main_stream, node->thunk.virtual_value); streamer_write_uhwi_stream (ob->main_stream, node->thunk.virtual_value);
} }
if ((node->symbol.alias || node->thunk.thunk_p)
&& (!boundary_p || (node->symbol.alias && DECL_EXTERNAL (node->symbol.decl))))
{
streamer_write_hwi_in_range (ob->main_stream, 0, 1,
node->thunk.alias != NULL);
if (node->thunk.alias != NULL)
lto_output_fn_decl_index (ob->decl_state, ob->main_stream,
node->thunk.alias);
}
} }
/* Output the varpool NODE to OB. /* Output the varpool NODE to OB.
...@@ -522,10 +515,10 @@ static void ...@@ -522,10 +515,10 @@ static void
lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node *node, lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node *node,
lto_symtab_encoder_t encoder) lto_symtab_encoder_t encoder)
{ {
bool boundary_p = (node->symbol.definition bool boundary_p = !lto_symtab_encoder_in_partition_p (encoder, (symtab_node)node);
&& !lto_symtab_encoder_in_partition_p (encoder, (symtab_node)node));
struct bitpack_d bp; struct bitpack_d bp;
int ref; int ref;
bool alias_p;
streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag, streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
LTO_symtab_variable); LTO_symtab_variable);
...@@ -536,8 +529,9 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node ...@@ -536,8 +529,9 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node
bp_pack_value (&bp, node->symbol.force_output, 1); bp_pack_value (&bp, node->symbol.force_output, 1);
bp_pack_value (&bp, node->symbol.unique_name, 1); bp_pack_value (&bp, node->symbol.unique_name, 1);
bp_pack_value (&bp, node->symbol.definition, 1); bp_pack_value (&bp, node->symbol.definition, 1);
bp_pack_value (&bp, node->symbol.alias, 1); alias_p = node->symbol.alias && (!boundary_p || DECL_EXTERNAL (node->symbol.decl));
bp_pack_value (&bp, node->alias_of != NULL, 1); bp_pack_value (&bp, alias_p, 1);
bp_pack_value (&bp, node->symbol.analyzed && !boundary_p, 1);
gcc_assert (node->symbol.definition || !node->symbol.analyzed); gcc_assert (node->symbol.definition || !node->symbol.analyzed);
/* Constant pool initializers can be de-unified into individual ltrans units. /* Constant pool initializers can be de-unified into individual ltrans units.
FIXME: Alternatively at -Os we may want to avoid generating for them the local FIXME: Alternatively at -Os we may want to avoid generating for them the local
...@@ -554,12 +548,11 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node ...@@ -554,12 +548,11 @@ lto_output_varpool_node (struct lto_simple_output_block *ob, struct varpool_node
bp_pack_value (&bp, node->symbol.definition bp_pack_value (&bp, node->symbol.definition
&& referenced_from_other_partition_p (&node->symbol.ref_list, && referenced_from_other_partition_p (&node->symbol.ref_list,
encoder), 1); encoder), 1);
bp_pack_value (&bp, boundary_p && !DECL_EXTERNAL (node->symbol.decl), 1); bp_pack_value (&bp, node->symbol.analyzed
&& boundary_p && !DECL_EXTERNAL (node->symbol.decl), 1);
/* in_other_partition. */ /* in_other_partition. */
} }
streamer_write_bitpack (&bp); streamer_write_bitpack (&bp);
if (node->alias_of)
lto_output_var_decl_index (ob->decl_state, ob->main_stream, node->alias_of);
if (node->symbol.same_comdat_group && !boundary_p) if (node->symbol.same_comdat_group && !boundary_p)
{ {
ref = lto_symtab_encoder_lookup (encoder, ref = lto_symtab_encoder_lookup (encoder,
...@@ -756,7 +749,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder) ...@@ -756,7 +749,7 @@ compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
!lsei_end_p (lsei); lsei_next_variable_in_partition (&lsei)) !lsei_end_p (lsei); lsei_next_variable_in_partition (&lsei))
{ {
struct varpool_node *vnode = lsei_varpool_node (lsei); struct varpool_node *vnode = lsei_varpool_node (lsei);
gcc_assert (!vnode->symbol.alias || vnode->alias_of);
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode); lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode);
lto_set_symtab_encoder_encode_initializer (encoder, vnode); lto_set_symtab_encoder_encode_initializer (encoder, vnode);
add_references (encoder, &vnode->symbol.ref_list); add_references (encoder, &vnode->symbol.ref_list);
...@@ -919,6 +912,17 @@ input_overwrite_node (struct lto_file_decl_data *file_data, ...@@ -919,6 +912,17 @@ input_overwrite_node (struct lto_file_decl_data *file_data,
LDPR_NUM_KNOWN); LDPR_NUM_KNOWN);
} }
/* Return string alias is alias of. */
static tree
get_alias_symbol (tree decl)
{
tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
gcc_assert (lookup_attribute ("weakref", DECL_ATTRIBUTES (decl)));
return get_identifier (TREE_STRING_POINTER
(TREE_VALUE (TREE_VALUE (alias))));
}
/* Read a node from input_block IB. TAG is the node's tag just read. /* Read a node from input_block IB. TAG is the node's tag just read.
Return the node read or overwriten. */ Return the node read or overwriten. */
...@@ -1004,15 +1008,8 @@ input_node (struct lto_file_decl_data *file_data, ...@@ -1004,15 +1008,8 @@ input_node (struct lto_file_decl_data *file_data,
node->thunk.virtual_value = virtual_value; node->thunk.virtual_value = virtual_value;
node->thunk.virtual_offset_p = (type & 4); node->thunk.virtual_offset_p = (type & 4);
} }
if (node->thunk.thunk_p || node->symbol.alias) if (node->symbol.alias && !node->symbol.analyzed)
{ node->symbol.alias_target = get_alias_symbol (node->symbol.decl);
if (streamer_read_hwi_in_range (ib, "alias nonzero flag", 0, 1))
{
decl_index = streamer_read_uhwi (ib);
node->thunk.alias = lto_file_decl_data_get_fn_decl (file_data,
decl_index);
}
}
return node; return node;
} }
...@@ -1028,7 +1025,6 @@ input_varpool_node (struct lto_file_decl_data *file_data, ...@@ -1028,7 +1025,6 @@ input_varpool_node (struct lto_file_decl_data *file_data,
struct varpool_node *node; struct varpool_node *node;
struct bitpack_d bp; struct bitpack_d bp;
int ref = LCC_NOT_FOUND; int ref = LCC_NOT_FOUND;
bool non_null_aliasof;
int order; int order;
order = streamer_read_hwi (ib) + order_base; order = streamer_read_hwi (ib) + order_base;
...@@ -1046,20 +1042,16 @@ input_varpool_node (struct lto_file_decl_data *file_data, ...@@ -1046,20 +1042,16 @@ input_varpool_node (struct lto_file_decl_data *file_data,
node->symbol.unique_name = bp_unpack_value (&bp, 1); node->symbol.unique_name = bp_unpack_value (&bp, 1);
node->symbol.definition = bp_unpack_value (&bp, 1); node->symbol.definition = bp_unpack_value (&bp, 1);
node->symbol.alias = bp_unpack_value (&bp, 1); node->symbol.alias = bp_unpack_value (&bp, 1);
non_null_aliasof = bp_unpack_value (&bp, 1); node->symbol.analyzed = bp_unpack_value (&bp, 1);
node->symbol.used_from_other_partition = bp_unpack_value (&bp, 1); node->symbol.used_from_other_partition = bp_unpack_value (&bp, 1);
node->symbol.in_other_partition = bp_unpack_value (&bp, 1); node->symbol.in_other_partition = bp_unpack_value (&bp, 1);
node->symbol.analyzed = (node->symbol.definition && (!node->symbol.alias || !node->symbol.in_other_partition));
if (node->symbol.in_other_partition) if (node->symbol.in_other_partition)
{ {
DECL_EXTERNAL (node->symbol.decl) = 1; DECL_EXTERNAL (node->symbol.decl) = 1;
TREE_STATIC (node->symbol.decl) = 0; TREE_STATIC (node->symbol.decl) = 0;
} }
if (non_null_aliasof) if (node->symbol.alias && !node->symbol.analyzed)
{ node->symbol.alias_target = get_alias_symbol (node->symbol.decl);
decl_index = streamer_read_uhwi (ib);
node->alias_of = lto_file_decl_data_get_var_decl (file_data, decl_index);
}
ref = streamer_read_hwi (ib); ref = streamer_read_hwi (ib);
/* Store a reference for now, and fix up later to be a pointer. */ /* Store a reference for now, and fix up later to be a pointer. */
node->symbol.same_comdat_group = (symtab_node) (intptr_t) ref; node->symbol.same_comdat_group = (symtab_node) (intptr_t) ref;
......
...@@ -898,7 +898,7 @@ lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder); ...@@ -898,7 +898,7 @@ lto_symtab_encoder_t compute_ltrans_boundary (lto_symtab_encoder_t encoder);
/* In lto-symtab.c. */ /* In lto-symtab.c. */
extern void lto_symtab_merge_decls (void); extern void lto_symtab_merge_decls (void);
extern void lto_symtab_merge_cgraph_nodes (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 GTY(()) vec<tree, va_gc> *lto_global_var_decls; extern GTY(()) vec<tree, va_gc> *lto_global_var_decls;
......
...@@ -542,7 +542,7 @@ lto_symtab_merge_decls (void) ...@@ -542,7 +542,7 @@ lto_symtab_merge_decls (void)
/* Helper to process the decl chain for the symbol table entry *SLOT. */ /* Helper to process the decl chain for the symbol table entry *SLOT. */
static void static void
lto_symtab_merge_cgraph_nodes_1 (symtab_node prevailing) lto_symtab_merge_symbols_1 (symtab_node prevailing)
{ {
symtab_node e, next; symtab_node e, next;
...@@ -568,88 +568,32 @@ lto_symtab_merge_cgraph_nodes_1 (symtab_node prevailing) ...@@ -568,88 +568,32 @@ lto_symtab_merge_cgraph_nodes_1 (symtab_node prevailing)
lto_symtab_merge_decls. */ lto_symtab_merge_decls. */
void void
lto_symtab_merge_cgraph_nodes (void) lto_symtab_merge_symbols (void)
{ {
struct cgraph_node *cnode;
struct varpool_node *vnode;
symtab_node node; symtab_node node;
/* Populate assembler name hash. */ if (!flag_ltrans)
{
symtab_initialize_asm_name_hash (); symtab_initialize_asm_name_hash ();
if (!flag_ltrans) /* Do the actual merging. */
FOR_EACH_SYMBOL (node) FOR_EACH_SYMBOL (node)
if (lto_symtab_symbol_p (node) if (lto_symtab_symbol_p (node)
&& node->symbol.next_sharing_asm_name && node->symbol.next_sharing_asm_name
&& !node->symbol.previous_sharing_asm_name) && !node->symbol.previous_sharing_asm_name)
lto_symtab_merge_cgraph_nodes_1 (node); lto_symtab_merge_symbols_1 (node);
FOR_EACH_FUNCTION (cnode)
{
/* Resolve weakrefs to symbol defined in other unit. */
if (!cnode->symbol.analyzed && cnode->thunk.alias && !DECL_P (cnode->thunk.alias))
{
symtab_node node = symtab_node_for_asm (cnode->thunk.alias);
if (node && is_a <cgraph_node> (node))
{
struct cgraph_node *n;
for (n = cgraph (node); n && n->symbol.alias;
n = n->symbol.analyzed ? cgraph_alias_target (n) : NULL)
if (n == cnode)
{
error ("function %q+D part of alias cycle", cnode->symbol.decl);
cnode->symbol.alias = false;
break;
}
if (cnode->symbol.alias)
{
cgraph_create_function_alias (cnode->symbol.decl, node->symbol.decl);
ipa_record_reference ((symtab_node)cnode, (symtab_node)node,
IPA_REF_ALIAS, NULL);
cnode->symbol.analyzed = true;
}
}
else if (node)
error ("%q+D alias in between function and variable is not supported", cnode->symbol.decl);
}
if ((cnode->thunk.thunk_p || cnode->symbol.alias)
&& cnode->thunk.alias && DECL_P (cnode->thunk.alias))
cnode->thunk.alias = lto_symtab_prevailing_decl (cnode->thunk.alias);
cnode->symbol.aux = NULL;
}
FOR_EACH_VARIABLE (vnode)
{
/* Resolve weakrefs to symbol defined in other unit. */
if (!vnode->symbol.analyzed && vnode->alias_of && !DECL_P (vnode->alias_of))
{
symtab_node node = symtab_node_for_asm (vnode->alias_of);
if (node && is_a <cgraph_node> (node))
{
struct varpool_node *n;
for (n = varpool (node); n && n->symbol.alias; /* Resolve weakref aliases whose target are now in the compilation unit. */
n = n->symbol.analyzed ? varpool_alias_target (n) : NULL) FOR_EACH_SYMBOL (node)
if (n == vnode)
{ {
error ("function %q+D part of alias cycle", vnode->symbol.decl); if (!node->symbol.analyzed && node->symbol.alias_target)
vnode->symbol.alias = false;
break;
}
if (vnode->symbol.alias)
{ {
varpool_create_variable_alias (vnode->symbol.decl, node->symbol.decl); symtab_node tgt = symtab_node_for_asm (node->symbol.alias_target);
ipa_record_reference ((symtab_node)vnode, (symtab_node)node, if (tgt)
IPA_REF_ALIAS, NULL); symtab_resolve_alias (node, tgt);
vnode->symbol.analyzed = true;
}
} }
else if (node) node->symbol.aux = NULL;
error ("%q+D alias in between function and variable is not supported", vnode->symbol.decl);
} }
if (vnode->symbol.alias && DECL_P (vnode->alias_of))
vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of);
vnode->symbol.aux = NULL;
} }
} }
......
2013-06-01 Jan Hubicka <jh@suse.cz>
* lto.c (read_cgraph_and_symbols): Simplify dumping; Replace
lto_symtab_merge_cgraph_nodes by lto_symtab_merge_symbols.
(do_whole_program_analysis): Update dumping.
2013-05-29 Jan Hubicka <jh@suse.cz> 2013-05-29 Jan Hubicka <jh@suse.cz>
* lto.c (has_analyzed_clone_p, lto_materialize_function): Update for new symtab * lto.c (has_analyzed_clone_p, lto_materialize_function): Update for new symtab
......
...@@ -3033,10 +3033,9 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames) ...@@ -3033,10 +3033,9 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
if (cgraph_dump_file) if (cgraph_dump_file)
{ {
fprintf (cgraph_dump_file, "Before merging:\n"); fprintf (cgraph_dump_file, "Before merging:\n");
dump_cgraph (cgraph_dump_file); dump_symtab (cgraph_dump_file);
dump_varpool (cgraph_dump_file);
} }
lto_symtab_merge_cgraph_nodes (); lto_symtab_merge_symbols ();
ggc_collect (); ggc_collect ();
/* FIXME: ipa_transforms_to_apply holds list of passes that have optimization /* FIXME: ipa_transforms_to_apply holds list of passes that have optimization
...@@ -3169,10 +3168,7 @@ do_whole_program_analysis (void) ...@@ -3169,10 +3168,7 @@ do_whole_program_analysis (void)
cgraph_function_flags_ready = true; cgraph_function_flags_ready = true;
if (cgraph_dump_file) if (cgraph_dump_file)
{ dump_symtab (cgraph_dump_file);
dump_cgraph (cgraph_dump_file);
dump_varpool (cgraph_dump_file);
}
bitmap_obstack_initialize (NULL); bitmap_obstack_initialize (NULL);
cgraph_state = CGRAPH_STATE_IPA_SSA; cgraph_state = CGRAPH_STATE_IPA_SSA;
...@@ -3182,8 +3178,7 @@ do_whole_program_analysis (void) ...@@ -3182,8 +3178,7 @@ do_whole_program_analysis (void)
if (cgraph_dump_file) if (cgraph_dump_file)
{ {
fprintf (cgraph_dump_file, "Optimized "); fprintf (cgraph_dump_file, "Optimized ");
dump_cgraph (cgraph_dump_file); dump_symtab (cgraph_dump_file);
dump_varpool (cgraph_dump_file);
} }
#ifdef ENABLE_CHECKING #ifdef ENABLE_CHECKING
verify_cgraph (); verify_cgraph ();
......
...@@ -2461,6 +2461,7 @@ ipa_write_summaries (void) ...@@ -2461,6 +2461,7 @@ ipa_write_summaries (void)
lto_symtab_encoder_t encoder; lto_symtab_encoder_t encoder;
int i, order_pos; int i, order_pos;
struct varpool_node *vnode; struct varpool_node *vnode;
struct cgraph_node *node;
struct cgraph_node **order; struct cgraph_node **order;
if (!flag_generate_lto || seen_error ()) if (!flag_generate_lto || seen_error ())
...@@ -2496,8 +2497,10 @@ ipa_write_summaries (void) ...@@ -2496,8 +2497,10 @@ ipa_write_summaries (void)
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)node); lto_set_symtab_encoder_in_partition (encoder, (symtab_node)node);
} }
FOR_EACH_DEFINED_FUNCTION (node)
if (node->symbol.alias)
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)node);
FOR_EACH_DEFINED_VARIABLE (vnode) FOR_EACH_DEFINED_VARIABLE (vnode)
if ((!vnode->symbol.alias || vnode->alias_of))
lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode); lto_set_symtab_encoder_in_partition (encoder, (symtab_node)vnode);
ipa_write_summaries_1 (compute_ltrans_boundary (encoder)); ipa_write_summaries_1 (compute_ltrans_boundary (encoder));
......
...@@ -481,6 +481,14 @@ dump_symtab_base (FILE *f, symtab_node node) ...@@ -481,6 +481,14 @@ dump_symtab_base (FILE *f, symtab_node node)
fprintf (f, " analyzed"); fprintf (f, " analyzed");
if (node->symbol.alias) if (node->symbol.alias)
fprintf (f, " alias"); fprintf (f, " alias");
if (node->symbol.cpp_implicit_alias)
fprintf (f, " cpp_implicit_alias");
if (node->symbol.alias_target)
fprintf (f, " target:%s",
DECL_P (node->symbol.alias_target)
? IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME
(node->symbol.alias_target))
: IDENTIFIER_POINTER (node->symbol.alias_target));
fprintf (f, "\n Visibility:"); fprintf (f, "\n Visibility:");
if (node->symbol.in_other_partition) if (node->symbol.in_other_partition)
fprintf (f, " in_other_partition"); fprintf (f, " in_other_partition");
...@@ -666,6 +674,17 @@ verify_symtab_base (symtab_node node) ...@@ -666,6 +674,17 @@ verify_symtab_base (symtab_node node)
error ("node is analyzed byt it is not a definition"); error ("node is analyzed byt it is not a definition");
error_found = true; error_found = true;
} }
if (node->symbol.cpp_implicit_alias && !node->symbol.alias)
{
error ("node is alias but not implicit alias");
error_found = true;
}
if (node->symbol.alias && !node->symbol.definition
&& !lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
{
error ("node is alias but not definition");
error_found = true;
}
if (node->symbol.same_comdat_group) if (node->symbol.same_comdat_group)
{ {
symtab_node n = node->symbol.same_comdat_group; symtab_node n = node->symbol.same_comdat_group;
...@@ -757,6 +776,7 @@ symtab_used_from_object_file_p (symtab_node node) ...@@ -757,6 +776,7 @@ symtab_used_from_object_file_p (symtab_node node)
/* Make DECL local. FIXME: We shouldn't need to mess with rtl this early, /* Make DECL local. FIXME: We shouldn't need to mess with rtl this early,
but other code such as notice_global_symbol generates rtl. */ but other code such as notice_global_symbol generates rtl. */
void void
symtab_make_decl_local (tree decl) symtab_make_decl_local (tree decl)
{ {
...@@ -796,6 +816,17 @@ symtab_make_decl_local (tree decl) ...@@ -796,6 +816,17 @@ symtab_make_decl_local (tree decl)
SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl); SYMBOL_REF_WEAK (symbol) = DECL_WEAK (decl);
} }
/* Return availability of NODE. */
enum availability
symtab_node_availability (symtab_node node)
{
if (is_a <cgraph_node> (node))
return cgraph_function_body_availability (cgraph (node));
else
return cgraph_variable_initializer_availability (varpool (node));
}
/* Given NODE, walk the alias chain to return the symbol NODE is alias of. /* Given NODE, walk the alias chain to return the symbol NODE is alias of.
If NODE is not an alias, return NODE. If NODE is not an alias, return NODE.
When AVAILABILITY is non-NULL, get minimal availability in the chain. */ When AVAILABILITY is non-NULL, get minimal availability in the chain. */
...@@ -804,12 +835,7 @@ symtab_node ...@@ -804,12 +835,7 @@ symtab_node
symtab_alias_ultimate_target (symtab_node node, enum availability *availability) symtab_alias_ultimate_target (symtab_node node, enum availability *availability)
{ {
if (availability) if (availability)
{ *availability = symtab_node_availability (node);
if (is_a <cgraph_node> (node))
*availability = cgraph_function_body_availability (cgraph (node));
else
*availability = cgraph_variable_initializer_availability (varpool (node));
}
while (node) while (node)
{ {
if (node->symbol.alias && node->symbol.analyzed) if (node->symbol.alias && node->symbol.analyzed)
...@@ -818,11 +844,7 @@ symtab_alias_ultimate_target (symtab_node node, enum availability *availability) ...@@ -818,11 +844,7 @@ symtab_alias_ultimate_target (symtab_node node, enum availability *availability)
return node; return node;
if (node && availability) if (node && availability)
{ {
enum availability a; enum availability a = symtab_node_availability (node);
if (is_a <cgraph_node> (node))
a = cgraph_function_body_availability (cgraph (node));
else
a = cgraph_variable_initializer_availability (varpool (node));
if (a < *availability) if (a < *availability)
*availability = a; *availability = a;
} }
...@@ -831,4 +853,93 @@ symtab_alias_ultimate_target (symtab_node node, enum availability *availability) ...@@ -831,4 +853,93 @@ symtab_alias_ultimate_target (symtab_node node, enum availability *availability)
*availability = AVAIL_NOT_AVAILABLE; *availability = AVAIL_NOT_AVAILABLE;
return NULL; return NULL;
} }
/* C++ FE sometimes change linkage flags after producing same body aliases.
FIXME: C++ produce implicit aliases for virtual functions and vtables that
are obviously equivalent. The way it is doing so is however somewhat
kludgy and interferes with the visibility code. As a result we need to
copy the visibility from the target to get things right. */
void
fixup_same_cpp_alias_visibility (symtab_node node, symtab_node target)
{
if (is_a <cgraph_node> (node))
{
DECL_DECLARED_INLINE_P (node->symbol.decl)
= DECL_DECLARED_INLINE_P (target->symbol.decl);
DECL_DISREGARD_INLINE_LIMITS (node->symbol.decl)
= DECL_DISREGARD_INLINE_LIMITS (target->symbol.decl);
}
/* FIXME: It is not really clear why those flags should not be copied for
functions, too. */
else
{
DECL_WEAK (node->symbol.decl) = DECL_WEAK (target->symbol.decl);
DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (target->symbol.decl);
DECL_VISIBILITY (node->symbol.decl) = DECL_VISIBILITY (target->symbol.decl);
}
DECL_VIRTUAL_P (node->symbol.decl) = DECL_VIRTUAL_P (target->symbol.decl);
if (TREE_PUBLIC (node->symbol.decl))
{
DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (target->symbol.decl);
DECL_COMDAT (node->symbol.decl) = DECL_COMDAT (target->symbol.decl);
DECL_COMDAT_GROUP (node->symbol.decl)
= DECL_COMDAT_GROUP (target->symbol.decl);
if (DECL_ONE_ONLY (target->symbol.decl)
&& !node->symbol.same_comdat_group)
symtab_add_to_same_comdat_group ((symtab_node)node, (symtab_node)target);
}
node->symbol.externally_visible = target->symbol.externally_visible;
}
/* Add reference recording that NODE is alias of TARGET.
The function can fail in the case of aliasing cycles; in this case
it returns false. */
bool
symtab_resolve_alias (symtab_node node, symtab_node target)
{
symtab_node n;
gcc_assert (!node->symbol.analyzed
&& !vec_safe_length (node->symbol.ref_list.references));
/* Never let cycles to creep into the symbol table alias references;
those will make alias walkers to be infinite. */
for (n = target; n && n->symbol.alias;
n = n->symbol.analyzed ? symtab_alias_target (n) : NULL)
if (n == node)
{
if (is_a <cgraph_node> (node))
error ("function %q+D part of alias cycle", node->symbol.decl);
else if (is_a <varpool_node> (node))
error ("variable %q+D part of alias cycle", node->symbol.decl);
else
gcc_unreachable ();
node->symbol.alias = false;
return false;
}
/* "analyze" the node - i.e. mark the reference. */
node->symbol.definition = true;
node->symbol.alias = true;
node->symbol.analyzed = true;
ipa_record_reference (node, target, IPA_REF_ALIAS, NULL);
/* Alias targets become reudndant after alias is resolved into an reference.
We do not want to keep it around or we would have to mind updating them
when renaming symbols. */
node->symbol.alias_target = NULL;
DECL_ATTRIBUTES (node->symbol.decl)
= remove_attribute ("alias", DECL_ATTRIBUTES (node->symbol.decl));
if (node->symbol.cpp_implicit_alias && cgraph_state >= CGRAPH_STATE_CONSTRUCTION)
fixup_same_cpp_alias_visibility (node, target);
/* If alias has address taken, so does the target. */
if (node->symbol.address_taken)
symtab_alias_ultimate_target (target, NULL)->symbol.address_taken = true;
return true;
}
#include "gt-symtab.h" #include "gt-symtab.h"
...@@ -3933,7 +3933,7 @@ get_cg_data (struct cgraph_node **node, bool traverse_aliases) ...@@ -3933,7 +3933,7 @@ get_cg_data (struct cgraph_node **node, bool traverse_aliases)
struct tm_ipa_cg_data *d; struct tm_ipa_cg_data *d;
if (traverse_aliases && (*node)->symbol.alias) if (traverse_aliases && (*node)->symbol.alias)
*node = cgraph_get_node ((*node)->thunk.alias); *node = cgraph_alias_target (*node);
d = (struct tm_ipa_cg_data *) (*node)->symbol.aux; d = (struct tm_ipa_cg_data *) (*node)->symbol.aux;
...@@ -4699,7 +4699,7 @@ ipa_tm_create_version_alias (struct cgraph_node *node, void *data) ...@@ -4699,7 +4699,7 @@ ipa_tm_create_version_alias (struct cgraph_node *node, void *data)
tree old_decl, new_decl, tm_name; tree old_decl, new_decl, tm_name;
struct cgraph_node *new_node; struct cgraph_node *new_node;
if (!node->same_body_alias) if (!node->symbol.cpp_implicit_alias)
return false; return false;
old_decl = node->symbol.decl; old_decl = node->symbol.decl;
...@@ -5369,7 +5369,7 @@ ipa_tm_execute (void) ...@@ -5369,7 +5369,7 @@ ipa_tm_execute (void)
bool doit = false; bool doit = false;
node = tm_callees[i]; node = tm_callees[i];
if (node->same_body_alias) if (node->symbol.cpp_implicit_alias)
continue; continue;
a = cgraph_function_body_availability (node); a = cgraph_function_body_availability (node);
......
...@@ -699,7 +699,9 @@ create_emultls_var (struct varpool_node *var, void *data) ...@@ -699,7 +699,9 @@ create_emultls_var (struct varpool_node *var, void *data)
tree cdecl; tree cdecl;
struct varpool_node *cvar; struct varpool_node *cvar;
cdecl = new_emutls_decl (var->symbol.decl, var->alias_of); cdecl = new_emutls_decl (var->symbol.decl,
var->symbol.alias && var->symbol.analyzed
? varpool_alias_target (var)->symbol.decl : NULL);
cvar = varpool_get_node (cdecl); cvar = varpool_get_node (cdecl);
control_vars.quick_push (cvar); control_vars.quick_push (cvar);
...@@ -711,7 +713,7 @@ create_emultls_var (struct varpool_node *var, void *data) ...@@ -711,7 +713,7 @@ create_emultls_var (struct varpool_node *var, void *data)
need to do this once for the main variable. */ need to do this once for the main variable. */
emutls_common_1 (var->symbol.decl, cdecl, (tree *)data); emutls_common_1 (var->symbol.decl, cdecl, (tree *)data);
} }
if (var->symbol.alias && !var->alias_of) if (var->symbol.alias && !var->symbol.analyzed)
cvar->symbol.alias = true; cvar->symbol.alias = true;
/* Indicate that the value of the TLS variable may be found elsewhere, /* Indicate that the value of the TLS variable may be found elsewhere,
...@@ -767,7 +769,7 @@ ipa_lower_emutls (void) ...@@ -767,7 +769,7 @@ ipa_lower_emutls (void)
{ {
var = tls_vars->nodes[i]; var = tls_vars->nodes[i];
if (var->symbol.alias && !var->alias_of) if (var->symbol.alias && !var->symbol.analyzed)
any_aliases = true; any_aliases = true;
else if (!var->symbol.alias) else if (!var->symbol.alias)
varpool_for_node_and_aliases (var, create_emultls_var, &ctor_body, true); varpool_for_node_and_aliases (var, create_emultls_var, &ctor_body, true);
......
...@@ -240,30 +240,9 @@ varpool_analyze_node (struct varpool_node *node) ...@@ -240,30 +240,9 @@ varpool_analyze_node (struct varpool_node *node)
already informed about increased alignment. */ already informed about increased alignment. */
align_variable (decl, 0); align_variable (decl, 0);
} }
if (node->symbol.alias && node->alias_of) if (node->symbol.alias)
{ symtab_resolve_alias
struct varpool_node *tgt = varpool_node_for_decl (node->alias_of); ((symtab_node) node, (symtab_node) varpool_get_node (node->symbol.alias_target));
struct varpool_node *n;
for (n = tgt; n && n->symbol.alias;
n = n->symbol.analyzed ? varpool_alias_target (n) : NULL)
if (n == node)
{
error ("variable %q+D part of alias cycle", node->symbol.decl);
node->symbol.alias = false;
continue;
}
if (!vec_safe_length (node->symbol.ref_list.references))
ipa_record_reference ((symtab_node)node, (symtab_node)tgt, IPA_REF_ALIAS, NULL);
if (node->extra_name_alias)
{
DECL_WEAK (node->symbol.decl) = DECL_WEAK (node->alias_of);
DECL_EXTERNAL (node->symbol.decl) = DECL_EXTERNAL (node->alias_of);
DECL_VISIBILITY (node->symbol.decl) = DECL_VISIBILITY (node->alias_of);
fixup_same_cpp_alias_visibility ((symtab_node) node,
(symtab_node) tgt, node->alias_of);
}
}
else if (DECL_INITIAL (decl)) else if (DECL_INITIAL (decl))
record_references_in_initializer (decl, node->symbol.analyzed); record_references_in_initializer (decl, node->symbol.analyzed);
node->symbol.analyzed = true; node->symbol.analyzed = true;
...@@ -281,7 +260,7 @@ assemble_aliases (struct varpool_node *node) ...@@ -281,7 +260,7 @@ assemble_aliases (struct varpool_node *node)
{ {
struct varpool_node *alias = ipa_ref_referring_varpool_node (ref); struct varpool_node *alias = ipa_ref_referring_varpool_node (ref);
do_assemble_alias (alias->symbol.decl, do_assemble_alias (alias->symbol.decl,
DECL_ASSEMBLER_NAME (alias->alias_of)); DECL_ASSEMBLER_NAME (node->symbol.decl));
assemble_aliases (alias); assemble_aliases (alias);
} }
} }
...@@ -494,18 +473,7 @@ varpool_create_variable_alias (tree alias, tree decl) ...@@ -494,18 +473,7 @@ varpool_create_variable_alias (tree alias, tree decl)
alias_node = varpool_node_for_decl (alias); alias_node = varpool_node_for_decl (alias);
alias_node->symbol.alias = true; alias_node->symbol.alias = true;
alias_node->symbol.definition = true; alias_node->symbol.definition = true;
alias_node->alias_of = decl; alias_node->symbol.alias_target = decl;
/* Extra name alias mechanizm creates aliases really late
via DECL_ASSEMBLER_NAME mechanizm.
This is unfortunate because they are not going through the
standard channels. Ensure they get output. */
if (cgraph_state >= CGRAPH_STATE_IPA)
{
varpool_analyze_node (alias_node);
if (TREE_PUBLIC (alias))
alias_node->symbol.externally_visible = true;
}
return alias_node; return alias_node;
} }
...@@ -522,7 +490,15 @@ varpool_extra_name_alias (tree alias, tree decl) ...@@ -522,7 +490,15 @@ varpool_extra_name_alias (tree alias, tree decl)
return NULL; return NULL;
#endif #endif
alias_node = varpool_create_variable_alias (alias, decl); alias_node = varpool_create_variable_alias (alias, decl);
alias_node->extra_name_alias = true; alias_node->symbol.cpp_implicit_alias = true;
/* Extra name alias mechanizm creates aliases really late
via DECL_ASSEMBLER_NAME mechanizm.
This is unfortunate because they are not going through the
standard channels. Ensure they get output. */
if (cpp_implicit_aliases_done)
symtab_resolve_alias ((symtab_node)alias_node,
(symtab_node)varpool_node_for_decl (decl));
return alias_node; return alias_node;
} }
......
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