aboutsummaryrefslogtreecommitdiff
path: root/gcc/lto
diff options
context:
space:
mode:
authorRichard Biener <rguenther@suse.de>2013-06-18 12:56:42 +0000
committerRichard Biener <rguenth@gcc.gnu.org>2013-06-18 12:56:42 +0000
commitac0511f2335deb48bc4c53b4305b1720e2cd7b73 (patch)
tree9e68c4d64c5b3c8af30ab8699be281e4d320a8e2 /gcc/lto
parent09485a08d3f4a486b59d969515e94ac3527eb3dd (diff)
downloadgcc-ac0511f2335deb48bc4c53b4305b1720e2cd7b73.zip
gcc-ac0511f2335deb48bc4c53b4305b1720e2cd7b73.tar.gz
gcc-ac0511f2335deb48bc4c53b4305b1720e2cd7b73.tar.bz2
tree-streamer.h (streamer_tree_cache_create): Adjust prototype.
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
Diffstat (limited to 'gcc/lto')
-rw-r--r--gcc/lto/ChangeLog11
-rw-r--r--gcc/lto/lto.c81
2 files changed, 63 insertions, 29 deletions
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index 8e5c160..aeda657 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -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.
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 065443c..7ddb84d 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -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);