tree-streamer.h (streamer_tree_cache_create): Adjust prototype.
authorRichard Biener <rguenther@suse.de>
Tue, 18 Jun 2013 12:56:42 +0000 (12:56 +0000)
committerRichard Biener <rguenth@gcc.gnu.org>
Tue, 18 Jun 2013 12:56:42 +0000 (12:56 +0000)
2013-06-18  Richard Biener  <rguenther@suse.de>

* tree-streamer.h (streamer_tree_cache_create): Adjust prototype.
* tree-streamer.c (streamer_tree_cache_create): Make maintaining
the map from cache entry to cache index optional.
(streamer_tree_cache_replace_tree): Adjust accordingly.
(streamer_tree_cache_append): Likewise.
(streamer_tree_cache_delete): Likewise.
* lto-streamer-in.c (lto_data_in_create): Do not maintain the
streamer cache map from cache entry to cache index.
* lto-streamer-out.c (create_output_block): Adjust.

lto/
* lto.c (lto_register_var_decl_in_symtab): Pass in cache index
and use it.
(lto_register_function_decl_in_symtab): Likewise.
(cmp_tree): New function.
(unify_scc): Instead of using the streamer cache map from entry
to cache index match up the two maps we have by sorting them.
Adjust calls to lto_register_var_decl_in_symtab and
lto_register_function_decl_in_symtab.

From-SVN: r200168

gcc/ChangeLog
gcc/lto-streamer-in.c
gcc/lto-streamer-out.c
gcc/lto/ChangeLog
gcc/lto/lto.c
gcc/tree-streamer.c
gcc/tree-streamer.h

index e3284925a88a1684cea45d679e3eff9a015792d9..94a19edca5bbb3256a55e7cb354cdfa7ed9e7244 100644 (file)
@@ -1,3 +1,15 @@
+2013-06-18  Richard Biener  <rguenther@suse.de>
+
+       * tree-streamer.h (streamer_tree_cache_create): Adjust prototype.
+       * tree-streamer.c (streamer_tree_cache_create): Make maintaining
+       the map from cache entry to cache index optional.
+       (streamer_tree_cache_replace_tree): Adjust accordingly.
+       (streamer_tree_cache_append): Likewise.
+       (streamer_tree_cache_delete): Likewise.
+       * lto-streamer-in.c (lto_data_in_create): Do not maintain the
+       streamer cache map from cache entry to cache index.
+       * lto-streamer-out.c (create_output_block): Adjust.
+
 2013-06-18  Sofiane Naci  <sofiane.naci@arm.com>
 
        * config/arm/arm.md (attribute "insn"): Move multiplication and division
index 2484cc23f5233339aa16dac64b0db52ead959120..fe7ab7c5067d58fa6812814b47287a77b7657156 100644 (file)
@@ -1305,7 +1305,7 @@ lto_data_in_create (struct lto_file_decl_data *file_data, const char *strings,
   data_in->strings = strings;
   data_in->strings_len = len;
   data_in->globals_resolution = resolutions;
-  data_in->reader_cache = streamer_tree_cache_create (false);
+  data_in->reader_cache = streamer_tree_cache_create (false, false);
 
   return data_in;
 }
index 1a72092f2970f7ce279c13cd6e0e8477ca20facb..b59bc8fe5d99fc85f36c213747e8928c5565f3a5 100644 (file)
@@ -71,7 +71,7 @@ create_output_block (enum lto_section_type section_type)
   ob->decl_state = lto_get_out_decl_state ();
   ob->main_stream = XCNEW (struct lto_output_stream);
   ob->string_stream = XCNEW (struct lto_output_stream);
-  ob->writer_cache = streamer_tree_cache_create (!flag_wpa);
+  ob->writer_cache = streamer_tree_cache_create (!flag_wpa, true);
 
   if (section_type == LTO_section_function_body)
     ob->cfg_stream = XCNEW (struct lto_output_stream);
index 8e5c160ea6daf48dea9a1925b9839e656f8bf9b0..aeda657fdba34f7e27cf470408d0cd59728a99c4 100644 (file)
@@ -1,3 +1,14 @@
+2013-06-18  Richard Biener  <rguenther@suse.de>
+
+       * lto.c (lto_register_var_decl_in_symtab): Pass in cache index
+       and use it.
+       (lto_register_function_decl_in_symtab): Likewise.
+       (cmp_tree): New function.
+       (unify_scc): Instead of using the streamer cache map from entry
+       to cache index match up the two maps we have by sorting them.
+       Adjust calls to lto_register_var_decl_in_symtab and
+       lto_register_function_decl_in_symtab.
+
 2013-06-17  Richard Biener  <rguenther@suse.de>
 
        * Make-lang.in (lto.o): Add $(DATA_STREAMER_H) dependency.
index 065443cc1a2d3c17e602b3b4c9fb309187f5742f..7ddb84d76cc093652f944f5afe6a40a5c2a26398 100644 (file)
@@ -1608,7 +1608,8 @@ register_resolution (struct lto_file_decl_data *file_data, tree decl,
    different files.  */
 
 static void
-lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl)
+lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl,
+                                unsigned ix)
 {
   tree context;
 
@@ -1616,19 +1617,13 @@ lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl)
   if (!TREE_PUBLIC (decl)
       && !((context = decl_function_context (decl))
           && auto_var_in_fn_p (decl, context)))
-    {
-      rest_of_decl_compilation (decl, 1, 0);
-    }
+    rest_of_decl_compilation (decl, 1, 0);
 
   /* If this variable has already been declared, queue the
      declaration for merging.  */
   if (TREE_PUBLIC (decl))
-    {
-      unsigned ix;
-      if (!streamer_tree_cache_lookup (data_in->reader_cache, decl, &ix))
-       gcc_unreachable ();
-      register_resolution (data_in->file_data, decl, get_resolution (data_in, ix));
-    }
+    register_resolution (data_in->file_data,
+                        decl, get_resolution (data_in, ix));
 }
 
 
@@ -1638,17 +1633,14 @@ lto_register_var_decl_in_symtab (struct data_in *data_in, tree decl)
    file being read.  */
 
 static void
-lto_register_function_decl_in_symtab (struct data_in *data_in, tree decl)
+lto_register_function_decl_in_symtab (struct data_in *data_in, tree decl,
+                                     unsigned ix)
 {
   /* If this variable has already been declared, queue the
      declaration for merging.  */
   if (TREE_PUBLIC (decl) && !DECL_ABSTRACT (decl))
-    {
-      unsigned ix;
-      if (!streamer_tree_cache_lookup (data_in->reader_cache, decl, &ix))
-       gcc_unreachable ();
-      register_resolution (data_in->file_data, decl, get_resolution (data_in, ix));
-    }
+    register_resolution (data_in->file_data,
+                        decl, get_resolution (data_in, ix));
 }
 
 
@@ -2259,6 +2251,19 @@ compare_tree_sccs (tree_scc *pscc, tree_scc *scc,
   return false;
 }
 
+/* QSort sort function to sort a map of two pointers after the 2nd
+   pointer.  */
+
+static int
+cmp_tree (const void *p1_, const void *p2_)
+{
+  tree *p1 = (tree *)(const_cast<void *>(p1_));
+  tree *p2 = (tree *)(const_cast<void *>(p2_));
+  if (p1[1] == p2[1])
+    return 0;
+  return ((uintptr_t)p1[1] < (uintptr_t)p2[1]) ? -1 : 1;
+}
+
 /* Try to unify the SCC with nodes FROM to FROM + LEN in CACHE and
    hash value SCC_HASH with an already recorded SCC.  Return true if
    that was successful, otherwise return false.  */
@@ -2323,29 +2328,47 @@ unify_scc (struct streamer_tree_cache_d *cache, unsigned from,
          num_sccs_merged++;
          total_scc_size_merged += len;
 
-         /* Fixup the streamer cache with the prevailing nodes according
-            to the tree node mapping computed by compare_tree_sccs.  */
+#ifdef ENABLE_CHECKING
          for (unsigned i = 0; i < len; ++i)
            {
              tree t = map[2*i+1];
              enum tree_code code = TREE_CODE (t);
-             unsigned ix;
-             bool r;
              /* IDENTIFIER_NODEs should be singletons and are merged by the
                 streamer.  The others should be singletons, too, and we
                 should not merge them in any way.  */
              gcc_assert (code != TRANSLATION_UNIT_DECL
                          && code != IDENTIFIER_NODE
                          && !streamer_handle_as_builtin_p (t));
-             r = streamer_tree_cache_lookup (cache, t, &ix);
-             gcc_assert (r && ix >= from);
-             streamer_tree_cache_replace_tree (cache, map[2 * i], ix);
-             if (TYPE_P (t))
-               num_merged_types++;
            }
+#endif
+
+         /* Fixup the streamer cache with the prevailing nodes according
+            to the tree node mapping computed by compare_tree_sccs.  */
+         if (len == 1)
+           streamer_tree_cache_replace_tree (cache, pscc->entries[0], from);
+         else
+           {
+             tree *map2 = XALLOCAVEC (tree, 2 * len);
+             for (unsigned i = 0; i < len; ++i)
+               {
+                 map2[i*2] = (tree)(uintptr_t)(from + i);
+                 map2[i*2+1] = scc->entries[i];
+               }
+             qsort (map2, len, 2 * sizeof (tree), cmp_tree);
+             qsort (map, len, 2 * sizeof (tree), cmp_tree);
+             for (unsigned i = 0; i < len; ++i)
+               streamer_tree_cache_replace_tree (cache, map[2*i],
+                                                 (uintptr_t)map2[2*i]);
+           }
+
          /* Free the tree nodes from the read SCC.  */
          for (unsigned i = 0; i < len; ++i)
-           ggc_free (scc->entries[i]);
+           {
+             if (TYPE_P (scc->entries[i]))
+               num_merged_types++;
+             ggc_free (scc->entries[i]);
+           }
+
          break;
        }
 
@@ -2493,10 +2516,10 @@ lto_read_decls (struct lto_file_decl_data *decl_data, const void *data,
                  /* Register variables and functions with the
                     symbol table.  */
                  if (TREE_CODE (t) == VAR_DECL)
-                   lto_register_var_decl_in_symtab (data_in, t);
+                   lto_register_var_decl_in_symtab (data_in, t, from + i);
                  else if (TREE_CODE (t) == FUNCTION_DECL
                           && !DECL_BUILT_IN (t))
-                   lto_register_function_decl_in_symtab (data_in, t);
+                   lto_register_function_decl_in_symtab (data_in, t, from + i);
                  /* Scan the tree for references to global functions or
                     variables and record those for later fixup.  */
                  maybe_remember_with_vars (t);
index fcdf432735063216a84f87f7a6d5cfdf5e038d4b..86bad29c0129699a6adaec636c829ecaa0699ce6 100644 (file)
@@ -197,7 +197,10 @@ streamer_tree_cache_replace_tree (struct streamer_tree_cache_d *cache,
   hashval_t hash = 0;
   if (cache->hashes.exists ())
     hash = streamer_tree_cache_get_hash (cache, ix);
-  streamer_tree_cache_insert_1 (cache, t, hash, &ix, false);
+  if (!cache->node_map)
+    streamer_tree_cache_add_to_node_array (cache, ix, t, hash);
+  else
+    streamer_tree_cache_insert_1 (cache, t, hash, &ix, false);
 }
 
 
@@ -208,7 +211,10 @@ streamer_tree_cache_append (struct streamer_tree_cache_d *cache,
                            tree t, hashval_t hash)
 {
   unsigned ix = cache->nodes.length ();
-  streamer_tree_cache_insert_1 (cache, t, hash, &ix, false);
+  if (!cache->node_map)
+    streamer_tree_cache_add_to_node_array (cache, ix, t, hash);
+  else
+    streamer_tree_cache_insert_1 (cache, t, hash, &ix, false);
 }
 
 /* Return true if tree node T exists in CACHE, otherwise false.  If IX_P is
@@ -319,13 +325,14 @@ preload_common_nodes (struct streamer_tree_cache_d *cache)
 /* Create a cache of pickled nodes.  */
 
 struct streamer_tree_cache_d *
-streamer_tree_cache_create (bool with_hashes)
+streamer_tree_cache_create (bool with_hashes, bool with_map)
 {
   struct streamer_tree_cache_d *cache;
 
   cache = XCNEW (struct streamer_tree_cache_d);
 
-  cache->node_map = pointer_map_create ();
+  if (with_map)
+    cache->node_map = pointer_map_create ();
   cache->nodes.create (165);
   if (with_hashes)
     cache->hashes.create (165);
@@ -347,7 +354,8 @@ streamer_tree_cache_delete (struct streamer_tree_cache_d *c)
   if (c == NULL)
     return;
 
-  pointer_map_destroy (c->node_map);
+  if (c->node_map)
+    pointer_map_destroy (c->node_map);
   c->nodes.release ();
   c->hashes.release ();
   free (c);
index d28552846c29b01ed243263a232eb6e967937f7e..241eae2c1bf22bc1f8de690ee1a90c1d2b78d1d8 100644 (file)
@@ -98,7 +98,7 @@ void streamer_tree_cache_append (struct streamer_tree_cache_d *, tree,
                                 hashval_t);
 bool streamer_tree_cache_lookup (struct streamer_tree_cache_d *, tree,
                                 unsigned *);
-struct streamer_tree_cache_d *streamer_tree_cache_create (bool);
+struct streamer_tree_cache_d *streamer_tree_cache_create (bool, bool);
 void streamer_tree_cache_delete (struct streamer_tree_cache_d *);
 
 /* Return the tree node at slot IX in CACHE.  */