/* Data structures and declarations used for reading and writing
GIMPLE to a file stream.
- Copyright (C) 2009, 2010 Free Software Foundation, Inc.
+ Copyright (C) 2009, 2010, 2011 Free Software Foundation, Inc.
Contributed by Doug Kwan <dougkwan@google.com>
This file is part of GCC.
#include "vec.h"
#include "vecprim.h"
#include "alloc-pool.h"
+#include "gcov-io.h"
+#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
sections a '.' and the section type are appended. */
#define LTO_SECTION_NAME_PREFIX ".gnu.lto_"
-#define LTO_major_version 1
-#define LTO_minor_version 0
+#define LTO_major_version 2
+#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).
Conversely, to map between LTO tags and tree/gimple codes, the
reverse operation must be applied. */
- LTO_bb0 = 1 + NUM_TREE_CODES + LAST_AND_UNUSED_GIMPLE_CODE,
+ LTO_bb0 = 1 + MAX_TREE_CODES + LAST_AND_UNUSED_GIMPLE_CODE,
LTO_bb1,
/* EH region holding the previous statement. */
LTO_type_ref,
LTO_const_decl_ref,
LTO_imported_decl_ref,
+ LTO_translation_unit_decl_ref,
LTO_global_decl_ref, /* Do not change. */
/* This tag must always be last. */
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,
LTO_section_symtab,
LTO_section_opts,
LTO_section_cgraph_opt_sum,
+ LTO_section_inline_summary,
LTO_N_SECTION_TYPES /* Must be last. */
};
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. */
- htab_t node_map;
-
- /* Node map to store entries into. */
- alloc_pool node_map_entries;
-
- /* Next available slot in the nodes and offsets arrays. */
- unsigned next_slot;
-
- /* The nodes pickled so far. */
- VEC(tree,heap) *nodes;
-
- /* Offset into the stream where the nodes have been written. */
- VEC(unsigned,heap) *offsets;
-};
-
-
/* Structure used as buffer for reading an LTO file. */
struct lto_input_block
{
};
+/* 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
{
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) *resolutions;
+ VEC(ld_plugin_symbol_resolution_t,heap) * GTY((skip)) resolutions;
+
+ struct gcov_ctr_summary GTY((skip)) profile_info;
};
typedef struct lto_file_decl_data *lto_file_decl_data_ptr;
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. */
+ struct obstack obstack;
};
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;
};
extern void lto_free_section_data (struct lto_file_decl_data *,
enum lto_section_type,
const char *, const char *, size_t);
-extern unsigned char lto_input_1_unsigned (struct lto_input_block *);
-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 *);
extern int lto_eq_in_decl_state (const void *, const void *);
extern struct lto_in_decl_state *lto_get_function_in_decl_state (
struct lto_file_decl_data *, tree);
+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;
/* In lto-section-out.c */
extern hashval_t lto_hash_decl_slot_node (const void *);
extern void lto_begin_section (const char *, bool);
extern void lto_end_section (void);
extern void lto_write_stream (struct lto_output_stream *);
-extern void lto_output_1_stream (struct lto_output_stream *, char);
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 *);
extern struct lto_out_decl_state *lto_pop_out_decl_state (void);
extern void lto_record_function_out_decl_state (tree,
struct lto_out_decl_state *);
+extern void lto_append_block (struct lto_output_stream *);
/* In lto-streamer.c. */
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,
- int *, unsigned *);
-extern bool lto_streamer_cache_insert_at (struct lto_streamer_cache_d *, tree,
- int);
-extern bool lto_streamer_cache_lookup (struct lto_streamer_cache_d *, tree,
- int *);
-extern tree lto_streamer_cache_get (struct lto_streamer_cache_d *, int);
-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
extern void lto_orig_address_remove (tree);
#endif
extern void lto_check_version (int, int);
-
+extern void lto_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 tree lto_input_tree (struct lto_input_block *, struct data_in *);
+extern void lto_reader_init (void);
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 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 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 */
extern tree lto_symtab_prevailing_decl (tree decl);
extern enum ld_plugin_symbol_resolution lto_symtab_get_resolution (tree decl);
extern void lto_symtab_free (void);
+extern GTY(()) VEC(tree,gc) *lto_global_var_decls;
/* In lto-opts.c. */
-extern void lto_register_user_option (size_t, const char *, int, 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 */
static inline bool
lto_tag_is_tree_code_p (enum LTO_tags tag)
{
- return tag > LTO_null && (unsigned) tag <= NUM_TREE_CODES;
+ return tag > LTO_null && (unsigned) tag <= MAX_TREE_CODES;
}
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,
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));
-}
-
-/* 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 == 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)
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;
- /* 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;
-}
-
#endif /* GCC_LTO_STREAMER_H */