X-Git-Url: http://git.sourceforge.jp/view?a=blobdiff_plain;f=gcc%2Flto-streamer.h;h=5c2f4eaac0671848d9ff851c15b6c4ce7cb9c3e2;hb=376a287d5002e5e9a5ed836fd2104d6f0292a09b;hp=157e5c0052e4ef235757c43ca37b2a6b97170b52;hpb=a0605d65f057d09d208c6175c8ef78b8809184da;p=pf3gnuchains%2Fgcc-fork.git diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h index 157e5c0052e..5c2f4eaac06 100644 --- a/gcc/lto-streamer.h +++ b/gcc/lto-streamer.h @@ -32,12 +32,7 @@ along with GCC; see the file COPYING3. If not see #include "vecprim.h" #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; +#include "diagnostic.h" /* Define when debugging the LTO streamer. This causes the writer to output the numeric value for the memory address of the tree node @@ -147,32 +142,11 @@ struct bitpack_d; #define LTO_SECTION_NAME_PREFIX ".gnu.lto_" #define LTO_major_version 2 -#define LTO_minor_version 0 +#define LTO_minor_version 1 typedef unsigned char lto_decl_flags_t; -/* Data structures used to pack values and bitflags into a vector of - words. Used to stream values of a fixed number of bits in a space - efficient way. */ -static unsigned const BITS_PER_BITPACK_WORD = HOST_BITS_PER_WIDE_INT; - -typedef unsigned HOST_WIDE_INT bitpack_word_t; -DEF_VEC_I(bitpack_word_t); -DEF_VEC_ALLOC_I(bitpack_word_t, heap); - -struct bitpack_d -{ - /* The position of the first unused or unconsumed bit in the word. */ - unsigned pos; - - /* The current word we are (un)packing. */ - bitpack_word_t word; - - /* The lto_output_stream or the lto_input_block we are streaming to/from. */ - void *stream; -}; - /* Tags representing the various IL objects written to the bytecode file (GIMPLE statements, basic blocks, EH regions, tree nodes, etc). @@ -264,6 +238,7 @@ enum lto_section_type LTO_section_cgraph, LTO_section_varpool, LTO_section_refs, + LTO_section_asm, LTO_section_jump_functions, LTO_section_ipa_pure_const, LTO_section_ipa_reference, @@ -332,33 +307,6 @@ typedef void (lto_free_section_data_f) (struct lto_file_decl_data *, const char *, size_t); -/* Cache of pickled nodes. Used to avoid writing the same node more - than once. The first time a tree node is streamed out, it is - entered in this cache. Subsequent references to the same node are - resolved by looking it up in this cache. - - This is used in two ways: - - - On the writing side, the first time T is added to STREAMER_CACHE, - a new reference index is created for T and T is emitted on the - stream. If T needs to be emitted again to the stream, instead of - pickling it again, the reference index is emitted. - - - On the reading side, the first time T is read from the stream, it - is reconstructed in memory and a new reference index created for - T. The reconstructed T is inserted in some array so that when - the reference index for T is found in the input stream, it can be - used to look up into the array to get the reconstructed T. */ -struct lto_streamer_cache_d -{ - /* The mapping between tree nodes and slots into the nodes array. */ - struct pointer_map_t *node_map; - - /* The nodes pickled so far. */ - VEC(tree,heap) *nodes; -}; - - /* Structure used as buffer for reading an LTO file. */ struct lto_input_block { @@ -440,6 +388,23 @@ struct lto_decl_header }; +/* Structure describing top level asm()s. */ +struct lto_asm_header +{ + /* The header for all types of sections. */ + struct lto_header lto_header; + + /* Size compressed or 0 if not compressed. */ + int32_t compressed_size; + + /* Size of region for expressions, decls, types, etc. */ + int32_t main_size; + + /* Size of the string table. */ + int32_t string_size; +}; + + /* Statistics gathered during LTO, WPA and LTRANS. */ struct lto_stats_d { @@ -605,7 +570,7 @@ struct GTY(()) lto_file_decl_data struct lto_file_decl_data *next; /* Sub ID for merged objects. */ - unsigned id; + unsigned HOST_WIDE_INT id; /* Symbol resolutions for this file */ VEC(ld_plugin_symbol_resolution_t,heap) * GTY((skip)) resolutions; @@ -705,7 +670,7 @@ struct output_block bool global; /* Cache of nodes written in this section. */ - struct lto_streamer_cache_d *writer_cache; + struct streamer_tree_cache_d *writer_cache; /* All data persistent across whole duration of output block can go here. */ @@ -743,90 +708,10 @@ struct data_in VEC(ld_plugin_symbol_resolution_t,heap) *globals_resolution; /* Cache of pickled nodes. */ - struct lto_streamer_cache_d *reader_cache; + struct streamer_tree_cache_d *reader_cache; }; -/* 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 *, @@ -845,10 +730,6 @@ extern const char *lto_get_section_data (struct lto_file_decl_data *, extern void lto_free_section_data (struct lto_file_decl_data *, enum lto_section_type, const char *, const char *, size_t); -extern unsigned HOST_WIDE_INT lto_input_uleb128 (struct lto_input_block *); -extern unsigned HOST_WIDEST_INT lto_input_widest_uint_uleb128 ( - struct lto_input_block *); -extern HOST_WIDE_INT lto_input_sleb128 (struct lto_input_block *); extern htab_t lto_create_renaming_table (void); extern void lto_record_renamed_decl (struct lto_file_decl_data *, const char *, const char *); @@ -864,10 +745,6 @@ extern void lto_section_overrun (struct lto_input_block *) ATTRIBUTE_NORETURN; extern void lto_value_range_error (const char *, HOST_WIDE_INT, HOST_WIDE_INT, HOST_WIDE_INT) ATTRIBUTE_NORETURN; -extern void bp_pack_var_len_unsigned (struct bitpack_d *, unsigned HOST_WIDE_INT); -extern void bp_pack_var_len_int (struct bitpack_d *, HOST_WIDE_INT); -extern unsigned HOST_WIDE_INT bp_unpack_var_len_unsigned (struct bitpack_d *); -extern HOST_WIDE_INT bp_unpack_var_len_int (struct bitpack_d *); /* In lto-section-out.c */ extern hashval_t lto_hash_decl_slot_node (const void *); @@ -879,12 +756,6 @@ extern void lto_end_section (void); extern void lto_write_stream (struct lto_output_stream *); extern void lto_output_data_stream (struct lto_output_stream *, const void *, size_t); -extern void lto_output_uleb128_stream (struct lto_output_stream *, - unsigned HOST_WIDE_INT); -extern void lto_output_widest_uint_uleb128_stream (struct lto_output_stream *, - unsigned HOST_WIDEST_INT); -extern void lto_output_sleb128_stream (struct lto_output_stream *, - HOST_WIDE_INT); extern bool lto_output_decl_index (struct lto_output_stream *, struct lto_tree_ref_encoder *, tree, unsigned int *); @@ -919,16 +790,6 @@ extern bitmap lto_bitmap_alloc (void); extern void lto_bitmap_free (bitmap); extern char *lto_get_section_name (int, const char *, struct lto_file_decl_data *); extern void print_lto_report (void); -extern bool lto_streamer_cache_insert (struct lto_streamer_cache_d *, tree, - unsigned *); -extern bool lto_streamer_cache_insert_at (struct lto_streamer_cache_d *, tree, - unsigned); -extern void lto_streamer_cache_append (struct lto_streamer_cache_d *, tree); -extern bool lto_streamer_cache_lookup (struct lto_streamer_cache_d *, tree, - unsigned *); -extern tree lto_streamer_cache_get (struct lto_streamer_cache_d *, unsigned); -extern struct lto_streamer_cache_d *lto_streamer_cache_create (void); -extern void lto_streamer_cache_delete (struct lto_streamer_cache_d *); extern void lto_streamer_init (void); extern bool gate_lto_out (void); #ifdef LTO_STREAMER_DEBUG @@ -938,39 +799,41 @@ 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_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_input_toplevel_asms (struct lto_file_decl_data *, int); extern struct data_in *lto_data_in_create (struct lto_file_decl_data *, const char *, unsigned, VEC(ld_plugin_symbol_resolution_t,heap) *); extern void lto_data_in_delete (struct data_in *); -extern const char *lto_input_string (struct data_in *, - struct lto_input_block *); extern void lto_input_data_block (struct lto_input_block *, void *, size_t); +location_t lto_input_location (struct lto_input_block *, struct data_in *); +tree lto_input_tree_ref (struct lto_input_block *, struct data_in *, + struct function *, enum LTO_tags); +void lto_tag_check_set (enum LTO_tags, int, ...); +void lto_init_eh (void); +tree lto_input_tree (struct lto_input_block *, struct data_in *); /* In lto-streamer-out.c */ extern void lto_register_decl_definition (tree, struct lto_file_decl_data *); extern struct output_block *create_output_block (enum lto_section_type); extern void destroy_output_block (struct output_block *); -extern void lto_output_tree (struct output_block *, tree, bool); +extern void lto_output_tree (struct output_block *, tree, bool, bool); +extern void lto_output_toplevel_asms (void); extern void produce_asm (struct output_block *ob, tree fn); void lto_output_decl_state_streams (struct output_block *, struct lto_out_decl_state *); void lto_output_decl_state_refs (struct output_block *, struct lto_output_stream *, struct lto_out_decl_state *); +void lto_output_location (struct output_block *, location_t); /* In lto-cgraph.c */ @@ -1019,12 +882,7 @@ extern GTY(()) VEC(tree,gc) *lto_global_var_decls; /* In lto-opts.c. */ -extern void lto_register_user_option (size_t, const char *, int, unsigned int); -extern void lto_read_file_options (struct lto_file_decl_data *); extern void lto_write_options (void); -extern void lto_reissue_options (void); -void lto_clear_user_options (void); -void lto_clear_file_options (void); /* In lto-wpa-fixup.c */ @@ -1096,6 +954,28 @@ lto_tag_to_tree_code (enum LTO_tags tag) return (enum tree_code) ((unsigned) tag - 1); } +/* Check that tag ACTUAL == EXPECTED. */ +static inline void +lto_tag_check (enum LTO_tags actual, enum LTO_tags expected) +{ + if (actual != expected) + internal_error ("bytecode stream: expected tag %s instead of %s", + lto_tag_name (expected), lto_tag_name (actual)); +} + +/* Check that tag ACTUAL is in the range [TAG1, TAG2]. */ +static inline void +lto_tag_check_range (enum LTO_tags actual, enum LTO_tags tag1, + enum LTO_tags tag2) +{ + if (actual < tag1 || actual > tag2) + internal_error ("bytecode stream: tag %s is not in the expected range " + "[%s, %s]", + lto_tag_name (actual), + lto_tag_name (tag1), + lto_tag_name (tag2)); +} + /* Initialize an lto_out_decl_buffer ENCODER. */ static inline void lto_init_tree_ref_encoder (struct lto_tree_ref_encoder *encoder, @@ -1141,17 +1021,6 @@ emit_label_in_global_context_p (tree label) return DECL_NONLOCAL (label) || FORCED_LABEL (label); } -/* Return true if tree node EXPR should be streamed as a builtin. For - these nodes, we just emit the class and function code. */ -static inline bool -lto_stream_as_builtin_p (tree expr) -{ - return (TREE_CODE (expr) == FUNCTION_DECL - && DECL_IS_BUILTIN (expr) - && (DECL_BUILT_IN_CLASS (expr) == BUILT_IN_NORMAL - || DECL_BUILT_IN_CLASS (expr) == BUILT_IN_MD)); -} - DEFINE_DECL_STREAM_FUNCS (TYPE, type) DEFINE_DECL_STREAM_FUNCS (FIELD_DECL, field_decl) DEFINE_DECL_STREAM_FUNCS (FN_DECL, fn_decl) @@ -1160,232 +1029,4 @@ DEFINE_DECL_STREAM_FUNCS (TYPE_DECL, type_decl) DEFINE_DECL_STREAM_FUNCS (NAMESPACE_DECL, namespace_decl) DEFINE_DECL_STREAM_FUNCS (LABEL_DECL, label_decl) -/* Returns a new bit-packing context for bit-packing into S. */ -static inline struct bitpack_d -bitpack_create (struct lto_output_stream *s) -{ - struct bitpack_d bp; - bp.pos = 0; - bp.word = 0; - bp.stream = (void *)s; - return bp; -} - -/* Pack the NBITS bit sized value VAL into the bit-packing context BP. */ -static inline void -bp_pack_value (struct bitpack_d *bp, bitpack_word_t val, unsigned nbits) -{ - bitpack_word_t word = bp->word; - int pos = bp->pos; - - /* Verify that VAL fits in the NBITS. */ - gcc_checking_assert (nbits == BITS_PER_BITPACK_WORD - || !(val & ~(((bitpack_word_t)1< BITS_PER_BITPACK_WORD) - { - lto_output_uleb128_stream ((struct lto_output_stream *) bp->stream, word); - word = val; - pos = nbits; - } - else - { - word |= val << pos; - pos += nbits; - } - bp->word = word; - bp->pos = pos; -} - -/* Finishes bit-packing of BP. */ -static inline void -lto_output_bitpack (struct bitpack_d *bp) -{ - lto_output_uleb128_stream ((struct lto_output_stream *) bp->stream, - bp->word); - bp->word = 0; - bp->pos = 0; -} - -/* Returns a new bit-packing context for bit-unpacking from IB. */ -static inline struct bitpack_d -lto_input_bitpack (struct lto_input_block *ib) -{ - struct bitpack_d bp; - bp.word = lto_input_uleb128 (ib); - bp.pos = 0; - bp.stream = (void *)ib; - return bp; -} - -/* Unpacks NBITS bits from the bit-packing context BP and returns them. */ -static inline bitpack_word_t -bp_unpack_value (struct bitpack_d *bp, unsigned nbits) -{ - bitpack_word_t mask, val; - int pos = bp->pos; - - mask = (nbits == BITS_PER_BITPACK_WORD - ? (bitpack_word_t) -1 - : ((bitpack_word_t) 1 << nbits) - 1); - - /* If there are not continuous nbits in the current bitpack word - switch to the next one. */ - if (pos + nbits > BITS_PER_BITPACK_WORD) - { - bp->word = val = lto_input_uleb128 ((struct lto_input_block *)bp->stream); - bp->pos = nbits; - return val & mask; - } - val = bp->word; - val >>= pos; - bp->pos = pos + nbits; - - return val & mask; -} - - -/* Write a character to the output block. */ - -static inline void -lto_output_1_stream (struct lto_output_stream *obs, char c) -{ - /* No space left. */ - if (obs->left_in_block == 0) - lto_append_block (obs); - - /* Write the actual character. */ - *obs->current_pointer = c; - obs->current_pointer++; - obs->total_size++; - obs->left_in_block--; -} - - -/* Read byte from the input block. */ - -static inline unsigned char -lto_input_1_unsigned (struct lto_input_block *ib) -{ - if (ib->p >= ib->len) - lto_section_overrun (ib); - return (ib->data[ib->p++]); -} - -/* Output VAL into OBS and verify it is in range MIN...MAX that is supposed - to be compile time constant. - Be host independent, limit range to 31bits. */ - -static inline void -lto_output_int_in_range (struct lto_output_stream *obs, - HOST_WIDE_INT min, - HOST_WIDE_INT max, - HOST_WIDE_INT val) -{ - HOST_WIDE_INT range = max - min; - - gcc_checking_assert (val >= min && val <= max && range > 0 - && range < 0x7fffffff); - - val -= min; - lto_output_1_stream (obs, val & 255); - if (range >= 0xff) - lto_output_1_stream (obs, (val >> 8) & 255); - if (range >= 0xffff) - lto_output_1_stream (obs, (val >> 16) & 255); - if (range >= 0xffffff) - lto_output_1_stream (obs, (val >> 24) & 255); -} - -/* Input VAL into OBS and verify it is in range MIN...MAX that is supposed - to be compile time constant. PURPOSE is used for error reporting. */ - -static inline HOST_WIDE_INT -lto_input_int_in_range (struct lto_input_block *ib, - const char *purpose, - HOST_WIDE_INT min, - HOST_WIDE_INT max) -{ - HOST_WIDE_INT range = max - min; - HOST_WIDE_INT val = lto_input_1_unsigned (ib); - - gcc_checking_assert (range > 0 && range < 0x7fffffff); - - if (range >= 0xff) - val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 8; - if (range >= 0xffff) - val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 16; - if (range >= 0xffffff) - val |= ((HOST_WIDE_INT)lto_input_1_unsigned (ib)) << 24; - val += min; - if (val < min || val > max) - lto_value_range_error (purpose, val, min, max); - return val; -} - - -/* Output VAL into BP and verify it is in range MIN...MAX that is supposed - to be compile time constant. - Be host independent, limit range to 31bits. */ - -static inline void -bp_pack_int_in_range (struct bitpack_d *bp, - HOST_WIDE_INT min, - HOST_WIDE_INT max, - HOST_WIDE_INT val) -{ - HOST_WIDE_INT range = max - min; - int nbits = floor_log2 (range) + 1; - - gcc_checking_assert (val >= min && val <= max && range > 0 - && range < 0x7fffffff); - - val -= min; - bp_pack_value (bp, val, nbits); -} - -/* Input VAL into BP and verify it is in range MIN...MAX that is supposed - to be compile time constant. PURPOSE is used for error reporting. */ - -static inline HOST_WIDE_INT -bp_unpack_int_in_range (struct bitpack_d *bp, - const char *purpose, - HOST_WIDE_INT min, - HOST_WIDE_INT max) -{ - HOST_WIDE_INT range = max - min; - int nbits = floor_log2 (range) + 1; - HOST_WIDE_INT val = bp_unpack_value (bp, nbits); - - gcc_checking_assert (range > 0 && range < 0x7fffffff); - - if (val < min || val > max) - lto_value_range_error (purpose, val, min, max); - return val; -} - -/* Output VAL of type "enum enum_name" into OBS. - Assume range 0...ENUM_LAST - 1. */ -#define lto_output_enum(obs,enum_name,enum_last,val) \ - lto_output_int_in_range ((obs), 0, (int)(enum_last) - 1, (int)(val)) - -/* Input enum of type "enum enum_name" from IB. - Assume range 0...ENUM_LAST - 1. */ -#define lto_input_enum(ib,enum_name,enum_last) \ - (enum enum_name)lto_input_int_in_range ((ib), #enum_name, 0, \ - (int)(enum_last) - 1) - -/* Output VAL of type "enum enum_name" into BP. - Assume range 0...ENUM_LAST - 1. */ -#define bp_pack_enum(bp,enum_name,enum_last,val) \ - bp_pack_int_in_range ((bp), 0, (int)(enum_last) - 1, (int)(val)) - -/* Input enum of type "enum enum_name" from BP. - Assume range 0...ENUM_LAST - 1. */ -#define bp_unpack_enum(bp,enum_name,enum_last) \ - (enum enum_name)bp_unpack_int_in_range ((bp), #enum_name, 0, \ - (int)(enum_last) - 1) - #endif /* GCC_LTO_STREAMER_H */