From 47c79d563b4e5d80a48f0c0c870c9025b9d095b4 Mon Sep 17 00:00:00 2001 From: Diego Novillo Date: Mon, 6 Jun 2011 12:49:11 -0400 Subject: [PATCH] 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 --- gcc/ChangeLog | 53 ++++++++++++++++++ gcc/Makefile.in | 7 +-- gcc/cgraphunit.c | 5 ++ gcc/lto-streamer-in.c | 48 ++++++++++++----- gcc/lto-streamer-out.c | 107 +++++++++++++++++++++++------------- gcc/lto-streamer.c | 54 ++++++++++++++++++- gcc/lto-streamer.h | 120 +++++++++++++++++++++++++++++++---------- gcc/lto/ChangeLog | 5 ++ gcc/lto/lto.c | 20 +++++-- 9 files changed, 334 insertions(+), 85 deletions(-) diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 59c7656f817..3166f93c28c 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,56 @@ +2011-06-04 Diego Novillo + + * 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 * longlong.h (smul_ppmm): The resulting register pair contains the diff --git a/gcc/Makefile.in b/gcc/Makefile.in index 81736a045a0..496177cde63 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 834acb101e5..614b7858a3f 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 3a5eb5a63fe..25ccb24a105 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 (<o_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 66b1ac6f100..02ac9583ace 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 763ecc5e903..0608b33a76b 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 5f69655fb98..157e5c0052e 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 b247dbbdd07..e8393c1f523 100644 --- a/gcc/lto/ChangeLog +++ b/gcc/lto/ChangeLog @@ -1,3 +1,8 @@ +2011-06-04 Diego Novillo + + * lto.c (lto_init): New. + (lto_main): Call it. + 2011-06-03 Diego Novillo * lto.c (get_resolution): Move from lto-streamer-in.c. diff --git a/gcc/lto/lto.c b/gcc/lto/lto.c index 70d5bdee458..74dfecdbc3e 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 (<o_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. */ -- 2.30.2