]> gcc.gnu.org Git - gcc.git/commitdiff
symtab.c (insert_to_assembler_name_hash): Do not insert register vars.
authorJan Hubicka <jh@suse.cz>
Wed, 19 Sep 2012 10:01:56 +0000 (12:01 +0200)
committerJan Hubicka <hubicka@gcc.gnu.org>
Wed, 19 Sep 2012 10:01:56 +0000 (10:01 +0000)
* symtab.c (insert_to_assembler_name_hash): Do not insert
register vars.
(unlink_from_assembler_name_hash): NULL out pointers of unlinked
var.
(symtab_prevail_in_asm_name_hash): New.
(symtab_initialize_asm_name_hash): Break out from ...
(symtab_node_for_asm): ... here.
(dump_symtab_base): Dump LTO file data.
(verify_symtab_base): Register vars are not in symtab.
* cgraph.h (symtab_initialize_asm_name_hash,
symtab_prevail_in_asm_name_hash): New functions.
(symtab_real_symbol_p): New inline.
* lto-symtab.c: Do not include gt-lto-symtab.h.
(lto_symtab_entry_def): Remove.
(lto_symtab_entry_t): Remove.
(lto_symtab_identifiers): Remove.
(lto_symtab_free): Remove.
(lto_symtab_entry_hash): Remove.
(lto_symtab_entry_eq): Remove.
(lto_symtab_entry_marked_p): Remove.
(lto_symtab_maybe_init_hash_table): Remove.
(resolution_guessed_p, set_resolution_guessed): New functions.
(lto_symtab_register_decl): Only set resolution info.
(lto_symtab_get, lto_symtab_get_resolution): Remove.
(lto_symtab_merge): Reorg to work across symtab; do nothing if decls
are same.
(lto_symtab_resolve_replaceable_p): Reorg to work on symtab.
(lto_symtab_resolve_can_prevail_p): Likewise; only real symbols can
prevail.
(lto_symtab_resolve_symbols): Reorg to work on symtab.
(lto_symtab_merge_decls_2): Likewise.
(lto_symtab_merge_decls_1): Likewise; add debug dumps.
(lto_symtab_merge_decls): Likewise; do not merge at ltrans stage.
(lto_symtab_merge_cgraph_nodes_1): Reorg to work on symtab.
(lto_symtab_merge_cgraph_nodes): Likewise; do not merge at ltrans stage.
(lto_symtab_prevailing_decl): Rewrite to lookup into symtab.
* lto-streaer.h (lto_symtab_free): Remove.
* lto-cgraph.c (add_references): Cleanup.
* varpool.c (varpool_assemble_decl): Skip hard regs.

* lto.c (lto_materialize_function): Update confused comment.
(read_cgraph_and_symbols): Do not free symtab.

From-SVN: r191466

gcc/ChangeLog
gcc/cgraph.h
gcc/lto-cgraph.c
gcc/lto-streamer.h
gcc/lto-symtab.c
gcc/lto/ChangeLog
gcc/lto/lto.c
gcc/symtab.c
gcc/varpool.c

index d4d4f1b6ce73ae3295389b6a16f8a73b3d86983f..d00f3e2944970f94401cf1606398a16025206cb1 100644 (file)
@@ -1,3 +1,45 @@
+2012-09-19  Jan Hubicka  <jh@suse.cz>
+
+       * symtab.c (insert_to_assembler_name_hash): Do not insert
+       register vars.
+       (unlink_from_assembler_name_hash): NULL out pointers of unlinked
+       var.
+       (symtab_prevail_in_asm_name_hash): New.
+       (symtab_initialize_asm_name_hash): Break out from ...
+       (symtab_node_for_asm): ... here.
+       (dump_symtab_base): Dump LTO file data.
+       (verify_symtab_base): Register vars are not in symtab.
+       * cgraph.h (symtab_initialize_asm_name_hash,
+       symtab_prevail_in_asm_name_hash): New functions.
+       (symtab_real_symbol_p): New inline.
+       * lto-symtab.c: Do not include gt-lto-symtab.h.
+       (lto_symtab_entry_def): Remove.
+       (lto_symtab_entry_t): Remove.
+       (lto_symtab_identifiers): Remove.
+       (lto_symtab_free): Remove.
+       (lto_symtab_entry_hash): Remove.
+       (lto_symtab_entry_eq): Remove.
+       (lto_symtab_entry_marked_p): Remove.
+       (lto_symtab_maybe_init_hash_table): Remove.
+       (resolution_guessed_p, set_resolution_guessed): New functions.
+       (lto_symtab_register_decl): Only set resolution info.
+       (lto_symtab_get, lto_symtab_get_resolution): Remove.
+       (lto_symtab_merge): Reorg to work across symtab; do nothing if decls
+       are same.
+       (lto_symtab_resolve_replaceable_p): Reorg to work on symtab.
+       (lto_symtab_resolve_can_prevail_p): Likewise; only real symbols can
+       prevail.
+       (lto_symtab_resolve_symbols): Reorg to work on symtab.
+       (lto_symtab_merge_decls_2): Likewise.
+       (lto_symtab_merge_decls_1): Likewise; add debug dumps.
+       (lto_symtab_merge_decls): Likewise; do not merge at ltrans stage.
+       (lto_symtab_merge_cgraph_nodes_1): Reorg to work on symtab.
+       (lto_symtab_merge_cgraph_nodes): Likewise; do not merge at ltrans stage.
+       (lto_symtab_prevailing_decl): Rewrite to lookup into symtab.
+       * lto-streaer.h (lto_symtab_free): Remove.
+       * lto-cgraph.c (add_references): Cleanup.
+       * varpool.c (varpool_assemble_decl): Skip hard regs.
+
 2012-09-19  Richard Guenther  <rguenther@suse.de>
 
        PR other/53316
index 0d2ad41c43afdbeb12d5c971307069bf20220ba9..b8001a62bc78e0c2aca9c0b53ebef713ad7cb0cb 100644 (file)
@@ -704,6 +704,8 @@ bool varpool_for_node_and_aliases (struct varpool_node *,
                                   bool (*) (struct varpool_node *, void *),
                                   void *, bool);
 void varpool_add_new_variable (tree);
+void symtab_initialize_asm_name_hash (void);
+void symtab_prevail_in_asm_name_hash (symtab_node node);
 
 /* Return true when NODE is function.  */
 static inline bool
@@ -1309,4 +1311,27 @@ cgraph_mark_force_output_node (struct cgraph_node *node)
   gcc_checking_assert (!node->global.inlined_to);
 }
 
+/* Return true when the symbol is real symbol, i.e. it is not inline clone
+   or extern function kept around just for inlining.  */
+
+static inline bool
+symtab_real_symbol_p (symtab_node node)
+{
+  struct cgraph_node *cnode;
+  struct ipa_ref *ref;
+
+  if (!symtab_function_p (node))
+    return true;
+  cnode = cgraph (node);
+  if (cnode->global.inlined_to)
+    return false;
+  if (cnode->abstract_and_needed)
+    return false;
+  /* We keep virtual clones in symtab.  */
+  if (!cnode->analyzed
+      || DECL_EXTERNAL (cnode->symbol.decl))
+    return (cnode->callers
+           || ipa_ref_list_referring_iterate (&cnode->symbol.ref_list, 0, ref));
+  return true;
+}
 #endif  /* GCC_CGRAPH_H  */
index 24222883da4e7f44c1dca8c551f9401f0fe2c094..b86933430904178afea0bc00b2bc0e619eced562 100644 (file)
@@ -668,10 +668,7 @@ add_references (lto_symtab_encoder_t encoder,
     if (symtab_function_p (ref->referred))
       add_node_to (encoder, ipa_ref_node (ref), false);
     else
-      {
-       struct varpool_node *vnode = ipa_ref_varpool_node (ref);
-        lto_symtab_encoder_encode (encoder, (symtab_node)vnode);
-      }
+      lto_symtab_encoder_encode (encoder, ref->referred);
 }
 
 /* Find all symbols we want to stream into given partition and insert them
index abeaa4b2417bd6eaf8499a1a076cee28064e6961..059959e737ff32999571b61db0b88baa11d7e1a6 100644 (file)
@@ -866,7 +866,6 @@ extern void lto_symtab_merge_decls (void);
 extern void lto_symtab_merge_cgraph_nodes (void);
 extern tree lto_symtab_prevailing_decl (tree decl);
 extern enum ld_plugin_symbol_resolution lto_symtab_get_resolution (tree decl);
-extern void lto_symtab_free (void);
 extern GTY(()) VEC(tree,gc) *lto_global_var_decls;
 
 
index c5efb7f0156ed430d9fbfa1089a96b59290e9832..58b77a353a7ba31c1b9521b481c2f2a1aca19ee4 100644 (file)
@@ -32,98 +32,19 @@ along with GCC; see the file COPYING3.  If not see
 /* Vector to keep track of external variables we've seen so far.  */
 VEC(tree,gc) *lto_global_var_decls;
 
-/* Symbol table entry.  */
-
-struct GTY(()) lto_symtab_entry_def
-{
-  /* The symbol table entry key, an IDENTIFIER.  */
-  tree id;
-  /* The symbol table entry, a DECL.  */
-  tree decl;
-  /* The cgraph node if decl is a function decl.  Filled in during the
-     merging process.  */
-  struct cgraph_node *node;
-  /* The varpool node if decl is a variable decl.  Filled in during the
-     merging process.  */
-  struct varpool_node *vnode;
-  /* LTO file-data and symbol resolution for this decl.  */
-  struct lto_file_decl_data * GTY((skip (""))) file_data;
-  enum ld_plugin_symbol_resolution resolution;
-  /* True when resolution was guessed and not read from the file.  */
-  bool guessed;
-  /* Pointer to the next entry with the same key.  Before decl merging
-     this links all symbols from the different TUs.  After decl merging
-     this links merged but incompatible decls, thus all prevailing ones
-     remaining.  */
-  struct lto_symtab_entry_def *next;
-};
-typedef struct lto_symtab_entry_def *lto_symtab_entry_t;
-
-/* A poor man's symbol table. This hashes identifier to prevailing DECL
-   if there is one. */
-
-static GTY ((if_marked ("lto_symtab_entry_marked_p"),
-            param_is (struct lto_symtab_entry_def)))
-  htab_t lto_symtab_identifiers;
-
-/* Free symtab hashtable.  */
-
-void
-lto_symtab_free (void)
-{
-  htab_delete (lto_symtab_identifiers);
-  lto_symtab_identifiers = NULL;
-}
-
-/* Return the hash value of an lto_symtab_entry_t object pointed to by P.  */
-
-static hashval_t
-lto_symtab_entry_hash (const void *p)
-{
-  const struct lto_symtab_entry_def *base =
-    (const struct lto_symtab_entry_def *) p;
-  return IDENTIFIER_HASH_VALUE (base->id);
-}
-
-/* Return non-zero if P1 and P2 points to lto_symtab_entry_def structs
-   corresponding to the same symbol.  */
-
-static int
-lto_symtab_entry_eq (const void *p1, const void *p2)
+/* Return true if the resolution was guessed and not obtained from
+   the file.  */
+static inline bool
+resolution_guessed_p (symtab_node node)
 {
-  const struct lto_symtab_entry_def *base1 =
-     (const struct lto_symtab_entry_def *) p1;
-  const struct lto_symtab_entry_def *base2 =
-     (const struct lto_symtab_entry_def *) p2;
-  return (base1->id == base2->id);
+  return node->symbol.aux != NULL;
 }
 
-/* Returns non-zero if P points to an lto_symtab_entry_def struct that needs
-   to be marked for GC.  */
-
-static int
-lto_symtab_entry_marked_p (const void *p)
+/* Set guessed flag for NODE.  */
+static inline void
+set_resolution_guessed (symtab_node node, bool value)
 {
-  const struct lto_symtab_entry_def *base =
-     (const struct lto_symtab_entry_def *) p;
-
-  /* Keep this only if the common IDENTIFIER_NODE of the symtab chain
-     is marked which it will be if at least one of the DECLs in the
-     chain is marked.  */
-  return ggc_marked_p (base->id);
-}
-
-/* Lazily initialize resolution hash tables.  */
-
-static void
-lto_symtab_maybe_init_hash_table (void)
-{
-  if (lto_symtab_identifiers)
-    return;
-
-  lto_symtab_identifiers =
-    htab_create_ggc (1021, lto_symtab_entry_hash,
-                    lto_symtab_entry_eq, NULL);
+  node->symbol.aux = (void *)(size_t)value;
 }
 
 /* Registers DECL with the LTO symbol table as having resolution RESOLUTION
@@ -134,8 +55,7 @@ lto_symtab_register_decl (tree decl,
                          ld_plugin_symbol_resolution_t resolution,
                          struct lto_file_decl_data *file_data)
 {
-  lto_symtab_entry_t new_entry;
-  void **slot;
+  symtab_node node;
 
   /* Check that declarations reaching this function do not have
      properties inconsistent with having external linkage.  If any of
@@ -153,54 +73,15 @@ lto_symtab_register_decl (tree decl,
   if (TREE_CODE (decl) == FUNCTION_DECL)
     gcc_assert (!DECL_ABSTRACT (decl));
 
-  new_entry = ggc_alloc_cleared_lto_symtab_entry_def ();
-  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;
-
-  lto_symtab_maybe_init_hash_table ();
-  slot = htab_find_slot (lto_symtab_identifiers, new_entry, INSERT);
-  new_entry->next = (lto_symtab_entry_t) *slot;
-  *slot = new_entry;
-}
-
-/* Get the lto_symtab_entry_def struct associated with ID
-   if there is one.  */
-
-static lto_symtab_entry_t
-lto_symtab_get (tree id)
-{
-  struct lto_symtab_entry_def temp;
-  void **slot;
-
-  lto_symtab_maybe_init_hash_table ();
-  temp.id = id;
-  slot = htab_find_slot (lto_symtab_identifiers, &temp, NO_INSERT);
-  return slot ? (lto_symtab_entry_t) *slot : NULL;
-}
-
-/* Get the linker resolution for DECL.  */
-
-enum ld_plugin_symbol_resolution
-lto_symtab_get_resolution (tree decl)
-{
-  lto_symtab_entry_t e;
-
-  gcc_assert (DECL_ASSEMBLER_NAME_SET_P (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)
-    return LDPR_UNKNOWN;
-
-  return e->resolution;
+  node = symtab_get_node (decl);
+  if (node)
+    {
+      node->symbol.resolution = resolution;
+      gcc_assert (node->symbol.lto_file_data == file_data);
+      gcc_assert (!resolution_guessed_p (node));
+    }
 }
 
-
 /* Replace the cgraph node NODE with PREVAILING_NODE in the cgraph, merging
    all edges and removing the old node.  */
 
@@ -277,12 +158,15 @@ lto_varpool_replace_node (struct varpool_node *vnode,
    should be emitted.  */
 
 static bool
-lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
+lto_symtab_merge (symtab_node prevailing, symtab_node entry)
 {
-  tree prevailing_decl = prevailing->decl;
-  tree decl = entry->decl;
+  tree prevailing_decl = prevailing->symbol.decl;
+  tree decl = entry->symbol.decl;
   tree prevailing_type, type;
 
+  if (prevailing_decl == decl)
+    return true;
+
   /* Merge decl state in both directions, we may still end up using
      the new decl.  */
   TREE_ADDRESSABLE (prevailing_decl) |= TREE_ADDRESSABLE (decl);
@@ -377,17 +261,17 @@ lto_symtab_merge (lto_symtab_entry_t prevailing, lto_symtab_entry_t entry)
    entry.  */
 
 static bool
-lto_symtab_resolve_replaceable_p (lto_symtab_entry_t e)
+lto_symtab_resolve_replaceable_p (symtab_node e)
 {
-  if (DECL_EXTERNAL (e->decl)
-      || DECL_COMDAT (e->decl)
-      || DECL_ONE_ONLY (e->decl)
-      || DECL_WEAK (e->decl))
+  if (DECL_EXTERNAL (e->symbol.decl)
+      || DECL_COMDAT (e->symbol.decl)
+      || DECL_ONE_ONLY (e->symbol.decl)
+      || DECL_WEAK (e->symbol.decl))
     return true;
 
-  if (TREE_CODE (e->decl) == VAR_DECL)
-    return (DECL_COMMON (e->decl)
-           || (!flag_no_common && !DECL_INITIAL (e->decl)));
+  if (TREE_CODE (e->symbol.decl) == VAR_DECL)
+    return (DECL_COMMON (e->symbol.decl)
+           || (!flag_no_common && !DECL_INITIAL (e->symbol.decl)));
 
   return false;
 }
@@ -395,24 +279,23 @@ lto_symtab_resolve_replaceable_p (lto_symtab_entry_t e)
 /* Return true if the symtab entry E can be the prevailing one.  */
 
 static bool
-lto_symtab_resolve_can_prevail_p (lto_symtab_entry_t e)
+lto_symtab_resolve_can_prevail_p (symtab_node e)
 {
+  if (!symtab_real_symbol_p (e))
+    return false;
+
   /* The C++ frontend ends up neither setting TREE_STATIC nor
      DECL_EXTERNAL on virtual methods but only TREE_PUBLIC.
      So do not reject !TREE_STATIC here but only DECL_EXTERNAL.  */
-  if (DECL_EXTERNAL (e->decl))
+  if (DECL_EXTERNAL (e->symbol.decl))
     return false;
 
   /* For functions we need a non-discarded body.  */
-  if (TREE_CODE (e->decl) == FUNCTION_DECL)
-    return (e->node && e->node->analyzed);
+  if (TREE_CODE (e->symbol.decl) == FUNCTION_DECL)
+    return (cgraph (e)->analyzed);
 
-  else if (TREE_CODE (e->decl) == VAR_DECL)
-    {
-      if (!e->vnode)
-       return false;
-      return e->vnode->finalized;
-    }
+  else if (TREE_CODE (e->symbol.decl) == VAR_DECL)
+    return varpool (e)->finalized;
 
   gcc_unreachable ();
 }
@@ -421,23 +304,18 @@ lto_symtab_resolve_can_prevail_p (lto_symtab_entry_t e)
    their resolutions.  */
 
 static void
-lto_symtab_resolve_symbols (void **slot)
+lto_symtab_resolve_symbols (symtab_node first)
 {
-  lto_symtab_entry_t e;
-  lto_symtab_entry_t prevailing = NULL;
+  symtab_node e;
+  symtab_node prevailing = NULL;
 
   /* Always set e->node so that edges are updated to reflect decl merging. */
-  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);
-      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;
-    }
+  for (e = first; e; e = e->symbol.next_sharing_asm_name)
+    if (symtab_real_symbol_p (e)
+       && (e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
+           || e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
+           || e->symbol.resolution == LDPR_PREVAILING_DEF))
+      prevailing = e;
 
   /* If the chain is already resolved there is nothing else to do.  */
   if (prevailing)
@@ -445,26 +323,26 @@ lto_symtab_resolve_symbols (void **slot)
 
   /* Find the single non-replaceable prevailing symbol and
      diagnose ODR violations.  */
-  for (e = (lto_symtab_entry_t) *slot; e; e = e->next)
+  for (e = first; e; e = e->symbol.next_sharing_asm_name)
     {
       if (!lto_symtab_resolve_can_prevail_p (e))
        {
-         e->resolution = LDPR_RESOLVED_IR;
-          e->guessed = true;
+         e->symbol.resolution = LDPR_RESOLVED_IR;
+          set_resolution_guessed (e, true);
          continue;
        }
 
       /* Set a default resolution - the final prevailing one will get
          adjusted later.  */
-      e->resolution = LDPR_PREEMPTED_IR;
-      e->guessed = true;
+      e->symbol.resolution = LDPR_PREEMPTED_IR;
+      set_resolution_guessed (e, true);
       if (!lto_symtab_resolve_replaceable_p (e))
        {
          if (prevailing)
            {
-             error_at (DECL_SOURCE_LOCATION (e->decl),
-                       "%qD has already been defined", e->decl);
-             inform (DECL_SOURCE_LOCATION (prevailing->decl),
+             error_at (DECL_SOURCE_LOCATION (e->symbol.decl),
+                       "%qD has already been defined", e->symbol.decl);
+             inform (DECL_SOURCE_LOCATION (prevailing->symbol.decl),
                      "previously defined here");
            }
          prevailing = e;
@@ -474,13 +352,14 @@ lto_symtab_resolve_symbols (void **slot)
     goto found;
 
   /* Do a second round choosing one from the replaceable prevailing decls.  */
-  for (e = (lto_symtab_entry_t) *slot; e; e = e->next)
+  for (e = first; e; e = e->symbol.next_sharing_asm_name)
     {
-      if (e->resolution != LDPR_PREEMPTED_IR)
+      if (e->symbol.resolution != LDPR_PREEMPTED_IR
+         || !symtab_real_symbol_p (e))
        continue;
 
       /* Choose the first function that can prevail as prevailing.  */
-      if (TREE_CODE (e->decl) == FUNCTION_DECL)
+      if (TREE_CODE (e->symbol.decl) == FUNCTION_DECL)
        {
          prevailing = e;
          break;
@@ -488,8 +367,8 @@ lto_symtab_resolve_symbols (void **slot)
 
       /* From variables that can prevail choose the largest one.  */
       if (!prevailing
-         || tree_int_cst_lt (DECL_SIZE (prevailing->decl),
-                             DECL_SIZE (e->decl))
+         || tree_int_cst_lt (DECL_SIZE (prevailing->symbol.decl),
+                             DECL_SIZE (e->symbol.decl))
          /* When variables are equivalent try to chose one that has useful
             DECL_INITIAL.  This makes sense for keyed vtables that are
             DECL_EXTERNAL but initialized.  In units that do not need them
@@ -499,11 +378,11 @@ lto_symtab_resolve_symbols (void **slot)
             We know that the vtable is keyed outside the LTO unit - otherwise
             the keyed instance would prevail.  We still can preserve useful
             info in the initializer.  */
-         || (DECL_SIZE (prevailing->decl) == DECL_SIZE (e->decl)
-             && (DECL_INITIAL (e->decl)
-                 && DECL_INITIAL (e->decl) != error_mark_node)
-             && (!DECL_INITIAL (prevailing->decl)
-                 || DECL_INITIAL (prevailing->decl) == error_mark_node)))
+         || (DECL_SIZE (prevailing->symbol.decl) == DECL_SIZE (e->symbol.decl)
+             && (DECL_INITIAL (e->symbol.decl)
+                 && DECL_INITIAL (e->symbol.decl) != error_mark_node)
+             && (!DECL_INITIAL (prevailing->symbol.decl)
+                 || DECL_INITIAL (prevailing->symbol.decl) == error_mark_node)))
        prevailing = e;
     }
 
@@ -524,8 +403,8 @@ found:
     variables IRONLY, which are indeed PREVAILING_DEF in
     resolution file.  These variables still need manual
     externally_visible attribute.  */
-    prevailing->resolution = LDPR_PREVAILING_DEF_IRONLY;
-    prevailing->guessed = true;
+    prevailing->symbol.resolution = LDPR_PREVAILING_DEF_IRONLY;
+    set_resolution_guessed (prevailing, true);
 }
 
 /* Merge all decls in the symbol table chain to the prevailing decl and
@@ -533,24 +412,25 @@ found:
    do not issue further diagnostics.*/
 
 static void
-lto_symtab_merge_decls_2 (void **slot, bool diagnosed_p)
+lto_symtab_merge_decls_2 (symtab_node first, bool diagnosed_p)
 {
-  lto_symtab_entry_t prevailing, e;
+  symtab_node prevailing, e;
   VEC(tree, heap) *mismatches = NULL;
   unsigned i;
   tree decl;
 
   /* Nothing to do for a single entry.  */
-  prevailing = (lto_symtab_entry_t) *slot;
-  if (!prevailing->next)
+  prevailing = first;
+  if (!prevailing->symbol.next_sharing_asm_name)
     return;
 
   /* Try to merge each entry with the prevailing one.  */
-  for (e = prevailing->next; e; e = e->next)
+  for (e = prevailing->symbol.next_sharing_asm_name;
+       e; e = e->symbol.next_sharing_asm_name)
     {
       if (!lto_symtab_merge (prevailing, e)
          && !diagnosed_p)
-       VEC_safe_push (tree, heap, mismatches, e->decl);
+       VEC_safe_push (tree, heap, mismatches, e->symbol.decl);
     }
   if (VEC_empty (tree, mismatches))
     return;
@@ -558,13 +438,15 @@ lto_symtab_merge_decls_2 (void **slot, bool diagnosed_p)
   /* Diagnose all mismatched re-declarations.  */
   FOR_EACH_VEC_ELT (tree, mismatches, i, decl)
     {
-      if (!types_compatible_p (TREE_TYPE (prevailing->decl), TREE_TYPE (decl)))
+      if (!types_compatible_p (TREE_TYPE (prevailing->symbol.decl),
+                              TREE_TYPE (decl)))
        diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
                                   "type of %qD does not match original "
                                   "declaration", decl);
 
-      else if ((DECL_USER_ALIGN (prevailing->decl) && DECL_USER_ALIGN (decl))
-              && DECL_ALIGN (prevailing->decl) < DECL_ALIGN (decl))
+      else if ((DECL_USER_ALIGN (prevailing->symbol.decl)
+               && DECL_USER_ALIGN (decl))
+              && DECL_ALIGN (prevailing->symbol.decl) < DECL_ALIGN (decl))
        {
          diagnosed_p |= warning_at (DECL_SOURCE_LOCATION (decl), 0,
                                     "alignment of %qD is bigger than "
@@ -572,7 +454,7 @@ lto_symtab_merge_decls_2 (void **slot, bool diagnosed_p)
        }
     }
   if (diagnosed_p)
-    inform (DECL_SOURCE_LOCATION (prevailing->decl),
+    inform (DECL_SOURCE_LOCATION (prevailing->symbol.decl),
            "previously declared here");
 
   VEC_free (tree, heap, mismatches);
@@ -580,47 +462,50 @@ lto_symtab_merge_decls_2 (void **slot, bool diagnosed_p)
 
 /* Helper to process the decl chain for the symbol table entry *SLOT.  */
 
-static int
-lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
+static void
+lto_symtab_merge_decls_1 (symtab_node first)
 {
-  lto_symtab_entry_t e, prevailing;
+  symtab_node e, prevailing;
   bool diagnosed_p = false;
 
+  if (cgraph_dump_file)
+    {
+      fprintf (cgraph_dump_file, "Merging nodes for %s. Candidates:\n",
+              symtab_node_asm_name (first));
+      for (e = first; e; e = e->symbol.next_sharing_asm_name)
+       dump_symtab_node (cgraph_dump_file, e);
+    }
+
   /* Compute the symbol resolutions.  This is a no-op when using the
-     linker plugin.  */
-  lto_symtab_resolve_symbols (slot);
+     linker plugin and resolution was decided by the linker.  */
+  lto_symtab_resolve_symbols (first);
 
   /* Find the prevailing decl.  */
-  for (prevailing = (lto_symtab_entry_t) *slot;
+  for (prevailing = first;
        prevailing
-       && prevailing->resolution != LDPR_PREVAILING_DEF_IRONLY
-       && prevailing->resolution != LDPR_PREVAILING_DEF_IRONLY_EXP
-       && prevailing->resolution != LDPR_PREVAILING_DEF;
-       prevailing = prevailing->next)
+       && (!symtab_real_symbol_p (prevailing)
+          || (prevailing->symbol.resolution != LDPR_PREVAILING_DEF_IRONLY
+              && prevailing->symbol.resolution != LDPR_PREVAILING_DEF_IRONLY_EXP
+              && prevailing->symbol.resolution != LDPR_PREVAILING_DEF));
+       prevailing = prevailing->symbol.next_sharing_asm_name)
     ;
 
   /* Assert it's the only one.  */
   if (prevailing)
-    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));
-      }
+    for (e = prevailing->symbol.next_sharing_asm_name; e; e = e->symbol.next_sharing_asm_name)
+      if (symtab_real_symbol_p (e)
+         && (e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY
+             || e->symbol.resolution == LDPR_PREVAILING_DEF_IRONLY_EXP
+             || e->symbol.resolution == LDPR_PREVAILING_DEF))
+       fatal_error ("multiple prevailing defs for %qE",
+                    DECL_NAME (prevailing->symbol.decl));
 
   /* If there's not a prevailing symbol yet it's an external reference.
      Happens a lot during ltrans.  Choose the first symbol with a
      cgraph or a varpool node.  */
   if (!prevailing)
     {
-      prevailing = (lto_symtab_entry_t) *slot;
-      /* For functions choose one with a cgraph node.  */
-      if (TREE_CODE (prevailing->decl) == FUNCTION_DECL)
-       while (!prevailing->node
-              && prevailing->next)
-         prevailing = prevailing->next;
+      prevailing = first;
       /* For variables chose with a priority variant with vnode
         attached (i.e. from unit where external declaration of
         variable is actually used).
@@ -628,49 +513,45 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
         This is needed for C++ typeinfos, for example in
         lto/20081204-1 there are typeifos in both units, just
         one of them do have size.  */
-      if (TREE_CODE (prevailing->decl) == VAR_DECL)
+      if (TREE_CODE (prevailing->symbol.decl) == VAR_DECL)
        {
-         for (e = prevailing->next; e; e = e->next)
-           if ((!prevailing->vnode && e->vnode)
-               || ((prevailing->vnode != NULL) == (e->vnode != NULL)
-                   && !COMPLETE_TYPE_P (TREE_TYPE (prevailing->decl))
-                   && COMPLETE_TYPE_P (TREE_TYPE (e->decl))))
+         for (e = prevailing->symbol.next_sharing_asm_name;
+              e; e = e->symbol.next_sharing_asm_name)
+           if (!COMPLETE_TYPE_P (TREE_TYPE (prevailing->symbol.decl))
+               && COMPLETE_TYPE_P (TREE_TYPE (e->symbol.decl)))
              prevailing = e;
        }
     }
 
-  /* Move it first in the list.  */
-  if ((lto_symtab_entry_t) *slot != prevailing)
-    {
-      for (e = (lto_symtab_entry_t) *slot; e->next != prevailing; e = e->next)
-       ;
-      e->next = prevailing->next;
-      prevailing->next = (lto_symtab_entry_t) *slot;
-      *slot = (void *) prevailing;
-    }
+  symtab_prevail_in_asm_name_hash (prevailing);
 
   /* Record the prevailing variable.  */
-  if (TREE_CODE (prevailing->decl) == VAR_DECL)
-    VEC_safe_push (tree, gc, lto_global_var_decls, prevailing->decl);
+  if (TREE_CODE (prevailing->symbol.decl) == VAR_DECL)
+    VEC_safe_push (tree, gc, lto_global_var_decls,
+                  prevailing->symbol.decl);
 
   /* Diagnose mismatched objects.  */
-  for (e = prevailing->next; e; e = e->next)
+  for (e = prevailing->symbol.next_sharing_asm_name;
+       e; e = e->symbol.next_sharing_asm_name)
     {
-      if (TREE_CODE (prevailing->decl) == TREE_CODE (e->decl))
+      if (TREE_CODE (prevailing->symbol.decl)
+         == TREE_CODE (e->symbol.decl))
        continue;
 
-      switch (TREE_CODE (prevailing->decl))
+      switch (TREE_CODE (prevailing->symbol.decl))
        {
        case VAR_DECL:
-         gcc_assert (TREE_CODE (e->decl) == FUNCTION_DECL);
-         error_at (DECL_SOURCE_LOCATION (e->decl),
-                   "variable %qD redeclared as function", prevailing->decl);
+         gcc_assert (TREE_CODE (e->symbol.decl) == FUNCTION_DECL);
+         error_at (DECL_SOURCE_LOCATION (e->symbol.decl),
+                   "variable %qD redeclared as function",
+                   prevailing->symbol.decl);
          break;
 
        case FUNCTION_DECL:
-         gcc_assert (TREE_CODE (e->decl) == VAR_DECL);
-         error_at (DECL_SOURCE_LOCATION (e->decl),
-                   "function %qD redeclared as variable", prevailing->decl);
+         gcc_assert (TREE_CODE (e->symbol.decl) == VAR_DECL);
+         error_at (DECL_SOURCE_LOCATION (e->symbol.decl),
+                   "function %qD redeclared as variable",
+                   prevailing->symbol.decl);
          break;
 
        default:
@@ -680,12 +561,19 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
       diagnosed_p = true;
     }
   if (diagnosed_p)
-      inform (DECL_SOURCE_LOCATION (prevailing->decl),
+      inform (DECL_SOURCE_LOCATION (prevailing->symbol.decl),
              "previously declared here");
 
   /* Merge the chain to the single prevailing decl and diagnose
      mismatches.  */
-  lto_symtab_merge_decls_2 (slot, diagnosed_p);
+  lto_symtab_merge_decls_2 (first, diagnosed_p);
+
+  if (cgraph_dump_file)
+    {
+      fprintf (cgraph_dump_file, "After resolution:\n");
+      for (e = first; e; e = e->symbol.next_sharing_asm_name)
+       dump_symtab_node (cgraph_dump_file, e);
+    }
 
   /* Store resolution decision into the callgraph.  
      In LTRANS don't overwrite information we stored into callgraph at
@@ -698,11 +586,9 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
      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->symbol.resolution = prevailing->resolution;
-  else if (prevailing->vnode && !flag_ltrans && !prevailing->guessed)
-    prevailing->vnode->symbol.resolution = prevailing->resolution;
-  return 1;
+  if (resolution_guessed_p (prevailing))
+    prevailing->symbol.resolution = LDPR_UNKNOWN;
+  return;
 }
 
 /* Resolve and merge all symbol table chains to a prevailing decl.  */
@@ -710,50 +596,46 @@ lto_symtab_merge_decls_1 (void **slot, void *data ATTRIBUTE_UNUSED)
 void
 lto_symtab_merge_decls (void)
 {
-  lto_symtab_maybe_init_hash_table ();
-  htab_traverse (lto_symtab_identifiers, lto_symtab_merge_decls_1, NULL);
+  symtab_node node;
+
+  /* In ltrans mode we read merged cgraph, we do not really need to care
+     about resolving symbols again, we only need to replace duplicated declarations
+     read from the callgraph and from function sections.  */
+  if (flag_ltrans)
+    return;
+
+  /* Populate assembler name hash.   */
+  symtab_initialize_asm_name_hash ();
+
+  FOR_EACH_SYMBOL (node)
+    if (TREE_PUBLIC (node->symbol.decl)
+       && node->symbol.next_sharing_asm_name
+       && !node->symbol.previous_sharing_asm_name)
+    lto_symtab_merge_decls_1 (node);
 }
 
 /* Helper to process the decl chain for the symbol table entry *SLOT.  */
 
-static int
-lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED)
+static void
+lto_symtab_merge_cgraph_nodes_1 (symtab_node prevailing)
 {
-  lto_symtab_entry_t e, prevailing = (lto_symtab_entry_t) *slot;
-
-  if (!prevailing->next)
-    return 1;
+  symtab_node e, next;
 
   /* Replace the cgraph node of each entry with the prevailing one.  */
-  for (e = prevailing->next; e; e = e->next)
+  for (e = prevailing->symbol.next_sharing_asm_name; e;
+       e = next)
     {
-      if (e->node != NULL)
-       {
-         /* 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)
-       {
-         if (!prevailing->vnode)
-           {
-             prevailing->vnode = varpool_node (prevailing->decl);
-             prevailing->vnode->alias = true;
-           }
-         lto_varpool_replace_node (e->vnode, prevailing->vnode);
-       }
-    }
+      next = e->symbol.next_sharing_asm_name;
 
-  /* Drop all but the prevailing decl from the symtab.  */
-  prevailing->next = NULL;
+      if (!symtab_real_symbol_p (e))
+       continue;
+      if (symtab_function_p (e))
+       lto_cgraph_replace_node (cgraph (e), cgraph (prevailing));
+      if (symtab_variable_p (e))
+       lto_varpool_replace_node (varpool (e), varpool (prevailing));
+    }
 
-  return 1;
+  return;
 }
 
 /* Merge cgraph nodes according to the symbol merging done by
@@ -762,18 +644,33 @@ lto_symtab_merge_cgraph_nodes_1 (void **slot, void *data ATTRIBUTE_UNUSED)
 void
 lto_symtab_merge_cgraph_nodes (void)
 {
-  struct cgraph_node *node;
+  struct cgraph_node *cnode;
   struct varpool_node *vnode;
-  lto_symtab_maybe_init_hash_table ();
-  htab_traverse (lto_symtab_identifiers, lto_symtab_merge_cgraph_nodes_1, NULL);
+  symtab_node node;
+
+  /* Populate assembler name hash.   */
+  symtab_initialize_asm_name_hash ();
 
-  FOR_EACH_FUNCTION (node)
-    if ((node->thunk.thunk_p || node->alias)
-       && node->thunk.alias)
-      node->thunk.alias = lto_symtab_prevailing_decl (node->thunk.alias);
+  if (!flag_ltrans)
+    FOR_EACH_SYMBOL (node)
+      if (TREE_PUBLIC (node->symbol.decl)
+         && node->symbol.next_sharing_asm_name
+         && !node->symbol.previous_sharing_asm_name)
+        lto_symtab_merge_cgraph_nodes_1 (node);
+
+  FOR_EACH_FUNCTION (cnode)
+    {
+      if ((cnode->thunk.thunk_p || cnode->alias)
+         && cnode->thunk.alias)
+        cnode->thunk.alias = lto_symtab_prevailing_decl (cnode->thunk.alias);
+      cnode->symbol.aux = NULL;
+    }
   FOR_EACH_VARIABLE (vnode)
-    if (vnode->alias_of)
-      vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of);
+    {
+      if (vnode->alias_of)
+        vnode->alias_of = lto_symtab_prevailing_decl (vnode->alias_of);
+      vnode->symbol.aux = NULL;
+    }
 }
 
 /* Given the decl DECL, return the prevailing decl with the same name. */
@@ -781,7 +678,7 @@ lto_symtab_merge_cgraph_nodes (void)
 tree
 lto_symtab_prevailing_decl (tree decl)
 {
-  lto_symtab_entry_t ret;
+  symtab_node ret;
 
   /* Builtins and local symbols are their own prevailing decl.  */
   if (!TREE_PUBLIC (decl) || is_builtin_fn (decl))
@@ -795,12 +692,9 @@ 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 ((*targetm.asm_out.mangle_assembler_name)
-                       (IDENTIFIER_POINTER (DECL_ASSEMBLER_NAME (decl))));
+  ret = symtab_node_for_asm (DECL_ASSEMBLER_NAME (decl));
   if (!ret)
-    return NULL_TREE;
+    return decl;
 
-  return ret->decl;
+  return ret->symbol.decl;
 }
-
-#include "gt-lto-symtab.h"
index 8b2a469d8647bda6bd235141f26611608bbcd989..c6abe4b221f4042aa2d939bcbdb8694c142bdc2a 100644 (file)
@@ -1,3 +1,8 @@
+2012-09-19  Jan Hubicka  <jh@suse.cz>
+
+       * lto.c (lto_materialize_function): Update confused comment.
+       (read_cgraph_and_symbols): Do not free symtab.
+
 2012-09-12  Jan Hubicka  <jh@suse.cz>
 
        * lto.c (do_whole_program_analysis): Care timevars, statistics and
index c15f9cff5a793e41408bc53bdeb6b9f4cc3e9625..930e990b78048c2412f82a08e34e1a20b1a9adec 100644 (file)
@@ -198,7 +198,7 @@ lto_materialize_function (struct cgraph_node *node)
      and also functions that are needed to produce virtual clones.  */
   if (cgraph_function_with_gimple_body_p (node) || has_analyzed_clone_p (node))
     {
-      /* Clones and thunks don't need to be read.  */
+      /* Clones don't need to be read.  */
       if (node->clone_of)
        return;
 
@@ -3006,7 +3006,6 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
       VEC_safe_push (ipa_opt_pass, heap,
                     node->ipa_transforms_to_apply,
                     (ipa_opt_pass)&pass_ipa_inline);
-  lto_symtab_free ();
 
   timevar_pop (TV_IPA_LTO_CGRAPH_MERGE);
 
@@ -3035,7 +3034,6 @@ materialize_cgraph (void)
     fprintf (stderr,
             flag_wpa ? "Materializing decls:" : "Reading function bodies:");
 
-
   /* Now that we have input the cgraph, we need to clear all of the aux
      nodes and read the functions if we are not running in WPA mode.  */
   timevar_push (TV_IPA_LTO_GIMPLE_IN);
index 1dceb799dadb8940585db9103d975baf1a243e2a..c21edcbb79dc8cae717a73e4cdad333fd04882cd 100644 (file)
@@ -104,6 +104,8 @@ eq_assembler_name (const void *p1, const void *p2)
 static void
 insert_to_assembler_name_hash (symtab_node node)
 {
+  if (symtab_variable_p (node) && DECL_HARD_REGISTER (node->symbol.decl))
+    return;
   gcc_checking_assert (!node->symbol.previous_sharing_asm_name
                       && !node->symbol.next_sharing_asm_name);
   if (assembler_name_hash)
@@ -151,9 +153,20 @@ unlink_from_assembler_name_hash (symtab_node node)
          else
            *slot = node->symbol.next_sharing_asm_name;
        }
+      node->symbol.next_sharing_asm_name = NULL;
+      node->symbol.previous_sharing_asm_name = NULL;
     }
 }
 
+/* Arrange node to be first in its entry of assembler_name_hash.  */
+
+void
+symtab_prevail_in_asm_name_hash (symtab_node node)
+{
+  unlink_from_assembler_name_hash (node);
+  insert_to_assembler_name_hash (node);
+}
+
 
 /* Add node into symbol table.  This function is not used directly, but via
    cgraph/varpool node creation routines.  */
@@ -287,15 +300,12 @@ symtab_remove_node (symtab_node node)
     varpool_remove_node (varpool (node));
 }
 
-/* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
-   Return NULL if there's no such node.  */
+/* Initalize asm name hash unless.  */
 
-symtab_node
-symtab_node_for_asm (const_tree asmname)
+void
+symtab_initialize_asm_name_hash (void)
 {
   symtab_node node;
-  void **slot;
-
   if (!assembler_name_hash)
     {
       assembler_name_hash =
@@ -304,7 +314,18 @@ symtab_node_for_asm (const_tree asmname)
       FOR_EACH_SYMBOL (node)
        insert_to_assembler_name_hash (node);
     }
+}
 
+/* Return the cgraph node that has ASMNAME for its DECL_ASSEMBLER_NAME.
+   Return NULL if there's no such node.  */
+
+symtab_node
+symtab_node_for_asm (const_tree asmname)
+{
+  symtab_node node;
+  void **slot;
+
+  symtab_initialize_asm_name_hash ();
   slot = htab_find_slot_with_hash (assembler_name_hash, asmname,
                                   decl_assembler_name_hash (asmname),
                                   NO_INSERT);
@@ -507,6 +528,9 @@ dump_symtab_base (FILE *f, symtab_node node)
   ipa_dump_references (f, &node->symbol.ref_list);
   fprintf (f, "  Referring: ");
   ipa_dump_referring (f, &node->symbol.ref_list);
+  if (node->symbol.lto_file_data)
+    fprintf (f, "  Read from file: %s\n",
+            node->symbol.lto_file_data->file_name);
 }
 
 /* Dump symtab node.  */
@@ -597,7 +621,8 @@ verify_symtab_base (symtab_node node)
            break;
          hashed_node = hashed_node->symbol.next_sharing_asm_name;
        }
-      if (!hashed_node)
+      if (!hashed_node
+          && !(symtab_variable_p (node) || DECL_HARD_REGISTER (node->symbol.decl)))
        {
           error ("node not found in symtab assembler name hash");
           error_found = true;
@@ -733,6 +758,8 @@ symtab_make_decl_local (tree decl)
   DECL_COMDAT_GROUP (decl) = 0;
   DECL_WEAK (decl) = 0;
   DECL_EXTERNAL (decl) = 0;
+  DECL_VISIBILITY_SPECIFIED (decl) = 0;
+  DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
   TREE_PUBLIC (decl) = 0;
   DECL_VISIBILITY_SPECIFIED (decl) = 0;
   DECL_VISIBILITY (decl) = VISIBILITY_DEFAULT;
index b0063c1632894511fd683bc908a0b753ee1d3dad..314c66ee308f31f1fd2fa4ba208e1303cb7cb338 100644 (file)
@@ -301,6 +301,10 @@ varpool_assemble_decl (struct varpool_node *node)
       && !targetm.have_tls)
     return false;
 
+  /* Hard register vars do not need to be output.  */
+  if (DECL_HARD_REGISTER (decl))
+    return false;
+
   gcc_checking_assert (!TREE_ASM_WRITTEN (decl)
                       && TREE_CODE (decl) == VAR_DECL
                       && !DECL_HAS_VALUE_EXPR_P (decl));
This page took 0.108006 seconds and 5 git commands to generate.