OSDN Git Service

PR tree-optimization/51680
[pf3gnuchains/gcc-fork.git] / gcc / tree-streamer-in.c
index cd2f221..c721510 100644 (file)
@@ -34,12 +34,12 @@ along with GCC; see the file COPYING3.  If not see
    block IB.  */
 
 tree
-input_string_cst (struct data_in *data_in, struct lto_input_block *ib)
+streamer_read_string_cst (struct data_in *data_in, struct lto_input_block *ib)
 {
   unsigned int len;
   const char * ptr;
 
-  ptr = input_string_internal (data_in, ib, &len);
+  ptr = streamer_read_indexed_string (data_in, ib, &len);
   if (!ptr)
     return NULL;
   return build_string (len, ptr);
@@ -55,7 +55,7 @@ input_identifier (struct data_in *data_in, struct lto_input_block *ib)
   unsigned int len;
   const char *ptr;
 
-  ptr = input_string_internal (data_in, ib, &len);
+  ptr = streamer_read_indexed_string (data_in, ib, &len);
   if (!ptr)
     return NULL;
   return get_identifier_with_length (ptr, len);
@@ -65,17 +65,17 @@ input_identifier (struct data_in *data_in, struct lto_input_block *ib)
 /* Read a chain of tree nodes from input block IB. DATA_IN contains
    tables and descriptors for the file being read.  */
 
-static tree
-lto_input_chain (struct lto_input_block *ib, struct data_in *data_in)
+tree
+streamer_read_chain (struct lto_input_block *ib, struct data_in *data_in)
 {
   int i, count;
   tree first, prev, curr;
 
   first = prev = NULL_TREE;
-  count = lto_input_sleb128 (ib);
+  count = streamer_read_hwi (ib);
   for (i = 0; i < count; i++)
     {
-      curr = lto_input_tree (ib, data_in);
+      curr = stream_read_tree (ib, data_in);
       if (prev)
        TREE_CHAIN (prev) = curr;
       else
@@ -96,7 +96,7 @@ static void
 unpack_ts_base_value_fields (struct bitpack_d *bp, tree expr)
 {
   /* Note that the code for EXPR has already been unpacked to create EXPR in
-     lto_materialize_tree.  */
+     streamer_alloc_tree.  */
   if (!TYPE_P (expr))
     {
       TREE_SIDE_EFFECTS (expr) = (unsigned) bp_unpack_value (bp, 1);
@@ -130,7 +130,10 @@ unpack_ts_base_value_fields (struct bitpack_d *bp, tree expr)
   TREE_PROTECTED (expr) = (unsigned) bp_unpack_value (bp, 1);
   TREE_DEPRECATED (expr) = (unsigned) bp_unpack_value (bp, 1);
   if (TYPE_P (expr))
-    TYPE_SATURATING (expr) = (unsigned) bp_unpack_value (bp, 1);
+    {
+      TYPE_SATURATING (expr) = (unsigned) bp_unpack_value (bp, 1);
+      TYPE_ADDR_SPACE (expr) = (unsigned) bp_unpack_value (bp, 8);
+    }
   else if (TREE_CODE (expr) == SSA_NAME)
     SSA_NAME_IS_DEFAULT_DEF (expr) = (unsigned) bp_unpack_value (bp, 1);
   else
@@ -401,9 +404,32 @@ 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);
+}
+
+
+/* Read all the language-independent bitfield values for EXPR from IB.
+   Return the partially unpacked bitpack so the caller can unpack any other
+   bitfield values that the writer may have written.  */
+
+struct bitpack_d
+streamer_read_tree_bitfields (struct lto_input_block *ib, tree expr)
+{
+  enum tree_code code;
+  struct bitpack_d bp;
+
+  /* Read the bitpack of non-pointer values from IB.  */
+  bp = streamer_read_bitpack (ib);
+
+  /* The first word in BP contains the code of the tree that we
+     are about to read.  */
+  code = (enum tree_code) bp_unpack_value (&bp, 16);
+  lto_tag_check (lto_tree_code_to_tag (code),
+                lto_tree_code_to_tag (TREE_CODE (expr)));
+
+  /* Unpack all the value fields from BP.  */
+  unpack_value_fields (&bp, expr);
 
-  if (streamer_hooks.unpack_value_fields)
-    streamer_hooks.unpack_value_fields (bp, expr);
+  return bp;
 }
 
 
@@ -411,11 +437,10 @@ unpack_value_fields (struct bitpack_d *bp, tree expr)
    DATA_IN.  The code for the new tree should match TAG.  Store in
    *IX_P the index into the reader cache where the new tree is stored.  */
 
-static tree
-lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in,
-                     enum LTO_tags tag)
+tree
+streamer_alloc_tree (struct lto_input_block *ib, struct data_in *data_in,
+                    enum LTO_tags tag)
 {
-  struct bitpack_d bp;
   enum tree_code code;
   tree result;
 #ifdef LTO_STREAMER_DEBUG
@@ -428,7 +453,7 @@ lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in,
   /* Read the word representing the memory address for the tree
      as it was written by the writer.  This is useful when
      debugging differences between the writer and reader.  */
-  orig_address_in_writer = lto_input_sleb128 (ib);
+  orig_address_in_writer = streamer_read_hwi (ib);
   gcc_assert ((intptr_t) orig_address_in_writer == orig_address_in_writer);
 #endif
 
@@ -440,30 +465,29 @@ lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in,
 
   /* Instantiate a new tree using the header data.  */
   if (CODE_CONTAINS_STRUCT (code, TS_STRING))
-    result = input_string_cst (data_in, ib);
+    result = streamer_read_string_cst (data_in, ib);
   else if (CODE_CONTAINS_STRUCT (code, TS_IDENTIFIER))
     result = input_identifier (data_in, ib);
   else if (CODE_CONTAINS_STRUCT (code, TS_VEC))
     {
-      HOST_WIDE_INT len = lto_input_sleb128 (ib);
+      HOST_WIDE_INT len = streamer_read_hwi (ib);
       result = make_tree_vec (len);
     }
   else if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
     {
-      unsigned HOST_WIDE_INT len = lto_input_uleb128 (ib);
+      unsigned HOST_WIDE_INT len = streamer_read_uhwi (ib);
       result = make_tree_binfo (len);
     }
+  else if (code == CALL_EXPR)
+    {
+      unsigned HOST_WIDE_INT nargs = streamer_read_uhwi (ib);
+      return build_vl_exp (CALL_EXPR, nargs + 3);
+    }
   else
     {
-      /* 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
+      /* For all other nodes, materialize the tree with a raw
         make_node call.  */
-      if (result == NULL_TREE)
-       result = make_node (code);
+      result = make_node (code);
     }
 
 #ifdef LTO_STREAMER_DEBUG
@@ -475,22 +499,6 @@ lto_materialize_tree (struct lto_input_block *ib, struct data_in *data_in,
   lto_orig_address_map (result, (intptr_t) orig_address_in_writer);
 #endif
 
-  /* Read the bitpack of non-pointer values from IB.  */
-  bp = lto_input_bitpack (ib);
-
-  /* The first word in BP contains the code of the tree that we
-     are about to read.  */
-  code = (enum tree_code) bp_unpack_value (&bp, 16);
-  lto_tag_check (lto_tree_code_to_tag (code), tag);
-
-  /* Unpack all the value fields from BP.  */
-  unpack_value_fields (&bp, result);
-
-  /* Enter RESULT in the reader cache.  This will make RESULT
-     available so that circular references in the rest of the tree
-     structure can be resolved in subsequent calls to lto_input_tree.  */
-  lto_streamer_cache_append (data_in->reader_cache, result);
-
   return result;
 }
 
@@ -505,7 +513,7 @@ lto_input_ts_common_tree_pointers (struct lto_input_block *ib,
                                   struct data_in *data_in, tree expr)
 {
   if (TREE_CODE (expr) != IDENTIFIER_NODE)
-    TREE_TYPE (expr) = lto_input_tree (ib, data_in);
+    TREE_TYPE (expr) = stream_read_tree (ib, data_in);
 }
 
 
@@ -517,7 +525,7 @@ static void
 lto_input_ts_vector_tree_pointers (struct lto_input_block *ib,
                                   struct data_in *data_in, tree expr)
 {
-  TREE_VECTOR_CST_ELTS (expr) = lto_input_chain (ib, data_in);
+  TREE_VECTOR_CST_ELTS (expr) = streamer_read_chain (ib, data_in);
 }
 
 
@@ -529,8 +537,8 @@ static void
 lto_input_ts_complex_tree_pointers (struct lto_input_block *ib,
                                    struct data_in *data_in, tree expr)
 {
-  TREE_REALPART (expr) = lto_input_tree (ib, data_in);
-  TREE_IMAGPART (expr) = lto_input_tree (ib, data_in);
+  TREE_REALPART (expr) = stream_read_tree (ib, data_in);
+  TREE_IMAGPART (expr) = stream_read_tree (ib, data_in);
 }
 
 
@@ -542,8 +550,8 @@ static void
 lto_input_ts_decl_minimal_tree_pointers (struct lto_input_block *ib,
                                         struct data_in *data_in, tree expr)
 {
-  DECL_NAME (expr) = lto_input_tree (ib, data_in);
-  DECL_CONTEXT (expr) = lto_input_tree (ib, data_in);
+  DECL_NAME (expr) = stream_read_tree (ib, data_in);
+  DECL_CONTEXT (expr) = stream_read_tree (ib, data_in);
   DECL_SOURCE_LOCATION (expr) = lto_input_location (ib, data_in);
 }
 
@@ -556,25 +564,25 @@ static void
 lto_input_ts_decl_common_tree_pointers (struct lto_input_block *ib,
                                        struct data_in *data_in, tree expr)
 {
-  DECL_SIZE (expr) = lto_input_tree (ib, data_in);
-  DECL_SIZE_UNIT (expr) = lto_input_tree (ib, data_in);
-  DECL_ATTRIBUTES (expr) = lto_input_tree (ib, data_in);
+  DECL_SIZE (expr) = stream_read_tree (ib, data_in);
+  DECL_SIZE_UNIT (expr) = stream_read_tree (ib, data_in);
+  DECL_ATTRIBUTES (expr) = stream_read_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.  */
 
   if (TREE_CODE (expr) == PARM_DECL)
-    TREE_CHAIN (expr) = lto_input_chain (ib, data_in);
+    TREE_CHAIN (expr) = streamer_read_chain (ib, data_in);
 
   if ((TREE_CODE (expr) == VAR_DECL
        || TREE_CODE (expr) == PARM_DECL)
       && DECL_HAS_VALUE_EXPR_P (expr))
-    SET_DECL_VALUE_EXPR (expr, lto_input_tree (ib, data_in));
+    SET_DECL_VALUE_EXPR (expr, stream_read_tree (ib, data_in));
 
   if (TREE_CODE (expr) == VAR_DECL)
     {
-      tree dexpr = lto_input_tree (ib, data_in);
+      tree dexpr = stream_read_tree (ib, data_in);
       if (dexpr)
        SET_DECL_DEBUG_EXPR (expr, dexpr);
     }
@@ -591,10 +599,12 @@ lto_input_ts_decl_non_common_tree_pointers (struct lto_input_block *ib,
 {
   if (TREE_CODE (expr) == FUNCTION_DECL)
     {
-      DECL_ARGUMENTS (expr) = lto_input_tree (ib, data_in);
-      DECL_RESULT (expr) = lto_input_tree (ib, data_in);
+      DECL_ARGUMENTS (expr) = stream_read_tree (ib, data_in);
+      DECL_RESULT (expr) = stream_read_tree (ib, data_in);
     }
-  DECL_VINDEX (expr) = lto_input_tree (ib, data_in);
+  else if (TREE_CODE (expr) == TYPE_DECL)
+    DECL_ORIGINAL_TYPE (expr) = stream_read_tree (ib, data_in);
+  DECL_VINDEX (expr) = stream_read_tree (ib, data_in);
 }
 
 
@@ -608,15 +618,15 @@ lto_input_ts_decl_with_vis_tree_pointers (struct lto_input_block *ib,
 {
   tree id;
 
-  id = lto_input_tree (ib, data_in);
+  id = stream_read_tree (ib, data_in);
   if (id)
     {
       gcc_assert (TREE_CODE (id) == IDENTIFIER_NODE);
       SET_DECL_ASSEMBLER_NAME (expr, id);
     }
 
-  DECL_SECTION_NAME (expr) = lto_input_tree (ib, data_in);
-  DECL_COMDAT_GROUP (expr) = lto_input_tree (ib, data_in);
+  DECL_SECTION_NAME (expr) = stream_read_tree (ib, data_in);
+  DECL_COMDAT_GROUP (expr) = stream_read_tree (ib, data_in);
 }
 
 
@@ -628,12 +638,11 @@ static void
 lto_input_ts_field_decl_tree_pointers (struct lto_input_block *ib,
                                       struct data_in *data_in, tree expr)
 {
-  DECL_FIELD_OFFSET (expr) = lto_input_tree (ib, data_in);
-  DECL_BIT_FIELD_TYPE (expr) = lto_input_tree (ib, data_in);
-  DECL_QUALIFIER (expr) = lto_input_tree (ib, data_in);
-  DECL_FIELD_BIT_OFFSET (expr) = lto_input_tree (ib, data_in);
-  DECL_FCONTEXT (expr) = lto_input_tree (ib, data_in);
-  TREE_CHAIN (expr) = lto_input_chain (ib, data_in);
+  DECL_FIELD_OFFSET (expr) = stream_read_tree (ib, data_in);
+  DECL_BIT_FIELD_TYPE (expr) = stream_read_tree (ib, data_in);
+  DECL_QUALIFIER (expr) = stream_read_tree (ib, data_in);
+  DECL_FIELD_BIT_OFFSET (expr) = stream_read_tree (ib, data_in);
+  DECL_FCONTEXT (expr) = stream_read_tree (ib, data_in);
 }
 
 
@@ -647,9 +656,9 @@ lto_input_ts_function_decl_tree_pointers (struct lto_input_block *ib,
 {
   /* DECL_STRUCT_FUNCTION is handled by lto_input_function.  FIXME lto,
      maybe it should be handled here?  */
-  DECL_FUNCTION_PERSONALITY (expr) = lto_input_tree (ib, data_in);
-  DECL_FUNCTION_SPECIFIC_TARGET (expr) = lto_input_tree (ib, data_in);
-  DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr) = lto_input_tree (ib, data_in);
+  DECL_FUNCTION_PERSONALITY (expr) = stream_read_tree (ib, data_in);
+  DECL_FUNCTION_SPECIFIC_TARGET (expr) = stream_read_tree (ib, data_in);
+  DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr) = stream_read_tree (ib, data_in);
 
   /* If the file contains a function with an EH personality set,
      then it was compiled with -fexceptions.  In that case, initialize
@@ -667,19 +676,19 @@ static void
 lto_input_ts_type_common_tree_pointers (struct lto_input_block *ib,
                                        struct data_in *data_in, tree expr)
 {
-  TYPE_SIZE (expr) = lto_input_tree (ib, data_in);
-  TYPE_SIZE_UNIT (expr) = lto_input_tree (ib, data_in);
-  TYPE_ATTRIBUTES (expr) = lto_input_tree (ib, data_in);
-  TYPE_NAME (expr) = lto_input_tree (ib, data_in);
+  TYPE_SIZE (expr) = stream_read_tree (ib, data_in);
+  TYPE_SIZE_UNIT (expr) = stream_read_tree (ib, data_in);
+  TYPE_ATTRIBUTES (expr) = stream_read_tree (ib, data_in);
+  TYPE_NAME (expr) = stream_read_tree (ib, data_in);
   /* Do not stream TYPE_POINTER_TO or TYPE_REFERENCE_TO.  They will be
      reconstructed during fixup.  */
   /* Do not stream TYPE_NEXT_VARIANT, we reconstruct the variant lists
      during fixup.  */
-  TYPE_MAIN_VARIANT (expr) = lto_input_tree (ib, data_in);
-  TYPE_CONTEXT (expr) = lto_input_tree (ib, data_in);
+  TYPE_MAIN_VARIANT (expr) = stream_read_tree (ib, data_in);
+  TYPE_CONTEXT (expr) = stream_read_tree (ib, data_in);
   /* TYPE_CANONICAL gets re-computed during type merging.  */
   TYPE_CANONICAL (expr) = NULL_TREE;
-  TYPE_STUB_DECL (expr) = lto_input_tree (ib, data_in);
+  TYPE_STUB_DECL (expr) = stream_read_tree (ib, data_in);
 }
 
 /* Read all pointer fields in the TS_TYPE_NON_COMMON structure of EXPR
@@ -692,20 +701,20 @@ lto_input_ts_type_non_common_tree_pointers (struct lto_input_block *ib,
                                            tree expr)
 {
   if (TREE_CODE (expr) == ENUMERAL_TYPE)
-    TYPE_VALUES (expr) = lto_input_tree (ib, data_in);
+    TYPE_VALUES (expr) = stream_read_tree (ib, data_in);
   else if (TREE_CODE (expr) == ARRAY_TYPE)
-    TYPE_DOMAIN (expr) = lto_input_tree (ib, data_in);
+    TYPE_DOMAIN (expr) = stream_read_tree (ib, data_in);
   else if (RECORD_OR_UNION_TYPE_P (expr))
-    TYPE_FIELDS (expr) = lto_input_tree (ib, data_in);
+    TYPE_FIELDS (expr) = streamer_read_chain (ib, data_in);
   else if (TREE_CODE (expr) == FUNCTION_TYPE
           || TREE_CODE (expr) == METHOD_TYPE)
-    TYPE_ARG_TYPES (expr) = lto_input_tree (ib, data_in);
+    TYPE_ARG_TYPES (expr) = stream_read_tree (ib, data_in);
 
   if (!POINTER_TYPE_P (expr))
-    TYPE_MINVAL (expr) = lto_input_tree (ib, data_in);
-  TYPE_MAXVAL (expr) = lto_input_tree (ib, data_in);
+    TYPE_MINVAL (expr) = stream_read_tree (ib, data_in);
+  TYPE_MAXVAL (expr) = stream_read_tree (ib, data_in);
   if (RECORD_OR_UNION_TYPE_P (expr))
-    TYPE_BINFO (expr) = lto_input_tree (ib, data_in);
+    TYPE_BINFO (expr) = stream_read_tree (ib, data_in);
 }
 
 
@@ -717,9 +726,9 @@ static void
 lto_input_ts_list_tree_pointers (struct lto_input_block *ib,
                                 struct data_in *data_in, tree expr)
 {
-  TREE_PURPOSE (expr) = lto_input_tree (ib, data_in);
-  TREE_VALUE (expr) = lto_input_tree (ib, data_in);
-  TREE_CHAIN (expr) = lto_input_chain (ib, data_in);
+  TREE_PURPOSE (expr) = stream_read_tree (ib, data_in);
+  TREE_VALUE (expr) = stream_read_tree (ib, data_in);
+  TREE_CHAIN (expr) = streamer_read_chain (ib, data_in);
 }
 
 
@@ -733,10 +742,10 @@ lto_input_ts_vec_tree_pointers (struct lto_input_block *ib,
 {
   int i;
 
-  /* Note that TREE_VEC_LENGTH was read by lto_materialize_tree to
+  /* Note that TREE_VEC_LENGTH was read by streamer_alloc_tree to
      instantiate EXPR.  */
   for (i = 0; i < TREE_VEC_LENGTH (expr); i++)
-    TREE_VEC_ELT (expr, i) = lto_input_tree (ib, data_in);
+    TREE_VEC_ELT (expr, i) = stream_read_tree (ib, data_in);
 }
 
 
@@ -752,15 +761,15 @@ lto_input_ts_exp_tree_pointers (struct lto_input_block *ib,
   int i, length;
   location_t loc;
 
-  length = lto_input_sleb128 (ib);
+  length = streamer_read_hwi (ib);
   gcc_assert (length == TREE_OPERAND_LENGTH (expr));
 
   for (i = 0; i < length; i++)
-    TREE_OPERAND (expr, i) = lto_input_tree (ib, data_in);
+    TREE_OPERAND (expr, i) = stream_read_tree (ib, data_in);
 
   loc = lto_input_location (ib, data_in);
   SET_EXPR_LOCATION (expr, loc);
-  TREE_BLOCK (expr) = lto_input_tree (ib, data_in);
+  TREE_BLOCK (expr) = stream_read_tree (ib, data_in);
 }
 
 
@@ -775,19 +784,19 @@ lto_input_ts_block_tree_pointers (struct lto_input_block *ib,
   /* Do not stream BLOCK_SOURCE_LOCATION.  We cannot handle debug information
      for early inlining so drop it on the floor instead of ICEing in
      dwarf2out.c.  */
-  BLOCK_VARS (expr) = lto_input_chain (ib, data_in);
+  BLOCK_VARS (expr) = streamer_read_chain (ib, data_in);
 
   /* Do not stream BLOCK_NONLOCALIZED_VARS.  We cannot handle debug information
      for early inlining so drop it on the floor instead of ICEing in
      dwarf2out.c.  */
 
-  BLOCK_SUPERCONTEXT (expr) = lto_input_tree (ib, data_in);
+  BLOCK_SUPERCONTEXT (expr) = stream_read_tree (ib, data_in);
 
   /* Do not stream BLOCK_ABSTRACT_ORIGIN.  We cannot handle debug information
      for early inlining so drop it on the floor instead of ICEing in
      dwarf2out.c.  */
-  BLOCK_FRAGMENT_ORIGIN (expr) = lto_input_tree (ib, data_in);
-  BLOCK_FRAGMENT_CHAIN (expr) = lto_input_tree (ib, data_in);
+  BLOCK_FRAGMENT_ORIGIN (expr) = stream_read_tree (ib, data_in);
+  BLOCK_FRAGMENT_CHAIN (expr) = stream_read_tree (ib, data_in);
 
   /* We re-compute BLOCK_SUBBLOCKS of our parent here instead
      of streaming it.  For non-BLOCK BLOCK_SUPERCONTEXTs we still
@@ -822,37 +831,36 @@ lto_input_ts_binfo_tree_pointers (struct lto_input_block *ib,
   tree t;
 
   /* Note that the number of slots in EXPR was read in
-     lto_materialize_tree when instantiating EXPR.  However, the
+     streamer_alloc_tree when instantiating EXPR.  However, the
      vector is empty so we cannot rely on VEC_length to know how many
      elements to read.  So, this list is emitted as a 0-terminated
      list on the writer side.  */
   do
     {
-      t = lto_input_tree (ib, data_in);
+      t = stream_read_tree (ib, data_in);
       if (t)
        VEC_quick_push (tree, BINFO_BASE_BINFOS (expr), t);
     }
   while (t);
 
-  BINFO_OFFSET (expr) = lto_input_tree (ib, data_in);
-  BINFO_VTABLE (expr) = lto_input_tree (ib, data_in);
-  BINFO_VIRTUALS (expr) = lto_input_tree (ib, data_in);
-  BINFO_VPTR_FIELD (expr) = lto_input_tree (ib, data_in);
+  BINFO_OFFSET (expr) = stream_read_tree (ib, data_in);
+  BINFO_VTABLE (expr) = stream_read_tree (ib, data_in);
+  BINFO_VPTR_FIELD (expr) = stream_read_tree (ib, data_in);
 
-  len = lto_input_uleb128 (ib);
+  len = streamer_read_uhwi (ib);
   if (len > 0)
     {
       VEC_reserve_exact (tree, gc, BINFO_BASE_ACCESSES (expr), len);
       for (i = 0; i < len; i++)
        {
-         tree a = lto_input_tree (ib, data_in);
+         tree a = stream_read_tree (ib, data_in);
          VEC_quick_push (tree, BINFO_BASE_ACCESSES (expr), a);
        }
     }
 
-  BINFO_INHERITANCE_CHAIN (expr) = lto_input_tree (ib, data_in);
-  BINFO_SUBVTT_INDEX (expr) = lto_input_tree (ib, data_in);
-  BINFO_VPTR_INDEX (expr) = lto_input_tree (ib, data_in);
+  BINFO_INHERITANCE_CHAIN (expr) = stream_read_tree (ib, data_in);
+  BINFO_SUBVTT_INDEX (expr) = stream_read_tree (ib, data_in);
+  BINFO_VPTR_INDEX (expr) = stream_read_tree (ib, data_in);
 }
 
 
@@ -866,13 +874,13 @@ lto_input_ts_constructor_tree_pointers (struct lto_input_block *ib,
 {
   unsigned i, len;
 
-  len = lto_input_uleb128 (ib);
+  len = streamer_read_uhwi (ib);
   for (i = 0; i < len; i++)
     {
       tree index, value;
 
-      index = lto_input_tree (ib, data_in);
-      value = lto_input_tree (ib, data_in);
+      index = stream_read_tree (ib, data_in);
+      value = stream_read_tree (ib, data_in);
       CONSTRUCTOR_APPEND_ELT (CONSTRUCTOR_ELTS (expr), index, value);
     }
 }
@@ -887,7 +895,7 @@ lto_input_ts_target_option (struct lto_input_block *ib, tree expr)
   struct bitpack_d bp;
   struct cl_target_option *t = TREE_TARGET_OPTION (expr);
 
-  bp = lto_input_bitpack (ib);
+  bp = streamer_read_bitpack (ib);
   len = sizeof (struct cl_target_option);
   for (i = 0; i < len; i++)
     ((unsigned char *)t)[i] = bp_unpack_value (&bp, 8);
@@ -895,6 +903,23 @@ lto_input_ts_target_option (struct lto_input_block *ib, tree expr)
     fatal_error ("cl_target_option size mismatch in LTO reader and writer");
 }
 
+/* Input a TS_OPTIMIZATION tree from IB into EXPR.  */
+
+static void
+lto_input_ts_optimization (struct lto_input_block *ib, tree expr)
+{
+  unsigned i, len;
+  struct bitpack_d bp;
+  struct cl_optimization *t = TREE_OPTIMIZATION (expr);
+
+  bp = streamer_read_bitpack (ib);
+  len = sizeof (struct cl_optimization);
+  for (i = 0; i < len; i++)
+    ((unsigned char *)t)[i] = bp_unpack_value (&bp, 8);
+  if (bp_unpack_value (&bp, 32) != 0x12345678)
+    fatal_error ("cl_optimization size mismatch in LTO reader and writer");
+}
+
 /* Input a TS_TRANSLATION_UNIT_DECL tree from IB and DATA_IN into EXPR.  */
 
 static void
@@ -902,16 +927,15 @@ lto_input_ts_translation_unit_decl_tree_pointers (struct lto_input_block *ib,
                                                  struct data_in *data_in,
                                                  tree expr)
 {
-  TRANSLATION_UNIT_LANGUAGE (expr) = xstrdup (lto_input_string (data_in, ib));
+  TRANSLATION_UNIT_LANGUAGE (expr) = xstrdup (streamer_read_string (data_in, ib));
   VEC_safe_push (tree, gc, all_translation_units, expr);
 }
 
-/* Helper for lto_input_tree.  Read all pointer fields in EXPR from
-   input block IB.  DATA_IN contains tables and descriptors for the
-   file being read.  */
+/* Read all pointer fields in EXPR from input block IB.  DATA_IN
+   contains tables and descriptors for the file being read.  */
 
-static void
-lto_input_tree_pointers (struct lto_input_block *ib, struct data_in *data_in,
+void
+streamer_read_tree_body (struct lto_input_block *ib, struct data_in *data_in,
                         tree expr)
 {
   enum tree_code code;
@@ -972,60 +996,28 @@ lto_input_tree_pointers (struct lto_input_block *ib, struct data_in *data_in,
   if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
     lto_input_ts_target_option (ib, expr);
 
+  if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
+    lto_input_ts_optimization (ib, expr);
+
   if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
     lto_input_ts_translation_unit_decl_tree_pointers (ib, data_in, expr);
 }
 
 
-/* Read the physical representation of a tree node with tag TAG from
-   input block IB using the per-file context in DATA_IN.  */
-
-static tree
-lto_read_tree (struct lto_input_block *ib, struct data_in *data_in,
-              enum LTO_tags tag)
-{
-  tree result;
-
-  result = lto_materialize_tree (ib, data_in, tag);
-
-  /* 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));
-
-  /* end_marker = */ lto_input_1_unsigned (ib);
-
-#ifdef LTO_STREAMER_DEBUG
-  /* Remove the mapping to RESULT's original address set by
-     lto_materialize_tree.  */
-  lto_orig_address_remove (result);
-#endif
-
-  return result;
-}
-
-
 /* Read and INTEGER_CST node from input block IB using the per-file
    context in DATA_IN.  */
 
-static tree
-lto_input_integer_cst (struct lto_input_block *ib, struct data_in *data_in)
+tree
+streamer_read_integer_cst (struct lto_input_block *ib, struct data_in *data_in)
 {
   tree result, type;
   HOST_WIDE_INT low, high;
   bool overflow_p;
 
-  type = lto_input_tree (ib, data_in);
-  overflow_p = (lto_input_1_unsigned (ib) != 0);
-  low = lto_input_uleb128 (ib);
-  high = lto_input_uleb128 (ib);
+  type = stream_read_tree (ib, data_in);
+  overflow_p = (streamer_read_uchar (ib) != 0);
+  low = streamer_read_uhwi (ib);
+  high = streamer_read_uhwi (ib);
   result = build_int_cst_wide (type, low, high);
 
   /* If the original constant had overflown, build a replica of RESULT to
@@ -1043,17 +1035,17 @@ lto_input_integer_cst (struct lto_input_block *ib, struct data_in *data_in)
 /* Read an index IX from input block IB and return the tree node at
    DATA_IN->FILE_DATA->GLOBALS_INDEX[IX].  */
 
-static tree
-lto_get_pickled_tree (struct lto_input_block *ib, struct data_in *data_in)
+tree
+streamer_get_pickled_tree (struct lto_input_block *ib, struct data_in *data_in)
 {
   unsigned HOST_WIDE_INT ix;
   tree result;
   enum LTO_tags expected_tag;
 
-  ix = lto_input_uleb128 (ib);
-  expected_tag = lto_input_enum (ib, LTO_tags, LTO_NUM_TAGS);
+  ix = streamer_read_uhwi (ib);
+  expected_tag = streamer_read_enum (ib, LTO_tags, LTO_NUM_TAGS);
 
-  result = lto_streamer_cache_get (data_in->reader_cache, ix);
+  result = streamer_tree_cache_get (data_in->reader_cache, ix);
   gcc_assert (result
               && TREE_CODE (result) == lto_tag_to_tree_code (expected_tag));
 
@@ -1062,26 +1054,26 @@ lto_get_pickled_tree (struct lto_input_block *ib, struct data_in *data_in)
 
 
 /* Read a code and class from input block IB and return the
-   corresponding builtin.  DATA_IN is as in lto_input_tree.  */
+   corresponding builtin.  DATA_IN is as in stream_read_tree.  */
 
-static tree
-lto_get_builtin_tree (struct lto_input_block *ib, struct data_in *data_in)
+tree
+streamer_get_builtin_tree (struct lto_input_block *ib, struct data_in *data_in)
 {
   enum built_in_class fclass;
   enum built_in_function fcode;
   const char *asmname;
   tree result;
 
-  fclass = lto_input_enum (ib, built_in_class, BUILT_IN_LAST);
+  fclass = streamer_read_enum (ib, built_in_class, BUILT_IN_LAST);
   gcc_assert (fclass == BUILT_IN_NORMAL || fclass == BUILT_IN_MD);
 
-  fcode = (enum built_in_function) lto_input_uleb128 (ib);
+  fcode = (enum built_in_function) streamer_read_uhwi (ib);
 
   if (fclass == BUILT_IN_NORMAL)
     {
       if (fcode >= END_BUILTINS)
        fatal_error ("machine independent builtin code out of range");
-      result = built_in_decls[fcode];
+      result = builtin_decl_explicit (fcode);
       gcc_assert (result);
     }
   else if (fclass == BUILT_IN_MD)
@@ -1093,61 +1085,11 @@ lto_get_builtin_tree (struct lto_input_block *ib, struct data_in *data_in)
   else
     gcc_unreachable ();
 
-  asmname = lto_input_string (data_in, ib);
+  asmname = streamer_read_string (data_in, ib);
   if (asmname)
     set_builtin_user_assembler_name (result, asmname);
 
-  lto_streamer_cache_append (data_in->reader_cache, result);
-
-  return result;
-}
-
-
-/* Read a tree from input block IB using the per-file context in
-   DATA_IN.  This context is used, for example, to resolve references
-   to previously read nodes.  */
-
-tree
-lto_input_tree (struct lto_input_block *ib, struct data_in *data_in)
-{
-  enum LTO_tags tag;
-  tree result;
-
-  tag = input_record_start (ib);
-  gcc_assert ((unsigned) tag < (unsigned) LTO_NUM_TAGS);
-
-  if (tag == LTO_null)
-    result = NULL_TREE;
-  else if (tag >= LTO_field_decl_ref && tag <= LTO_global_decl_ref)
-    {
-      /* If TAG is a reference to an indexable tree, the next value
-        in IB is the index into the table where we expect to find
-        that tree.  */
-      result = lto_input_tree_ref (ib, data_in, cfun, tag);
-    }
-  else if (tag == LTO_tree_pickle_reference)
-    {
-      /* If TAG is a reference to a previously read tree, look it up in
-        the reader cache.  */
-      result = lto_get_pickled_tree (ib, data_in);
-    }
-  else if (tag == LTO_builtin_decl)
-    {
-      /* If we are going to read a built-in function, all we need is
-        the code and class.  */
-      result = lto_get_builtin_tree (ib, data_in);
-    }
-  else if (tag == lto_tree_code_to_tag (INTEGER_CST))
-    {
-      /* For integer constants we only need the type and its hi/low
-        words.  */
-      result = lto_input_integer_cst (ib, data_in);
-    }
-  else
-    {
-      /* Otherwise, materialize a new node from IB.  */
-      result = lto_read_tree (ib, data_in, tag);
-    }
+  streamer_tree_cache_append (data_in->reader_cache, result);
 
   return result;
 }