From patchwork Fri Mar 25 20:32:51 2011 Content-Type: text/plain; charset="utf-8" MIME-Version: 1.0 Content-Transfer-Encoding: 7bit X-Patchwork-Submitter: Diego Novillo X-Patchwork-Id: 88426 Return-Path: X-Original-To: incoming@patchwork.ozlabs.org Delivered-To: patchwork-incoming@bilbo.ozlabs.org Received: from sourceware.org (server1.sourceware.org [209.132.180.131]) by ozlabs.org (Postfix) with SMTP id BA3CFB6F9B for ; Sat, 26 Mar 2011 07:33:06 +1100 (EST) Received: (qmail 331 invoked by alias); 25 Mar 2011 20:33:04 -0000 Received: (qmail 32743 invoked by uid 22791); 25 Mar 2011 20:33:02 -0000 X-SWARE-Spam-Status: No, hits=-2.1 required=5.0 tests=AWL, BAYES_00, DKIM_SIGNED, DKIM_VALID, DKIM_VALID_AU, SPF_HELO_PASS, TW_TM, T_RP_MATCHES_RCVD X-Spam-Check-By: sourceware.org Received: from smtp-out.google.com (HELO smtp-out.google.com) (216.239.44.51) by sourceware.org (qpsmtpd/0.43rc1) with ESMTP; Fri, 25 Mar 2011 20:32:56 +0000 Received: from hpaq13.eem.corp.google.com (hpaq13.eem.corp.google.com [172.25.149.13]) by smtp-out.google.com with ESMTP id p2PKWrel023102; Fri, 25 Mar 2011 13:32:54 -0700 Received: from topo.tor.corp.google.com (topo.tor.corp.google.com [172.29.41.2]) by hpaq13.eem.corp.google.com with ESMTP id p2PKWqCM019042; Fri, 25 Mar 2011 13:32:52 -0700 Received: by topo.tor.corp.google.com (Postfix, from userid 54752) id C8CB31DA1B8; Fri, 25 Mar 2011 16:32:51 -0400 (EDT) To: reply@codereview.appspotmail.com, gcc-patches@gcc.gnu.org Subject: [pph] Add hooks for writing/reading ASTs (2/2) (issue4275081) Message-Id: <20110325203251.C8CB31DA1B8@topo.tor.corp.google.com> Date: Fri, 25 Mar 2011 16:32:51 -0400 (EDT) From: dnovillo@google.com (Diego Novillo) X-System-Of-Record: true X-IsSubscribed: yes Mailing-List: contact gcc-patches-help@gcc.gnu.org; run by ezmlm Precedence: bulk List-Id: List-Unsubscribe: List-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org Delivered-To: mailing list gcc-patches@gcc.gnu.org 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 * 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 * 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): --- This patch is available for review at http://codereview.appspot.com/4275081 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)