[pph] Add hooks for writing/reading ASTs (2/2) (issue4275081)
Diego Novillo
dnovillo@google.com
Fri Mar 25 20:36:00 GMT 2011
Handle STATEMENT_LIST and add hooks for writing non-pointer values
into bitpacks.
This patch fixes most of the failures in pph.exp (only 14 remain). We
now handle STATEMENT_LIST properly.
The patch also introduces hooks for writing/reading non pointer values
from trees.
Tested on x86_64. Committed to pph.
cp/ChangeLog.pph
2011-03-25 Diego Novillo <dnovillo@google.com>
* Make-lang.in (cp/pph-streamer.o): Add dependency on
tree-iterator.h.
* pph-streamer.c: Include tree-iterator.h
(pph_stream_write_tree): Handle STATEMENT_LIST.
(pph_stream_read_tree): Likewise.
(pph_is_streamable): New.
(pph_stream_pack_value_fields): New.
(pph_stream_unpack_valude_fields): New.
(pph_stream_hooks_init): Rename from pph_streamer_hooks_init.
Fill in callbacks for name, is_streamable, pack_value_fields
and unpack_value_fields;
(pph_stream_open):
ChangeLog.pph
2011-03-25 Diego Novillo <dnovillo@google.com>
* lto-streamer-in.c (unpack_value_fields): Remove checks for
TS_SSA_NAME, TS_STATEMENT_LIST and TS_OMP_CLAUSE.
Call streamer_hooks.unpack_value_fields if defined.
* lto-streamer-out.c (pack_value_fields): Remove checks for
TS_SSA_NAME, TS_STATEMENT_LIST and TS_OMP_CLAUSE.
Call streamer_hooks.pack_value_fields if defined.
(lto_output_tree_header): Call streamer_hooks.is_streamable
if defined.
* lto-streamer.c (gimple_streamer_hooks_init): Assign hooks
for name and is_streamable.
(lto_is_streamable): Move from ...
* lto-streamer.h: ... here.
(lto_streamer_hooks): Add field name, pack_value_fields,
unpack_value_fields and is_streamable.
(lto_stream_as_builtin_p):
diff --git a/gcc/cp/Make-lang.in b/gcc/cp/Make-lang.in
index 7f21322..70548c6 100644
--- a/gcc/cp/Make-lang.in
+++ b/gcc/cp/Make-lang.in
@@ -336,4 +336,4 @@ cp/pph.o: cp/pph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(CPPLIB_H) \
$(CXX_PARSER_H) $(CXX_PPH_H) $(CXX_PPH_STREAMER_H)
cp/pph-streamer.o: cp/pph-streamer.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
$(TREE_H) tree-pretty-print.h $(LTO_STREAMER_H) $(CXX_PPH_STREAMER_H) \
- $(CXX_PPH_H) $(TREE_PASS_H) version.h cppbuiltin.h
+ $(CXX_PPH_H) $(TREE_PASS_H) version.h cppbuiltin.h tree-iterator.h
diff --git a/gcc/cp/pph-streamer.c b/gcc/cp/pph-streamer.c
index af9602c..d2790fc 100644
--- a/gcc/cp/pph-streamer.c
+++ b/gcc/cp/pph-streamer.c
@@ -23,6 +23,7 @@ along with GCC; see the file COPYING3. If not see
#include "coretypes.h"
#include "tree.h"
#include "langhooks.h"
+#include "tree-iterator.h"
#include "tree-pretty-print.h"
#include "lto-streamer.h"
#include "pph-streamer.h"
@@ -146,6 +147,21 @@ pph_stream_write_tree (struct output_block *ob, tree expr, bool ref_p)
{
if (TREE_CODE (expr) == FUNCTION_DECL)
lto_output_tree_or_ref (ob, DECL_SAVED_TREE (expr), ref_p);
+ else if (TREE_CODE (expr) == STATEMENT_LIST)
+ {
+ tree_stmt_iterator i;
+ unsigned num_stmts;
+
+ /* Compute and write the number of statements in the list. */
+ for (num_stmts = 0, i = tsi_start (expr); !tsi_end_p (i); tsi_next (&i))
+ num_stmts++;
+
+ lto_output_sleb128_stream (ob->main_stream, num_stmts);
+
+ /* Write the statements. */
+ for (i = tsi_start (expr); !tsi_end_p (i); tsi_next (&i))
+ lto_output_tree_or_ref (ob, tsi_stmt (i), ref_p);
+ }
}
@@ -160,17 +176,64 @@ pph_stream_read_tree (struct lto_input_block *ib, struct data_in *data_in,
{
if (TREE_CODE (expr) == FUNCTION_DECL)
DECL_SAVED_TREE (expr) = lto_input_tree (ib, data_in);
+ else if (TREE_CODE (expr) == STATEMENT_LIST)
+ {
+ HOST_WIDE_INT i, num_trees = lto_input_sleb128 (ib);
+ for (i = 0; i < num_trees; i++)
+ {
+ tree stmt = lto_input_tree (ib, data_in);
+ append_to_statement_list (stmt, &expr);
+ }
+ }
+}
+
+
+/* Return true if the given tree T is streamable. */
+
+static bool
+pph_is_streamable (tree t ATTRIBUTE_UNUSED)
+{
+ /* We accept most trees. */
+ return TREE_CODE (t) != SSA_NAME
+ && (TREE_CODE (t) < OMP_PARALLEL
+ || TREE_CODE (t) > OMP_CRITICAL);
+}
+
+
+/* Callback for packing value fields in ASTs. BP is the bitpack
+ we are packing into. EXPR is the tree to pack. */
+
+static void
+pph_stream_pack_value_fields (struct bitpack_d *bp ATTRIBUTE_UNUSED,
+ tree expr ATTRIBUTE_UNUSED)
+{
+ /* Do nothing for now. */
+}
+
+
+/* Callback for unpacking value fields in ASTs. BP is the bitpack
+ we are unpacking from. EXPR is the tree to unpack. */
+
+static void
+pph_stream_unpack_value_fields (struct bitpack_d *bp ATTRIBUTE_UNUSED,
+ tree expr ATTRIBUTE_UNUSED)
+{
+ /* Do nothing for now. */
}
/* Initialize all the streamer hooks used for streaming ASTs. */
static void
-pph_streamer_hooks_init (void)
+pph_stream_hooks_init (void)
{
lto_streamer_hooks *h = streamer_hooks_init ();
+ h->name = "C++ AST";
+ h->is_streamable = pph_is_streamable;
h->write_tree = pph_stream_write_tree;
h->read_tree = pph_stream_read_tree;
+ h->pack_value_fields = pph_stream_pack_value_fields;
+ h->unpack_value_fields = pph_stream_unpack_value_fields;
}
@@ -187,7 +250,7 @@ pph_stream_open (const char *name, const char *mode)
f = fopen (name, mode);
if (f)
{
- pph_streamer_hooks_init ();
+ pph_stream_hooks_init ();
stream = XCNEW (pph_stream);
stream->file = f;
stream->name = xstrdup (name);
diff --git a/gcc/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 9574d77..2347ffa 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -1790,26 +1790,11 @@ unpack_value_fields (struct bitpack_d *bp, tree expr)
if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
unpack_ts_block_value_fields (bp, expr);
- if (CODE_CONTAINS_STRUCT (code, TS_SSA_NAME))
- {
- /* We only stream the version number of SSA names. */
- gcc_unreachable ();
- }
-
- if (CODE_CONTAINS_STRUCT (code, TS_STATEMENT_LIST))
- {
- /* This is only used by GENERIC. */
- gcc_unreachable ();
- }
-
- if (CODE_CONTAINS_STRUCT (code, TS_OMP_CLAUSE))
- {
- /* This is only used by High GIMPLE. */
- gcc_unreachable ();
- }
-
if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
unpack_ts_translation_unit_decl_value_fields (bp, expr);
+
+ if (streamer_hooks ()->unpack_value_fields)
+ streamer_hooks ()->unpack_value_fields (bp, expr);
}
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index e8390ed..f41cf0c 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -574,26 +574,11 @@ pack_value_fields (struct bitpack_d *bp, tree expr)
if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
pack_ts_block_value_fields (bp, expr);
- if (CODE_CONTAINS_STRUCT (code, TS_SSA_NAME))
- {
- /* We only stream the version number of SSA names. */
- gcc_unreachable ();
- }
-
- if (CODE_CONTAINS_STRUCT (code, TS_STATEMENT_LIST))
- {
- /* This is only used by GENERIC. */
- gcc_unreachable ();
- }
-
- if (CODE_CONTAINS_STRUCT (code, TS_OMP_CLAUSE))
- {
- /* This is only used by High GIMPLE. */
- gcc_unreachable ();
- }
-
if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
pack_ts_translation_unit_decl_value_fields (bp, expr);
+
+ if (streamer_hooks ()->pack_value_fields)
+ streamer_hooks ()->pack_value_fields (bp, expr);
}
@@ -1229,12 +1214,14 @@ lto_output_tree_header (struct output_block *ob, tree expr, int ix)
{
enum LTO_tags tag;
enum tree_code code;
+ lto_streamer_hooks *h = streamer_hooks ();
+
/* We should not see any non-GIMPLE tree nodes here. */
code = TREE_CODE (expr);
- if (!lto_is_streamable (expr))
- internal_error ("tree code %qs is not supported in gimple streams",
- tree_code_name[code]);
+ if (h->is_streamable && !h->is_streamable (expr))
+ internal_error ("tree code %qs is not supported in %s streams",
+ h->name, tree_code_name[code]);
/* The header of a tree node consists of its tag, the size of
the node, and any other information needed to instantiate
diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c
index f9b5285..7b51763 100644
--- a/gcc/lto-streamer.c
+++ b/gcc/lto-streamer.c
@@ -804,14 +804,41 @@ lto_check_version (int major, int minor)
}
+/* Return true if EXPR is a tree node that can be written to disk. */
+
+static inline bool
+lto_is_streamable (tree expr)
+{
+ enum tree_code code = TREE_CODE (expr);
+
+ /* Notice that we reject SSA_NAMEs as well. We only emit the SSA
+ name version in lto_output_tree_ref (see output_ssa_names). */
+ return !is_lang_specific (expr)
+ && code != SSA_NAME
+ && code != CALL_EXPR
+ && code != LANG_TYPE
+ && code != MODIFY_EXPR
+ && code != INIT_EXPR
+ && code != TARGET_EXPR
+ && code != BIND_EXPR
+ && code != WITH_CLEANUP_EXPR
+ && code != STATEMENT_LIST
+ && (code == CASE_LABEL_EXPR
+ || code == DECL_EXPR
+ || TREE_CODE_CLASS (code) != tcc_statement);
+}
+
+
/* Initialize all the streamer hooks used for streaming GIMPLE. */
void
gimple_streamer_hooks_init (void)
{
lto_streamer_hooks *h = streamer_hooks_init ();
+ h->name = "gimple";
h->reader_init = gimple_streamer_reader_init;
h->writer_init = NULL;
+ 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 b58bb62..1502b0c 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -37,6 +37,7 @@ along with GCC; see the file COPYING3. If not see
struct output_block;
struct lto_input_block;
struct data_in;
+struct bitpack_d;
/* Define when debugging the LTO streamer. This causes the writer
to output the numeric value for the memory address of the tree node
@@ -51,12 +52,18 @@ struct data_in;
replace the default behavior and those that supplement it. Any
or all of these hooks can be NULL. */
typedef struct lto_streamer_hooks {
+ /* A string identifying this streamer. */
+ const char *name;
+
/* Called by lto_reader_init after it does basic initialization. */
void (*reader_init) (void);
/* Called by lto_writer_init after it does basic initalization. */
void (*writer_init) (void);
+ /* Return true if the given tree is supported by this streamer. */
+ bool (*is_streamable) (tree);
+
/* Called by lto_write_tree after writing all the common parts of
a tree. If defined, the callback is in charge of writing all
the fields that lto_write_tree did not write out. Arguments
@@ -78,6 +85,14 @@ typedef struct lto_streamer_hooks {
the fields that lto_read_tree did not read in. Arguments
are as in lto_read_tree. */
void (*read_tree) (struct lto_input_block *, struct data_in *, tree);
+
+ /* Called by pack_value_fields to store any non-pointer fields
+ in the tree structure. The arguments are as in pack_value_fields. */
+ void (*pack_value_fields) (struct bitpack_d *, tree);
+
+ /* Called by unpack_value_fields to retrieve any non-pointer fields
+ in the tree structure. The arguments are as in unpack_value_fields. */
+ void (*unpack_value_fields) (struct bitpack_d *, tree);
} lto_streamer_hooks;
@@ -1113,29 +1128,6 @@ lto_stream_as_builtin_p (tree expr)
|| DECL_BUILT_IN_CLASS (expr) == BUILT_IN_MD));
}
-/* Return true if EXPR is a tree node that can be written to disk. */
-static inline bool
-lto_is_streamable (tree expr)
-{
- enum tree_code code = TREE_CODE (expr);
-
- /* Notice that we reject SSA_NAMEs as well. We only emit the SSA
- name version in lto_output_tree_ref (see output_ssa_names). */
- return !is_lang_specific (expr)
- && code != SSA_NAME
- && code != CALL_EXPR
- && code != LANG_TYPE
- && code != MODIFY_EXPR
- && code != INIT_EXPR
- && code != TARGET_EXPR
- && code != BIND_EXPR
- && code != WITH_CLEANUP_EXPR
- && code != STATEMENT_LIST
- && (code == CASE_LABEL_EXPR
- || code == DECL_EXPR
- || TREE_CODE_CLASS (code) != tcc_statement);
-}
-
DEFINE_DECL_STREAM_FUNCS (TYPE, type)
DEFINE_DECL_STREAM_FUNCS (FIELD_DECL, field_decl)
DEFINE_DECL_STREAM_FUNCS (FN_DECL, fn_decl)
--
This patch is available for review at http://codereview.appspot.com/4275081
More information about the Gcc-patches
mailing list