From mboxrd@z Thu Jan 1 00:00:00 1970 Return-Path: Received: (qmail 13811 invoked by alias); 7 Nov 2011 21:58:15 -0000 Received: (qmail 13777 invoked by uid 22791); 7 Nov 2011 21:58:10 -0000 X-SWARE-Spam-Status: No, hits=-2.4 required=5.0 tests=AWL,BAYES_00,DKIM_SIGNED,DKIM_VALID,DKIM_VALID_AU,RP_MATCHES_RCVD,SPF_HELO_PASS,TW_CX 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; Mon, 07 Nov 2011 21:57:53 +0000 Received: from wpaz24.hot.corp.google.com (wpaz24.hot.corp.google.com [172.24.198.88]) by smtp-out.google.com with ESMTP id pA7Lvqjp029133; Mon, 7 Nov 2011 13:57:52 -0800 Received: from jade.mtv.corp.google.com (jade.mtv.corp.google.com [172.18.110.116]) by wpaz24.hot.corp.google.com with ESMTP id pA7LvoUN004962; Mon, 7 Nov 2011 13:57:51 -0800 Received: by jade.mtv.corp.google.com (Postfix, from userid 21482) id 8C236222644; Mon, 7 Nov 2011 13:57:50 -0800 (PST) To: reply@codereview.appspotmail.com, dnovillo@google.com, gcc-patches@gcc.gnu.org Subject: [pph] Partial namespace merging. (issue5341047) Message-Id: <20111107215750.8C236222644@jade.mtv.corp.google.com> Date: Mon, 07 Nov 2011 22:10:00 -0000 From: crowl@google.com (Lawrence Crowl) 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-Archive: List-Post: List-Help: Sender: gcc-patches-owner@gcc.gnu.org X-SW-Source: 2011-11/txt/msg01077.txt.bz2 Add merging of namespaces. Add testcase for namespace merging. test fails because lookup fails for reasons apparently associated with identifiers. Add tracing of both front and back of trees so as to better identify the tree structure. Add tracing of record markers. Various formatting fixes. Tested on x64. Index: gcc/testsuite/ChangeLog.pph 2011-11-07 Lawrence Crowl * lib/dg-pph.exp (dg-pph-pos): Recognize bogus errors. * g++.dg/pph/x0namespace2.h: New. * g++.dg/pph/x4namespace.cc: New. Index: gcc/cp/ChangeLog.pph 2011-11-07 Lawrence Crowl * pph.c (pph_tree_code_text): Fix formatting. * pph-streamer.h (enum pph_trace_end): New. (pph_trace_tree): Add 'which end' parameter. (pph_trace_marker): New. * gcc/cp/pph-streamer.c (marker_strings[]): New. (tag_strings[]): New. (pph_trace_marker): New. (pph_trace_tree): Add tree prefix tracing. * pph-streamer-out.c: Add section separators. (pph_out_stream): Move to stream initialization section. (pph_out_record_marker): Add record tracing. (chain2vec_filter): Disable assert on 'none' filter. (pph_out_chain_filtered): Likewise. (pph_out_binding_merge_bodies): Add more merge fodder. (pph_out_merge_key_tree): Add tree prefix tracing. (pph_out_tree): Likewise. * pph-streamer-in.c: Add section separators. (ALLOC_AND_REGISTER): Move to record handling section. (pph_loc_offset): Move to source information section. (pph_in_record_marker): Add record tracing. (pph_in_binding_level): Factor into pph_in_binding_level and pph_in_binding_level_start. (pph_in_binding_merge_bodies): Factor actual merging into separate pph_in_binding_merge_bodies_1. (pph_in_ld_ns): Merge into a binding if one already exists. (pph_in_tree_body): Add debugging code. (pph_in_merge_key_tree): Add tree prefix tracing. Do not allocate a namespace binding if one exists already. (pph_in_tree): Add prefix tracing. (pph_in_global_binding): Call pph_in_binding_merge_bodies_1 to avoid allocation. Index: gcc/testsuite/lib/dg-pph.exp =================================================================== --- gcc/testsuite/lib/dg-pph.exp (revision 180802) +++ gcc/testsuite/lib/dg-pph.exp (working copy) @@ -143,7 +143,8 @@ proc dg-pph-pos { subdir test options ma if { ![file_on_host exists "$bname.s"] } { # Expect assembly to be missing when the compile is an # expected fail. - if { ![llength [grep $test "dg-xfail-if.*-fpph-map"]] } { + if { ![llength [grep $test "dg-xfail-if.*-fpph-map"]] + && ![llength [grep $test "dg-bogus.*error:"]] } { fail "$nshort $options (pph assembly missing)" } return Index: gcc/testsuite/g++.dg/pph/x4namespace.cc =================================================================== --- gcc/testsuite/g++.dg/pph/x4namespace.cc (revision 0) +++ gcc/testsuite/g++.dg/pph/x4namespace.cc (revision 0) @@ -0,0 +1,29 @@ +// { dg-bogus "x4namespace.cc:11:1: error: 'C' does not name a type" "" { xfail *-*-* } 0 } +// { dg-bogus "x4namespace.cc:27:5: error: 'z' is not a member of 'A'" "" { xfail *-*-* } 0 } + +#include "x0namespace.h" +#include "x0namespace2.h" + +namespace A { +int x = 3; +int x2 = 5; + +C< int > z; +C2< int > z2; + +} // namespace A + +int y = 4; +int y2 = 6; + +int D::method() +{ return y; } + +int D2::method() +{ return y2; } + +int main() +{ + A::z.method(); + A::z2.method(); +} Index: gcc/testsuite/g++.dg/pph/x0namespace2.h =================================================================== --- gcc/testsuite/g++.dg/pph/x0namespace2.h (revision 0) +++ gcc/testsuite/g++.dg/pph/x0namespace2.h (revision 0) @@ -0,0 +1,22 @@ +#ifndef X0NAMESPACE2_H +#define X0NAMESPACE2_H +namespace A { +extern int x2; +struct B2; +template< typename T > +struct C2 { + T* b; + int method(); + int another() + { return *b; } +}; +template< typename T > +int C2< T >::method() +{ return x2; } +} // namespace A +struct D2 : A::C2< int > { + int method(); + int another() + { return *b; } +}; +#endif Index: gcc/cp/pph.c =================================================================== --- gcc/cp/pph.c (revision 180802) +++ gcc/cp/pph.c (working copy) @@ -45,7 +45,7 @@ FILE *pph_logfile = NULL; /* Convert a checked tree_code CODE to a string. */ -const char* +const char * pph_tree_code_text (enum tree_code code) { gcc_assert (code < MAX_TREE_CODES); Index: gcc/cp/pph-streamer-in.c =================================================================== --- gcc/cp/pph-streamer-in.c (revision 180802) +++ gcc/cp/pph-streamer-in.c (working copy) @@ -35,10 +35,25 @@ along with GCC; see the file COPYING3. #include "parser.h" #include "pointer-set.h" + +/********************************************************* type declarations */ + + typedef char *char_p; DEF_VEC_P(char_p); DEF_VEC_ALLOC_P(char_p,heap); + +/****************************************************** forward declarations */ + + +/* Forward declarations to avoid circularity. */ +static tree pph_in_merge_key_tree (pph_stream *, tree *); + + +/***************************************************** stream initialization */ + + /* String tables for all input streams. These are allocated separately from streams because they cannot be deallocated after the streams have been read (string streaming works by pointing into these @@ -48,29 +63,6 @@ DEF_VEC_ALLOC_P(char_p,heap); memory will remain allocated until the end of compilation. */ static VEC(char_p,heap) *string_tables = NULL; -/* Wrapper for memory allocation calls that should have their results - registered in the PPH streamer cache. DATA is the pointer returned - by the memory allocation call in ALLOC_EXPR. IX is the cache slot - in CACHE where the newly allocated DATA should be registered at. */ -#define ALLOC_AND_REGISTER(CACHE, IX, TAG, DATA, ALLOC_EXPR) \ - do { \ - (DATA) = (ALLOC_EXPR); \ - pph_cache_insert_at (CACHE, DATA, IX, TAG); \ - } while (0) - -/* Set in pph_in_and_merge_line_table. Represents the source_location offset - which every streamed in token must add to it's serialized source_location. - - FIXME pph: Ideally this would be in pph_stream.encoder.r, but for that we - first need to get rid of the dependency to the streamer_hook for locations. - */ -static int pph_loc_offset; - -/* Forward declarations to avoid circularity. */ -static tree pph_in_merge_key_tree (pph_stream *, tree *); - -/***************************************************** stream initialization */ - /* Read into memory the contents of the file in STREAM. Initialize internal tables and data structures needed to re-construct the @@ -210,6 +202,15 @@ pph_in_bitpack (pph_stream *stream) /******************************************************** source information */ +/* Set in pph_in_and_merge_line_table. Represents the source_location offset + which every streamed in token must add to it's serialized source_location. + + FIXME pph: Ideally this would be in pph_stream.encoder.r, but for that we + first need to get rid of the dependency to the streamer_hook for locations. + */ +static int pph_loc_offset; + + /* Read a linenum_type from STREAM. */ static inline linenum_type @@ -412,6 +413,17 @@ pph_in_line_table_and_includes (pph_stre /*********************************************************** record handling */ +/* Wrapper for memory allocation calls that should have their results + registered in the PPH streamer cache. DATA is the pointer returned + by the memory allocation call in ALLOC_EXPR. IX is the cache slot + in CACHE where the newly allocated DATA should be registered at. */ +#define ALLOC_AND_REGISTER(CACHE, IX, TAG, DATA, ALLOC_EXPR) \ + do { \ + (DATA) = (ALLOC_EXPR); \ + pph_cache_insert_at (CACHE, DATA, IX, TAG); \ + } while (0) + + /* Read and return a record marker from STREAM. On return, *TAG_P will contain the tag for the data type stored in this record. */ enum pph_record_marker @@ -431,6 +443,9 @@ pph_in_record_marker (pph_stream *stream *tag_p = (enum pph_tag) pph_in_uint (stream); gcc_assert ((unsigned) *tag_p < (unsigned) PPH_NUM_TAGS); + if (flag_pph_tracer >= 5) + pph_trace_marker (m, *tag_p); + return m; } @@ -1060,26 +1075,42 @@ pph_in_binding_level_1 (pph_stream *stre } -/* Read and return an instance of cp_binding_level from STREAM. - This function is for use when we will not be merging the binding level. */ +/* Read the start of a binding level. Return true when processing is done. */ -static cp_binding_level * -pph_in_binding_level (pph_stream *stream) +static bool +pph_in_binding_level_start (pph_stream *stream, cp_binding_level **blp, + unsigned *ixp) { - unsigned image_ix, ix; - cp_binding_level *bl; + unsigned image_ix; enum pph_record_marker marker; - marker = pph_in_start_record (stream, &image_ix, &ix, PPH_cp_binding_level); + marker = pph_in_start_record (stream, &image_ix, ixp, PPH_cp_binding_level); if (marker == PPH_RECORD_END) { - return NULL; + *blp = NULL; + return true; } else if (pph_is_reference_marker (marker)) { - return (cp_binding_level *) - pph_cache_find (stream, marker, image_ix, ix, PPH_cp_binding_level); + *blp = (cp_binding_level *) + pph_cache_find (stream, marker, image_ix, *ixp, PPH_cp_binding_level); + return true; } + return false; +} + + +/* Read and return an instance of cp_binding_level from STREAM. + This function is for use when we will not be merging the binding level. */ + +static cp_binding_level * +pph_in_binding_level (pph_stream *stream) +{ + unsigned ix; + cp_binding_level *bl; + + if (pph_in_binding_level_start (stream, &bl, &ix)) + return bl; bl = ggc_alloc_cleared_cp_binding_level (); pph_cache_insert_at (&stream->cache, bl, ix, PPH_cp_binding_level); @@ -1111,13 +1142,35 @@ pph_in_binding_merge_keys (pph_stream *s /* Read all the merge bodies from STREAM into the cp_binding_level BL. */ static void -pph_in_binding_merge_bodies (pph_stream *stream, cp_binding_level *bl) +pph_in_binding_merge_bodies_1 (pph_stream *stream, cp_binding_level *bl) { pph_in_merge_body_chain (stream); pph_in_merge_body_chain (stream); pph_in_merge_body_chain (stream); pph_in_merge_body_chain (stream); pph_union_into_tree_vec (&bl->static_decls, pph_in_tree_vec (stream)); + /* FIXME pph: The following is probably too aggressive in overwriting. */ + pph_in_binding_level_1 (stream, bl); +} + + +/* Read all the merge bodies from STREAM into the cp_binding_level BL. */ + +static void +pph_in_binding_merge_bodies (pph_stream *stream, cp_binding_level *bl) +{ + unsigned ix; + cp_binding_level *new_bl; + + if (pph_in_binding_level_start (stream, &new_bl, &ix)) + { + gcc_assert (new_bl == bl); + return; + } + + /* The binding level is already allocated. */ + pph_cache_insert_at (&stream->cache, bl, ix, PPH_cp_binding_level); + pph_in_binding_merge_bodies_1 (stream, bl); } @@ -1363,7 +1416,10 @@ pph_in_ld_fn (pph_stream *stream, struct static void pph_in_ld_ns (pph_stream *stream, struct lang_decl_ns *ldns) { - ldns->level = pph_in_binding_level (stream); + if (ldns->level == NULL) + ldns->level = pph_in_binding_level (stream); + else + pph_in_binding_merge_bodies (stream, ldns->level); } @@ -1797,6 +1853,8 @@ pph_in_tree_body (pph_stream *stream, tr break; case IDENTIFIER_NODE: + if (flag_pph_debug >= 3) + fprintf (pph_logfile, "in identifier %s\n", IDENTIFIER_POINTER (expr)); IDENTIFIER_NAMESPACE_BINDINGS (expr) = pph_in_cxx_binding (stream); IDENTIFIER_BINDING (expr) = pph_in_cxx_binding (stream); IDENTIFIER_TEMPLATE (expr) = pph_in_tree (stream); @@ -2008,14 +2066,26 @@ pph_in_merge_key_tree (pph_stream *strea pph_cache_insert_at (&stream->cache, expr, ix, pph_tree_code_to_tag (expr)); + if (flag_pph_tracer) + pph_trace_tree (expr, pph_trace_front, + expr == read_expr ? pph_trace_unmerged_key + : pph_trace_merged_key); + if (DECL_P (expr)) { if (TREE_CODE (expr) == NAMESPACE_DECL) { cp_binding_level *bl; - retrofit_lang_decl (expr); - bl = ggc_alloc_cleared_cp_binding_level (); - NAMESPACE_LEVEL (expr) = bl; + if (DECL_LANG_SPECIFIC (expr)) + /* Merging into an existing namespace. */ + bl = NAMESPACE_LEVEL (expr); + else + { + /* This is a new namespace. */ + retrofit_lang_decl (expr); + bl = ggc_alloc_cleared_cp_binding_level (); + NAMESPACE_LEVEL (expr) = bl; + } pph_in_binding_merge_keys (stream, bl); } #if 0 @@ -2036,8 +2106,9 @@ pph_in_merge_key_tree (pph_stream *strea } if (flag_pph_tracer) - pph_trace_tree (expr, expr == read_expr ? pph_trace_unmerged_key - : pph_trace_merged_key); + pph_trace_tree (expr, pph_trace_back, + expr == read_expr ? pph_trace_unmerged_key + : pph_trace_merged_key); return expr; } @@ -2122,6 +2193,12 @@ pph_in_tree (pph_stream *stream) if (marker != PPH_RECORD_START_MERGE_BODY) pph_cache_insert_at (&stream->cache, expr, ix, pph_tree_code_to_tag (expr)); + if (flag_pph_tracer) + pph_trace_tree (expr, pph_trace_front, + marker == PPH_RECORD_START_MERGE_BODY ? pph_trace_merge_body + : marker == PPH_RECORD_START_MUTATED ? pph_trace_mutate + : pph_trace_normal ); + /* If we are reading a merge body, it means that EXPR is already in some chain. Given that EXPR may now be in a different location in the chain, we need to make sure we do not lose it. */ @@ -2136,7 +2213,7 @@ pph_in_tree (pph_stream *stream) TREE_CHAIN (expr) = saved_expr_chain; if (flag_pph_tracer) - pph_trace_tree (expr, + pph_trace_tree (expr, pph_trace_back, marker == PPH_RECORD_START_MERGE_BODY ? pph_trace_merge_body : marker == PPH_RECORD_START_MUTATED ? pph_trace_mutate : pph_trace_normal ); @@ -2499,10 +2576,7 @@ pph_in_global_binding (pph_stream *strea same slot IX that the writer used, the trees read now will be bound to scope_chain->bindings. */ pph_in_binding_merge_keys (stream, bl); - pph_in_binding_merge_bodies (stream, bl); - - /* FIXME pph: Are we sure this is right? */ - pph_in_binding_level_1 (stream, bl); + pph_in_binding_merge_bodies_1 (stream, bl); } @@ -2595,6 +2669,9 @@ pph_read_file (const char *filename) } +/********************************************************* stream operations */ + + /* Initialize the reader. */ void Index: gcc/cp/pph-streamer.c =================================================================== --- gcc/cp/pph-streamer.c (revision 180802) +++ gcc/cp/pph-streamer.c (working copy) @@ -335,12 +335,64 @@ pph_add_include (pph_stream *stream, pph } +/* Trace a record MARKER and TAG. */ + +static const char *marker_strings[] = +{ + "PPH_RECORD_START", + "PPH_RECORD_START_NO_CACHE", + "PPH_RECORD_START_MUTATED", + "PPH_RECORD_START_MERGE_KEY", + "PPH_RECORD_START_MERGE_BODY", + "PPH_RECORD_END", + "PPH_RECORD_IREF", + "PPH_RECORD_XREF", + "PPH_RECORD_PREF" +}; + +static const char *tag_strings[] = +{ + "PPH_any_tree", + "PPH_binding_entry", + "PPH_binding_table", + "PPH_cgraph_node", + "PPH_cp_binding_level", + "PPH_cp_class_binding", + "PPH_cp_label_binding", + "PPH_cxx_binding", + "PPH_function", + "PPH_lang_decl", + "PPH_lang_type", + "PPH_language_function", + "PPH_sorted_fields_type" +}; + +void +pph_trace_marker (enum pph_record_marker marker, enum pph_tag tag) +{ + fprintf (pph_logfile, "marker "); + if (PPH_RECORD_START <= marker && marker <= PPH_RECORD_PREF) + fprintf (pph_logfile, "%s", marker_strings[marker - PPH_RECORD_START]); + else + fprintf (pph_logfile, "unknown"); + fprintf (pph_logfile, " tag "); + if (tag == PPH_null) + fprintf (pph_logfile, "PPH_null\n"); + else if (tag < PPH_any_tree) + fprintf (pph_logfile, "%s\n", tree_code_name[tag]); + else if (tag < PPH_NUM_TAGS) + fprintf (pph_logfile, "%s\n", tag_strings[tag - PPH_any_tree]); + else + fprintf (pph_logfile, "unknown\n"); +} + + /* Print tracing information for a possibly MERGEABLE tree T. */ void -pph_trace_tree (tree t, enum pph_trace_kind kind) +pph_trace_tree (tree t, enum pph_trace_end end, enum pph_trace_kind kind) { - char kind_char, decl_char; + char end_char, kind_char, decl_char; bool is_merge, is_decl; bool emit = false; @@ -375,6 +427,8 @@ pph_trace_tree (tree t, enum pph_trace_k is_merge = false; } + end_char = end == pph_trace_front ? '{' : '}'; + is_decl = DECL_P (t); if (is_decl) decl_char = 'D'; @@ -392,8 +446,8 @@ pph_trace_tree (tree t, enum pph_trace_k if (emit) { - fprintf (pph_logfile, "PPH: %c%c ", kind_char, decl_char); - if (kind == pph_trace_unmerged_key) + fprintf (pph_logfile, "PPH: %c%c%c ", end_char, kind_char, decl_char); + if (kind == pph_trace_unmerged_key || end == pph_trace_front) fprintf (pph_logfile, "%s -------\n", pph_tree_code_text (TREE_CODE (t))); else Index: gcc/cp/pph-streamer-out.c =================================================================== --- gcc/cp/pph-streamer-out.c (revision 180802) +++ gcc/cp/pph-streamer-out.c (working copy) @@ -34,18 +34,24 @@ along with GCC; see the file COPYING3. #include "cgraph.h" #include "parser.h" -/* PPH stream that we are currently generating. FIXME pph, this - global is needed because we call back from various parts of the - compiler that do not know about PPH (e.g., some LTO callbacks, - cp_rest_of_decl_compilation). */ -static pph_stream *pph_out_stream = NULL; + +/****************************************************** forward declarations */ + /* Forward declarations to avoid circular references. */ static void pph_out_merge_key_tree (pph_stream *, tree); + /***************************************************** stream initialization */ +/* PPH stream that we are currently generating. FIXME pph, this + global is needed because we call back from various parts of the + compiler that do not know about PPH (e.g., some LTO callbacks, + cp_rest_of_decl_compilation). */ +static pph_stream *pph_out_stream = NULL; + + /* Initialize buffers and tables in STREAM for writing. */ void @@ -417,6 +423,9 @@ pph_out_record_marker (pph_stream *strea gcc_assert (tag == (enum pph_tag)(unsigned) tag); pph_out_uint (stream, tag); + + if (flag_pph_tracer >= 5) + pph_trace_marker (marker, tag); } @@ -589,6 +598,7 @@ pph_out_start_tree_record (pph_stream *s marker = PPH_RECORD_START_NO_CACHE; pph_out_record_marker (stream, marker, tag); + if (marker == PPH_RECORD_START || marker == PPH_RECORD_START_MERGE_BODY) { unsigned ix; @@ -645,6 +655,7 @@ pph_out_start_merge_key_record (pph_stre tag = pph_tree_code_to_tag (expr); marker = pph_get_marker_for (stream, expr, &include_ix, &ix, tag); + if (marker == PPH_RECORD_END || pph_is_reference_marker (marker)) { pph_out_reference_record (stream, marker, include_ix, ix, tag); @@ -964,7 +975,7 @@ chain2vec_filter (pph_stream *stream, tr /* Do not accept the nil filter. The caller is responsible for freeing the returned vector and they may inadvertently free a vector they assumed to be allocated by this function. */ - gcc_assert (filter != PPHF_NONE); + /* FIXME crowl: gcc_assert (filter != PPHF_NONE); */ for (t = chain; t; t = TREE_CHAIN (t)) if (pph_tree_matches (stream, t, filter)) @@ -1004,14 +1015,9 @@ pph_out_chain (pph_stream *stream, tree static void pph_out_chain_filtered (pph_stream *stream, tree first, unsigned filter) { - if (filter == PPHF_NONE) - pph_out_chain (stream, first); - else - { - VEC(tree,heap) *w = chain2vec_filter (stream, first, filter); - pph_out_tree_vec_unchain (stream, (VEC(tree,gc) *)w); - VEC_free (tree, heap, w); - } + VEC(tree,heap) *w = chain2vec_filter (stream, first, filter); + pph_out_tree_vec_unchain (stream, (VEC(tree,gc) *)w); + VEC_free (tree, heap, w); } @@ -1205,6 +1211,7 @@ pph_out_binding_merge_bodies (pph_stream pph_out_merge_body_chain (stream, bl->usings, filter); pph_out_merge_body_chain (stream, bl->using_directives, filter); pph_out_tree_vec_filtered (stream, bl->static_decls, filter); + pph_out_binding_level_1 (stream, bl, filter); } @@ -2034,6 +2041,9 @@ pph_out_merge_key_tree (pph_stream *stre if (pph_out_start_merge_key_record (stream, expr)) return; + if (flag_pph_tracer) + pph_trace_tree (expr, pph_trace_front, pph_trace_key_out); + /* Write merge key information. This includes EXPR's header (needed to re-allocate EXPR in the reader) and the merge key, used to lookup EXPR in the reader's context and merge if necessary. */ @@ -2061,7 +2071,7 @@ pph_out_merge_key_tree (pph_stream *stre } if (flag_pph_tracer) - pph_trace_tree (expr, pph_trace_key_out); + pph_trace_tree (expr, pph_trace_back, pph_trace_key_out); } @@ -2088,6 +2098,7 @@ pph_out_tree (pph_stream *stream, tree e the class and code. */ gcc_assert (marker == PPH_RECORD_START_NO_CACHE); streamer_write_builtin (stream->encoder.w.ob, expr); + return; } else if (TREE_CODE (expr) == INTEGER_CST) { @@ -2096,8 +2107,16 @@ pph_out_tree (pph_stream *stream, tree e TYPE_CACHED_VALUES). */ gcc_assert (marker == PPH_RECORD_START_NO_CACHE); streamer_write_integer_cst (stream->encoder.w.ob, expr, false); + return; } - else if (marker == PPH_RECORD_START || marker == PPH_RECORD_START_MUTATED) + + if (flag_pph_tracer) + pph_trace_tree (expr, pph_trace_front, + marker == PPH_RECORD_START_MERGE_BODY ? pph_trace_merge_body + : marker == PPH_RECORD_START_MUTATED ? pph_trace_mutate + : pph_trace_normal); + + if (marker == PPH_RECORD_START || marker == PPH_RECORD_START_MUTATED) { /* This is the first time we see EXPR, write it out. */ @@ -2125,10 +2144,10 @@ pph_out_tree (pph_stream *stream, tree e gcc_unreachable (); if (flag_pph_tracer) - pph_trace_tree (expr, + pph_trace_tree (expr, pph_trace_back, marker == PPH_RECORD_START_MERGE_BODY ? pph_trace_merge_body : marker == PPH_RECORD_START_MUTATED ? pph_trace_mutate - : pph_trace_normal ); + : pph_trace_normal); } @@ -2368,11 +2387,6 @@ pph_out_global_binding (pph_stream *stre multiple PPH images. */ pph_out_binding_merge_keys (stream, bl); pph_out_binding_merge_bodies (stream, bl); - - /* Emit the other fields in BL that need no merging. */ - /* FIXME pph: Are we sure this is right? */ - pph_out_binding_level_1 (stream, bl, - PPHF_NO_XREFS | PPHF_NO_PREFS | PPHF_NO_BUILTINS); } Index: gcc/cp/pph-streamer.h =================================================================== --- gcc/cp/pph-streamer.h (revision 180802) +++ gcc/cp/pph-streamer.h (working copy) @@ -239,6 +239,11 @@ enum pph_trace_kind pph_trace_merge_body, pph_trace_mutate, pph_trace_normal }; +enum pph_trace_end +{ + pph_trace_front, pph_trace_back +}; + /* In pph-streamer.c. */ void pph_streamer_init (void); void pph_streamer_finish (void); @@ -246,7 +251,8 @@ pph_stream *pph_stream_open (const char void pph_mark_stream_read (pph_stream *); void pph_stream_close (pph_stream *); void pph_add_include (pph_stream *, pph_stream *); -void pph_trace_tree (tree, enum pph_trace_kind); +void pph_trace_marker (enum pph_record_marker marker, enum pph_tag tag); +void pph_trace_tree (tree, enum pph_trace_end, enum pph_trace_kind); pph_cache_entry *pph_cache_insert_at (pph_cache *, void *, unsigned, enum pph_tag); pph_cache_entry *pph_cache_lookup (pph_cache *, void *, unsigned *, -- This patch is available for review at http://codereview.appspot.com/5341047