===================================================================
@@ -1838,6 +1838,8 @@ dump_cgraph_node (FILE *f, struct cgraph
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");
===================================================================
@@ -1249,6 +1249,18 @@ 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)
+ {
+ 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,24 +2078,36 @@ 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. */
-void
+static void
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_outpu
|| 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_outpu
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);