summaryrefslogtreecommitdiff
path: root/gcc/lto-streamer.h
diff options
context:
space:
mode:
Diffstat (limited to 'gcc/lto-streamer.h')
-rw-r--r--gcc/lto-streamer.h413
1 files changed, 30 insertions, 383 deletions
diff --git a/gcc/lto-streamer.h b/gcc/lto-streamer.h
index 157e5c0052e..230838ba9c1 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
@@ -152,27 +147,6 @@ struct bitpack_d;
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).
@@ -332,33 +306,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
{
@@ -747,86 +694,6 @@ 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 *,
@@ -864,10 +731,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 *);
@@ -919,16 +782,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,15 +791,10 @@ 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 *,
@@ -955,9 +803,12 @@ 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);
/* In lto-streamer-out.c */
@@ -971,6 +822,8 @@ void lto_output_decl_state_streams (struct output_block *,
void lto_output_decl_state_refs (struct output_block *,
struct lto_output_stream *,
struct lto_out_decl_state *);
+void lto_output_tree_ref (struct output_block *, tree);
+void lto_output_location (struct output_block *, location_t);
/* In lto-cgraph.c */
@@ -1096,6 +949,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,
@@ -1160,232 +1035,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<<nbits)-1)));
-
- /* If val does not fit into the current bitpack word switch to the
- next one. */
- if (pos + nbits > 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 */