@@ -1,3 +1,11 @@
+2012-03-13 Diego Novillo <dnovillo@google.com>
+
+ * c-common.h (pph_writer_enabled_p): Declare.
+ (pph_enabled_p): Declare.
+ * c-opts.c (pph_writer_enabled_p): New.
+ (pph_enabled_p): New.
+ * c.opt (fpph-gen): Add Var(flag_pph_gen).
+
2012-03-09 Lawrence Crowl <crowl@google.com>
* c.opt (-fprimary-system-header-okay): New.
@@ -590,6 +590,16 @@ extern const char *pph_out_file;
extern bool
pph_reader_enabled_p (void);
+/* Return true if we are generating a PPH file. */
+
+extern bool
+pph_writer_enabled_p (void);
+
+/* Return true if we are either generating or reading a PPH file. */
+
+extern bool
+pph_enabled_p (void);
+
/* Disable the PPH reader. */
extern void
@@ -132,6 +132,24 @@ static void c_finish_options (void);
static strstrmap_t *include_pph_mapping;
+/* Return true if we are generating a PPH image. */
+
+bool
+pph_writer_enabled_p (void)
+{
+ return flag_pph_gen;
+}
+
+
+/* Return true if PPH has been enabled. */
+
+bool
+pph_enabled_p (void)
+{
+ return pph_writer_enabled_p () || pph_reader_enabled_p ();
+}
+
+
/* Return true if we have any map from INCLUDE to PPH file. */
bool
@@ -990,7 +990,7 @@ C++ Var(flag_pph_dump_tree)
-fpph-dump-tree Dump global namespace tree around PPH reads/writes.
fpph-gen
-C++
+C++ Var(flag_pph_gen)
-fpph-gen Generate a PPH image from the input file
fpph-hdr=
@@ -1,5 +1,45 @@
2012-03-13 Diego Novillo <dnovillo@google.com>
+ * decl.c (cp_rest_of_decl_compilation): When generating a PPH
+ file, call pph_add_decl_to_symtab and return.
+ * pph-core.c (tag_strings): Remove "PPH_cgraph_node".
+ * pph-in.c (pph_in_merge_ld_base): Merge
+ ldb->not_really_extern with |=.
+ (pph_in_merge_lang_indep_tree_body): Preserve existing
+ DECL_ARGUMENTS for a FUNCTION_DECL only if the decl already
+ has a DECL_SAVED_TREE.
+ (pph_reset_external): Remove. Update all users.
+ (pph_in_nonnull_tree): Overwrite *FIELD only if it is
+ currently NULL.
+ (pph_in_cgraph_node): Remove. Update all users.
+ (pph_node_already_emitted): Remove. Update all users.
+ (pph_fn_already_expanded): New.
+ (pph_in_symtab): Call it.
+ Read all new fields in pph_symtab_entry.
+ Handle PPH_SYMTAB_EXPAND and PPH_SYMTAB_EXPAND_1 actions.
+ * pph-out.c (pph_out_struct_function_for_decl): Remove.
+ (pph_out_symtab_action): Assert that the action is in the set
+ of known action.
+ (pph_out_cgraph_node): Remove. Update all users.
+ (pph_out_cgraph_node_for_decl): Remove. Update all users.
+ (pph_add_decl_to_symtab): Capture global state required to
+ re-play symtab actions in the reader.
+ (pph_out_symtab): Write all new fields from pph_symtab_entry.
+ * pph-streamer.h (struct pph_symtab_entry): Add fields AT_EOF,
+ X_PROCESSING_TEMPLATE_DECL and FUNCTION_DEPTH.
+ * pph.h (enum pph_symtab_action): Add value PPH_SYMTAB_EXPAND_1.
+ (enum pph_tag): Remove value PPH_cgraph_node. Update all
+ users.
+ (pph_writer_enabled_p): Move to c-family/c-opts.c.
+ (pph_enabled_p): Likewise.
+ * cp/semantics.c (expand_or_defer_fn_1): If we are generating
+ a PPH file, add it to the symbol table and return.
+ (expand_or_defer_fn): Likewise.
+ * toplev.c (compile_file): If -fpph-gen is used, do not
+ generate code.
+
+2012-03-13 Diego Novillo <dnovillo@google.com>
+
* decl.c (record_builtin_type): Call pph_register_builtin_type.
* pph-core.c (pph_cache_add_full_tree_r): New.
(pph_cache_add_full_tree): New.
@@ -5961,11 +5961,14 @@ value_dependent_init_p (tree init)
void
cp_rest_of_decl_compilation (tree decl, int top_level, int at_end)
{
- rest_of_decl_compilation (decl, top_level, at_end);
-
/* If we are generating a PPH image, add DECL to its symbol table. */
if (pph_writer_enabled_p ())
- pph_add_decl_to_symtab (decl, PPH_SYMTAB_DECLARE, top_level, at_end);
+ {
+ pph_add_decl_to_symtab (decl, PPH_SYMTAB_DECLARE, top_level, at_end);
+ return;
+ }
+
+ rest_of_decl_compilation (decl, top_level, at_end);
}
@@ -338,7 +338,6 @@ 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",
@@ -1483,7 +1483,7 @@ pph_in_merge_ld_base (pph_stream *stream, struct lang_decl_base *ldb)
ldb->selector = bp_unpack_value (&bp, 16);
ldb->language = (enum languages) bp_unpack_value (&bp, 4);
ldb->use_template = bp_unpack_value (&bp, 2);
- ldb->not_really_extern = bp_unpack_value (&bp, 1);
+ ldb->not_really_extern |= bp_unpack_value (&bp, 1);
ldb->initialized_in_class = bp_unpack_value (&bp, 1);
ldb->repo_available_p = bp_unpack_value (&bp, 1);
ldb->threadprivate_or_deleted_p = bp_unpack_value (&bp, 1);
@@ -1647,7 +1647,13 @@ pph_in_lang_indep_tree_body (pph_stream *stream, tree expr)
}
-/* Stream in the language-independent parts of EXPR's body. */
+/* Merge in from STREAM the language-independent parts of EXPR's body.
+ This merging operates in three phases: (1) fields that need to be
+ preserved are saved, (2) the new body for EXPR is read-in, (3)
+ preserved fields are restored back into EXPR.
+
+ This three stage merging is needed because the generic tree reader
+ is not merge-aware. */
static void
pph_in_merge_lang_indep_tree_body (pph_stream *stream, tree expr)
@@ -1657,7 +1663,10 @@ pph_in_merge_lang_indep_tree_body (pph_stream *stream, tree expr)
tree decl_comdat_group = NULL;
bool decl_declared_inline = false;
tree decl_result = NULL;
+ tree decl_arguments = NULL;
+ /* Preserve some fields which should not be overwritten by the DECL
+ that we are merging in. */
if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
{
decl_comdat = DECL_COMDAT (expr);
@@ -1670,16 +1679,19 @@ pph_in_merge_lang_indep_tree_body (pph_stream *stream, tree expr)
tree decl_section_name = DECL_SECTION_NAME (expr);
*/
}
+
if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
{
decl_declared_inline = DECL_DECLARED_INLINE_P (expr);
- }
- if (code == FUNCTION_DECL)
- {
- decl_result = DECL_RESULT (expr);
- /* FIXME pph: These too?
- decl_arguments = DECL_ARGUMENTS (expr);
- */
+
+ /* DECL_RESULT and DECL_ARGUMENTS are used inside the body
+ of a function. Preserve them only if EXPR already has a
+ body. */
+ if (DECL_SAVED_TREE (expr))
+ {
+ decl_result = DECL_RESULT (expr);
+ decl_arguments = DECL_ARGUMENTS (expr);
+ }
}
/* FIXME pph: Also see the functions below for more potential fields.
@@ -1689,8 +1701,11 @@ pph_in_merge_lang_indep_tree_body (pph_stream *stream, tree expr)
lto_input_ts_decl_non_common_tree_pointers
*/
+ /* Read the body of the new decl (this overwrites all the fields of
+ EXPR). */
pph_in_lang_indep_tree_body (stream, expr);
+ /* Restore values that we do not want overwritten. */
if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
{
decl_comdat ? DECL_COMDAT (expr) = true : 0;
@@ -1703,16 +1718,19 @@ pph_in_merge_lang_indep_tree_body (pph_stream *stream, tree expr)
decl_section_name ? DECL_SECTION_NAME (expr) = decl_section_name : 0;
*/
}
+
if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
{
decl_declared_inline ? DECL_DECLARED_INLINE_P (expr) = true : 0;
- }
- if (code == FUNCTION_DECL)
- {
- decl_result ? DECL_RESULT (expr) = decl_result : 0;
- /* FIXME pph: These too?
- decl_arguments ? DECL_ARGUMENTS (expr) = decl_arguments : 0;
- */
+
+ /* DECL_RESULT and DECL_ARGUMENTS are used inside the body
+ of a function. Preserve them only if EXPR already has a
+ body. */
+ if (DECL_SAVED_TREE (expr))
+ {
+ decl_result ? DECL_RESULT (expr) = decl_result : 0;
+ decl_arguments ? DECL_ARGUMENTS (expr) = decl_arguments : 0;
+ }
}
}
@@ -1997,26 +2015,6 @@ pph_in_tcc_type (pph_stream *stream, tree type)
}
-/* Reset the external state for a function DECL. */
-
-static void
-pph_reset_external (tree decl)
-{
- /* When the declaration was compiled originally, the parser marks
- it DECL_EXTERNAL, to avoid emitting it more than once. It also
- remembers the true external state in DECL_NOT_REALLY_EXTERN. So,
- if both bits are set, the declaration should not be considered
- external. */
- gcc_assert (DECL_LANG_SPECIFIC (decl));
- if (DECL_NOT_REALLY_EXTERN (decl)
- && DECL_EXTERNAL (decl))
- {
- DECL_EXTERNAL (decl) = 0;
- DECL_NOT_REALLY_EXTERN (decl) = 0;
- }
-}
-
-
/* Read from STREAM the body of tcc_declaration tree DECL. */
static void
@@ -2042,7 +2040,6 @@ pph_in_tcc_declaration (pph_stream *stream, tree decl)
case FUNCTION_DECL:
TREE_CHAIN (decl) = pph_in_tree (stream);
DECL_SAVED_TREE (decl) = pph_in_tree (stream);
- pph_reset_external (decl);
break;
case TYPE_DECL:
@@ -2067,7 +2064,7 @@ pph_in_nonnull_tree (tree *field, pph_stream *stream)
{
tree candidate;
candidate = pph_in_tree (stream);
- if (candidate)
+ if (candidate && *field == NULL)
*field = candidate;
}
@@ -2081,7 +2078,6 @@ pph_in_merge_tcc_declaration (pph_stream *stream, tree decl)
pph_in_lang_decl (stream, decl);
/* FIXME pph: Some of the following may not be necessary. */
-
pph_in_nonnull_tree (&DECL_INITIAL (decl), stream);
pph_in_nonnull_tree (&DECL_ABSTRACT_ORIGIN (decl), stream);
@@ -2102,7 +2098,6 @@ pph_in_merge_tcc_declaration (pph_stream *stream, tree decl)
case FUNCTION_DECL:
/* ignore TREE_CHAIN (decl) = */ pph_in_tree (stream);
pph_in_nonnull_tree (&DECL_SAVED_TREE (decl), stream);
- pph_reset_external (decl);
break;
case TYPE_DECL:
@@ -2315,10 +2310,8 @@ pph_in_merge_tree_body (pph_stream *stream, tree expr)
switch (TREE_CODE_CLASS (TREE_CODE (expr)))
{
case tcc_declaration:
- {
- pph_in_merge_tcc_declaration (stream, expr);
- }
- break;
+ pph_in_merge_tcc_declaration (stream, expr);
+ break;
case tcc_type:
pph_in_lang_indep_tree_body (stream, expr);
@@ -2841,90 +2834,6 @@ pph_in_symtab_action (pph_stream *stream)
}
-/* Read and return a callgraph node from STREAM. If this is the first
- time we read this node, add it to the callgraph. */
-
-static struct cgraph_node *
-pph_in_cgraph_node (pph_stream *stream)
-{
- enum pph_record_marker marker;
- unsigned image_ix, ix;
- struct cgraph_node *node;
- tree fndecl;
- struct bitpack_d bp;
-
- marker = pph_in_start_record (stream, &image_ix, &ix, PPH_cgraph_node);
- if (marker == PPH_RECORD_END)
- return NULL;
- else if (pph_is_reference_marker (marker))
- return (struct cgraph_node *) pph_cache_find (stream, marker, image_ix,
- ix, PPH_cgraph_node);
-
- fndecl = pph_in_tree (stream);
- ALLOC_AND_REGISTER (&stream->cache, ix, PPH_cgraph_node, node,
- cgraph_get_create_node (fndecl));
-
- node->origin = pph_in_cgraph_node (stream);
- node->nested = pph_in_cgraph_node (stream);
- node->next_nested = pph_in_cgraph_node (stream);
- node->next_needed = pph_in_cgraph_node (stream);
- node->next_sibling_clone = pph_in_cgraph_node (stream);
- node->prev_sibling_clone = pph_in_cgraph_node (stream);
- node->clones = pph_in_cgraph_node (stream);
- node->clone_of = pph_in_cgraph_node (stream);
- node->same_comdat_group = pph_in_cgraph_node (stream);
- gcc_assert (node->call_site_hash == NULL);
- node->former_clone_of = pph_in_tree (stream);
- gcc_assert (node->aux == NULL);
- gcc_assert (VEC_empty (ipa_opt_pass, node->ipa_transforms_to_apply));
-
- gcc_assert (VEC_empty (ipa_ref_t, node->ref_list.references));
- gcc_assert (VEC_empty (ipa_ref_ptr, node->ref_list.refering));
-
- gcc_assert (node->local.lto_file_data == NULL);
- bp = pph_in_bitpack (stream);
- node->local.local = bp_unpack_value (&bp, 1);
- node->local.externally_visible = bp_unpack_value (&bp, 1);
- node->local.finalized = bp_unpack_value (&bp, 1);
- node->local.can_change_signature = bp_unpack_value (&bp, 1);
- node->local.redefined_extern_inline = bp_unpack_value (&bp, 1);
-
- node->global.inlined_to = pph_in_cgraph_node (stream);
-
- node->rtl.preferred_incoming_stack_boundary = pph_in_uint (stream);
-
- gcc_assert (VEC_empty (ipa_replace_map_p, node->clone.tree_map));
- node->thunk.fixed_offset = pph_in_uhwi (stream);
- node->thunk.virtual_value = pph_in_uhwi (stream);
- node->thunk.alias = pph_in_tree (stream);
- bp = pph_in_bitpack (stream);
- node->thunk.this_adjusting = bp_unpack_value (&bp, 1);
- node->thunk.virtual_offset_p = bp_unpack_value (&bp, 1);
- node->thunk.thunk_p = bp_unpack_value (&bp, 1);
-
- node->count = pph_in_uhwi (stream);
- node->count_materialization_scale = pph_in_uint (stream);
-
- bp = pph_in_bitpack (stream);
- node->needed = bp_unpack_value (&bp, 1);
- node->address_taken = bp_unpack_value (&bp, 1);
- node->abstract_and_needed = bp_unpack_value (&bp, 1);
- node->reachable = bp_unpack_value (&bp, 1);
- node->reachable_from_other_partition = bp_unpack_value (&bp, 1);
- node->lowered = bp_unpack_value (&bp, 1);
- node->analyzed = bp_unpack_value (&bp, 1);
- node->in_other_partition = bp_unpack_value (&bp, 1);
- node->process = bp_unpack_value (&bp, 1);
- node->alias = bp_unpack_value (&bp, 1);
- node->same_body_alias = bp_unpack_value (&bp, 1);
- node->frequency = (enum node_frequency) bp_unpack_value (&bp, 2);
- node->only_called_at_startup = bp_unpack_value (&bp, 1);
- node->only_called_at_exit = bp_unpack_value (&bp, 1);
-
- return node;
-}
-
-
/* Have we already emitted this DECL? */
static bool
@@ -2938,16 +2847,16 @@ pph_decl_already_emitted (tree decl)
}
-/* Have we already emitted this cgraph NODE? */
+/* Have we already expanded this FN? */
static bool
-pph_node_already_emitted (struct cgraph_node *node)
+pph_fn_already_expanded (tree fn)
{
- static struct pointer_set_t *emitted_nodes = NULL;
- gcc_assert (node != NULL);
- if (!emitted_nodes)
- emitted_nodes = pointer_set_create ();
- return pointer_set_insert (emitted_nodes, node) != 0;
+ static struct pointer_set_t *expanded_fns = NULL;
+ gcc_assert (fn != NULL);
+ if (!expanded_fns)
+ expanded_fns = pointer_set_create ();
+ return pointer_set_insert (expanded_fns, fn) != 0;
}
@@ -2969,44 +2878,74 @@ pph_in_symtab (pph_stream *stream)
num = pph_in_uint (stream);
for (i = 0; i < num; i++)
{
- enum pph_symtab_action action;
- tree decl;
- bool top_level, at_end;
-
- action = pph_in_symtab_action (stream);
- decl = pph_in_tree (stream);
- if (action == PPH_SYMTAB_DECLARE)
+ pph_symtab_entry entry;
+ struct bitpack_d bp;
+
+ entry.action = pph_in_symtab_action (stream);
+ entry.decl = pph_in_tree (stream);
+ bp = pph_in_bitpack (stream);
+ entry.top_level = bp_unpack_value (&bp, 1);
+ entry.at_end = bp_unpack_value (&bp, 1);
+ entry.at_eof = bp_unpack_value (&bp, 1);
+ entry.x_processing_template_decl = pph_in_int (stream);
+ entry.function_depth = pph_in_int (stream);
+
+ if (entry.action == PPH_SYMTAB_DECLARE)
{
- struct bitpack_d bp;
- bp = pph_in_bitpack (stream);
- top_level = bp_unpack_value (&bp, 1);
- at_end = bp_unpack_value (&bp, 1);
- if (pph_decl_already_emitted (decl))
+ if (pph_decl_already_emitted (entry.decl))
continue;
-
- cp_rest_of_decl_compilation (decl, top_level, at_end);
+ cp_rest_of_decl_compilation (entry.decl, entry.top_level,
+ entry.at_end);
}
- else if (action == PPH_SYMTAB_EXPAND)
+ else if (entry.action == PPH_SYMTAB_EXPAND
+ || entry.action == PPH_SYMTAB_EXPAND_1)
{
- struct cgraph_node *node;
+ bool prev_processing_template_decl, prev_at_eof;
+ int prev_function_depth;
+ bool need_cgraph_node_p;
+ tree prev_current_function_decl;
+
+ pph_in_struct_function (stream, entry.decl);
+ need_cgraph_node_p = pph_in_bool (stream);
+ if (pph_fn_already_expanded (entry.decl))
+ continue;
+
+ /* ENTRY.DECL was reset to being external by the original
+ expansion code, so we need to restore its value before
+ expanding again. */
+ DECL_EXTERNAL (entry.decl) = false;
+
+ /* Re-establish needed global state before calling the
+ expanders. FIXME pph, get rid of this by fixing the
+ expanders. */
+ prev_processing_template_decl = processing_template_decl;
+ prev_at_eof = at_eof;
+ prev_function_depth = function_depth;
+
+ processing_template_decl = entry.x_processing_template_decl;
+ at_eof = entry.at_eof;
+ function_depth = entry.function_depth;
+
+ /* Do the expansion. */
+ prev_current_function_decl = current_function_decl;
+ current_function_decl = entry.decl;
+ push_cfun (DECL_STRUCT_FUNCTION (entry.decl));
+
+ if (entry.action == PPH_SYMTAB_EXPAND)
+ expand_or_defer_fn (entry.decl);
+ else
+ expand_or_defer_fn_1 (entry.decl);
- pph_in_struct_function (stream, decl);
- node = pph_in_cgraph_node (stream);
- if (node && node->local.finalized)
- {
- if (pph_node_already_emitted (node))
- continue;
-
- /* Since the writer had finalized this cgraph node,
- we have to re-play its actions. To do that, we need
- to clear the finalized and reachable bits in the
- node, otherwise cgraph_finalize_function will toss
- out this node. */
- DECL_EXTERNAL (node->decl) = false;
- node->local.finalized = false;
- node->reachable = false;
- cgraph_finalize_function (node->decl, true);
- }
+ if (need_cgraph_node_p)
+ cgraph_get_create_node (entry.decl);
+
+ current_function_decl = prev_current_function_decl;
+ pop_cfun ();
+
+ /* Restore global state. */
+ processing_template_decl = prev_processing_template_decl;
+ at_eof = prev_at_eof;
+ function_depth = prev_function_depth;
}
else
gcc_unreachable ();
@@ -1477,15 +1477,6 @@ pph_out_struct_function (pph_stream *stream, struct function *fn)
}
-/* Write the struct function instance for DECL to STREAM. */
-
-static void
-pph_out_struct_function_for_decl (pph_stream *stream, tree decl)
-{
- pph_out_struct_function (stream, DECL_STRUCT_FUNCTION (decl));
-}
-
-
/* Write all the fields in lang_decl_base instance LDB to OB. */
static void
@@ -2437,97 +2428,13 @@ pph_out_tree (pph_stream *stream, tree expr)
static inline void
pph_out_symtab_action (pph_stream *stream, enum pph_symtab_action action)
{
- gcc_assert (action == (enum pph_symtab_action)(unsigned char) action);
+ gcc_assert ((action == PPH_SYMTAB_DECLARE
+ || action == PPH_SYMTAB_EXPAND
+ || action == PPH_SYMTAB_EXPAND_1)
+ && (enum pph_symtab_action)(unsigned char) action);
pph_out_uchar (stream, action);
}
-
-/* Emit callgraph NODE to STREAM. */
-
-static void
-pph_out_cgraph_node (pph_stream *stream, struct cgraph_node *node)
-{
- struct bitpack_d bp;
- enum pph_record_marker marker;
-
- marker = pph_out_start_record (stream, node, PPH_cgraph_node);
- if (pph_is_reference_or_end_marker (marker))
- return;
-
- /* Remove if we start emitting merge keys for this structure. */
- gcc_assert (marker == PPH_RECORD_START);
-
- pph_out_tree (stream, node->decl);
- pph_out_cgraph_node (stream, node->origin);
- pph_out_cgraph_node (stream, node->nested);
- pph_out_cgraph_node (stream, node->next_nested);
- pph_out_cgraph_node (stream, node->next_needed);
- pph_out_cgraph_node (stream, node->next_sibling_clone);
- pph_out_cgraph_node (stream, node->prev_sibling_clone);
- pph_out_cgraph_node (stream, node->clones);
- pph_out_cgraph_node (stream, node->clone_of);
- pph_out_cgraph_node (stream, node->same_comdat_group);
- gcc_assert (node->call_site_hash == NULL);
- pph_out_tree (stream, node->former_clone_of);
- gcc_assert (node->aux == NULL);
- gcc_assert (VEC_empty (ipa_opt_pass, node->ipa_transforms_to_apply));
-
- gcc_assert (VEC_empty (ipa_ref_t, node->ref_list.references));
- gcc_assert (VEC_empty (ipa_ref_ptr, node->ref_list.refering));
-
- gcc_assert (node->local.lto_file_data == NULL);
- bp = bitpack_create (stream->encoder.w.ob->main_stream);
- bp_pack_value (&bp, node->local.local, 1);
- bp_pack_value (&bp, node->local.externally_visible, 1);
- bp_pack_value (&bp, node->local.finalized, 1);
- bp_pack_value (&bp, node->local.can_change_signature, 1);
- bp_pack_value (&bp, node->local.redefined_extern_inline, 1);
- pph_out_bitpack (stream, &bp);
-
- pph_out_cgraph_node (stream, node->global.inlined_to);
-
- pph_out_uint (stream, node->rtl.preferred_incoming_stack_boundary);
-
- gcc_assert (VEC_empty (ipa_replace_map_p, node->clone.tree_map));
- pph_out_uhwi (stream, node->thunk.fixed_offset);
- pph_out_uhwi (stream, node->thunk.virtual_value);
- pph_out_tree (stream, node->thunk.alias);
- bp = bitpack_create (stream->encoder.w.ob->main_stream);
- bp_pack_value (&bp, node->thunk.this_adjusting, 1);
- bp_pack_value (&bp, node->thunk.virtual_offset_p, 1);
- bp_pack_value (&bp, node->thunk.thunk_p, 1);
- pph_out_bitpack (stream, &bp);
-
- pph_out_uhwi (stream, node->count);
- pph_out_uint (stream, node->count_materialization_scale);
-
- bp = bitpack_create (stream->encoder.w.ob->main_stream);
- bp_pack_value (&bp, node->needed, 1);
- bp_pack_value (&bp, node->address_taken, 1);
- bp_pack_value (&bp, node->abstract_and_needed, 1);
- bp_pack_value (&bp, node->reachable, 1);
- bp_pack_value (&bp, node->reachable_from_other_partition, 1);
- bp_pack_value (&bp, node->lowered, 1);
- bp_pack_value (&bp, node->analyzed, 1);
- bp_pack_value (&bp, node->in_other_partition, 1);
- bp_pack_value (&bp, node->process, 1);
- bp_pack_value (&bp, node->alias, 1);
- bp_pack_value (&bp, node->same_body_alias, 1);
- bp_pack_value (&bp, node->frequency, 2);
- bp_pack_value (&bp, node->only_called_at_startup, 1);
- bp_pack_value (&bp, node->only_called_at_exit, 1);
- pph_out_bitpack (stream, &bp);
-}
-
-/* Emit callgraph for DECL to STREAM. */
-
-static void
-pph_out_cgraph_node_for_decl (pph_stream *stream, tree decl)
-{
- pph_out_cgraph_node (stream, cgraph_get_node (decl));
-}
-
-
/* Add DECL to the symbol table for pph_out_stream. ACTION determines
how DECL should be presented to the middle-end when reading this
image. TOP_LEVEL and AT_END are as in rest_of_decl_compilation. */
@@ -2547,6 +2454,17 @@ pph_add_decl_to_symtab (tree decl, enum pph_symtab_action action,
entry.decl = decl;
entry.top_level = top_level;
entry.at_end = at_end;
+
+ /* Capture some global state that is needed when re-playing this
+ entry. FIXME pph, this should not be needed. There is even
+ inconsistencies in the values for AT_END, the values passed on by
+ various callers is not necessarily the same as the value for
+ ENTRY.AT_EOF below (sigh). */
+ entry.x_processing_template_decl = processing_template_decl;
+ entry.function_depth = function_depth;
+ gcc_assert (at_end == at_eof && (at_eof == 0 || at_eof == 1));
+ entry.at_eof = at_eof;
+
VEC_safe_push (pph_symtab_entry, heap, pph_out_stream->symtab.v, &entry);
}
@@ -2568,23 +2486,23 @@ pph_out_symtab (pph_stream *stream)
pph_out_uint (stream, VEC_length (pph_symtab_entry, stream->symtab.v));
FOR_EACH_VEC_ELT (pph_symtab_entry, stream->symtab.v, i, entry)
{
+ struct bitpack_d bp;
+
pph_out_symtab_action (stream, entry->action);
pph_out_tree (stream, entry->decl);
- if (entry->action == PPH_SYMTAB_DECLARE)
+ bp = bitpack_create (stream->encoder.w.ob->main_stream);
+ bp_pack_value (&bp, entry->top_level, 1);
+ bp_pack_value (&bp, entry->at_end, 1);
+ bp_pack_value (&bp, entry->at_eof, 1);
+ pph_out_bitpack (stream, &bp);
+ pph_out_int (stream, entry->x_processing_template_decl);
+ pph_out_int (stream, entry->function_depth);
+ if (entry->action == PPH_SYMTAB_EXPAND
+ || entry->action == PPH_SYMTAB_EXPAND_1)
{
- struct bitpack_d bp;
- bp = bitpack_create (stream->encoder.w.ob->main_stream);
- bp_pack_value (&bp, entry->top_level, 1);
- bp_pack_value (&bp, entry->at_end, 1);
- pph_out_bitpack (stream, &bp);
+ pph_out_struct_function (stream, DECL_STRUCT_FUNCTION (entry->decl));
+ pph_out_bool (stream, cgraph_get_node (entry->decl) != NULL);
}
- else if (entry->action == PPH_SYMTAB_EXPAND)
- {
- pph_out_struct_function_for_decl (stream, entry->decl);
- pph_out_cgraph_node_for_decl (stream, entry->decl);
- }
- else
- gcc_unreachable ();
}
}
@@ -141,6 +141,13 @@ typedef struct pph_symtab_entry
/* Values to be passed to rest_of_decl_compilation. */
unsigned int top_level : 1;
unsigned int at_end : 1;
+
+ /* Values captured from global state used by expand_or_defer_fn and
+ expand_or_defer_fn_1. FIXME pph, all this global state should
+ disappear. */
+ unsigned int at_eof : 1;
+ int x_processing_template_decl;
+ int function_depth;
} pph_symtab_entry;
DEF_VEC_O(pph_symtab_entry);
@@ -39,7 +39,10 @@ enum pph_symtab_action {
PPH_SYMTAB_DECLARE = 0x23,
/* Expand this function with expand_or_defer_fn. */
- PPH_SYMTAB_EXPAND
+ PPH_SYMTAB_EXPAND,
+
+ /* Expand this function with expand_or_defer_fn_1. */
+ PPH_SYMTAB_EXPAND_1
};
/* Record markers. */
@@ -113,7 +116,6 @@ enum pph_tag {
/* Maintain the tags below in alphabetical order. */
PPH_binding_entry,
PPH_binding_table,
- PPH_cgraph_node,
PPH_cp_binding_level,
PPH_cp_class_binding,
PPH_cp_label_binding,
@@ -198,22 +200,4 @@ extern void pph_in_canonical_template_parms (pph_stream *);
/* FIXME pph: These functions should be moved to tree.c on merge. */
extern VEC(tree,heap) *chain2vec (tree chain); /* In pph-out.c. */
-
-/* Inline functions. */
-
-/* Return true if we are generating a PPH image. */
-static inline bool
-pph_writer_enabled_p (void)
-{
- return pph_out_file != NULL;
-}
-
-/* Return true if PPH has been enabled. */
-static inline bool
-pph_enabled_p (void)
-{
- return pph_writer_enabled_p () || pph_reader_enabled_p ();
-}
-
-
#endif /* GCC_CP_PPH_H */
@@ -3720,7 +3720,10 @@ expand_or_defer_fn_1 (tree fn)
{
/* If we are generating a PPH image, add FN to its symbol table. */
if (pph_writer_enabled_p ())
- pph_add_decl_to_symtab (fn, PPH_SYMTAB_EXPAND, false, at_eof);
+ {
+ pph_add_decl_to_symtab (fn, PPH_SYMTAB_EXPAND_1, false, at_eof);
+ return false;
+ }
/* When the parser calls us after finishing the body of a template
function, we don't really want to expand the body. */
@@ -3811,6 +3814,13 @@ expand_or_defer_fn_1 (tree fn)
void
expand_or_defer_fn (tree fn)
{
+ /* If we are generating a PPH image, add FN to its symbol table. */
+ if (pph_writer_enabled_p ())
+ {
+ pph_add_decl_to_symtab (fn, PPH_SYMTAB_EXPAND, false, at_eof);
+ return;
+ }
+
if (expand_or_defer_fn_1 (fn))
{
function_depth++;
@@ -1,3 +1,15 @@
+2012-03-13 Diego Novillo <dnovillo@google.com>
+
+ * g++.dg/pph/x2incomplete4.cc: Mark fixed.
+ * g++.dg/pph/x4incomplete4123.cc: Likewise.
+ * g++.dg/pph/x4incomplete4321.cc: Likewise.
+ * g++.dg/pph/x4keyed.cc: Likewise.
+ * g++.dg/pph/x4keyex.cc: Likewise.
+ * g++.dg/pph/x4keyno.cc: Likewise.
+ * g++.dg/pph/x6dynarray5.h: Update expected failure patterns.
+ * g++.dg/pph/x7dynarray6.cc: Likewise.
+ * g++.dg/pph/x7rtti.cc: Likewise.
+
2012-03-09 Lawrence Crowl <crowl@google.com>
* g++.dg/pph/a0neststruct.cci: New.
@@ -1,6 +1,2 @@
-// pph asm xdiff 21766
-// xfail-if BOGUS XTRAFUN
-// copies::copies() is wrongly generated
-
#include "x1incomplete3.h"
#include "a0incomplete4.cci"
@@ -1,6 +1,3 @@
-// pph asm xdiff 21766
-// xfail-if unneeded copy of copies::copies() emitted
-
#include "x0incomplete1.h"
#include "x0incomplete2.h"
#include "x0incomplete3.h"
@@ -1,6 +1,3 @@
-// { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "a0incomplete2.hi:7:5: internal compiler error: in gimple_expand_cfg, at cfgexpand.c:4454" "" { xfail *-*-* } 0 }
-
#include "x0incomplete3.h"
#include "x0incomplete2.h"
#include "x0incomplete1.h"
@@ -1,6 +1,3 @@
-// { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "x4keyed.cc:13:1: internal compiler error: in cgraph_analyze_functions, at cgraphunit.c:1210" "" { xfail *-*-* } 0 }
-
#include "x0keyed1.h"
#include "x0keyed2.h"
@@ -1,23 +1,3 @@
-// { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "x4keyex.cc:28:1: internal compiler error: in cgraph_analyze_functions, at cgraphunit.c:1210" "" { xfail *-*-* } 0 }
-
-// formerly was asm xokay 32642
-//
-// This test case fails to compare because LFB/LFE labels are different.
-//
-// 1- Both x0keyno1.h and x0keyno2.h declare exactly the same, as
-// they both textually include a0keyed.h.
-// 2- When we read x0keyno1.pph, we instantiate all the decls and cgraph
-// nodes for struct keyed.
-// 3- When we read x0keyno2.pph, we re-instantiate the same decls and
-// cgraph nodes, which are used instead of the ones in x0keyno1.pph.
-// 4- Since the new decls and nodes have been created later, the functions
-// have different function numbers (function::funcdef_no field), which
-// is used to emit the LFB/LFE labels.
-//
-// The future merging process will fix this by choosing the decls and nodes
-// created first by x0keyno1.pph.
-
#include "x0keyed1.h"
#include "x0keyed2.h"
@@ -1,8 +1,3 @@
-// { dg-xfail-if "ICE" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "x4keyno.cc:13:1: internal compiler error: in cgraph_analyze_functions, at cgraphunit.c:1210" "" { xfail *-*-* } 0 }
-
-// was asm xokay 32642
-
#include "x0keyno1.h"
#include "x0keyno2.h"
@@ -1,9 +1,11 @@
// { dg-xfail-if "UNIMPL TRAIT MANGLING" { "*-*-*" } { "-fpph-map=pph.map" } }
+// { dg-bogus "bits/stl_uninitialized.h:66:12: sorry, unimplemented: mangling trait_expr" "" { xfail *-*-* } 0 }
+// { dg-bogus "bits/stl_uninitialized.h:124:12: sorry, unimplemented: mangling trait_expr" "" { xfail *-*-* } 0 }
// { dg-bogus "bits/stl_uninitialized.h:178:12: sorry, unimplemented: mangling trait_expr" "" { xfail *-*-* } 0 }
// { dg-bogus "bits/allocator.h:153:12: sorry, unimplemented: mangling trait_expr" "" { xfail *-*-* } 0 }
// { dg-bogus "bits/stl_construct.h:98:12: sorry, unimplemented: mangling trait_expr" "" { xfail *-*-* } 0 }
// { dg-bogus "bits/stl_tempbuf.h:183:12: sorry, unimplemented: mangling trait_expr" "" { xfail *-*-* } 0 }
-// { dg-bogus "bits/cpp_type_traits.h:87:12: internal compiler error: tree check: expected integer_cst, have const_decl in tree_int_cst_sgn, at tree.c:6567" "" { xfail *-*-* } 0 }
+// { dg-bogus "bits/cpp_type_traits.h:87:12: internal compiler error: tree check: expected integer_cst, have const_decl in tree_int_cst_sgn" "" { xfail *-*-* } 0 }
#ifndef X6DYNARRAY5_H
#define X6DYNARRAY5_H
@@ -1,5 +1,4 @@
// { dg-xfail-if "BOGUS INTRINSIC RETURN" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "ext/atomicity.h:48:61: error: void value not ignored as it ought to be" "" { xfail *-*-* } 0 }
#include <algorithm>
#include <iostream>
@@ -1,9 +1,8 @@
-// { dg-xfail-if "UNKNOWN MACRO AND BOGUS RTTI" { "*-*-*" } { "-fpph-map=pph.map" } }
-// { dg-bogus "x7rtti.cc:10:0: warning: .__STDC_IEC_559_COMPLEX__. redefined" "" { xfail *-*-* } 0 }
-// { dg-bogus "x7rtti.cc:10:0: warning: .__STDC_ISO_10646__. redefined" "" { xfail *-*-* } 0 }
-// { dg-bogus "x7rtti.cc:10:0: warning: .__STDC_IEC_559__. redefined" "" { xfail *-*-* } 0 }
-// { dg-bogus "x7rtti.cc:22:1: internal compiler error: in cgraph_analyze_functions, at cgraphunit.c:1210" "" { xfail *-*-* } 0 }
// FIXME pph: This should be a { dg=do run } (with '=' replaced by '-')
+// { xfail-if "UNKNOWN MACRO AND BOGUS RTTI" { "*-*-*" } { "-fpph-map=pph.map" } }
+// { dg-bogus "warning: .__STDC_IEC_559_COMPLEX__. redefined" "" { xfail *-*-* } 0 }
+// { dg-bogus "warning: .__STDC_ISO_10646__. redefined" "" { xfail *-*-* } 0 }
+// { dg-bogus "warning: .__STDC_IEC_559__. redefined" "" { xfail *-*-* } 0 }
#include "x5rtti1.h"
#include "x5rtti2.h"
@@ -562,7 +562,7 @@ compile_file (void)
/* Compilation is now finished except for writing
what's left of the symbol table output. */
- if (flag_syntax_only || flag_wpa)
+ if (flag_syntax_only || flag_wpa || flag_pph_gen)
return;
timevar_start (TV_PHASE_GENERATE);