OSDN Git Service

* lto-symtab.c (lto_cgraph_replace_node): Handle aliases.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 Jul 2010 18:54:38 +0000 (18:54 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Tue, 6 Jul 2010 18:54:38 +0000 (18:54 +0000)
(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.

git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@161877 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/ChangeLog
gcc/cgraph.c
gcc/lto-symtab.c

index 164b890..65b7883 100644 (file)
@@ -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
index aaa50b6..3736769 100644 (file)
@@ -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;
index e94bc20..9985745 100644 (file)
@@ -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);
     }