Commit 25e2c40d by Jan Hubicka Committed by Jan Hubicka

cgraph.c (dump_cgraph_node): Dump alias flag.

	* cgraph.c (dump_cgraph_node): Dump alias flag.
	* cgraphunit.c (handle_alias_pairs): Handle weakrefs with no destination.
	(get_alias_symbol): New function.
	(output_weakrefs): Output also weakrefs with no destinatoin.
	(lto_output_node): Output weakref alias flag when at function boundary.

From-SVN: r180292
parent 49008cb9
2011-10-21 Jan Hubicka <jh@suse.cz>
* cgraph.c (dump_cgraph_node): Dump alias flag.
* cgraphunit.c (handle_alias_pairs): Handle weakrefs with no destination.
(get_alias_symbol): New function.
(output_weakrefs): Output also weakrefs with no destinatoin.
(lto_output_node): Output weakref alias flag when at function boundary.
2011-10-21 Andrew Stubbs <ams@codesourcery.com> 2011-10-21 Andrew Stubbs <ams@codesourcery.com>
PR target/50809 PR target/50809
...@@ -1838,6 +1838,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node) ...@@ -1838,6 +1838,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
fprintf (f, " only_called_at_startup"); fprintf (f, " only_called_at_startup");
if (node->only_called_at_exit) if (node->only_called_at_exit)
fprintf (f, " only_called_at_exit"); fprintf (f, " only_called_at_exit");
else if (node->alias)
fprintf (f, " alias");
fprintf (f, "\n"); fprintf (f, "\n");
...@@ -2567,7 +2569,7 @@ cgraph_for_node_thunks_and_aliases (struct cgraph_node *node, ...@@ -2567,7 +2569,7 @@ cgraph_for_node_thunks_and_aliases (struct cgraph_node *node,
for (e = node->callers; e; e = e->next_caller) for (e = node->callers; e; e = e->next_caller)
if (e->caller->thunk.thunk_p if (e->caller->thunk.thunk_p
&& (include_overwritable && (include_overwritable
|| cgraph_function_body_availability (e->caller))) || cgraph_function_body_availability (e->caller) > AVAIL_OVERWRITABLE))
if (cgraph_for_node_thunks_and_aliases (e->caller, callback, data, if (cgraph_for_node_thunks_and_aliases (e->caller, callback, data,
include_overwritable)) include_overwritable))
return true; return true;
......
...@@ -1249,6 +1249,21 @@ handle_alias_pairs (void) ...@@ -1249,6 +1249,21 @@ handle_alias_pairs (void)
varpool_create_variable_alias (p->decl, target_vnode->decl); varpool_create_variable_alias (p->decl, target_vnode->decl);
VEC_unordered_remove (alias_pair, alias_pairs, i); VEC_unordered_remove (alias_pair, alias_pairs, i);
} }
/* Weakrefs with target not defined in current unit are easy to handle; they
behave just as external variables except we need to note the alias flag
to later output the weakref pseudo op into asm file. */
else if (lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL
&& (TREE_CODE (p->decl) == FUNCTION_DECL
? (varpool_node_for_asm (p->target) == NULL)
: (cgraph_node_for_asm (p->target) == NULL)))
{
if (TREE_CODE (p->decl) == FUNCTION_DECL)
cgraph_get_create_node (p->decl)->alias = true;
else
varpool_get_node (p->decl)->alias = true;
DECL_EXTERNAL (p->decl) = 1;
VEC_unordered_remove (alias_pair, alias_pairs, i);
}
else else
{ {
if (dump_file) if (dump_file)
...@@ -2064,6 +2079,18 @@ ipa_passes (void) ...@@ -2064,6 +2079,18 @@ ipa_passes (void)
bitmap_obstack_release (NULL); bitmap_obstack_release (NULL);
} }
/* Return string alias is alias of. */
static tree
get_alias_symbol (tree decl)
{
tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
return get_identifier (TREE_STRING_POINTER
(TREE_VALUE (TREE_VALUE (alias))));
}
/* Weakrefs may be associated to external decls and thus not output /* Weakrefs may be associated to external decls and thus not output
at expansion time. Emit all neccesary aliases. */ at expansion time. Emit all neccesary aliases. */
...@@ -2073,15 +2100,17 @@ output_weakrefs (void) ...@@ -2073,15 +2100,17 @@ output_weakrefs (void)
struct cgraph_node *node; struct cgraph_node *node;
struct varpool_node *vnode; struct varpool_node *vnode;
for (node = cgraph_nodes; node; node = node->next) for (node = cgraph_nodes; node; node = node->next)
if (node->alias && node->thunk.alias && DECL_EXTERNAL (node->decl) if (node->alias && DECL_EXTERNAL (node->decl)
&& !TREE_ASM_WRITTEN (node->decl)) && !TREE_ASM_WRITTEN (node->decl))
assemble_alias (node->decl, assemble_alias (node->decl,
DECL_ASSEMBLER_NAME (node->thunk.alias)); node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
: get_alias_symbol (node->decl));
for (vnode = varpool_nodes; vnode; vnode = vnode->next) for (vnode = varpool_nodes; vnode; vnode = vnode->next)
if (vnode->alias && vnode->alias_of && DECL_EXTERNAL (vnode->decl) if (vnode->alias && DECL_EXTERNAL (vnode->decl)
&& !TREE_ASM_WRITTEN (vnode->decl)) && !TREE_ASM_WRITTEN (vnode->decl))
assemble_alias (vnode->decl, assemble_alias (vnode->decl,
DECL_ASSEMBLER_NAME (vnode->alias_of)); vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
: get_alias_symbol (vnode->decl));
} }
......
...@@ -512,7 +512,13 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, ...@@ -512,7 +512,13 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
|| referenced_from_other_partition_p (&node->ref_list, set, vset)), 1); || referenced_from_other_partition_p (&node->ref_list, set, vset)), 1);
bp_pack_value (&bp, node->lowered, 1); bp_pack_value (&bp, node->lowered, 1);
bp_pack_value (&bp, in_other_partition, 1); bp_pack_value (&bp, in_other_partition, 1);
bp_pack_value (&bp, node->alias && !boundary_p, 1); /* Real aliases in a boundary become non-aliases. However we still stream
alias info on weakrefs.
TODO: We lose a bit of information here - when we know that variable is
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
otherwise. */
bp_pack_value (&bp, node->alias && (!boundary_p || DECL_EXTERNAL (node->decl)), 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);
...@@ -530,7 +536,8 @@ lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node, ...@@ -530,7 +536,8 @@ 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->alias || node->thunk.thunk_p) && !boundary_p) if ((node->alias || node->thunk.thunk_p)
&& (!boundary_p || (node->alias && DECL_EXTERNAL (node->decl))))
{ {
streamer_write_hwi_in_range (ob->main_stream, 0, 1, streamer_write_hwi_in_range (ob->main_stream, 0, 1,
node->thunk.alias != NULL); node->thunk.alias != NULL);
......
...@@ -1481,6 +1481,8 @@ add_varpool_node_to_partition (ltrans_partition part, struct varpool_node *vnode ...@@ -1481,6 +1481,8 @@ add_varpool_node_to_partition (ltrans_partition part, struct varpool_node *vnode
{ {
varpool_node_set_iterator vsi; varpool_node_set_iterator vsi;
vnode = varpool_variable_node (vnode, NULL);
/* If NODE is already there, we have nothing to do. */ /* If NODE is already there, we have nothing to do. */
vsi = varpool_node_set_find (part->varpool_set, vnode); vsi = varpool_node_set_find (part->varpool_set, vnode);
if (!vsi_end_p (vsi)) if (!vsi_end_p (vsi))
......
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