aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDiego Novillo <dnovillo@google.com>2011-06-06 12:49:11 -0400
committerDiego Novillo <dnovillo@gcc.gnu.org>2011-06-06 12:49:11 -0400
commit47c79d563b4e5d80a48f0c0c870c9025b9d095b4 (patch)
tree833ac0df274e1c8def946237e10bd907c5de11ee
parent7aca3d94becc5827df345447c94b128fd0c45cf8 (diff)
downloadgcc-47c79d563b4e5d80a48f0c0c870c9025b9d095b4.zip
gcc-47c79d563b4e5d80a48f0c0c870c9025b9d095b4.tar.gz
gcc-47c79d563b4e5d80a48f0c0c870c9025b9d095b4.tar.bz2
Makefile.in (lto-compress.o): Add dependency on LTO_STREAMER_H.
* Makefile.in (lto-compress.o): Add dependency on LTO_STREAMER_H. (cgraph.o): Likewise. (cgraphunit.o): Likewise. * cgraphunit.c: Include lto-streamer.h (cgraph_finalize_compilation_unit): Call lto_streamer_hooks_init if LTO is enabled. * lto-streamer-in.c (unpack_value_fields): Call streamer_hooks.unpack_value_fields if set. (lto_materialize_tree): For unhandled nodes, first try to call lto_streamer_hooks.alloc_tree, if it exists. (lto_input_ts_decl_common_tree_pointers): Move reading of DECL_INITIAL to lto_streamer_read_tree. (lto_read_tree): Call lto_streamer_hooks.read_tree if set. (lto_streamer_read_tree): New. (lto_reader_init): Rename from lto_init_reader. Move initialization code to lto/lto.c. * lto-streamer-out.c (pack_value_fields): Call streamer_hooks.pack_value_fields if set. (lto_output_tree_ref): For tree nodes that are not normally indexable, call streamer_hooks.indexable_with_decls_p before giving up. (lto_output_ts_decl_common_tree_pointers): Move handling for FUNCTION_DECL and TRANSLATION_UNIT_DECL to lto_streamer_write_tree. (lto_output_tree_header): Call streamer_hooks.is_streamable instead of lto_is_streamable. Call lto_streamer_hooks.output_tree_header if set. (lto_write_tree): Call lto_streamer_hooks.write_tree if set. (lto_streamer_write_tree): New. (lto_output): Call lto_streamer_init directly. (lto_writer_init): Remove. * lto-streamer.c (streamer_hooks): New. (lto_streamer_cache_create): Call streamer_hooks.preload_common_nodes instead of lto_preload_common_nodes. (lto_is_streamable): Move from lto-streamer.h (lto_streamer_hooks_init): New. (streamer_hooks): New. (streamer_hooks_init): New. * lto-streamer.h (struct output_block): Forward declare. (struct lto_input_block): Likewise. (struct data_in): Likewise. (struct bitpack_d): Likewise. (struct streamer_hooks): Declare. (streamer_hooks): Declare. (lto_streamer_hooks_init): Declare. (lto_streamer_write_tree): Declare. (lto_streamer_read_tree): Declare. (streamer_hooks_init): Declare. (lto_is_streamable): Move to lto-streamer.c lto/ChangeLog * lto.c (lto_init): New. (lto_main): Call it. From-SVN: r174709
-rw-r--r--gcc/ChangeLog53
-rw-r--r--gcc/Makefile.in7
-rw-r--r--gcc/cgraphunit.c5
-rw-r--r--gcc/lto-streamer-in.c48
-rw-r--r--gcc/lto-streamer-out.c107
-rw-r--r--gcc/lto-streamer.c54
-rw-r--r--gcc/lto-streamer.h120
-rw-r--r--gcc/lto/ChangeLog5
-rw-r--r--gcc/lto/lto.c20
9 files changed, 334 insertions, 85 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog
index 59c7656..3166f93 100644
--- a/gcc/ChangeLog
+++ b/gcc/ChangeLog
@@ -1,3 +1,56 @@
+2011-06-04 Diego Novillo <dnovillo@google.com>
+
+ * Makefile.in (lto-compress.o): Add dependency on LTO_STREAMER_H.
+ (cgraph.o): Likewise.
+ (cgraphunit.o): Likewise.
+ * cgraphunit.c: Include lto-streamer.h
+ (cgraph_finalize_compilation_unit): Call lto_streamer_hooks_init
+ if LTO is enabled.
+ * lto-streamer-in.c (unpack_value_fields): Call
+ streamer_hooks.unpack_value_fields if set.
+ (lto_materialize_tree): For unhandled nodes, first try to
+ call lto_streamer_hooks.alloc_tree, if it exists.
+ (lto_input_ts_decl_common_tree_pointers): Move reading of
+ DECL_INITIAL to lto_streamer_read_tree.
+ (lto_read_tree): Call lto_streamer_hooks.read_tree if set.
+ (lto_streamer_read_tree): New.
+ (lto_reader_init): Rename from lto_init_reader.
+ Move initialization code to lto/lto.c.
+ * lto-streamer-out.c (pack_value_fields): Call
+ streamer_hooks.pack_value_fields if set.
+ (lto_output_tree_ref): For tree nodes that are not
+ normally indexable, call streamer_hooks.indexable_with_decls_p
+ before giving up.
+ (lto_output_ts_decl_common_tree_pointers): Move handling
+ for FUNCTION_DECL and TRANSLATION_UNIT_DECL to
+ lto_streamer_write_tree.
+ (lto_output_tree_header): Call streamer_hooks.is_streamable
+ instead of lto_is_streamable.
+ Call lto_streamer_hooks.output_tree_header if set.
+ (lto_write_tree): Call lto_streamer_hooks.write_tree if
+ set.
+ (lto_streamer_write_tree): New.
+ (lto_output): Call lto_streamer_init directly.
+ (lto_writer_init): Remove.
+ * lto-streamer.c (streamer_hooks): New.
+ (lto_streamer_cache_create): Call streamer_hooks.preload_common_nodes
+ instead of lto_preload_common_nodes.
+ (lto_is_streamable): Move from lto-streamer.h
+ (lto_streamer_hooks_init): New.
+ (streamer_hooks): New.
+ (streamer_hooks_init): New.
+ * lto-streamer.h (struct output_block): Forward declare.
+ (struct lto_input_block): Likewise.
+ (struct data_in): Likewise.
+ (struct bitpack_d): Likewise.
+ (struct streamer_hooks): Declare.
+ (streamer_hooks): Declare.
+ (lto_streamer_hooks_init): Declare.
+ (lto_streamer_write_tree): Declare.
+ (lto_streamer_read_tree): Declare.
+ (streamer_hooks_init): Declare.
+ (lto_is_streamable): Move to lto-streamer.c
+
2011-06-06 Andreas Krebbel <Andreas.Krebbel@de.ibm.com>
* longlong.h (smul_ppmm): The resulting register pair contains the
diff --git a/gcc/Makefile.in b/gcc/Makefile.in
index 81736a0..496177c 100644
--- a/gcc/Makefile.in
+++ b/gcc/Makefile.in
@@ -2348,7 +2348,7 @@ double-int.o: double-int.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
# lto-compress.o needs $(ZLIBINC) added to the include flags.
lto-compress.o: lto-compress.c $(CONFIG_H) $(SYSTEM_H) coretypes.h \
- $(TREE_H) langhooks.h $(LTO_HEADER_H) $(LTO_SECTION_H) \
+ $(TREE_H) langhooks.h $(LTO_STREAMER_H) $(LTO_SECTION_H) \
lto-compress.h $(DIAGNOSTIC_CORE_H) $(DIAGNOSTIC_CORE_H)
$(COMPILER) -c $(ALL_COMPILERFLAGS) $(ALL_CPPFLAGS) $(ZLIBINC) $< $(OUTPUT_OPTION)
@@ -3030,14 +3030,15 @@ cgraph.o : cgraph.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) $(TREE_H) \
gt-cgraph.h output.h intl.h $(BASIC_BLOCK_H) debug.h $(HASHTAB_H) \
$(TREE_INLINE_H) $(TREE_DUMP_H) $(TREE_FLOW_H) cif-code.def \
value-prof.h $(EXCEPT_H) $(IPA_UTILS_H) $(DIAGNOSTIC_CORE_H) \
- ipa-inline.h
+ ipa-inline.h $(LTO_STREAMER_H)
cgraphunit.o : cgraphunit.c $(CONFIG_H) $(SYSTEM_H) coretypes.h $(TM_H) \
$(TREE_H) langhooks.h $(TREE_INLINE_H) toplev.h $(DIAGNOSTIC_CORE_H) $(FLAGS_H) $(GGC_H) \
$(TARGET_H) $(CGRAPH_H) intl.h pointer-set.h $(FUNCTION_H) $(GIMPLE_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 ipa-inline.h $(IPA_UTILS_H)
+ tree-pretty-print.h gimple-pretty-print.h ipa-inline.h $(IPA_UTILS_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 834acb1..614b785 100644
--- a/gcc/cgraphunit.c
+++ b/gcc/cgraphunit.c
@@ -140,6 +140,7 @@ along with GCC; see the file COPYING3. If not see
#include "plugin.h"
#include "ipa-inline.h"
#include "ipa-utils.h"
+#include "lto-streamer.h"
static void cgraph_expand_all_functions (void);
static void cgraph_mark_functions_to_output (void);
@@ -1092,6 +1093,10 @@ cgraph_finalize_compilation_unit (void)
{
timevar_push (TV_CGRAPH);
+ /* If LTO is enabled, initialize the streamer hooks needed by GIMPLE. */
+ if (flag_lto)
+ lto_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/lto-streamer-in.c b/gcc/lto-streamer-in.c
index 3a5eb5a..25ccb24 100644
--- a/gcc/lto-streamer-in.c
+++ b/gcc/lto-streamer-in.c
@@ -1841,6 +1841,9 @@ unpack_value_fields (struct bitpack_d *bp, tree expr)
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);
}
@@ -1892,8 +1895,15 @@ lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in,
}
else
{
- /* All other nodes can be materialized with a raw make_node call. */
- result = make_node (code);
+ /* For all other nodes, see if the streamer knows how to allocate
+ it. */
+ if (streamer_hooks.alloc_tree)
+ result = streamer_hooks.alloc_tree (code, ib, data_in);
+
+ /* If the hook did not handle it, materialize the tree with a raw
+ make_node call. */
+ if (result == NULL_TREE)
+ result = make_node (code);
}
#ifdef LTO_STREAMER_DEBUG
@@ -1988,12 +1998,8 @@ lto_input_ts_decl_common_tree_pointers (struct lto_input_block *ib,
{
DECL_SIZE (expr) = lto_input_tree (ib, data_in);
DECL_SIZE_UNIT (expr) = lto_input_tree (ib, data_in);
-
- if (TREE_CODE (expr) != FUNCTION_DECL
- && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
- DECL_INITIAL (expr) = lto_input_tree (ib, data_in);
-
DECL_ATTRIBUTES (expr) = lto_input_tree (ib, data_in);
+
/* Do not stream DECL_ABSTRACT_ORIGIN. We cannot handle debug information
for early inlining so drop it on the floor instead of ICEing in
dwarf2out.c. */
@@ -2484,6 +2490,11 @@ lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
/* Read all the pointer fields in RESULT. */
lto_input_tree_pointers (ib, data_in, result);
+ /* Call back into the streaming module to read anything else it
+ may need. */
+ if (streamer_hooks.read_tree)
+ streamer_hooks.read_tree (ib, data_in, result);
+
/* We should never try to instantiate an MD or NORMAL builtin here. */
if (TREE_CODE (result) == FUNCTION_DECL)
gcc_assert (!lto_stream_as_builtin_p (result));
@@ -2500,6 +2511,21 @@ lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
}
+/* LTO streamer hook for reading GIMPLE trees. IB and DATA_IN are as in
+ lto_read_tree. EXPR is the tree was materialized by lto_read_tree and
+ needs GIMPLE specific data to be filled in. */
+
+void
+lto_streamer_read_tree (struct lto_input_block *ib, struct data_in *data_in,
+ tree expr)
+{
+ if (DECL_P (expr)
+ && TREE_CODE (expr) != FUNCTION_DECL
+ && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
+ DECL_INITIAL (expr) = lto_input_tree (ib, data_in);
+}
+
+
/* Read and INTEGER_CST node from input block IB using the per-file
context in DATA_IN. */
@@ -2581,17 +2607,11 @@ lto_input_tree (struct lto_input_block *ib, struct data_in *data_in)
/* Initialization for the LTO reader. */
void
-lto_init_reader (void)
+lto_reader_init (void)
{
lto_streamer_init ();
-
- memset (&lto_stats, 0, sizeof (lto_stats));
- bitmap_obstack_initialize (NULL);
-
file_name_hash_table = htab_create (37, hash_string_slot_node,
eq_string_slot_node, free);
-
- gimple_register_cfg_hooks ();
}
diff --git a/gcc/lto-streamer-out.c b/gcc/lto-streamer-out.c
index 66b1ac6..02ac958 100644
--- a/gcc/lto-streamer-out.c
+++ b/gcc/lto-streamer-out.c
@@ -591,6 +591,9 @@ pack_value_fields (struct bitpack_d *bp, tree expr)
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);
}
@@ -754,9 +757,22 @@ lto_output_tree_ref (struct output_block *ob, tree expr)
break;
default:
- /* No other node is indexable, so it should have been handled
- by lto_output_tree. */
- gcc_unreachable ();
+ {
+ /* See if the streamer allows this node to be indexable
+ like other global declarations. */
+ if (streamer_hooks.indexable_with_decls_p
+ && streamer_hooks.indexable_with_decls_p (expr))
+ {
+ output_record_start (ob, LTO_global_decl_ref);
+ lto_output_var_decl_index (ob->decl_state, ob->main_stream, expr);
+ }
+ else
+ {
+ /* No other node is indexable, so it should have been
+ handled by lto_output_tree. */
+ gcc_unreachable ();
+ }
+ }
}
}
@@ -865,27 +881,11 @@ lto_output_ts_decl_common_tree_pointers (struct output_block *ob, tree expr,
lto_output_tree_or_ref (ob, DECL_SIZE (expr), ref_p);
lto_output_tree_or_ref (ob, DECL_SIZE_UNIT (expr), ref_p);
- if (TREE_CODE (expr) != FUNCTION_DECL
- && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
- {
- tree initial = DECL_INITIAL (expr);
- if (TREE_CODE (expr) == VAR_DECL
- && (TREE_STATIC (expr) || DECL_EXTERNAL (expr))
- && initial)
- {
- lto_varpool_encoder_t varpool_encoder = ob->decl_state->varpool_node_encoder;
- struct varpool_node *vnode = varpool_get_node (expr);
- if (!vnode)
- initial = error_mark_node;
- else if (!lto_varpool_encoder_encode_initializer_p (varpool_encoder,
- vnode))
- initial = NULL;
- }
-
- lto_output_tree_or_ref (ob, initial, ref_p);
- }
+ /* Note, DECL_INITIAL is not handled here. Since DECL_INITIAL needs
+ special handling in LTO, it must be handled by streamer hooks. */
lto_output_tree_or_ref (ob, DECL_ATTRIBUTES (expr), ref_p);
+
/* Do not stream DECL_ABSTRACT_ORIGIN. We cannot handle debug information
for early inlining so drop it on the floor instead of ICEing in
dwarf2out.c. */
@@ -1261,11 +1261,11 @@ lto_output_tree_header (struct output_block *ob, tree expr)
enum LTO_tags tag;
enum tree_code code;
- /* We should not see any non-GIMPLE tree nodes here. */
+ /* We should not see any tree nodes not handled by the streamer. */
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 (!streamer_hooks.is_streamable (expr))
+ internal_error ("tree code %qs is not supported in %s streams",
+ tree_code_name[code], streamer_hooks.name);
/* The header of a tree node consists of its tag, the size of
the node, and any other information needed to instantiate
@@ -1294,6 +1294,11 @@ lto_output_tree_header (struct output_block *ob, tree expr)
output_sleb128 (ob, TREE_VEC_LENGTH (expr));
else if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
output_uleb128 (ob, BINFO_N_BASE_BINFOS (expr));
+
+ /* Allow the streamer to write any streamer-specific information
+ needed to instantiate the node when reading. */
+ if (streamer_hooks.output_tree_header)
+ streamer_hooks.output_tree_header (ob, expr);
}
@@ -1355,11 +1360,49 @@ lto_write_tree (struct output_block *ob, tree expr, bool ref_p)
/* Write all the pointer fields in EXPR. */
lto_output_tree_pointers (ob, expr, ref_p);
+ /* Call back into the streaming module to see if it needs to write
+ anything that was not written by the common streamer. */
+ if (streamer_hooks.write_tree)
+ streamer_hooks.write_tree (ob, expr, ref_p);
+
/* Mark the end of EXPR. */
output_zero (ob);
}
+/* GIMPLE hook for writing GIMPLE-specific parts of trees. OB, EXPR
+ and REF_P are as in lto_write_tree. */
+
+void
+lto_streamer_write_tree (struct output_block *ob, tree expr, bool ref_p)
+{
+ if (DECL_P (expr)
+ && TREE_CODE (expr) != FUNCTION_DECL
+ && TREE_CODE (expr) != TRANSLATION_UNIT_DECL)
+ {
+ /* Handle DECL_INITIAL for symbols. */
+ tree initial = DECL_INITIAL (expr);
+ if (TREE_CODE (expr) == VAR_DECL
+ && (TREE_STATIC (expr) || DECL_EXTERNAL (expr))
+ && initial)
+ {
+ lto_varpool_encoder_t varpool_encoder;
+ struct varpool_node *vnode;
+
+ varpool_encoder = ob->decl_state->varpool_node_encoder;
+ vnode = varpool_get_node (expr);
+ if (!vnode)
+ initial = error_mark_node;
+ else if (!lto_varpool_encoder_encode_initializer_p (varpool_encoder,
+ vnode))
+ initial = NULL;
+ }
+
+ lto_output_tree_or_ref (ob, initial, ref_p);
+ }
+}
+
+
/* Emit the integer constant CST to output block OB. If REF_P is true,
CST's type will be emitted as a reference. */
@@ -2188,15 +2231,6 @@ copy_function (struct cgraph_node *node)
}
-/* Initialize the LTO writer. */
-
-static void
-lto_writer_init (void)
-{
- lto_streamer_init ();
-}
-
-
/* Main entry point from the pass manager. */
static void
@@ -2210,7 +2244,8 @@ 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;
- lto_writer_init ();
+ /* Initialize the streamer. */
+ lto_streamer_init ();
n_nodes = lto_cgraph_encoder_size (encoder);
/* Process only the functions with bodies. */
diff --git a/gcc/lto-streamer.c b/gcc/lto-streamer.c
index 763ecc5..0608b33 100644
--- a/gcc/lto-streamer.c
+++ b/gcc/lto-streamer.c
@@ -37,6 +37,9 @@ along with GCC; see the file COPYING3. If not see
/* Statistics gathered during LTO, WPA and LTRANS. */
struct lto_stats_d lto_stats;
+/* Streamer hooks. */
+struct streamer_hooks streamer_hooks;
+
/* LTO uses bitmaps with different life-times. So use a seperate
obstack for all LTO bitmaps. */
static bitmap_obstack lto_obstack;
@@ -568,7 +571,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. */
- lto_preload_common_nodes (cache);
+ streamer_hooks.preload_common_nodes (cache);
return cache;
}
@@ -713,3 +716,52 @@ lto_check_version (int major, int minor)
major, minor,
LTO_major_version, LTO_minor_version);
}
+
+
+/* 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 != OMP_CLAUSE
+ && code != OPTIMIZATION_NODE
+ && (code == CASE_LABEL_EXPR
+ || code == DECL_EXPR
+ || TREE_CODE_CLASS (code) != tcc_statement);
+}
+
+
+/* Initialize all the streamer hooks used for streaming GIMPLE. */
+
+void
+lto_streamer_hooks_init (void)
+{
+ streamer_hooks_init ();
+ streamer_hooks.name = "gimple";
+ streamer_hooks.preload_common_nodes = lto_preload_common_nodes;
+ streamer_hooks.is_streamable = lto_is_streamable;
+ streamer_hooks.write_tree = lto_streamer_write_tree;
+ streamer_hooks.read_tree = lto_streamer_read_tree;
+}
+
+
+/* Initialize the current set of streamer hooks. */
+
+void
+streamer_hooks_init (void)
+{
+ memset (&streamer_hooks, 0, sizeof (streamer_hooks));
+}
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 5f69655..157e5c0 100644
--- a/gcc/lto-streamer.h
+++ b/gcc/lto-streamer.h
@@ -33,6 +33,12 @@ along with GCC; see the file COPYING3. If not see
#include "alloc-pool.h"
#include "gcov-io.h"
+/* Forward declarations to avoid including unnecessary headers. */
+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
being emitted. When debugging a problem in the reader, check the
@@ -741,6 +747,86 @@ struct data_in
};
+/* Streamer hooks. These functions do additional processing as
+ needed by the module. There are two types of callbacks, those that
+ replace the default behavior and those that supplement it.
+
+ Hooks marked [REQ] are required to be set. Those marked [OPT] may
+ be NULL, if the streamer does not need to implement them. */
+struct streamer_hooks {
+ /* [REQ] A string identifying this streamer. */
+ const char *name;
+
+ /* [REQ] 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 should call
+ lto_streamer_cache_append on every tree node that it wishes to
+ preload in 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. */
+ void (*preload_common_nodes) (struct lto_streamer_cache_d *);
+
+ /* [REQ] Return true if the given tree is supported by this streamer. */
+ bool (*is_streamable) (tree);
+
+ /* [OPT] 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
+ are as in lto_write_tree.
+
+ The following tree fields are not handled by common code:
+
+ DECL_ABSTRACT_ORIGIN
+ DECL_INITIAL
+ DECL_SAVED_TREE
+
+ Callbacks may choose to ignore or handle them. If handled,
+ the reader should read them in the exact same sequence written
+ by the writer. */
+ void (*write_tree) (struct output_block *, tree, bool);
+
+ /* [OPT] Called by lto_read_tree after reading all the common parts of
+ a tree. If defined, the callback is in charge of reading all
+ 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);
+
+ /* [OPT] Called by lto_output_tree_ref to determine if the given tree node
+ should be emitted as a reference to the table of declarations
+ (the same table that holds global declarations). */
+ bool (*indexable_with_decls_p) (tree);
+
+ /* [OPT] 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);
+
+ /* [OPT] 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);
+
+ /* [OPT] Called by lto_materialize_tree for tree nodes that it does not
+ know how to allocate memory for. If defined, this hook should
+ return a new tree node of the given code. The data_in and
+ input_block arguments are passed in case the hook needs to
+ read more data from the stream to allocate the node.
+ If this hook returns NULL, then lto_materialize_tree will attempt
+ to allocate the tree by calling make_node directly. */
+ tree (*alloc_tree) (enum tree_code, struct lto_input_block *,
+ struct data_in *);
+
+ /* [OPT] Called by lto_output_tree_header to write any streamer-specific
+ information needed to allocate the tree. This hook may assume
+ that the basic header data (tree code, etc) has already been
+ written. It should only write any extra data needed to allocate
+ the node (e.g., in the case of CALL_EXPR, this hook would write
+ the number of arguments to the CALL_EXPR). */
+ void (*output_tree_header) (struct output_block *, tree);
+};
+
+/* Streamer hooks. */
+extern struct streamer_hooks streamer_hooks;
+
/* In lto-section-in.c */
extern struct lto_input_block * lto_create_simple_input_block (
struct lto_file_decl_data *,
@@ -851,17 +937,20 @@ extern intptr_t lto_orig_address_get (tree);
extern void lto_orig_address_remove (tree);
#endif
extern void lto_check_version (int, int);
-
+extern void lto_streamer_hooks_init (void);
+extern void lto_streamer_write_tree (struct output_block *, tree, bool);
+extern void lto_streamer_read_tree (struct lto_input_block *,
+ struct data_in *, tree);
+extern void streamer_hooks_init (void);
/* In lto-streamer-in.c */
extern void lto_input_cgraph (struct lto_file_decl_data *, const char *);
-extern void lto_init_reader (void);
+extern void lto_reader_init (void);
extern tree lto_input_tree (struct lto_input_block *, struct data_in *);
extern void lto_input_function_body (struct lto_file_decl_data *, tree,
const char *);
extern void lto_input_constructors_and_inits (struct lto_file_decl_data *,
const char *);
-extern void lto_init_reader (void);
extern struct data_in *lto_data_in_create (struct lto_file_decl_data *,
const char *, unsigned,
VEC(ld_plugin_symbol_resolution_t,heap) *);
@@ -1063,31 +1152,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 != OMP_CLAUSE
- && code != OPTIMIZATION_NODE
- && (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)
diff --git a/gcc/lto/ChangeLog b/gcc/lto/ChangeLog
index b247dbb..e8393c1 100644
--- a/gcc/lto/ChangeLog
+++ b/gcc/lto/ChangeLog
@@ -1,3 +1,8 @@
+2011-06-04 Diego Novillo <dnovillo@google.com>
+
+ * lto.c (lto_init): New.
+ (lto_main): Call it.
+
2011-06-03 Diego Novillo <dnovillo@google.com>
* lto.c (get_resolution): Move from lto-streamer-in.c.
diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c
index 70d5bde..74dfecd 100644
--- a/gcc/lto/lto.c
+++ b/gcc/lto/lto.c
@@ -2732,6 +2732,21 @@ lto_process_name (void)
setproctitle ("lto1-ltrans");
}
+
+/* Initialize the LTO front end. */
+
+static void
+lto_init (void)
+{
+ lto_process_name ();
+ lto_streamer_hooks_init ();
+ lto_reader_init ();
+ memset (&lto_stats, 0, sizeof (lto_stats));
+ bitmap_obstack_initialize (NULL);
+ gimple_register_cfg_hooks ();
+}
+
+
/* Main entry point for the GIMPLE front end. This front end has
three main personalities:
@@ -2755,9 +2770,8 @@ lto_process_name (void)
void
lto_main (void)
{
- lto_process_name ();
-
- lto_init_reader ();
+ /* Initialize the LTO front end. */
+ lto_init ();
/* Read all the symbols and call graph from all the files in the
command line. */