]> git.ipfire.org Git - thirdparty/gcc.git/commitdiff
* lto-symtab.c (lto_symtab_merge_symbols): Populate symtab hashtable.
authorhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 12 Jun 2013 09:12:47 +0000 (09:12 +0000)
committerhubicka <hubicka@138bc75d-0d04-0410-961f-82ee72b054a4>
Wed, 12 Jun 2013 09:12:47 +0000 (09:12 +0000)
* cgraph.h (varpool_create_empty_node): Declare.
* lto-cgraph.c (input_node, input_varpool_node): Forcingly create
duplicated nodes.
* symtab.c (symtab_unregister_node): Be lax about missin entries
in node hash.
(symtab_get_node): Update comment.
* varpool.c (varpool_create_empty_node): Break out from ...
(varpool_node_for_decl): ... here.
* lto-streamer.h (lto_file_decl_data): Add RESOLUTION_MAP.

* lto.c (register_resolution): Take lto_file_data argument.
(lto_register_var_decl_in_symtab,
lto_register_function_decl_in_symtab): Update.
(read_cgraph_and_symbols): Update resolution_map handling.

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

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 0a577c3033ee5540996539d5555589f0960aeebd..16b4ca23c3df810de53b45e0fba28f69dc7f6b28 100644 (file)
@@ -1,3 +1,16 @@
+2013-06-12  Jan Hubicka  <jh@suse.cz>
+
+       * lto-symtab.c (lto_symtab_merge_symbols): Populate symtab hashtable.
+       * cgraph.h (varpool_create_empty_node): Declare.
+       * lto-cgraph.c (input_node, input_varpool_node): Forcingly create
+       duplicated nodes.
+       * symtab.c (symtab_unregister_node): Be lax about missin entries
+       in node hash.
+       (symtab_get_node): Update comment.
+       * varpool.c (varpool_create_empty_node): Break out from ...
+       (varpool_node_for_decl): ... here.
+       * lto-streamer.h (lto_file_decl_data): Add RESOLUTION_MAP.
+
 2013-06-12  Eric Botcazou  <ebotcazou@adacore.com>
 
        * expr.c (expand_expr_real_1) <TARGET_MEM_REF>: Use straight-line flow.
index c67506d42f5eb75186b88ce06370b28fc9b3b888..96614272fd391f63a7fde555a112f0577a48652b 100644 (file)
@@ -773,6 +773,7 @@ bool cgraph_maybe_hot_edge_p (struct cgraph_edge *e);
 bool cgraph_optimize_for_size_p (struct cgraph_node *);
 
 /* In varpool.c  */
+struct varpool_node *varpool_create_empty_node (void);
 struct varpool_node *varpool_node_for_decl (tree);
 struct varpool_node *varpool_node_for_asm (tree asmname);
 void varpool_mark_needed_node (struct varpool_node *);
index 63a9ddb222738232a954997e5bbe52888c80210a..e3f8880be7668a5f90369b21ead29e88ba94ada6 100644 (file)
@@ -959,7 +959,14 @@ input_node (struct lto_file_decl_data *file_data,
                                vNULL, false);
     }
   else
-    node = cgraph_get_create_node (fn_decl);
+    {
+      /* Declaration of functions can be already merged with a declaration
+        from other input file.  We keep cgraph unmerged until after streaming
+        of ipa passes is done.  Alays forcingly create a fresh node.  */
+      node = cgraph_create_empty_node ();
+      node->symbol.decl = fn_decl;
+      symtab_register_node ((symtab_node)node);
+    }
 
   node->symbol.order = order;
   if (order >= symtab_order)
@@ -1035,7 +1042,14 @@ input_varpool_node (struct lto_file_decl_data *file_data,
   order = streamer_read_hwi (ib) + order_base;
   decl_index = streamer_read_uhwi (ib);
   var_decl = lto_file_decl_data_get_var_decl (file_data, decl_index);
-  node = varpool_node_for_decl (var_decl);
+
+  /* Declaration of functions can be already merged with a declaration
+     from other input file.  We keep cgraph unmerged until after streaming
+     of ipa passes is done.  Alays forcingly create a fresh node.  */
+  node = varpool_create_empty_node ();
+  node->symbol.decl = var_decl;
+  symtab_register_node ((symtab_node)node);
+
   node->symbol.order = order;
   if (order >= symtab_order)
     symtab_order = order + 1;
index a0eca6d8e2e740521298980ccdb9538090ca6999..88985ddca233978db9884743c15c803ebe321ce5 100644 (file)
@@ -569,6 +569,9 @@ struct GTY(()) lto_file_decl_data
   unsigned max_index;
 
   struct gcov_ctr_summary GTY((skip)) profile_info;
+
+  /* Map assigning declarations their resolutions.  */
+  pointer_map_t * GTY((skip)) resolution_map;
 };
 
 typedef struct lto_file_decl_data *lto_file_decl_data_ptr;
index 5f0b97165560690f4aa7d44e7c3b613619ac06ec..a92e14c0dceae6fd6a8f7f93d7916e3e773c5a62 100644 (file)
@@ -573,16 +573,21 @@ lto_symtab_merge_symbols (void)
     {
       symtab_initialize_asm_name_hash ();
 
-      /* Do the actual merging.  */
+      /* Do the actual merging.  
+         At this point we invalidate hash translating decls into symtab nodes
+        because after removing one of duplicate decls the hash is not correcly
+        updated to the ohter dupliate.  */
       FOR_EACH_SYMBOL (node)
        if (lto_symtab_symbol_p (node)
            && node->symbol.next_sharing_asm_name
            && !node->symbol.previous_sharing_asm_name)
          lto_symtab_merge_symbols_1 (node);
 
-      /* Resolve weakref aliases whose target are now in the compilation unit.  */
+      /* Resolve weakref aliases whose target are now in the compilation unit.  
+        also re-populate the hash translating decls into symtab nodes*/
       FOR_EACH_SYMBOL (node)
        {
+         cgraph_node *cnode;
          if (!node->symbol.analyzed && node->symbol.alias_target)
            {
              symtab_node tgt = symtab_node_for_asm (node->symbol.alias_target);
@@ -591,6 +596,10 @@ lto_symtab_merge_symbols (void)
                symtab_resolve_alias (node, tgt);
            }
          node->symbol.aux = NULL;
+         if (!(cnode = dyn_cast <cgraph_node> (node))
+             || !cnode->clone_of
+             || cnode->clone_of->symbol.decl != cnode->symbol.decl)
+           symtab_insert_node_to_hashtable ((symtab_node)node);
        }
     }
 }
index 153f023b4a13ddc9ce15b0e5f192ed8ac84accb2..216882afd13a75808e0020166763d690161c7116 100644 (file)
@@ -1,3 +1,10 @@
+2013-06-12  Jan Hubicka  <jh@suse.cz>
+
+       * lto.c (register_resolution): Take lto_file_data argument.
+       (lto_register_var_decl_in_symtab,
+       lto_register_function_decl_in_symtab): Update.
+       (read_cgraph_and_symbols): Update resolution_map handling.
+
 2013-06-11 Jan Hubicka  <jh@suse.cz>
 
        * lto-partition.c (get_symbol_class): Simplify weakref handling.
index c90a2d8496eb301a80a4da75d1a46ea78452ce3e..a4c5d29e974e634912df73bd3c9d34987dccf4a0 100644 (file)
@@ -1726,18 +1726,16 @@ get_resolution (struct data_in *data_in, unsigned index)
     return LDPR_UNKNOWN;
 }
 
-/* Map assigning declarations their resolutions.  */
-static pointer_map_t *resolution_map;
-
 /* We need to record resolutions until symbol table is read.  */
 static void
-register_resolution (tree decl, enum ld_plugin_symbol_resolution resolution)
+register_resolution (struct lto_file_decl_data *file_data, tree decl,
+                    enum ld_plugin_symbol_resolution resolution)
 {
   if (resolution == LDPR_UNKNOWN)
     return;
-  if (!resolution_map)
-    resolution_map = pointer_map_create ();
-  *pointer_map_insert (resolution_map, decl) = (void *)(size_t)resolution;
+  if (!file_data->resolution_map)
+    file_data->resolution_map = pointer_map_create ();
+  *pointer_map_insert (file_data->resolution_map, decl) = (void *)(size_t)resolution;
 }
 
 /* Register DECL with the global symbol table and change its
@@ -1764,7 +1762,7 @@ lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl)
       unsigned ix;
       if (!streamer_tree_cache_lookup (data_in->reader_cache, decl, &ix))
        gcc_unreachable ();
-      register_resolution (decl, get_resolution (data_in, ix));
+      register_resolution (data_in->file_data, decl, get_resolution (data_in, ix));
     }
 }
 
@@ -1784,7 +1782,7 @@ lto_register_function_decl_in_symtab (struct data_in *data_in, tree decl)
       unsigned ix;
       if (!streamer_tree_cache_lookup (data_in->reader_cache, decl, &ix))
        gcc_unreachable ();
-      register_resolution (decl, get_resolution (data_in, ix));
+      register_resolution (data_in->file_data, decl, get_resolution (data_in, ix));
     }
 }
 
@@ -2865,6 +2863,8 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
   struct cgraph_node *node;
   int count = 0;
   struct lto_file_decl_data **decl_data;
+  void **res;
+  symtab_node snode;
 
   init_cgraph ();
 
@@ -2971,21 +2971,21 @@ read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
   input_symtab ();
 
   /* Store resolutions into the symbol table.  */
-  if (resolution_map)
-    {
-      void **res;
-      symtab_node snode;
 
-      FOR_EACH_SYMBOL (snode)
-       if (symtab_real_symbol_p (snode)
-           && (res = pointer_map_contains (resolution_map,
-                                           snode->symbol.decl)))
-         snode->symbol.resolution
-           = (enum ld_plugin_symbol_resolution)(size_t)*res;
-
-      pointer_map_destroy (resolution_map);
-      resolution_map = NULL;
-    }
+  FOR_EACH_SYMBOL (snode)
+    if (symtab_real_symbol_p (snode)
+       && snode->symbol.lto_file_data
+       && snode->symbol.lto_file_data->resolution_map
+       && (res = pointer_map_contains (snode->symbol.lto_file_data->resolution_map,
+                                       snode->symbol.decl)))
+      snode->symbol.resolution
+       = (enum ld_plugin_symbol_resolution)(size_t)*res;
+  for (i = 0; all_file_decl_data[i]; i++)
+    if (all_file_decl_data[i]->resolution_map)
+      {
+        pointer_map_destroy (all_file_decl_data[i]->resolution_map);
+        all_file_decl_data[i]->resolution_map = NULL;
+      }
   
   timevar_pop (TV_IPA_LTO_CGRAPH_IO);
 
index 7a02270c2578f7a57377334f33a98a087bf34288..0ce44a9180db7bfe4274af5009b22d07612380db 100644 (file)
@@ -269,7 +269,11 @@ symtab_unregister_node (symtab_node node)
   node->symbol.previous = NULL;
 
   slot = htab_find_slot (symtab_hash, node, NO_INSERT);
-  if (*slot == node)
+
+  /* During LTO symtab merging we temporarily corrupt decl to symtab node
+     hash.  */
+  gcc_assert ((slot && *slot) || in_lto_p);
+  if (slot && *slot && *slot == node)
     {
       symtab_node replacement_node = NULL;
       if (cgraph_node *cnode = dyn_cast <cgraph_node> (node))
@@ -291,10 +295,14 @@ symtab_get_node (const_tree decl)
   symtab_node *slot;
   struct symtab_node_base key;
 
+#ifdef ENABLE_CHECKING
+  /* Check that we are called for sane type of object - functions
+     and static or external variables.  */
   gcc_checking_assert (TREE_CODE (decl) == FUNCTION_DECL
                       || (TREE_CODE (decl) == VAR_DECL
                           && (TREE_STATIC (decl) || DECL_EXTERNAL (decl)
                               || in_lto_p)));
+#endif
 
   if (!symtab_hash)
     return NULL;
index 4b238843aea940a46c49482489b468fbfe47184d..fd193d3c74a8887c14129f5152677256b46fde7a 100644 (file)
@@ -36,18 +36,26 @@ along with GCC; see the file COPYING3.  If not see
 #include "tree-flow.h"
 #include "flags.h"
 
+/* Allocate new callgraph node and insert it into basic data structures.  */
+
+struct varpool_node *
+varpool_create_empty_node (void)
+{   
+  struct varpool_node *node = ggc_alloc_cleared_varpool_node ();
+  node->symbol.type = SYMTAB_VARIABLE;
+  return node;
+}   
+
 /* Return varpool node assigned to DECL.  Create new one when needed.  */
 struct varpool_node *
 varpool_node_for_decl (tree decl)
 {
   struct varpool_node *node = varpool_get_node (decl);
-  gcc_assert (TREE_CODE (decl) == VAR_DECL
-             && (TREE_STATIC (decl) || DECL_EXTERNAL (decl) || in_lto_p));
+  gcc_checking_assert (TREE_CODE (decl) == VAR_DECL);
   if (node)
     return node;
 
-  node = ggc_alloc_cleared_varpool_node ();
-  node->symbol.type = SYMTAB_VARIABLE;
+  node = varpool_create_empty_node ();
   node->symbol.decl = decl;
   symtab_register_node ((symtab_node)node);
   return node;