OSDN Git Service

2012-02-02 Vladimir Makarov <vmakarov@redhat.com>
[pf3gnuchains/gcc-fork.git] / gcc / lto-streamer.h
index 65e2b3f..5c2f4ea 100644 (file)
@@ -1,7 +1,7 @@
 /* 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.
@@ -31,6 +31,8 @@ along with GCC; see the file COPYING3.  If not see
 #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
@@ -139,36 +141,12 @@ along with GCC; see the file COPYING3.  If not see
    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
-{
-  /* Total number of bits packed/unpacked so far.  */
-  size_t num_bits;
-
-  /* Values are stored contiguously, so there may be internal
-     fragmentation (words with unused bits).  Therefore, we need to
-     keep track of the first available bit in the last word of the
-     bitpack.  */
-  size_t first_unused_bit;
-
-  /* Vector of words holding the packed values.  */
-  VEC(bitpack_word_t, heap) *values;
-};
-
 /* Tags representing the various IL objects written to the bytecode file
    (GIMPLE statements, basic blocks, EH regions, tree nodes, etc).
 
@@ -188,7 +166,7 @@ enum LTO_tags
 
      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.  */
@@ -238,6 +216,7 @@ enum LTO_tags
   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.  */
@@ -259,11 +238,14 @@ 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,
   LTO_section_symtab,
   LTO_section_opts,
+  LTO_section_cgraph_opt_sum,
+  LTO_section_inline_summary,
   LTO_N_SECTION_TYPES          /* Must be last.  */
 };
 
@@ -325,42 +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.  */
-  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,gc) *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
 {
@@ -442,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
 {
@@ -467,10 +430,22 @@ struct lto_cgraph_encoder_d
 
   /* Map reference number to node. */
   VEC(cgraph_node_ptr,heap) *nodes;
+
+  /* Map of nodes where we want to output body.  */
+  struct pointer_set_t *body;
 };
 
 typedef struct lto_cgraph_encoder_d *lto_cgraph_encoder_t;
 
+/* Return number of encoded nodes in ENCODER.  */
+
+static inline int
+lto_cgraph_encoder_size (lto_cgraph_encoder_t encoder)
+{
+  return VEC_length (cgraph_node_ptr, encoder->nodes);
+}
+
+
 /* Encoder data structure used to stream callgraph nodes.  */
 struct lto_varpool_encoder_d
 {
@@ -485,6 +460,14 @@ struct lto_varpool_encoder_d
 };
 typedef struct lto_varpool_encoder_d *lto_varpool_encoder_t;
 
+/* Return number of encoded nodes in ENCODER.  */
+
+static inline int
+lto_varpool_encoder_size (lto_varpool_encoder_t encoder)
+{
+  return VEC_length (varpool_node_ptr, encoder->nodes);
+}
+
 /* Mapping from indices to trees.  */
 struct GTY(()) lto_tree_ref_table
 {
@@ -582,8 +565,21 @@ struct GTY(()) lto_file_decl_data
 
   /* Hash new name of renamed global declaration to its original name.  */
   htab_t GTY((skip)) renaming_hash_table;
+
+  /* Linked list used temporarily in reader */
+  struct lto_file_decl_data *next;
+
+  /* Sub ID for merged objects. */
+  unsigned HOST_WIDE_INT id;
+
+  /* Symbol resolutions for this file */
+  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;
+
 struct lto_char_ptr_base
 {
   char *ptr;
@@ -674,7 +670,11 @@ 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.  */
+  struct obstack obstack;
 };
 
 
@@ -708,7 +708,7 @@ 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;
 };
 
 
@@ -730,11 +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 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 *);
@@ -746,6 +741,10 @@ extern hashval_t lto_hash_in_decl_state (const void *);
 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 *);
@@ -755,15 +754,8 @@ extern int lto_eq_type_slot_node (const void *, 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 *);
@@ -789,27 +781,15 @@ extern void lto_push_out_decl_state (struct lto_out_decl_state *);
 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 const char *lto_tag_name (enum LTO_tags);
 extern bitmap lto_bitmap_alloc (void);
 extern void lto_bitmap_free (bitmap);
-extern char *lto_get_section_name (int, const char *);
+extern char *lto_get_section_name (int, const char *, struct lto_file_decl_data *);
 extern void print_lto_report (void);
-extern struct bitpack_d *bitpack_create (void);
-extern void bitpack_delete (struct bitpack_d *);
-extern void bp_pack_value (struct bitpack_d *, bitpack_word_t, unsigned);
-extern bitpack_word_t bp_unpack_value (struct bitpack_d *, unsigned);
-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
@@ -818,31 +798,42 @@ 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);
 
 /* 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 struct bitpack_d *lto_input_bitpack (struct lto_input_block *);
-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_bitpack (struct lto_output_stream *, struct bitpack_d *);
+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  */
@@ -851,6 +842,11 @@ int lto_cgraph_encoder_lookup (lto_cgraph_encoder_t, struct cgraph_node *);
 lto_cgraph_encoder_t lto_cgraph_encoder_new (void);
 int lto_cgraph_encoder_encode (lto_cgraph_encoder_t, struct cgraph_node *);
 void lto_cgraph_encoder_delete (lto_cgraph_encoder_t);
+bool lto_cgraph_encoder_encode_body_p (lto_cgraph_encoder_t,
+                                      struct cgraph_node *);
+
+bool lto_varpool_encoder_encode_body_p (lto_varpool_encoder_t,
+                                       struct varpool_node *);
 struct varpool_node *lto_varpool_encoder_deref (lto_varpool_encoder_t, int);
 int lto_varpool_encoder_lookup (lto_varpool_encoder_t, struct varpool_node *);
 lto_varpool_encoder_t lto_varpool_encoder_new (void);
@@ -863,6 +859,15 @@ void input_cgraph (void);
 bool referenced_from_other_partition_p (struct ipa_ref_list *,
                                        cgraph_node_set,
                                        varpool_node_set vset);
+bool reachable_from_other_partition_p (struct cgraph_node *,
+                                      cgraph_node_set);
+bool referenced_from_this_partition_p (struct ipa_ref_list *,
+                                       cgraph_node_set,
+                                       varpool_node_set vset);
+bool reachable_from_this_partition_p (struct cgraph_node *,
+                                      cgraph_node_set);
+void compute_ltrans_boundary (struct lto_out_decl_state *state,
+                             cgraph_node_set, varpool_node_set);
 
 
 /* In lto-symtab.c.  */
@@ -872,15 +877,12 @@ extern void lto_symtab_merge_decls (void);
 extern void lto_symtab_merge_cgraph_nodes (void);
 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  */
@@ -902,7 +904,7 @@ extern VEC(lto_out_decl_state_ptr, heap) *lto_function_decl_states;
 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;
 }
 
 
@@ -952,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,
@@ -997,40 +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));
-}
-
-/* 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)