aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorJan Hubicka <jh@suse.cz>2010-07-06 20:54:38 +0200
committerJan Hubicka <hubicka@gcc.gnu.org>2010-07-06 18:54:38 +0000
commite10aaec029cf3918f75755a6365c1976be8ad6eb (patch)
treeda7ceb57fd3446fb3bfc8509e1cdccdfa6ff9e48
parent4bbf141cf116e3c59cba66e9c51fb33bc90793f1 (diff)
downloadgcc-e10aaec029cf3918f75755a6365c1976be8ad6eb.zip
gcc-e10aaec029cf3918f75755a6365c1976be8ad6eb.tar.gz
gcc-e10aaec029cf3918f75755a6365c1976be8ad6eb.tar.bz2
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
-rw-r--r--gcc/ChangeLog10
-rw-r--r--gcc/cgraph.c23
-rw-r--r--gcc/lto-symtab.c81
3 files changed, 81 insertions, 33 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 164b890..65b7883 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,13 @@
+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>
* config/i386/i386.c (ix86_function_ms_hook_prologue): Enable x64
diff --git a/gcc/cgraph.c b/gcc/cgraph.c
index aaa50b6..3736769 100644
--- a/gcc/cgraph.c
+++ b/gcc/cgraph.c
@@ -604,6 +604,29 @@ cgraph_add_thunk (tree alias, tree decl, bool this_adjusting,
is assigned. */
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)
{
struct cgraph_node key, *node = NULL, **slot;
diff --git a/gcc/lto-symtab.c b/gcc/lto-symtab.c
index e94bc20..9985745 100644
--- a/gcc/lto-symtab.c
+++ b/gcc/lto-symtab.c
@@ -206,6 +206,24 @@ lto_cgraph_replace_node (struct cgraph_node *node,
struct cgraph_node *prevailing_node)
{
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. */
if (node->needed)
@@ -227,27 +245,37 @@ lto_cgraph_replace_node (struct cgraph_node *node,
/* Redirect incomming references. */
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)
- if (DECL_ASSEMBLER_NAME_SET_P (alias->decl))
- {
- lto_symtab_entry_t se
- = lto_symtab_get (DECL_ASSEMBLER_NAME (alias->decl));
-
- for (; se; se = se->next)
- if (se->node == node)
- {
- se->node = NULL;
- break;
- }
- }
+ {
+ last = alias;
+ gcc_assert (alias->same_body_alias);
+ alias->same_body = prevailing_node;
+ alias->thunk.alias = prevailing_node->decl;
+ }
+ last->next = prevailing_node->same_body;
+ /* Node with aliases is prevailed by alias.
+ We could handle this, but combining thunks together will be tricky.
+ 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. */
- 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
@@ -433,7 +461,9 @@ lto_symtab_resolve_can_prevail_p (lto_symtab_entry_t e)
/* For functions we need a non-discarded body. */
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. */
else if (TREE_CODE (e->decl) == VAR_DECL)
@@ -461,7 +491,7 @@ lto_symtab_resolve_symbols (void **slot)
for (e = (lto_symtab_entry_t) *slot; e; e = e->next)
{
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)
{
e->vnode = varpool_get_node (e->decl);
@@ -751,22 +781,7 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED)
for (e = prevailing->next; e; e = e->next)
{
if (e->node != NULL)
- {
- 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);
- }
+ lto_cgraph_replace_node (e->node, prevailing->node);
if (e->vnode != NULL)
lto_varpool_replace_node (e->vnode, prevailing->vnode);
}