/* Routines for reading trees from a file stream.

   Copyright (C) 2011-2020 Free Software Foundation, Inc.
   Contributed by Diego Novillo <dnovillo@google.com>

This file is part of GCC.

GCC is free software; you can redistribute it and/or modify it under
the terms of the GNU General Public License as published by the Free
Software Foundation; either version 3, or (at your option) any later
version.

GCC is distributed in the hope that it will be useful, but WITHOUT ANY
WARRANTY; without even the implied warranty of MERCHANTABILITY or
FITNESS FOR A PARTICULAR PURPOSE.  See the GNU General Public License
for more details.

You should have received a copy of the GNU General Public License
along with GCC; see the file COPYING3.  If not see
<http://www.gnu.org/licenses/>.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "tree.h"
#include "gimple.h"
#include "stringpool.h"
#include "tree-streamer.h"
#include "cgraph.h"
#include "builtins.h"
#include "gomp-constants.h"
#include "stringpool.h"
#include "attribs.h"
#include "asan.h"
#include "opts.h"


/* Read a STRING_CST from the string table in DATA_IN using input
   block IB.  */

tree
streamer_read_string_cst (class data_in *data_in, class lto_input_block *ib)
{
  unsigned int len;
  const char * ptr;

  ptr = streamer_read_indexed_string (data_in, ib, &len);
  if (!ptr)
    return NULL;
  return build_string (len, ptr);
}


/* Read an IDENTIFIER from the string table in DATA_IN using input
   block IB.  */

static tree
input_identifier (class data_in *data_in, class lto_input_block *ib)
{
  unsigned int len;
  const char *ptr;

  ptr = streamer_read_indexed_string (data_in, ib, &len);
  if (!ptr)
    return NULL;
  return get_identifier_with_length (ptr, len);
}


/* Read a chain of tree nodes from input block IB. DATA_IN contains
   tables and descriptors for the file being read.  */

tree
streamer_read_chain (class lto_input_block *ib, class data_in *data_in)
{
  tree first, prev, curr;

  /* The chain is written as NULL terminated list of trees.  */
  first = prev = NULL_TREE;
  do
    {
      curr = stream_read_tree (ib, data_in);
      if (prev)
	TREE_CHAIN (prev) = curr;
      else
	first = curr;

      prev = curr;
    }
  while (curr);

  return first;
}


/* Unpack all the non-pointer fields of the TS_BASE structure of
   expression EXPR from bitpack BP.  */

static inline 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
     streamer_alloc_tree.  */
  if (!TYPE_P (expr))
    {
      TREE_SIDE_EFFECTS (expr) = (unsigned) bp_unpack_value (bp, 1);
      TREE_CONSTANT (expr) = (unsigned) bp_unpack_value (bp, 1);
      TREE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1);

      /* TREE_PUBLIC is used on types to indicate that the type
	 has a TYPE_CACHED_VALUES vector.  This is not streamed out,
	 so we skip it here.  */
      TREE_PUBLIC (expr) = (unsigned) bp_unpack_value (bp, 1);
    }
  else
    bp_unpack_value (bp, 4);
  TREE_ADDRESSABLE (expr) = (unsigned) bp_unpack_value (bp, 1);
  TREE_THIS_VOLATILE (expr) = (unsigned) bp_unpack_value (bp, 1);
  if (DECL_P (expr))
    {
      DECL_UNSIGNED (expr) = (unsigned) bp_unpack_value (bp, 1);
      DECL_NAMELESS (expr) = (unsigned) bp_unpack_value (bp, 1);
    }
  else if (TYPE_P (expr))
    TYPE_UNSIGNED (expr) = (unsigned) bp_unpack_value (bp, 1);
  else
    bp_unpack_value (bp, 1);
  TREE_ASM_WRITTEN (expr) = (unsigned) bp_unpack_value (bp, 1);
  if (TYPE_P (expr))
    TYPE_ARTIFICIAL (expr) = (unsigned) bp_unpack_value (bp, 1);
  else
    TREE_NO_WARNING (expr) = (unsigned) bp_unpack_value (bp, 1);
  TREE_NOTHROW (expr) = (unsigned) bp_unpack_value (bp, 1);
  TREE_STATIC (expr) = (unsigned) bp_unpack_value (bp, 1);
  if (TREE_CODE (expr) != TREE_BINFO)
    TREE_PRIVATE (expr) = (unsigned) bp_unpack_value (bp, 1);
  else
    bp_unpack_value (bp, 1);
  TREE_PROTECTED (expr) = (unsigned) bp_unpack_value (bp, 1);
  TREE_DEPRECATED (expr) = (unsigned) bp_unpack_value (bp, 1);
  if (TYPE_P (expr))
    {
      if (AGGREGATE_TYPE_P (expr))
	TYPE_REVERSE_STORAGE_ORDER (expr) = (unsigned) bp_unpack_value (bp, 1);
      else
	TYPE_SATURATING (expr) = (unsigned) bp_unpack_value (bp, 1);
      TYPE_ADDR_SPACE (expr) = (unsigned) bp_unpack_value (bp, 8);
    }
  else if (TREE_CODE (expr) == BIT_FIELD_REF || TREE_CODE (expr) == MEM_REF)
    {
      REF_REVERSE_STORAGE_ORDER (expr) = (unsigned) bp_unpack_value (bp, 1);
      bp_unpack_value (bp, 8);
    }
  else if (TREE_CODE (expr) == SSA_NAME)
    {
      SSA_NAME_IS_DEFAULT_DEF (expr) = (unsigned) bp_unpack_value (bp, 1);
      bp_unpack_value (bp, 8);
    }
  else if (TREE_CODE (expr) == CALL_EXPR)
    {
      CALL_EXPR_BY_DESCRIPTOR (expr) = (unsigned) bp_unpack_value (bp, 1);
      bp_unpack_value (bp, 8);
    }
  else
    bp_unpack_value (bp, 9);
}


/* Unpack all the non-pointer fields of the TS_INT_CST structure of
   expression EXPR from bitpack BP.  */

static void
unpack_ts_int_cst_value_fields (struct bitpack_d *bp, tree expr)
{
  int i;
  for (i = 0; i < TREE_INT_CST_EXT_NUNITS (expr); i++)
    TREE_INT_CST_ELT (expr, i) = bp_unpack_var_len_int (bp);
}


/* Unpack all the non-pointer fields of the TS_REAL_CST structure of
   expression EXPR from bitpack BP.  */

static void
unpack_ts_real_cst_value_fields (struct bitpack_d *bp, tree expr)
{
  unsigned i;
  REAL_VALUE_TYPE r;
  REAL_VALUE_TYPE *rp;

  /* Clear all bits of the real value type so that we can later do
     bitwise comparisons to see if two values are the same.  */
  memset (&r, 0, sizeof r);
  r.cl = (unsigned) bp_unpack_value (bp, 2);
  r.decimal = (unsigned) bp_unpack_value (bp, 1);
  r.sign = (unsigned) bp_unpack_value (bp, 1);
  r.signalling = (unsigned) bp_unpack_value (bp, 1);
  r.canonical = (unsigned) bp_unpack_value (bp, 1);
  r.uexp = (unsigned) bp_unpack_value (bp, EXP_BITS);
  for (i = 0; i < SIGSZ; i++)
    r.sig[i] = (unsigned long) bp_unpack_value (bp, HOST_BITS_PER_LONG);

  rp = ggc_alloc<real_value> ();
  memcpy (rp, &r, sizeof (REAL_VALUE_TYPE));
  TREE_REAL_CST_PTR (expr) = rp;
}


/* Unpack all the non-pointer fields of the TS_FIXED_CST structure of
   expression EXPR from bitpack BP.  */

static void
unpack_ts_fixed_cst_value_fields (struct bitpack_d *bp, tree expr)
{
  FIXED_VALUE_TYPE *fp = ggc_alloc<fixed_value> ();
  fp->mode = as_a <scalar_mode> (bp_unpack_machine_mode (bp));
  fp->data.low = bp_unpack_var_len_int (bp);
  fp->data.high = bp_unpack_var_len_int (bp);
  TREE_FIXED_CST_PTR (expr) = fp;
}

/* Unpack all the non-pointer fields of the TS_DECL_COMMON structure
   of expression EXPR from bitpack BP.  */

static void
unpack_ts_decl_common_value_fields (struct bitpack_d *bp, tree expr)
{
  SET_DECL_MODE (expr, bp_unpack_machine_mode (bp));
  DECL_NONLOCAL (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_VIRTUAL_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_IGNORED_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_ABSTRACT_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_ARTIFICIAL (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_PRESERVE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_EXTERNAL (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_GIMPLE_REG_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  SET_DECL_ALIGN (expr, (unsigned) bp_unpack_var_len_unsigned (bp));
#ifdef ACCEL_COMPILER
  if (DECL_ALIGN (expr) > targetm.absolute_biggest_alignment)
    SET_DECL_ALIGN (expr, targetm.absolute_biggest_alignment);
#endif
  if (TREE_CODE (expr) == LABEL_DECL)
    {
      EH_LANDING_PAD_NR (expr) = (int) bp_unpack_var_len_unsigned (bp);

      /* Always assume an initial value of -1 for LABEL_DECL_UID to
	 force gimple_set_bb to recreate label_to_block_map.  */
      LABEL_DECL_UID (expr) = -1;
    }

  else if (TREE_CODE (expr) == FIELD_DECL)
    {
      DECL_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1);
      DECL_NONADDRESSABLE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
      DECL_PADDING_P (expr) = (unsigned) bp_unpack_value (bp, 1);
      DECL_FIELD_ABI_IGNORED (expr) = (unsigned) bp_unpack_value (bp, 1);
      expr->decl_common.off_align = bp_unpack_value (bp, 8);
    }

  else if (VAR_P (expr))
    {
      DECL_HAS_DEBUG_EXPR_P (expr) = (unsigned) bp_unpack_value (bp, 1);
      DECL_NONLOCAL_FRAME (expr) = (unsigned) bp_unpack_value (bp, 1);
    }

  else if (TREE_CODE (expr) == PARM_DECL)
    DECL_HIDDEN_STRING_LENGTH (expr) = (unsigned) bp_unpack_value (bp, 1);

  if (TREE_CODE (expr) == RESULT_DECL
      || TREE_CODE (expr) == PARM_DECL
      || VAR_P (expr))
    {
      DECL_BY_REFERENCE (expr) = (unsigned) bp_unpack_value (bp, 1);
      if (VAR_P (expr) || TREE_CODE (expr) == PARM_DECL)
	DECL_HAS_VALUE_EXPR_P (expr) = (unsigned) bp_unpack_value (bp, 1);
    }
}


/* Unpack all the non-pointer fields of the TS_DECL_WRTL structure
   of expression EXPR from bitpack BP.  */

static void
unpack_ts_decl_wrtl_value_fields (struct bitpack_d *bp, tree expr)
{
  DECL_REGISTER (expr) = (unsigned) bp_unpack_value (bp, 1);
}


/* Unpack all the non-pointer fields of the TS_DECL_WITH_VIS structure
   of expression EXPR from bitpack BP.  */

static void
unpack_ts_decl_with_vis_value_fields (struct bitpack_d *bp, tree expr)
{
  DECL_COMMON (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_DLLIMPORT_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_WEAK (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_SEEN_IN_BIND_EXPR_P (expr) = (unsigned) bp_unpack_value (bp,  1);
  DECL_COMDAT (expr) = (unsigned) bp_unpack_value (bp,  1);
  DECL_VISIBILITY (expr) = (enum symbol_visibility) bp_unpack_value (bp,  2);
  DECL_VISIBILITY_SPECIFIED (expr) = (unsigned) bp_unpack_value (bp,  1);

  if (VAR_P (expr))
    {
      DECL_HARD_REGISTER (expr) = (unsigned) bp_unpack_value (bp, 1);
      DECL_IN_CONSTANT_POOL (expr) = (unsigned) bp_unpack_value (bp, 1);
    }

  if (TREE_CODE (expr) == FUNCTION_DECL)
    {
      DECL_FINAL_P (expr) = (unsigned) bp_unpack_value (bp, 1);
      DECL_CXX_CONSTRUCTOR_P (expr) = (unsigned) bp_unpack_value (bp, 1);
      DECL_CXX_DESTRUCTOR_P (expr) = (unsigned) bp_unpack_value (bp, 1);
    }
}


/* Unpack all the non-pointer fields of the TS_FUNCTION_DECL structure
   of expression EXPR from bitpack BP.  */

static void
unpack_ts_function_decl_value_fields (struct bitpack_d *bp, tree expr)
{
  built_in_class cl = bp_unpack_enum (bp, built_in_class, BUILT_IN_LAST);
  DECL_STATIC_CONSTRUCTOR (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_STATIC_DESTRUCTOR (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_UNINLINABLE (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_POSSIBLY_INLINED (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_IS_NOVOPS (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_IS_RETURNS_TWICE (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_IS_MALLOC (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_SET_IS_OPERATOR_NEW (expr, (unsigned) bp_unpack_value (bp, 1));
  DECL_SET_IS_OPERATOR_DELETE (expr, (unsigned) bp_unpack_value (bp, 1));
  DECL_DECLARED_INLINE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_STATIC_CHAIN (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_NO_INLINE_WARNING_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT (expr)
    			= (unsigned) bp_unpack_value (bp, 1);
  DECL_NO_LIMIT_STACK (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_DISREGARD_INLINE_LIMITS (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_LOOPING_CONST_OR_PURE_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  DECL_IS_REPLACEABLE_OPERATOR (expr) = (unsigned) bp_unpack_value (bp, 1);
  unsigned int fcode = 0;
  if (cl != NOT_BUILT_IN)
    {
      fcode = bp_unpack_value (bp, 32);
      if (cl == BUILT_IN_NORMAL && fcode >= END_BUILTINS)
	fatal_error (input_location,
		     "machine independent builtin code out of range");
      else if (cl == BUILT_IN_MD)
	{
          tree result = targetm.builtin_decl (fcode, true);
	  if (!result || result == error_mark_node)
	    fatal_error (input_location,
			 "target specific builtin not available");
	}
    }
  set_decl_built_in_function (expr, cl, fcode);
}


/* Unpack all the non-pointer fields of the TS_TYPE_COMMON structure
   of expression EXPR from bitpack BP.  */

static void
unpack_ts_type_common_value_fields (struct bitpack_d *bp, tree expr)
{
  machine_mode mode;

  mode = bp_unpack_machine_mode (bp);
  SET_TYPE_MODE (expr, mode);
  /* TYPE_NO_FORCE_BLK is private to stor-layout and need
     no streaming.  */
  TYPE_PACKED (expr) = (unsigned) bp_unpack_value (bp, 1);
  TYPE_RESTRICT (expr) = (unsigned) bp_unpack_value (bp, 1);
  TYPE_USER_ALIGN (expr) = (unsigned) bp_unpack_value (bp, 1);
  TYPE_READONLY (expr) = (unsigned) bp_unpack_value (bp, 1);
  TYPE_LANG_FLAG_0 (expr) = (unsigned) bp_unpack_value (bp, 1);
  if (RECORD_OR_UNION_TYPE_P (expr))
    {
      TYPE_TRANSPARENT_AGGR (expr) = (unsigned) bp_unpack_value (bp, 1);
      TYPE_FINAL_P (expr) = (unsigned) bp_unpack_value (bp, 1);
      TYPE_CXX_ODR_P (expr) = (unsigned) bp_unpack_value (bp, 1);
    }
  else if (TREE_CODE (expr) == ARRAY_TYPE)
    TYPE_NONALIASED_COMPONENT (expr) = (unsigned) bp_unpack_value (bp, 1);
  if (TREE_CODE (expr) == ARRAY_TYPE || TREE_CODE (expr) == INTEGER_TYPE)
    TYPE_STRING_FLAG (expr) = (unsigned) bp_unpack_value (bp, 1);
  if (AGGREGATE_TYPE_P (expr))
    TYPE_TYPELESS_STORAGE (expr) = (unsigned) bp_unpack_value (bp, 1);
  TYPE_EMPTY_P (expr) = (unsigned) bp_unpack_value (bp, 1);
  TYPE_PRECISION (expr) = bp_unpack_var_len_unsigned (bp);
  SET_TYPE_ALIGN (expr, bp_unpack_var_len_unsigned (bp));
#ifdef ACCEL_COMPILER
  if (TYPE_ALIGN (expr) > targetm.absolute_biggest_alignment)
    SET_TYPE_ALIGN (expr, targetm.absolute_biggest_alignment);
#endif
}


/* Unpack all the non-pointer fields of the TS_BLOCK structure
   of expression EXPR from bitpack BP.  */

static void
unpack_ts_block_value_fields (class data_in *data_in,
			      struct bitpack_d *bp, tree expr)
{
  /* BLOCK_NUMBER is recomputed.  */
  stream_input_location (&BLOCK_SOURCE_LOCATION (expr), bp, data_in);
}

/* Unpack all the non-pointer fields of the TS_TRANSLATION_UNIT_DECL
   structure of expression EXPR from bitpack BP.  */

static void
unpack_ts_translation_unit_decl_value_fields (class data_in *data_in,
					      struct bitpack_d *bp, tree expr)
{
  TRANSLATION_UNIT_LANGUAGE (expr) = xstrdup (bp_unpack_string (data_in, bp));
  vec_safe_push (all_translation_units, expr);
}


/* Unpack all the non-pointer fields of the TS_OMP_CLAUSE
   structure of expression EXPR from bitpack BP.  */

static void
unpack_ts_omp_clause_value_fields (class data_in *data_in,
				   struct bitpack_d *bp, tree expr)
{
  stream_input_location (&OMP_CLAUSE_LOCATION (expr), bp, data_in);
  switch (OMP_CLAUSE_CODE (expr))
    {
    case OMP_CLAUSE_DEFAULT:
      OMP_CLAUSE_DEFAULT_KIND (expr)
	= bp_unpack_enum (bp, omp_clause_default_kind,
			  OMP_CLAUSE_DEFAULT_LAST);
      break;
    case OMP_CLAUSE_SCHEDULE:
      OMP_CLAUSE_SCHEDULE_KIND (expr)
	= bp_unpack_enum (bp, omp_clause_schedule_kind,
			  OMP_CLAUSE_SCHEDULE_LAST);
      break;
    case OMP_CLAUSE_DEPEND:
      OMP_CLAUSE_DEPEND_KIND (expr)
	= bp_unpack_enum (bp, omp_clause_depend_kind, OMP_CLAUSE_DEPEND_LAST);
      break;
    case OMP_CLAUSE_MAP:
      OMP_CLAUSE_SET_MAP_KIND (expr, bp_unpack_enum (bp, gomp_map_kind,
						     GOMP_MAP_LAST));
      break;
    case OMP_CLAUSE_PROC_BIND:
      OMP_CLAUSE_PROC_BIND_KIND (expr)
	= bp_unpack_enum (bp, omp_clause_proc_bind_kind,
			  OMP_CLAUSE_PROC_BIND_LAST);
      break;
    case OMP_CLAUSE_REDUCTION:
    case OMP_CLAUSE_TASK_REDUCTION:
    case OMP_CLAUSE_IN_REDUCTION:
      OMP_CLAUSE_REDUCTION_CODE (expr)
	= bp_unpack_enum (bp, tree_code, MAX_TREE_CODES);
      break;
    default:
      break;
    }
}


/* 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.  */

void
streamer_read_tree_bitfields (class lto_input_block *ib,
			      class data_in *data_in, 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.  */
  if (streamer_debugging)
    {
      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)));
    }
  code = TREE_CODE (expr);

  /* Note that all these functions are highly sensitive to changes in
     the types and sizes of each of the fields being packed.  */
  unpack_ts_base_value_fields (&bp, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
    unpack_ts_int_cst_value_fields (&bp, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST))
    unpack_ts_real_cst_value_fields (&bp, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST))
    unpack_ts_fixed_cst_value_fields (&bp, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
    stream_input_location (&DECL_SOURCE_LOCATION (expr), &bp, data_in);

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
    unpack_ts_decl_common_value_fields (&bp, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL))
    unpack_ts_decl_wrtl_value_fields (&bp, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
    unpack_ts_decl_with_vis_value_fields (&bp, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
    unpack_ts_function_decl_value_fields (&bp, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
    unpack_ts_type_common_value_fields (&bp, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_EXP))
    {
      stream_input_location (&EXPR_CHECK (expr)->exp.locus, &bp, data_in);
      if (code == MEM_REF
	  || code == TARGET_MEM_REF)
	{
	  MR_DEPENDENCE_CLIQUE (expr)
	    = (unsigned)bp_unpack_value (&bp, sizeof (short) * 8);
	  if (MR_DEPENDENCE_CLIQUE (expr) != 0)
	    MR_DEPENDENCE_BASE (expr)
	      = (unsigned)bp_unpack_value (&bp, sizeof (short) * 8);
	}
      else if (code == CALL_EXPR)
	CALL_EXPR_IFN (expr) = bp_unpack_enum (&bp, internal_fn, IFN_LAST);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
    unpack_ts_block_value_fields (data_in, &bp, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
    unpack_ts_translation_unit_decl_value_fields (data_in, &bp, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
    cl_optimization_stream_in (data_in, &bp, TREE_OPTIMIZATION (expr));

  if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
    {
      unsigned HOST_WIDE_INT length = bp_unpack_var_len_unsigned (&bp);
      if (length > 0)
	vec_safe_grow (CONSTRUCTOR_ELTS (expr), length);
    }

#ifndef ACCEL_COMPILER
  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
    {
      cl_target_option_stream_in (data_in, &bp, TREE_TARGET_OPTION (expr));
      if (targetm.target_option.post_stream_in)
	targetm.target_option.post_stream_in (TREE_TARGET_OPTION (expr));
    }
#endif

  if (code == OMP_CLAUSE)
    unpack_ts_omp_clause_value_fields (data_in, &bp, expr);
}


/* Materialize a new tree from input block IB using descriptors in
   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.  */

tree
streamer_alloc_tree (class lto_input_block *ib, class data_in *data_in,
		     enum LTO_tags tag)
{
  enum tree_code code;
  tree result;

  result = NULL_TREE;

  code = lto_tag_to_tree_code (tag);

  /* We should never see an SSA_NAME tree.  Only the version numbers of
     SSA names are ever written out.  See input_ssa_names.  */
  gcc_assert (code != SSA_NAME);

  /* Instantiate a new tree using the header data.  */
  if (CODE_CONTAINS_STRUCT (code, TS_STRING))
    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 = streamer_read_hwi (ib);
      result = make_tree_vec (len);
    }
  else if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
    {
      bitpack_d bp = streamer_read_bitpack (ib);
      unsigned int log2_npatterns = bp_unpack_value (&bp, 8);
      unsigned int nelts_per_pattern = bp_unpack_value (&bp, 8);
      result = make_vector (log2_npatterns, nelts_per_pattern);
    }
  else if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
    {
      unsigned HOST_WIDE_INT len = streamer_read_uhwi (ib);
      result = make_tree_binfo (len);
    }
  else if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
    {
      unsigned HOST_WIDE_INT len = streamer_read_uhwi (ib);
      unsigned HOST_WIDE_INT ext_len = streamer_read_uhwi (ib);
      result = make_int_cst (len, ext_len);
    }
  else if (code == CALL_EXPR)
    {
      unsigned HOST_WIDE_INT nargs = streamer_read_uhwi (ib);
      return build_vl_exp (CALL_EXPR, nargs + 3);
    }
  else if (code == OMP_CLAUSE)
    {
      enum omp_clause_code subcode
	= (enum omp_clause_code) streamer_read_uhwi (ib);
      return build_omp_clause (UNKNOWN_LOCATION, subcode);
    }
  else
    {
      /* For all other nodes, materialize the tree with a raw
	 make_node call.  */
      result = make_node (code);
    }

  return result;
}


/* Read all pointer fields in the TS_COMMON structure of EXPR from input
   block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */


static void
lto_input_ts_common_tree_pointers (class lto_input_block *ib,
				   class data_in *data_in, tree expr)
{
  if (TREE_CODE (expr) != IDENTIFIER_NODE)
    TREE_TYPE (expr) = stream_read_tree (ib, data_in);
}


/* Read all pointer fields in the TS_VECTOR structure of EXPR from input
   block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_vector_tree_pointers (class lto_input_block *ib,
				   class data_in *data_in, tree expr)
{
  unsigned int count = vector_cst_encoded_nelts (expr);
  for (unsigned int i = 0; i < count; ++i)
    VECTOR_CST_ENCODED_ELT (expr, i) = stream_read_tree (ib, data_in);
}


/* Read all pointer fields in the TS_POLY_INT_CST structure of EXPR from
   input block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_poly_tree_pointers (class lto_input_block *ib,
				 class data_in *data_in, tree expr)
{
  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    POLY_INT_CST_COEFF (expr, i) = stream_read_tree (ib, data_in);
}


/* Read all pointer fields in the TS_COMPLEX structure of EXPR from input
   block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_complex_tree_pointers (class lto_input_block *ib,
				    class data_in *data_in, tree expr)
{
  TREE_REALPART (expr) = stream_read_tree (ib, data_in);
  TREE_IMAGPART (expr) = stream_read_tree (ib, data_in);
}


/* Read all pointer fields in the TS_DECL_MINIMAL structure of EXPR
   from input block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_decl_minimal_tree_pointers (class lto_input_block *ib,
					 class data_in *data_in, tree expr)
{
  DECL_NAME (expr) = stream_read_tree (ib, data_in);
  DECL_CONTEXT (expr) = stream_read_tree (ib, data_in);
}


/* Read all pointer fields in the TS_DECL_COMMON structure of EXPR from
   input block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_decl_common_tree_pointers (class lto_input_block *ib,
					class data_in *data_in, tree expr)
{
  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);
  DECL_ABSTRACT_ORIGIN (expr) = stream_read_tree (ib, data_in);

  if ((VAR_P (expr) || TREE_CODE (expr) == PARM_DECL)
      && DECL_HAS_VALUE_EXPR_P (expr))
    SET_DECL_VALUE_EXPR (expr, stream_read_tree (ib, data_in));

  if (VAR_P (expr)
      && DECL_HAS_DEBUG_EXPR_P (expr))
    {
      tree dexpr = stream_read_tree (ib, data_in);
      if (dexpr)
	SET_DECL_DEBUG_EXPR (expr, dexpr);
    }
}


/* Read all pointer fields in the TS_DECL_NON_COMMON structure of
   EXPR from input block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_decl_non_common_tree_pointers (class lto_input_block *,
					    class data_in *, tree)
{
}


/* Read all pointer fields in the TS_DECL_WITH_VIS structure of EXPR
   from input block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_decl_with_vis_tree_pointers (class lto_input_block *ib,
				          class data_in *data_in, tree expr)
{
  tree id;

  id = stream_read_tree (ib, data_in);
  if (id)
    {
      gcc_assert (TREE_CODE (id) == IDENTIFIER_NODE);
      SET_DECL_ASSEMBLER_NAME (expr, id);
    }
}


/* Read all pointer fields in the TS_FIELD_DECL structure of EXPR from
   input block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_field_decl_tree_pointers (class lto_input_block *ib,
				       class data_in *data_in, tree expr)
{
  DECL_FIELD_OFFSET (expr) = stream_read_tree (ib, data_in);
  DECL_BIT_FIELD_TYPE (expr) = stream_read_tree (ib, data_in);
  DECL_BIT_FIELD_REPRESENTATIVE (expr) = stream_read_tree (ib, data_in);
  DECL_FIELD_BIT_OFFSET (expr) = stream_read_tree (ib, data_in);
}


/* Read all pointer fields in the TS_FUNCTION_DECL structure of EXPR
   from input block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_function_decl_tree_pointers (class lto_input_block *ib,
					  class data_in *data_in, tree expr)
{
  /* DECL_STRUCT_FUNCTION is loaded on demand by cgraph_get_body.  */
  DECL_FUNCTION_PERSONALITY (expr) = stream_read_tree (ib, data_in);
#ifndef ACCEL_COMPILER
  DECL_FUNCTION_SPECIFIC_TARGET (expr) = stream_read_tree (ib, data_in);
#endif
  DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr) = stream_read_tree (ib, data_in);
#ifdef ACCEL_COMPILER
  {
    tree opts = DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr);
    if (opts)
      {
	struct gcc_options tmp;
	init_options_struct (&tmp, NULL);
	cl_optimization_restore (&tmp, TREE_OPTIMIZATION (opts));
	finish_options (&tmp, &global_options_set, UNKNOWN_LOCATION);
	opts = build_optimization_node (&tmp);
	DECL_FUNCTION_SPECIFIC_OPTIMIZATION (expr) = opts;
      }
  }
#endif
}


/* Read all pointer fields in the TS_TYPE_COMMON structure of EXPR from
   input block IB.  DATA_IN contains tables and descriptors for the file
   being read.  */

static void
lto_input_ts_type_common_tree_pointers (class lto_input_block *ib,
					class data_in *data_in, tree expr)
{
  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) = 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;
}

/* Read all pointer fields in the TS_TYPE_NON_COMMON structure of EXPR
   from input block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_type_non_common_tree_pointers (class lto_input_block *ib,
					    class data_in *data_in,
					    tree expr)
{
  if (TREE_CODE (expr) == ARRAY_TYPE)
    TYPE_DOMAIN (expr) = stream_read_tree (ib, data_in);
  else if (RECORD_OR_UNION_TYPE_P (expr))
    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) = stream_read_tree (ib, data_in);

  if (!POINTER_TYPE_P (expr))
    TYPE_MIN_VALUE_RAW (expr) = stream_read_tree (ib, data_in);
  TYPE_MAX_VALUE_RAW (expr) = stream_read_tree (ib, data_in);
}


/* Read all pointer fields in the TS_LIST structure of EXPR from input
   block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_list_tree_pointers (class lto_input_block *ib,
				 class data_in *data_in, tree expr)
{
  TREE_PURPOSE (expr) = stream_read_tree (ib, data_in);
  TREE_VALUE (expr) = stream_read_tree (ib, data_in);
  TREE_CHAIN (expr) = stream_read_tree (ib, data_in);
}


/* Read all pointer fields in the TS_VEC structure of EXPR from input
   block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_vec_tree_pointers (class lto_input_block *ib,
				class data_in *data_in, tree expr)
{
  int i;

  /* 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) = stream_read_tree (ib, data_in);
}


/* Read all pointer fields in the TS_EXP structure of EXPR from input
   block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */


static void
lto_input_ts_exp_tree_pointers (class lto_input_block *ib,
			        class data_in *data_in, tree expr)
{
  int i;
  tree block;

  for (i = 0; i < TREE_OPERAND_LENGTH (expr); i++)
    TREE_OPERAND (expr, i) = stream_read_tree (ib, data_in);

  block = stream_read_tree (ib, data_in);

  /* TODO: Block is stored in the locus information.  It may make more sense to
     to make it go via the location cache.  */
  if (block)
    {
      data_in->location_cache.apply_location_cache ();
      TREE_SET_BLOCK (expr, block);
    }
}


/* Read all pointer fields in the TS_BLOCK structure of EXPR from input
   block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_block_tree_pointers (class lto_input_block *ib,
				  class data_in *data_in, tree expr)
{
  BLOCK_VARS (expr) = streamer_read_chain (ib, data_in);

  BLOCK_SUPERCONTEXT (expr) = stream_read_tree (ib, data_in);
  BLOCK_ABSTRACT_ORIGIN (expr) = stream_read_tree (ib, data_in);
  /* We may end up prevailing a decl with DECL_ORIGIN (t) != t here
     which breaks the invariant that BLOCK_ABSTRACT_ORIGIN is the
     ultimate origin.  Fixup here.
     ???  This should get fixed with moving to DIE references.  */
  if (DECL_P (BLOCK_ORIGIN (expr)))
    BLOCK_ABSTRACT_ORIGIN (expr) = DECL_ORIGIN (BLOCK_ABSTRACT_ORIGIN (expr));
  /* Do not stream BLOCK_NONLOCALIZED_VARS.  We cannot handle debug information
     for early inlined BLOCKs so drop it on the floor instead of ICEing in
     dwarf2out.c.  */

  /* BLOCK_FRAGMENT_ORIGIN and BLOCK_FRAGMENT_CHAIN is not live at LTO
     streaming time.  */

  /* We re-compute BLOCK_SUBBLOCKS of our parent here instead
     of streaming it.  For non-BLOCK BLOCK_SUPERCONTEXTs we still
     stream the child relationship explicitly.  */
  if (BLOCK_SUPERCONTEXT (expr)
      && TREE_CODE (BLOCK_SUPERCONTEXT (expr)) == BLOCK)
    {
      BLOCK_CHAIN (expr) = BLOCK_SUBBLOCKS (BLOCK_SUPERCONTEXT (expr));
      BLOCK_SUBBLOCKS (BLOCK_SUPERCONTEXT (expr)) = expr;
    }

  /* The global block is rooted at the TU decl.  Hook it here to
     avoid the need to stream in this block during WPA time.  */
  else if (BLOCK_SUPERCONTEXT (expr)
	   && TREE_CODE (BLOCK_SUPERCONTEXT (expr)) == TRANSLATION_UNIT_DECL)
    DECL_INITIAL (BLOCK_SUPERCONTEXT (expr)) = expr;

  /* The function-level block is connected at the time we read in
     function bodies for the same reason.  */
}


/* Read all pointer fields in the TS_BINFO structure of EXPR from input
   block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_binfo_tree_pointers (class lto_input_block *ib,
				  class data_in *data_in, tree expr)
{
  tree t;

  /* Note that the number of slots in EXPR was read in
     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 = stream_read_tree (ib, data_in);
      if (t)
	BINFO_BASE_BINFOS (expr)->quick_push (t);
    }
  while (t);

  BINFO_OFFSET (expr) = stream_read_tree (ib, data_in);
  BINFO_VTABLE (expr) = stream_read_tree (ib, data_in);

  /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX,
     BINFO_BASE_ACCESSES and BINFO_VPTR_INDEX; these are used by C++ FE
     only.  */
}


/* Read all pointer fields in the TS_CONSTRUCTOR structure of EXPR from
   input block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_constructor_tree_pointers (class lto_input_block *ib,
				        class data_in *data_in, tree expr)
{
  unsigned i;

  for (i = 0; i < CONSTRUCTOR_NELTS (expr); i++)
    {
      constructor_elt e;
      e.index = stream_read_tree (ib, data_in);
      e.value = stream_read_tree (ib, data_in);
      (*CONSTRUCTOR_ELTS (expr))[i] = e;
    }
}


/* Read all pointer fields in the TS_OMP_CLAUSE structure of EXPR from
   input block IB.  DATA_IN contains tables and descriptors for the
   file being read.  */

static void
lto_input_ts_omp_clause_tree_pointers (class lto_input_block *ib,
				       class data_in *data_in, tree expr)
{
  int i;

  for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (expr)]; i++)
    OMP_CLAUSE_OPERAND (expr, i) = stream_read_tree (ib, data_in);
  OMP_CLAUSE_CHAIN (expr) = stream_read_tree (ib, data_in);
}


/* Read all pointer fields in EXPR from input block IB.  DATA_IN
   contains tables and descriptors for the file being read.  */

void
streamer_read_tree_body (class lto_input_block *ib, class data_in *data_in,
			 tree expr)
{
  enum tree_code code;

  code = TREE_CODE (expr);

  if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
    lto_input_ts_common_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
    lto_input_ts_vector_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_POLY_INT_CST))
    lto_input_ts_poly_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_COMPLEX))
    lto_input_ts_complex_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
    lto_input_ts_decl_minimal_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
    lto_input_ts_decl_common_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
    lto_input_ts_decl_non_common_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
    lto_input_ts_decl_with_vis_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
    lto_input_ts_field_decl_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
    lto_input_ts_function_decl_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
    lto_input_ts_type_common_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_NON_COMMON))
    lto_input_ts_type_non_common_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_LIST))
    lto_input_ts_list_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_VEC))
    lto_input_ts_vec_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_EXP))
    lto_input_ts_exp_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
    lto_input_ts_block_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
    lto_input_ts_binfo_tree_pointers (ib, data_in, expr);

  if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
    lto_input_ts_constructor_tree_pointers (ib, data_in, expr);

  if (code == OMP_CLAUSE)
    lto_input_ts_omp_clause_tree_pointers (ib, data_in, expr);
}


/* Read an index IX from input block IB and return the tree node at
   DATA_IN->FILE_DATA->GLOBALS_INDEX[IX].  */

tree
streamer_get_pickled_tree (class lto_input_block *ib, class data_in *data_in)
{
  unsigned HOST_WIDE_INT ix;
  tree result;
  enum LTO_tags expected_tag;

  ix = streamer_read_uhwi (ib);
  result = streamer_tree_cache_get_tree (data_in->reader_cache, ix);

  if (streamer_debugging)
    {
      expected_tag = streamer_read_enum (ib, LTO_tags, LTO_NUM_TAGS);
      gcc_assert (result
		  && TREE_CODE (result) == lto_tag_to_tree_code (expected_tag));
    }

  return result;
}
