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>
PR target/50809
......@@ -1838,6 +1838,8 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
fprintf (f, " only_called_at_startup");
if (node->only_called_at_exit)
fprintf (f, " only_called_at_exit");
else if (node->alias)
fprintf (f, " alias");
fprintf (f, "\n");
......@@ -2567,7 +2569,7 @@ cgraph_for_node_thunks_and_aliases (struct cgraph_node *node,
for (e = node->callers; e; e = e->next_caller)
if (e->caller->thunk.thunk_p
&& (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,
include_overwritable))
return true;
......
......@@ -1249,6 +1249,21 @@ handle_alias_pairs (void)
varpool_create_variable_alias (p->decl, target_vnode->decl);
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
{
if (dump_file)
......@@ -2064,6 +2079,18 @@ ipa_passes (void)
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
at expansion time. Emit all neccesary aliases. */
......@@ -2073,15 +2100,17 @@ output_weakrefs (void)
struct cgraph_node *node;
struct varpool_node *vnode;
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))
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)
if (vnode->alias && vnode->alias_of && DECL_EXTERNAL (vnode->decl)
if (vnode->alias && DECL_EXTERNAL (vnode->decl)
&& !TREE_ASM_WRITTEN (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,
|| referenced_from_other_partition_p (&node->ref_list, set, vset)), 1);
bp_pack_value (&bp, node->lowered, 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->only_called_at_startup, 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,
streamer_write_uhwi_stream (ob->main_stream, node->thunk.fixed_offset);
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,
node->thunk.alias != NULL);
......
......@@ -1481,6 +1481,8 @@ add_varpool_node_to_partition (ltrans_partition part, struct varpool_node *vnode
{
varpool_node_set_iterator vsi;
vnode = varpool_variable_node (vnode, NULL);
/* If NODE is already there, we have nothing to do. */
vsi = varpool_node_set_find (part->varpool_set, vnode);
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