Commit e01c7cca by Jan Hubicka Committed by Jan Hubicka

lto-symtab.c (lto_symtab_merge_cgraph_nodes): Resolve cross module weakrefs.

	* lto-symtab.c (lto_symtab_merge_cgraph_nodes): Resolve cross module
	weakrefs.
	* cgraph.c (dump_cgraph_node): Do not ice on unresolved alias.
	* cgraphunit.c (handle_alias_pairs): Store target of unresolved weakrefs.
	(output_weakrefs): Update.

From-SVN: r199041
parent 8ee05051
2013-05-17 Jan Hubicka <jh@suse.cz>
* lto-symtab.c (lto_symtab_merge_cgraph_nodes): Resolve cross module
weakrefs.
* cgraph.c (dump_cgraph_node): Do not ice on unresolved alias.
* cgraphunit.c (handle_alias_pairs): Store target of unresolved weakrefs.
(output_weakrefs): Update.
2013-05-17 Po-Chun Chang <pchang9@cs.wisc.edu>
Martin Jambor <mjambor@suse.cz>
......
......@@ -1558,7 +1558,7 @@ dump_cgraph_node (FILE *f, struct cgraph_node *node)
(int)node->thunk.virtual_value,
(int)node->thunk.virtual_offset_p);
}
if (node->alias && node->thunk.alias)
if (node->alias && node->thunk.alias && DECL_P (node->thunk.alias))
{
fprintf (f, " Alias of %s",
lang_hooks.decl_printable_name (node->thunk.alias, 2));
......
......@@ -1069,9 +1069,17 @@ handle_alias_pairs (void)
if (!target_node && lookup_attribute ("weakref", DECL_ATTRIBUTES (p->decl)) != NULL)
{
if (TREE_CODE (p->decl) == FUNCTION_DECL)
cgraph_get_create_node (p->decl)->alias = true;
{
struct cgraph_node *anode = cgraph_get_create_node (p->decl);
anode->alias = true;
anode->thunk.alias = p->target;
}
else
varpool_get_node (p->decl)->alias = true;
{
struct varpool_node *anode = varpool_get_node (p->decl);
anode->alias = true;
anode->alias_of = p->target;
}
DECL_EXTERNAL (p->decl) = 1;
alias_pairs->unordered_remove (i);
continue;
......@@ -1939,14 +1947,14 @@ output_weakrefs (void)
&& !TREE_ASM_WRITTEN (node->symbol.decl)
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (node->symbol.decl)))
do_assemble_alias (node->symbol.decl,
node->thunk.alias ? DECL_ASSEMBLER_NAME (node->thunk.alias)
node->thunk.alias && DECL_P (node->thunk.alias) ? DECL_ASSEMBLER_NAME (node->thunk.alias)
: get_alias_symbol (node->symbol.decl));
FOR_EACH_VARIABLE (vnode)
if (vnode->alias && DECL_EXTERNAL (vnode->symbol.decl)
&& !TREE_ASM_WRITTEN (vnode->symbol.decl)
&& lookup_attribute ("weakref", DECL_ATTRIBUTES (vnode->symbol.decl)))
do_assemble_alias (vnode->symbol.decl,
vnode->alias_of ? DECL_ASSEMBLER_NAME (vnode->alias_of)
vnode->alias_of && DECL_P (vnode->alias_of) ? DECL_ASSEMBLER_NAME (vnode->alias_of)
: get_alias_symbol (vnode->symbol.decl));
}
......
......@@ -593,13 +593,67 @@ lto_symtab_merge_cgraph_nodes (void)
FOR_EACH_FUNCTION (cnode)
{
/* Resolve weakrefs to symbol defined in other unit. */
if (!cnode->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->alias;
n = n->analyzed ? cgraph_alias_aliased_node (n) : NULL)
if (n == cnode)
{
error ("function %q+D part of alias cycle", cnode->symbol.decl);
cnode->alias = false;
break;
}
if (cnode->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->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->alias)
&& cnode->thunk.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->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->alias;
n = n->analyzed ? varpool_alias_aliased_node (n) : NULL)
if (n == vnode)
{
error ("function %q+D part of alias cycle", vnode->symbol.decl);
vnode->alias = false;
break;
}
if (vnode->alias)
{
varpool_create_variable_alias (vnode->symbol.decl, node->symbol.decl);
ipa_record_reference ((symtab_node)vnode, (symtab_node)node,
IPA_REF_ALIAS, NULL);
vnode->analyzed = true;
}
}
else if (node)
error ("%q+D alias in between function and variable is not supported", vnode->symbol.decl);
}
if (vnode->alias_of)
vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of);
vnode->symbol.aux = NULL;
......
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