OSDN Git Service

2011-07-24 François Dumont <francois.cppdevs@free.fr>
[pf3gnuchains/gcc-fork.git] / gcc / lto-symtab.c
index c86bbcc..3a7c783 100644 (file)
@@ -25,7 +25,6 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree.h"
 #include "gimple.h"
 #include "ggc.h"
-#include "lambda.h"    /* gcd */
 #include "hashtab.h"
 #include "plugin-api.h"
 #include "lto-streamer.h"
@@ -210,7 +209,6 @@ lto_cgraph_replace_node (struct cgraph_node *node,
                         struct cgraph_node *prevailing_node)
 {
   struct cgraph_edge *e, *next;
-  bool no_aliases_please = false;
   bool compatible_p;
 
   if (cgraph_dump_file)
@@ -224,13 +222,6 @@ lto_cgraph_replace_node (struct cgraph_node *node,
                 (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)
     cgraph_mark_needed_node (prevailing_node);
@@ -244,8 +235,8 @@ lto_cgraph_replace_node (struct cgraph_node *node,
 
   /* Redirect all incoming edges.  */
   compatible_p
-    = gimple_types_compatible_p (TREE_TYPE (TREE_TYPE (prevailing_node->decl)),
-                                TREE_TYPE (TREE_TYPE (node->decl)), GTC_DIAG);
+    = types_compatible_p (TREE_TYPE (TREE_TYPE (prevailing_node->decl)),
+                         TREE_TYPE (TREE_TYPE (node->decl)));
   for (e = node->callers; e; e = next)
     {
       next = e->next_caller;
@@ -260,37 +251,8 @@ lto_cgraph_replace_node (struct cgraph_node *node,
   /* Redirect incomming references.  */
   ipa_clone_refering (prevailing_node, NULL, &node->ref_list);
 
-  /* If we have aliases, redirect them to the prevailing node.  */
-  if (!node->same_body_alias && node->same_body)
-    {
-      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)
-       {
-         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.  */
-  if (node->same_body_alias)
-    cgraph_remove_same_body_alias (node);
-  else
-    cgraph_remove_node (node);
+  cgraph_remove_node (node);
 }
 
 /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
@@ -306,32 +268,9 @@ lto_varpool_replace_node (struct varpool_node *vnode,
       gcc_assert (!vnode->analyzed || prevailing_node->analyzed);
       varpool_mark_needed_node (prevailing_node);
     }
-  /* Relink aliases.  */
-  if (vnode->extra_name && !vnode->alias)
-    {
-      struct varpool_node *alias, *last;
-      for (alias = vnode->extra_name;
-          alias; alias = alias->next)
-       {
-         last = alias;
-         alias->extra_name = prevailing_node;
-       }
-
-      if (prevailing_node->extra_name)
-       {
-         last->next = prevailing_node->extra_name;
-         prevailing_node->extra_name->prev = last;
-       }
-      prevailing_node->extra_name = vnode->extra_name;
-      vnode->extra_name = NULL;
-    }
   gcc_assert (!vnode->finalized || prevailing_node->finalized);
   gcc_assert (!vnode->analyzed || prevailing_node->analyzed);
 
-  /* When replacing by an alias, the references goes to the original
-     variable.  */
-  if (prevailing_node->alias && prevailing_node->extra_name)
-    prevailing_node = prevailing_node->extra_name;
   ipa_clone_refering (NULL, prevailing_node, &vnode->ref_list);
 
   /* Be sure we can garbage collect the initializer.  */
@@ -362,8 +301,8 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
 
   if (TREE_CODE (decl) == FUNCTION_DECL)
     {
-      if (!gimple_types_compatible_p (TREE_TYPE (prevailing_decl),
-                                     TREE_TYPE (decl), GTC_DIAG))
+      if (!types_compatible_p (TREE_TYPE (prevailing_decl),
+                              TREE_TYPE (decl)))
        /* If we don't have a merged type yet...sigh.  The linker
           wouldn't complain if the types were mismatched, so we
           probably shouldn't either.  Just use the type from
@@ -392,11 +331,7 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
   prevailing_type = TYPE_MAIN_VARIANT (TREE_TYPE (prevailing_decl));
   type = TYPE_MAIN_VARIANT (TREE_TYPE (decl));
 
-  /* We have to register and fetch canonical types here as the global
-     fixup process didn't yet run.  */
-  prevailing_type = gimple_register_type (prevailing_type);
-  type = gimple_register_type (type);
-  if (!gimple_types_compatible_p (prevailing_type, type, GTC_DIAG))
+  if (!types_compatible_p (prevailing_type, type))
     {
       if (COMPLETE_TYPE_P (type))
        return false;
@@ -421,9 +356,7 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
          if (TREE_CODE (tem1) != TREE_CODE (tem2))
            return false;
 
-         if (!gimple_types_compatible_p (gimple_register_type (tem1),
-                                         gimple_register_type (tem2),
-                                         GTC_DIAG))
+         if (!types_compatible_p (tem1, tem2))
            return false;
        }
 
@@ -480,18 +413,13 @@ 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
-               || (e->node->same_body_alias && e->node->same_body->analyzed)));
+    return (e->node && e->node->analyzed);
 
-  /* A variable should have a size.  */
   else if (TREE_CODE (e->decl) == VAR_DECL)
     {
       if (!e->vnode)
        return false;
-      if (e->vnode->finalized)
-       return true;
-      return e->vnode->alias && e->vnode->extra_name->finalized;
+      return e->vnode->finalized;
     }
 
   gcc_unreachable ();
@@ -510,7 +438,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_or_alias (e->decl);
+       e->node = cgraph_get_node (e->decl);
       else if (TREE_CODE (e->decl) == VAR_DECL)
        e->vnode = varpool_get_node (e->decl);
     }
@@ -593,16 +521,16 @@ found:
 }
 
 /* Merge all decls in the symbol table chain to the prevailing decl and
-   issue diagnostics about type mismatches.  */
+   issue diagnostics about type mismatches.  If DIAGNOSED_P is true
+   do not issue further diagnostics.*/
 
 static void
-lto_symtab_merge_decls_2 (void **slot)
+lto_symtab_merge_decls_2 (void **slot, bool diagnosed_p)
 {
   lto_symtab_entry_t prevailing, e;
   VEC(tree, heap) *mismatches = NULL;
   unsigned i;
   tree decl;
-  bool diagnosed_p = false;
 
   /* Nothing to do for a single entry.  */
   prevailing = (lto_symtab_entry_t) *slot;
@@ -612,7 +540,8 @@ lto_symtab_merge_decls_2 (void **slot)
   /* Try to merge each entry with the prevailing one.  */
   for (e = prevailing->next; e; e = e->next)
     {
-      if (!lto_symtab_merge (prevailing, e))
+      if (!lto_symtab_merge (prevailing, e)
+         && !diagnosed_p)
        VEC_safe_push (tree, heap, mismatches, e->decl);
     }
   if (VEC_empty (tree, mismatches))
@@ -621,8 +550,7 @@ lto_symtab_merge_decls_2 (void **slot)
   /* Diagnose all mismatched re-declarations.  */
   FOR_EACH_VEC_ELT (tree, mismatches, i, decl)
     {
-      if (!gimple_types_compatible_p (TREE_TYPE (prevailing->decl),
-                                     TREE_TYPE (decl), GTC_DIAG))
+      if (!types_compatible_p (TREE_TYPE (prevailing->decl), TREE_TYPE (decl)))
        diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
                                   "type of %qD does not match original "
                                   "declaration", decl);
@@ -745,18 +673,9 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
       inform (DECL_SOURCE_LOCATION (prevailing->decl),
              "previously declared here");
 
-  /* Register and adjust types of the entries.  */
-  for (e = (lto_symtab_entry_t) *slot; e; e = e->next)
-    TREE_TYPE (e->decl) = gimple_register_type (TREE_TYPE (e->decl));
-
   /* Merge the chain to the single prevailing decl and diagnose
      mismatches.  */
-  lto_symtab_merge_decls_2 (slot);
-
-  /* Drop all but the prevailing decl from the symtab.  */
-  if (TREE_CODE (prevailing->decl) != FUNCTION_DECL
-      && TREE_CODE (prevailing->decl) != VAR_DECL)
-    prevailing->next = NULL;
+  lto_symtab_merge_decls_2 (slot, diagnosed_p);
 
   /* Store resolution decision into the callgraph.  
      In LTRANS don't overwrite information we stored into callgraph at
@@ -799,9 +718,26 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED)
   for (e = prevailing->next; e; e = e->next)
     {
       if (e->node != NULL)
-       lto_cgraph_replace_node (e->node, prevailing->node);
+       {
+         /* In case we prevail funcion by an alias, we can run into case
+            that the alias has no cgraph node attached, since it was
+            previously unused.  Create the node.  */
+         if (!prevailing->node)
+           {
+             prevailing->node = cgraph_create_node (prevailing->decl);
+             prevailing->node->alias = true;
+           }
+         lto_cgraph_replace_node (e->node, prevailing->node);
+       }
       if (e->vnode != NULL)
-       lto_varpool_replace_node (e->vnode, prevailing->vnode);
+       {
+         if (!prevailing->vnode)
+           {
+             prevailing->vnode = varpool_node (prevailing->decl);
+             prevailing->vnode->alias = true;
+           }
+         lto_varpool_replace_node (e->vnode, prevailing->vnode);
+       }
     }
 
   /* Drop all but the prevailing decl from the symtab.  */
@@ -816,8 +752,18 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED)
 void
 lto_symtab_merge_cgraph_nodes (void)
 {
+  struct cgraph_node *node;
+  struct varpool_node *vnode;
   lto_symtab_maybe_init_hash_table ();
   htab_traverse (lto_symtab_identifiers, lto_symtab_merge_cgraph_nodes_1, NULL);
+
+  for (node = cgraph_nodes; node; node = node->next)
+    if ((node->thunk.thunk_p || node->alias)
+       && node->thunk.alias)
+      node->thunk.alias = lto_symtab_prevailing_decl (node->thunk.alias);
+  for (vnode = varpool_nodes; vnode; vnode = vnode->next)
+    if (vnode->alias_of)
+      vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of);
 }
 
 /* Given the decl DECL, return the prevailing decl with the same name. */