I'm not altogether happy with this approach, so I'm looking for
suggestions on how to address this issue.
The front end defines a bunch of unique constants in c_global_trees
that are not meant to be shared and are subject to pointer comparisons
throughout the front end. Morevoer, some constants do not even have a
"valid" type. For instance, void_zero_node has type void, which
build_int_cst_wide refuses to build. So, we were ICEing when trying
to materialize these functions in the reader.
Other constants are fine, but they are pointer-compared against
c_global_trees[], so I need them to be materialized into the same
address.
Initially, I thought I would just make the streamer treat constants
the same as any other tree node, but this increases the size of the
on-disk representation. Writing cache references for constants takes
more space. It was also quite invasive, I was introducing regressions
in LTO and having a perfectly horrible time with it.
The approach I ended up taking is to allow the streamer to declare
that it has some INTEGER_CSTs that need to be unique. Since those
unique constants are preloaded in the cache, we can simply stream
references to them if we find a match.
So, regular constants are streamed like always, but unique constants
are streamed as cache references. This does not affect the gimple
streamer and allows the C++ FE to preload these constants in the cache
and continue to use pointer equality throughout the parser.
This was the least invasive and quick solution I could come up for
now. Any other ideas?
Tested on x86_64. Committed to pph.
Diego.
cp/ChangeLog.pph
* pph-streamer.c (pph_stream_hooks_init): Set
has_unique_integer_csts_p field to true.
ChangeLog.pph
* lto-streamer-out.c (lto_output_tree): If the streamer
has unique INTEGER_CST nodes and a match is found in the
streamer cache, do not call lto_output_integer_cst.
* lto-streamer.h (struct lto_streamer_hooks): Add field
has_unique_integer_csts_p.
diff --git a/gcc/cp/pph-streamer.c b/gcc/cp/pph-streamer.c
index efac32e..18a5e25 100644
--- a/gcc/cp/pph-streamer.c
+++ b/gcc/cp/pph-streamer.c
@@ -101,6 +101,7 @@ pph_stream_hooks_init (void)
h->unpack_value_fields = pph_stream_unpack_value_fields;
h->alloc_tree = pph_stream_alloc_tree;
h->output_tree_header = pph_stream_output_tree_header;
+ h->has_unique_integer_csts_p = true;
}
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index b578419..a7f0965 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -1387,8 +1387,27 @@ lto_output_tree (struct output_block *ob, tree expr,
bool ref_p)
to be materialized by the reader (to implement TYPE_CACHED_VALUES). */
if (TREE_CODE (expr) == INTEGER_CST)
{
- lto_output_integer_cst (ob, expr, ref_p);
- return;
+ bool is_special;
+
+ /* There are some constants that are special to the streamer
+ (e.g., void_zero_node, truthvalue_false_node).
+ These constants cannot be rematerialized with
+ build_int_cst_wide because they may actually lack a type (like
+ void_zero_node) and they need to be pointer-identical to trees
+ materialized by the compiler tables like global_trees or
+ c_global_trees.
+
+ If the streamer told us that it has special constants, they
+ will be preloaded in the streamer cache. If we find a match,
+ then stream the constant as a reference so the reader can
+ re-materialize it from the cache. */
+ is_special = streamer_hooks ()->has_unique_integer_csts_p
+ && lto_streamer_cache_lookup (ob->writer_cache, expr, NULL);
+ if (!is_special)
+ {
+ lto_output_integer_cst (ob, expr, ref_p);
+ return;
+ }
}
existed_p = lto_streamer_cache_insert (ob->writer_cache, expr, &ix);
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 8be17da..9b64619 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -113,6 +113,12 @@ typedef struct lto_streamer_hooks {
global symbol tables. */
unsigned register_decls_in_symtab_p : 1;
+ /* Non-zero if the streamer has special constants that cannot be
+ shared and are used in pointer-equality tests (e.g., void_zero_node,
+ truthvalue_false_node, etc). These constants will be present in
+ the streamer cache and should be streamed as references. */
+ unsigned has_unique_integer_csts_p : 1;
+
/* Called by lto_materialize_tree for tree nodes that it does not
know how to allocate memory for. If defined, this hook should
return a new tree node of the given code. The data_in and
--
This patch is available for review at http://codereview.appspot.com/4489044