This is the mail archive of the
gcc-patches@gcc.gnu.org
mailing list for the GCC project.
[pph] Add streamer hook for preloading common nodes (issue4478043)
- From: dnovillo at google dot com (Diego Novillo)
- To: reply at codereview dot appspotmail dot com, crowl at google dot com, gcc-patches at gcc dot gnu dot org
- Date: Wed, 4 May 2011 16:26:59 -0400 (EDT)
- Subject: [pph] Add streamer hook for preloading common nodes (issue4478043)
This patch adds a new streamer hook to populate the streamer cache
with common nodes.
The nodes we populate for GIMPLE in lto_get_common_nodes is not
sufficient for C++, unsurprisingly.
The patch fixes these regressions in pph.exp:
FAIL: g++.dg/pph/p1stdlib.cc -fpph-map=pph.map -I. (test for excess errors)
FAIL: g++.dg/pph/p1stdlib.cc , PPH assembly missing
There is a second part to this patch to handle INTEGER_CSTs as regular
trees (so they can be cached). This would allow us to handle special
constants in the C++ FE like void_zero_node, but that's giving me some
trouble with LTO tests.
Tested on x86_64. Committed to the branch.
Diego.
ChangeLog.pph
* Makefile.in (cgraphunit.o): Add dependency on LTO_STREAMER_H.
* cgraphunit.c: Include lto-streamer.h
(cgraph_finalize_compilation_unit): Call gimple_streamer_hooks_init
if LTO is enabled.
* lto-streamer-out.c (lto_output): Move call to
gimple_streamer_hooks_init to cgraph_finalize_compilation_unit.
* lto-streamer.c (lto_get_common_nodes): Remove if0 hack.
(lto_streamer_cache_create): Call streamer_hooks.get_common_nodes
instead of lto_get_common_nodes.
(gimple_streamer_hooks_init): Set h->get_common_nodes to
lto_get_common_nodes.
* lto-streamer.h (struct lto_streamer_hooks): Add field
get_common_nodes.
cp/ChangeLog.pph
* pph-streamer.c (pph_get_common_nodes): New.
(pph_stream_hooks_init): Set it in h->get_common_nodes.
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 0af93ba..f96e059 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -3001,7 +3001,7 @@ cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_FLOW_H) $(TREE_PASS_H) debug.h $(DIAGNOSTIC_H) \
$(FIBHEAP_H) output.h $(PARAMS_H) $(RTL_H) $(TIMEVAR_H) $(IPA_PROP_H) \
gt-cgraphunit.h tree-iterator.h $(COVERAGE_H) $(TREE_DUMP_H) \
- tree-pretty-print.h gimple-pretty-print.h
+ tree-pretty-print.h gimple-pretty-print.h $(LTO_STREAMER_H)
cgraphbuild.o : cgraphbuild.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(CGRAPH_H) intl.h pointer-set.h $(GIMPLE_H) \
$(TREE_FLOW_H) $(TREE_PASS_H) $(IPA_UTILS_H) $(EXCEPT_H) \
diff --git a/gcc/cgraphunit.c b/gcc/cgraphunit.c
index 3dbfc2b..0d1ec89 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -138,6 +138,7 @@ along with GCC; see the file COPYING3. If not see
#include "output.h"
#include "coverage.h"
#include "plugin.h"
+#include "lto-streamer.h"
static void cgraph_expand_all_functions (void);
static void cgraph_mark_functions_to_output (void);
@@ -1062,6 +1063,10 @@ cgraph_finalize_compilation_unit (void)
{
timevar_push (TV_CGRAPH);
+ /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
+ if (flag_lto)
+ gimple_streamer_hooks_init ();
+
/* If we're here there's no current function anymore. Some frontends
are lazy in clearing these. */
current_function_decl = NULL;
diff --git a/gcc/cp/pph-streamer.c b/gcc/cp/pph-streamer.c
index 5f2112e..c363c06 100644
--- a/gcc/cp/pph-streamer.c
+++ b/gcc/cp/pph-streamer.c
@@ -55,6 +55,36 @@ pph_indexable_with_decls_p (tree t)
}
+/* Generate a vector of common nodes that should always be streamed as
+ indexes into the streamer cache. These nodes are always built by
+ the front end, so there is no need to emit them. */
+
+static VEC(tree,heap) *
+pph_get_common_nodes (void)
+{
+ unsigned i;
+ VEC(tree,heap) *common_nodes = NULL;
+
+ for (i = itk_char; i < itk_none; i++)
+ VEC_safe_push (tree, heap, common_nodes, integer_types[i]);
+
+ for (i = 0; i < TYPE_KIND_LAST; i++)
+ VEC_safe_push (tree, heap, common_nodes, sizetype_tab[i]);
+
+ /* global_trees[] can have NULL entries in it. Skip them. */
+ for (i = 0; i < TI_MAX; i++)
+ if (global_trees[i])
+ VEC_safe_push (tree, heap, common_nodes, global_trees[i]);
+
+ /* c_global_trees[] can have NULL entries in it. Skip them. */
+ for (i = 0; i < CTI_MAX; i++)
+ if (c_global_trees[i])
+ VEC_safe_push (tree, heap, common_nodes, c_global_trees[i]);
+
+ return common_nodes;
+}
+
+
/* Initialize all the streamer hooks used for streaming ASTs. */
static void
@@ -62,6 +92,9 @@ pph_stream_hooks_init (void)
{
lto_streamer_hooks *h = streamer_hooks_init ();
h->name = "C++ AST";
+ h->get_common_nodes = pph_get_common_nodes;
h->is_streamable = pph_is_streamable;
h->write_tree = pph_stream_write_tree;
h->read_tree = pph_stream_read_tree;
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index c26de5d..b578419 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -2198,7 +2198,6 @@ lto_output (cgraph_node_set set, varpool_node_set vset)
int i, n_nodes;
lto_cgraph_encoder_t encoder = lto_get_out_decl_state ()->cgraph_node_encoder;
- gimple_streamer_hooks_init ();
lto_writer_init ();
n_nodes = lto_cgraph_encoder_size (encoder);
diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c
index 04a9f7a..d6b78c8 100644
--- a/gcc/lto-streamer.c
+++ b/gcc/lto-streamer.c
@@ -550,10 +550,6 @@ lto_get_common_nodes (void)
else
main_identifier_node = get_identifier ("main");
- /* FIXME pph. These assertions are never met while in the front end.
- There should be a way of checking this only when we are in LTO
- mode. */
-#if 0
gcc_assert (ptrdiff_type_node == integer_type_node);
/* FIXME lto. In the C++ front-end, fileptr_type_node is defined as a
@@ -564,7 +560,6 @@ lto_get_common_nodes (void)
These should be assured in pass_ipa_free_lang_data. */
gcc_assert (fileptr_type_node == ptr_type_node);
gcc_assert (TYPE_MAIN_VARIANT (fileptr_type_node) == ptr_type_node);
-#endif
seen_nodes = pointer_set_create ();
@@ -631,7 +626,7 @@ lto_streamer_cache_create (void)
/* Load all the well-known tree nodes that are always created by
the compiler on startup. This prevents writing them out
unnecessarily. */
- common_nodes = lto_get_common_nodes ();
+ common_nodes = streamer_hooks ()->get_common_nodes ();
FOR_EACH_VEC_ELT (tree, common_nodes, i, node)
preload_common_node (cache, node);
@@ -820,6 +815,7 @@ gimple_streamer_hooks_init (void)
h->name = "gimple";
h->reader_init = gimple_streamer_reader_init;
h->writer_init = NULL;
+ h->get_common_nodes = lto_get_common_nodes;
h->is_streamable = lto_is_streamable;
h->write_tree = gimple_streamer_write_tree;
h->read_tree = gimple_streamer_read_tree;
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index b6f4b79..8be17da 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -55,6 +55,16 @@ typedef struct lto_streamer_hooks {
/* A string identifying this streamer. */
const char *name;
+ /* Called by lto_streamer_cache_create to instantiate a cache of
+ well-known nodes. These are tree nodes that are always
+ instantiated by the compiler on startup. Additionally, these
+ nodes need to be shared. This function produces a vector of
+ these well known trees that are then added to the streamer cache.
+ This way, the writer will only write out a reference to the tree
+ and the reader will instantiate the tree out of this
+ pre-populated cache. */
+ VEC(tree,heap) *(*get_common_nodes) (void);
+
/* Called by lto_reader_init after it does basic initialization. */
void (*reader_init) (void);
--
This patch is available for review at http://codereview.appspot.com/4478043