OSDN Git Service

Daily bump.
[pf3gnuchains/gcc-fork.git] / gcc / lto-symtab.c
index dbdbcb2..976b9bf 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"
@@ -155,7 +154,8 @@ lto_symtab_register_decl (tree decl,
     gcc_assert (!DECL_ABSTRACT (decl));
 
   new_entry = ggc_alloc_cleared_lto_symtab_entry_def ();
-  new_entry->id = DECL_ASSEMBLER_NAME (decl);
+  new_entry->id = (*targetm.asm_out.mangle_assembler_name)
+                 (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl)));
   new_entry->decl = decl;
   new_entry->resolution = resolution;
   new_entry->file_data = file_data;
@@ -190,7 +190,8 @@ lto_symtab_get_resolution (tree decl)
 
   gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
 
-  e = lto_symtab_get (DECL_ASSEMBLER_NAME (decl));
+  e = lto_symtab_get ((*targetm.asm_out.mangle_assembler_name)
+                     (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
   while (e && e->decl != decl)
     e = e->next;
   if (!e)
@@ -208,24 +209,17 @@ 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)
     {
       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),
+              xstrdup (cgraph_node_name (node)), node->uid,
+              xstrdup (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;
+              IDENTIFIER_POINTER ((*targetm.asm_out.mangle_assembler_name)
+                (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (node->decl)))));
     }
 
   /* Merge node flags.  */
@@ -241,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;
@@ -257,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
@@ -303,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.  */
@@ -359,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
@@ -389,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;
@@ -418,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;
        }
 
@@ -477,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 ();
@@ -507,15 +438,17 @@ 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);
+      if (e->resolution == LDPR_PREVAILING_DEF_IRONLY
+         || e->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
+         || e->resolution == LDPR_PREVAILING_DEF)
+       prevailing = e;
     }
 
-  e = (lto_symtab_entry_t) *slot;
-
   /* If the chain is already resolved there is nothing else to do.  */
-  if (e->resolution != LDPR_UNKNOWN)
+  if (prevailing)
     return;
 
   /* Find the single non-replaceable prevailing symbol and
@@ -590,16 +523,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;
@@ -609,7 +542,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))
@@ -618,8 +552,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);
@@ -655,6 +588,7 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
   for (prevailing = (lto_symtab_entry_t) *slot;
        prevailing
        && prevailing->resolution != LDPR_PREVAILING_DEF_IRONLY
+       && prevailing->resolution != LDPR_PREVAILING_DEF_IRONLY_EXP
        && prevailing->resolution != LDPR_PREVAILING_DEF;
        prevailing = prevailing->next)
     ;
@@ -664,6 +598,7 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
     for (e = prevailing->next; e; e = e->next)
       {
        if (e->resolution == LDPR_PREVAILING_DEF_IRONLY
+           || e->resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
            || e->resolution == LDPR_PREVAILING_DEF)
          fatal_error ("multiple prevailing defs for %qE",
                       DECL_NAME (prevailing->decl));
@@ -742,18 +677,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
@@ -763,9 +689,9 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
      to handle UNKNOWN relocation well.
 
      The problem with storing guessed decision is whether to use
-     PREVAILING_DEF or PREVAILING_DEF_IRONLY.  First one would disable
-     some whole program optimizations, while ther second would imply
-     to many whole program assumptions.  */
+     PREVAILING_DEF, PREVAILING_DEF_IRONLY, PREVAILING_DEF_IRONLY_EXP.
+     First one would disable some whole program optimizations, while
+     ther second would imply to many whole program assumptions.  */
   if (prevailing->node && !flag_ltrans && !prevailing->guessed)
     prevailing->node->resolution = prevailing->resolution;
   else if (prevailing->vnode && !flag_ltrans && !prevailing->guessed)
@@ -796,9 +722,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.  */
@@ -813,8 +756,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. */
@@ -836,7 +789,8 @@ lto_symtab_prevailing_decl (tree decl)
   gcc_assert (DECL_ASSEMBLER_NAME_SET_P (decl));
 
   /* Walk through the list of candidates and return the one we merged to.  */
-  ret = lto_symtab_get (DECL_ASSEMBLER_NAME (decl));
+  ret = lto_symtab_get ((*targetm.asm_out.mangle_assembler_name)
+                       (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
   if (!ret)
     return NULL_TREE;