Commit e10aaec0 by Jan Hubicka Committed by Jan Hubicka

lto-symtab.c (lto_cgraph_replace_node): Handle aliases.


	* lto-symtab.c (lto_cgraph_replace_node): Handle aliases.
	(lto_symtab_resolve_can_prevail_p): Also alias of cgraph node
	with body can prevail.
	(lto_symtab_resolve_symbols): Use cgraph_get_node_or_alias.
	(lto_symtab_merge_cgraph_nodes_1): Do not remove nodes from aliases.
	* cgraph.c (cgraph_get_node_or_alias): New function.
	* cgraph.h (cgraph_get_node_or_alias): Declare.

From-SVN: r161877
parent 4bbf141c
2010-07-06 Jan Hubicka <jh@suse.cz>
* lto-symtab.c (lto_cgraph_replace_node): Handle aliases.
(lto_symtab_resolve_can_prevail_p): Also alias of cgraph node
with body can prevail.
(lto_symtab_resolve_symbols): Use cgraph_get_node_or_alias.
(lto_symtab_merge_cgraph_nodes_1): Do not remove nodes from aliases.
* cgraph.c (cgraph_get_node_or_alias): New function.
* cgraph.h (cgraph_get_node_or_alias): Declare.
2010-07-06 Kai Tietz <kai.tietz@onevision.com> 2010-07-06 Kai Tietz <kai.tietz@onevision.com>
* config/i386/i386.c (ix86_function_ms_hook_prologue): Enable x64 * config/i386/i386.c (ix86_function_ms_hook_prologue): Enable x64
......
...@@ -604,6 +604,29 @@ cgraph_add_thunk (tree alias, tree decl, bool this_adjusting, ...@@ -604,6 +604,29 @@ cgraph_add_thunk (tree alias, tree decl, bool this_adjusting,
is assigned. */ is assigned. */
struct cgraph_node * struct cgraph_node *
cgraph_get_node_or_alias (tree decl)
{
struct cgraph_node key, *node = NULL, **slot;
gcc_assert (TREE_CODE (decl) == FUNCTION_DECL);
if (!cgraph_hash)
return NULL;
key.decl = decl;
slot = (struct cgraph_node **) htab_find_slot (cgraph_hash, &key,
NO_INSERT);
if (slot && *slot)
node = *slot;
return node;
}
/* Returns the cgraph node assigned to DECL or NULL if no cgraph node
is assigned. */
struct cgraph_node *
cgraph_get_node (tree decl) cgraph_get_node (tree decl)
{ {
struct cgraph_node key, *node = NULL, **slot; struct cgraph_node key, *node = NULL, **slot;
......
...@@ -206,6 +206,24 @@ lto_cgraph_replace_node (struct cgraph_node *node, ...@@ -206,6 +206,24 @@ lto_cgraph_replace_node (struct cgraph_node *node,
struct cgraph_node *prevailing_node) struct cgraph_node *prevailing_node)
{ {
struct cgraph_edge *e, *next; struct cgraph_edge *e, *next;
bool no_aliases_please = false;
if (cgraph_dump_file)
{
fprintf (cgraph_dump_file, "Replacing cgraph node %s/%i by %s/%i"
" for symbol %s\n",
cgraph_node_name (node), node->uid,
cgraph_node_name (prevailing_node),
prevailing_node->uid,
IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl)));
}
if (prevailing_node->same_body_alias)
{
if (prevailing_node->thunk.thunk_p)
no_aliases_please = true;
prevailing_node = prevailing_node->same_body;
}
/* Merge node flags. */ /* Merge node flags. */
if (node->needed) if (node->needed)
...@@ -227,27 +245,37 @@ lto_cgraph_replace_node (struct cgraph_node *node, ...@@ -227,27 +245,37 @@ lto_cgraph_replace_node (struct cgraph_node *node,
/* Redirect incomming references. */ /* Redirect incomming references. */
ipa_clone_refering (prevailing_node, NULL, &node->ref_list); ipa_clone_refering (prevailing_node, NULL, &node->ref_list);
if (node->same_body) /* If we have aliases, redirect them to the prevailing node. */
if (!node->same_body_alias && node->same_body)
{ {
struct cgraph_node *alias; struct cgraph_node *alias, *last;
/* We prevail aliases/tunks by a thunk. This is doable but
would need thunk combination. Hopefully no ABI changes will
every be crazy enough. */
gcc_assert (!no_aliases_please);
for (alias = node->same_body; alias; alias = alias->next) for (alias = node->same_body; alias; alias = alias->next)
if (DECL_ASSEMBLER_NAME_SET_P (alias->decl)) {
{ last = alias;
lto_symtab_entry_t se gcc_assert (alias->same_body_alias);
= lto_symtab_get (DECL_ASSEMBLER_NAME (alias->decl)); alias->same_body = prevailing_node;
alias->thunk.alias = prevailing_node->decl;
for (; se; se = se->next) }
if (se->node == node) last->next = prevailing_node->same_body;
{ /* Node with aliases is prevailed by alias.
se->node = NULL; We could handle this, but combining thunks together will be tricky.
break; Hopefully this does not happen. */
} if (prevailing_node->same_body)
} prevailing_node->same_body->previous = last;
prevailing_node->same_body = node->same_body;
node->same_body = NULL;
} }
/* Finally remove the replaced node. */ /* Finally remove the replaced node. */
cgraph_remove_node (node); if (node->same_body_alias)
cgraph_remove_same_body_alias (node);
else
cgraph_remove_node (node);
} }
/* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
...@@ -433,7 +461,9 @@ lto_symtab_resolve_can_prevail_p (lto_symtab_entry_t e) ...@@ -433,7 +461,9 @@ lto_symtab_resolve_can_prevail_p (lto_symtab_entry_t e)
/* For functions we need a non-discarded body. */ /* For functions we need a non-discarded body. */
if (TREE_CODE (e->decl) == FUNCTION_DECL) if (TREE_CODE (e->decl) == FUNCTION_DECL)
return (e->node && e->node->analyzed); return (e->node
&& (e->node->analyzed
|| (e->node->same_body_alias && e->node->same_body->analyzed)));
/* A variable should have a size. */ /* A variable should have a size. */
else if (TREE_CODE (e->decl) == VAR_DECL) else if (TREE_CODE (e->decl) == VAR_DECL)
...@@ -461,7 +491,7 @@ lto_symtab_resolve_symbols (void **slot) ...@@ -461,7 +491,7 @@ lto_symtab_resolve_symbols (void **slot)
for (e = (lto_symtab_entry_t) *slot; e; e = e->next) for (e = (lto_symtab_entry_t) *slot; e; e = e->next)
{ {
if (TREE_CODE (e->decl) == FUNCTION_DECL) if (TREE_CODE (e->decl) == FUNCTION_DECL)
e->node = cgraph_get_node (e->decl); e->node = cgraph_get_node_or_alias (e->decl);
else if (TREE_CODE (e->decl) == VAR_DECL) else if (TREE_CODE (e->decl) == VAR_DECL)
{ {
e->vnode = varpool_get_node (e->decl); e->vnode = varpool_get_node (e->decl);
...@@ -751,22 +781,7 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED) ...@@ -751,22 +781,7 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED)
for (e = prevailing->next; e; e = e->next) for (e = prevailing->next; e; e = e->next)
{ {
if (e->node != NULL) if (e->node != NULL)
{ lto_cgraph_replace_node (e->node, prevailing->node);
if (e->node->decl != e->decl && e->node->same_body)
{
struct cgraph_node *alias;
for (alias = e->node->same_body; alias; alias = alias->next)
if (alias->decl == e->decl)
break;
if (alias)
{
cgraph_remove_same_body_alias (alias);
continue;
}
}
lto_cgraph_replace_node (e->node, prevailing->node);
}
if (e->vnode != NULL) if (e->vnode != NULL)
lto_varpool_replace_node (e->vnode, prevailing->vnode); lto_varpool_replace_node (e->vnode, prevailing->vnode);
} }
......
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