/* Top-level LTO routines.
   Copyright (C) 2009-2026 Free Software Foundation, Inc.
   Contributed by CodeSourcery, Inc.

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 "tm.h"
#include "function.h"
#include "bitmap.h"
#include "basic-block.h"
#include "tree.h"
#include "gimple.h"
#include "cfghooks.h"
#include "alloc-pool.h"
#include "tree-pass.h"
#include "tree-streamer.h"
#include "cgraph.h"
#include "opts.h"
#include "toplev.h"
#include "stor-layout.h"
#include "symbol-summary.h"
#include "tree-vrp.h"
#include "sreal.h"
#include "ipa-cp.h"
#include "ipa-prop.h"
#include "common.h"
#include "debug.h"
#include "lto.h"
#include "lto-section-names.h"
#include "splay-tree.h"
#include "lto-partition.h"
#include "context.h"
#include "pass_manager.h"
#include "ipa-fnsummary.h"
#include "ipa-utils.h"
#include "gomp-constants.h"
#include "lto-symtab.h"
#include "stringpool.h"
#include "fold-const.h"
#include "attribs.h"
#include "builtins.h"
#include "lto-common.h"
#include "tree-pretty-print.h"
#include "print-tree.h"

/* True when no new types are going to be streamd from the global stream.  */

static bool type_streaming_finished = false;

GTY(()) tree first_personality_decl;

/* Returns a hash code for P.  */

static hashval_t
hash_name (const void *p)
{
  const struct lto_section_slot *ds = (const struct lto_section_slot *) p;
  return (hashval_t) htab_hash_string (ds->name);
}


/* Returns nonzero if P1 and P2 are equal.  */

static int
eq_name (const void *p1, const void *p2)
{
  const struct lto_section_slot *s1
    = (const struct lto_section_slot *) p1;
  const struct lto_section_slot *s2
    = (const struct lto_section_slot *) p2;

  return strcmp (s1->name, s2->name) == 0;
}

/* Free lto_section_slot.  */

static void
free_with_string (void *arg)
{
  struct lto_section_slot *s = (struct lto_section_slot *)arg;

  free (const_cast<char *> (s->name));
  free (arg);
}

/* Create section hash table.  */

htab_t
lto_obj_create_section_hash_table (void)
{
  return htab_create (37, hash_name, eq_name, free_with_string);
}

/* Delete an allocated integer KEY in the splay tree.  */

static void
lto_splay_tree_delete_id (splay_tree_key key)
{
  free ((void *) key);
}

/* Compare splay tree node ids A and B.  */

static int
lto_splay_tree_compare_ids (splay_tree_key a, splay_tree_key b)
{
  unsigned HOST_WIDE_INT ai;
  unsigned HOST_WIDE_INT bi;

  ai = *(unsigned HOST_WIDE_INT *) a;
  bi = *(unsigned HOST_WIDE_INT *) b;

  if (ai < bi)
    return -1;
  else if (ai > bi)
    return 1;
  return 0;
}

/* Look up splay tree node by ID in splay tree T.  */

static splay_tree_node
lto_splay_tree_lookup (splay_tree t, unsigned HOST_WIDE_INT id)
{
  return splay_tree_lookup (t, (splay_tree_key) &id);
}

/* Check if KEY has ID.  */

static bool
lto_splay_tree_id_equal_p (splay_tree_key key, unsigned HOST_WIDE_INT id)
{
  return *(unsigned HOST_WIDE_INT *) key == id;
}

/* Insert a splay tree node into tree T with ID as key and FILE_DATA as value.
   The ID is allocated separately because we need HOST_WIDE_INTs which may
   be wider than a splay_tree_key.  */

static void
lto_splay_tree_insert (splay_tree t, unsigned HOST_WIDE_INT id,
		       struct lto_file_decl_data *file_data)
{
  unsigned HOST_WIDE_INT *idp = XCNEW (unsigned HOST_WIDE_INT);
  *idp = id;
  splay_tree_insert (t, (splay_tree_key) idp, (splay_tree_value) file_data);
}

/* Create a splay tree.  */

static splay_tree
lto_splay_tree_new (void)
{
  return splay_tree_new (lto_splay_tree_compare_ids,
			 lto_splay_tree_delete_id,
			 NULL);
}

/* Decode the content of memory pointed to by DATA in the in decl
   state object STATE.  DATA_IN points to a data_in structure for
   decoding.  Return the address after the decoded object in the
   input.  */

static const uint32_t *
lto_read_in_decl_state (class data_in *data_in, const uint32_t *data,
			struct lto_in_decl_state *state)
{
  uint32_t ix;
  tree decl;
  uint32_t i, j;

  ix = *data++;
  state->compressed = ix & 1;
  ix /= 2;
  decl = streamer_tree_cache_get_tree (data_in->reader_cache, ix);
  if (!VAR_OR_FUNCTION_DECL_P (decl))
    {
      gcc_assert (decl == void_type_node);
      decl = NULL_TREE;
    }
  state->fn_decl = decl;

  for (i = 0; i < LTO_N_DECL_STREAMS; i++)
    {
      uint32_t size = *data++;
      vec<tree, va_gc> *decls = NULL;
      vec_alloc (decls, size);

      for (j = 0; j < size; j++)
	vec_safe_push (decls,
		       streamer_tree_cache_get_tree (data_in->reader_cache,
						     data[j]));

      state->streams[i] = decls;
      data += size;
    }

  return data;
}


/* Global canonical type table.  */
static htab_t gimple_canonical_types;
static hash_map<const_tree, hashval_t> *canonical_type_hash_cache;
static unsigned long num_canonical_type_hash_entries;
static unsigned long num_canonical_type_hash_queries;

/* Types postponed for registration to the canonical type table.
   During streaming we postpone all TYPE_CXX_ODR_P types so we can alter
   decide whether there is conflict with non-ODR type or not.  */
static GTY(()) vec<tree, va_gc> *types_to_register = NULL;

static void iterative_hash_canonical_type (tree type, inchash::hash &hstate);
static hashval_t gimple_canonical_type_hash (const void *p);
static hashval_t gimple_register_canonical_type_1 (tree t, hashval_t hash);

/* Returning a hash value for gimple type TYPE.

   The hash value returned is equal for types considered compatible
   by gimple_canonical_types_compatible_p.  */

static hashval_t
hash_canonical_type (tree type)
{
  inchash::hash hstate;
  enum tree_code code;

  /* We compute alias sets only for types that needs them.
     Be sure we do not recurse to something else as we cannot hash incomplete
     types in a way they would have same hash value as compatible complete
     types.  */
  gcc_checking_assert (type_with_alias_set_p (type));

  /* Combine a few common features of types so that types are grouped into
     smaller sets; when searching for existing matching types to merge,
     only existing types having the same features as the new type will be
     checked.  */
  code = tree_code_for_canonical_type_merging (TREE_CODE (type));
  hstate.add_int (code);
  if (!RECORD_OR_UNION_TYPE_P (type))
    hstate.add_int (TYPE_MODE (type));

  /* Incorporate common features of numerical types.  */
  if (INTEGRAL_TYPE_P (type)
      || SCALAR_FLOAT_TYPE_P (type)
      || FIXED_POINT_TYPE_P (type)
      || TREE_CODE (type) == OFFSET_TYPE
      || POINTER_TYPE_P (type))
    {
      hstate.add_int (TYPE_PRECISION (type));
      if (!type_with_interoperable_signedness (type))
	hstate.add_int (TYPE_UNSIGNED (type));
    }

  if (VECTOR_TYPE_P (type))
    {
      hstate.add_poly_int (TYPE_VECTOR_SUBPARTS (type));
      hstate.add_int (TYPE_UNSIGNED (type));
    }

  if (TREE_CODE (type) == COMPLEX_TYPE)
    hstate.add_int (TYPE_UNSIGNED (type));

  /* Fortran's C_SIGNED_CHAR is !TYPE_STRING_FLAG but needs to be
     interoperable with "signed char".  Unless all frontends are revisited to
     agree on these types, we must ignore the flag completely.  */

  /* Fortran standard define C_PTR type that is compatible with every
     C pointer.  For this reason we need to glob all pointers into one.
     Still pointers in different address spaces are not compatible.  */
  if (POINTER_TYPE_P (type))
    hstate.add_int (TYPE_ADDR_SPACE (TREE_TYPE (type)));

  /* For array types hash the domain bounds and the string flag.  */
  if (TREE_CODE (type) == ARRAY_TYPE && TYPE_DOMAIN (type))
    {
      hstate.add_int (TYPE_STRING_FLAG (type));
      /* OMP lowering can introduce error_mark_node in place of
	 random local decls in types.  */
      if (TYPE_MIN_VALUE (TYPE_DOMAIN (type)) != error_mark_node)
	inchash::add_expr (TYPE_MIN_VALUE (TYPE_DOMAIN (type)), hstate);
      if (TYPE_MAX_VALUE (TYPE_DOMAIN (type)) != error_mark_node)
	inchash::add_expr (TYPE_MAX_VALUE (TYPE_DOMAIN (type)), hstate);
    }

  /* Recurse for aggregates with a single element type.  */
  if (TREE_CODE (type) == ARRAY_TYPE
      || TREE_CODE (type) == COMPLEX_TYPE
      || TREE_CODE (type) == VECTOR_TYPE)
    iterative_hash_canonical_type (TREE_TYPE (type), hstate);

  /* Incorporate function return and argument types.  */
  if (TREE_CODE (type) == FUNCTION_TYPE || TREE_CODE (type) == METHOD_TYPE)
    {
      unsigned na;
      tree p;

      iterative_hash_canonical_type (TREE_TYPE (type), hstate);

      for (p = TYPE_ARG_TYPES (type), na = 0; p; p = TREE_CHAIN (p))
	{
	  iterative_hash_canonical_type (TREE_VALUE (p), hstate);
	  na++;
	}

      hstate.add_int (na);
    }

  if (RECORD_OR_UNION_TYPE_P (type))
    {
      unsigned nf;
      tree f;

      for (f = TYPE_FIELDS (type), nf = 0; f; f = TREE_CHAIN (f))
	if (TREE_CODE (f) == FIELD_DECL
	    && (! DECL_SIZE (f)
		|| ! integer_zerop (DECL_SIZE (f))))
	  {
	    tree t = TREE_TYPE (f);
	    if (!TREE_CHAIN (f)
		&& TREE_CODE (t) == ARRAY_TYPE)
	      t = TREE_TYPE  (t);
	    iterative_hash_canonical_type (t, hstate);
	    nf++;
	  }

      hstate.add_int (nf);
    }

  return hstate.end();
}

/* Returning a hash value for gimple type TYPE combined with VAL.  */

static void
iterative_hash_canonical_type (tree type, inchash::hash &hstate)
{
  hashval_t v;

  /* All type variants have same TYPE_CANONICAL.  */
  type = TYPE_MAIN_VARIANT (type);

  if (!canonical_type_used_p (type))
    v = hash_canonical_type (type);
  /* An already processed type.  */
  else if (TYPE_CANONICAL (type))
    {
      type = TYPE_CANONICAL (type);
      v = gimple_canonical_type_hash (type);
    }
  else
    {
      /* Canonical types should not be able to form SCCs by design, this
	 recursion is just because we do not register canonical types in
	 optimal order.  To avoid quadratic behavior also register the
	 type here.  */
      v = hash_canonical_type (type);
      v = gimple_register_canonical_type_1 (type, v);
    }
  hstate.merge_hash (v);
}

/* Returns the hash for a canonical type P.  */

static hashval_t
gimple_canonical_type_hash (const void *p)
{
  num_canonical_type_hash_queries++;
  hashval_t *slot = canonical_type_hash_cache->get ((const_tree) p);
  gcc_assert (slot != NULL);
  return *slot;
}



/* Returns nonzero if P1 and P2 are equal.  */

static int
gimple_canonical_type_eq (const void *p1, const void *p2)
{
  const_tree t1 = (const_tree) p1;
  const_tree t2 = (const_tree) p2;
  return gimple_canonical_types_compatible_p (const_cast<tree> (t1),
					      const_cast<tree> (t2));
}

/* Main worker for gimple_register_canonical_type.  */

static hashval_t
gimple_register_canonical_type_1 (tree t, hashval_t hash)
{
  void **slot;

  gcc_checking_assert (TYPE_P (t) && !TYPE_CANONICAL (t)
		       && type_with_alias_set_p (t)
		       && canonical_type_used_p (t));

  /* ODR types for which there is no ODR violation and we did not record
     structurally equivalent non-ODR type can be treated as unique by their
     name.

     hash passed to gimple_register_canonical_type_1 is a structural hash
     that we can use to lookup structurally equivalent non-ODR type.
     In case we decide to treat type as unique ODR type we recompute hash based
     on name and let TBAA machinery know about our decision.  */
  if (RECORD_OR_UNION_TYPE_P (t) && odr_type_p (t)
      && TYPE_CXX_ODR_P (t) && !odr_type_violation_reported_p (t))
    {
      /* Anonymous namespace types never conflict with non-C++ types.  */
      if (type_with_linkage_p (t) && type_in_anonymous_namespace_p (t))
	slot = NULL;
      else
	{
	  /* Here we rely on fact that all non-ODR types was inserted into
	     canonical type hash and thus we can safely detect conflicts between
	     ODR types and interoperable non-ODR types.  */
	  gcc_checking_assert (type_streaming_finished
			       && TYPE_MAIN_VARIANT (t) == t);
	  slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash,
					   NO_INSERT);
	}
      if (slot && !TYPE_CXX_ODR_P (*(tree *)slot))
	{
	  tree nonodr = *(tree *)slot;
	  gcc_checking_assert (!flag_ltrans);
	  if (symtab->dump_file)
	    {
	      fprintf (symtab->dump_file,
		       "ODR and non-ODR type conflict: ");
	      print_generic_expr (symtab->dump_file, t);
	      fprintf (symtab->dump_file, " and ");
	      print_generic_expr (symtab->dump_file, nonodr);
	      fprintf (symtab->dump_file, " mangled:%s\n",
			 IDENTIFIER_POINTER
			   (DECL_ASSEMBLER_NAME (TYPE_NAME (t))));
	    }
	  /* Set canonical for T and all other ODR equivalent duplicates
	     including incomplete structures.  */
	  set_type_canonical_for_odr_type (t, nonodr);
	}
      else
	{
	  tree prevail = prevailing_odr_type (t);

	  if (symtab->dump_file)
	    {
	      fprintf (symtab->dump_file,
		       "New canonical ODR type: ");
	      print_generic_expr (symtab->dump_file, t);
	      fprintf (symtab->dump_file, " mangled:%s\n",
			 IDENTIFIER_POINTER
			   (DECL_ASSEMBLER_NAME (TYPE_NAME (t))));
	    }
	  /* Set canonical for T and all other ODR equivalent duplicates
	     including incomplete structures.  */
	  set_type_canonical_for_odr_type (t, prevail);
	  enable_odr_based_tbaa (t);
	  if (!type_in_anonymous_namespace_p (t))
	    hash = htab_hash_string (IDENTIFIER_POINTER
					   (DECL_ASSEMBLER_NAME
						   (TYPE_NAME (t))));
	  else
	    hash = TYPE_UID (t);

	  /* All variants of t now have TYPE_CANONICAL set to prevail.
	     Update canonical type hash cache accordingly.  */
	  num_canonical_type_hash_entries++;
	  bool existed_p = canonical_type_hash_cache->put (prevail, hash);
	  gcc_checking_assert (!existed_p);
	}
      return hash;
    }

  slot = htab_find_slot_with_hash (gimple_canonical_types, t, hash, INSERT);
  if (*slot)
    {
      tree new_type = (tree)(*slot);
      gcc_checking_assert (new_type != t);
      TYPE_CANONICAL (t) = new_type;
    }
  else
    {
      TYPE_CANONICAL (t) = t;
      *slot = (void *) t;
      /* Cache the just computed hash value.  */
      num_canonical_type_hash_entries++;
      bool existed_p = canonical_type_hash_cache->put (t, hash);
      gcc_assert (!existed_p);
    }
  return hash;
}

/* Register type T in the global type table gimple_types and set
   TYPE_CANONICAL of T accordingly.
   This is used by LTO to merge structurally equivalent types for
   type-based aliasing purposes across different TUs and languages.

   ???  This merging does not exactly match how the tree.cc middle-end
   functions will assign TYPE_CANONICAL when new types are created
   during optimization (which at least happens for pointer and array
   types).  */

static void
gimple_register_canonical_type (tree t)
{
  if (TYPE_CANONICAL (t) || !type_with_alias_set_p (t)
      || !canonical_type_used_p (t))
    return;

  /* Canonical types are same among all complete variants.  */
  if (TYPE_CANONICAL (TYPE_MAIN_VARIANT (t)))
    TYPE_CANONICAL (t) = TYPE_CANONICAL (TYPE_MAIN_VARIANT (t));
  else
    {
      hashval_t h = hash_canonical_type (TYPE_MAIN_VARIANT (t));
      gimple_register_canonical_type_1 (TYPE_MAIN_VARIANT (t), h);
      TYPE_CANONICAL (t) = TYPE_CANONICAL (TYPE_MAIN_VARIANT (t));
    }
}

/* Re-compute TYPE_CANONICAL for NODE and related types.  */

static void
lto_register_canonical_types (tree node, bool first_p)
{
  if (!node
      || !TYPE_P (node))
    return;

  if (first_p)
    TYPE_CANONICAL (node) = NULL_TREE;

  if (POINTER_TYPE_P (node)
      || TREE_CODE (node) == COMPLEX_TYPE
      || TREE_CODE (node) == ARRAY_TYPE)
    lto_register_canonical_types (TREE_TYPE (node), first_p);

 if (!first_p)
    gimple_register_canonical_type (node);
}

/* Finish canonical type calculation: after all units has been streamed in we
   can check if given ODR type structurally conflicts with a non-ODR type.  In
   the first case we set type canonical according to the canonical type hash.
   In the second case we use type names.  */

static void
lto_register_canonical_types_for_odr_types ()
{
  tree t;
  unsigned int i;

  if (!types_to_register)
    return;

  type_streaming_finished = true;

  /* Be sure that no types derived from ODR types was
     not inserted into the hash table.  */
  if (flag_checking)
    FOR_EACH_VEC_ELT (*types_to_register, i, t)
      gcc_assert (!TYPE_CANONICAL (t));

  /* Register all remaining types.  */
  FOR_EACH_VEC_ELT (*types_to_register, i, t)
    {
      /* For pre-streamed types like va-arg it is possible that main variant
	 is !CXX_ODR_P while the variant (which is streamed) is.
	 Copy CXX_ODR_P to make type verifier happy.  This is safe because
	 in canonical type calculation we only consider main variants.
	 However we can not change this flag before streaming is finished
	 to not affect tree merging.  */
      TYPE_CXX_ODR_P (t) = TYPE_CXX_ODR_P (TYPE_MAIN_VARIANT (t));
      if (!TYPE_CANONICAL (t))
        gimple_register_canonical_type (t);
    }
}


/* Remember trees that contains references to declarations.  */
vec <tree, va_gc> *tree_with_vars;

#define CHECK_VAR(tt) \
  do \
    { \
      if ((tt) && VAR_OR_FUNCTION_DECL_P (tt) \
	  && (TREE_PUBLIC (tt) || DECL_EXTERNAL (tt))) \
	return true; \
    } while (0)

#define CHECK_NO_VAR(tt) \
  gcc_checking_assert (!(tt) || !VAR_OR_FUNCTION_DECL_P (tt))

/* Check presence of pointers to decls in fields of a tree_typed T.  */

static inline bool
mentions_vars_p_typed (tree t)
{
  CHECK_NO_VAR (TREE_TYPE (t));
  return false;
}

/* Check presence of pointers to decls in fields of a tree_common T.  */

static inline bool
mentions_vars_p_common (tree t)
{
  if (mentions_vars_p_typed (t))
    return true;
  CHECK_NO_VAR (TREE_CHAIN (t));
  return false;
}

/* Check presence of pointers to decls in fields of a decl_minimal T.  */

static inline bool
mentions_vars_p_decl_minimal (tree t)
{
  if (mentions_vars_p_common (t))
    return true;
  CHECK_NO_VAR (DECL_NAME (t));
  CHECK_VAR (DECL_CONTEXT (t));
  return false;
}

/* Check presence of pointers to decls in fields of a decl_common T.  */

static inline bool
mentions_vars_p_decl_common (tree t)
{
  if (mentions_vars_p_decl_minimal (t))
    return true;
  CHECK_VAR (DECL_SIZE (t));
  CHECK_VAR (DECL_SIZE_UNIT (t));
  CHECK_VAR (DECL_INITIAL (t));
  CHECK_NO_VAR (DECL_ATTRIBUTES (t));
  CHECK_VAR (DECL_ABSTRACT_ORIGIN (t));
  return false;
}

/* Check presence of pointers to decls in fields of a decl_with_vis T.  */

static inline bool
mentions_vars_p_decl_with_vis (tree t)
{
  if (mentions_vars_p_decl_common (t))
    return true;

  /* Accessor macro has side-effects, use field-name here.  */
  CHECK_NO_VAR (DECL_ASSEMBLER_NAME_RAW (t));
  return false;
}

/* Check presence of pointers to decls in fields of a decl_non_common T.  */

static inline bool
mentions_vars_p_decl_non_common (tree t)
{
  if (mentions_vars_p_decl_with_vis (t))
    return true;
  CHECK_NO_VAR (DECL_RESULT_FLD (t));
  return false;
}

/* Check presence of pointers to decls in fields of a decl_non_common T.  */

static bool
mentions_vars_p_function (tree t)
{
  if (mentions_vars_p_decl_non_common (t))
    return true;
  CHECK_NO_VAR (DECL_ARGUMENTS (t));
  CHECK_NO_VAR (DECL_VINDEX (t));
  CHECK_VAR (DECL_FUNCTION_PERSONALITY (t));
  return false;
}

/* Check presence of pointers to decls in fields of a field_decl T.  */

static bool
mentions_vars_p_field_decl (tree t)
{
  if (mentions_vars_p_decl_common (t))
    return true;
  CHECK_VAR (DECL_FIELD_OFFSET (t));
  CHECK_NO_VAR (DECL_BIT_FIELD_TYPE (t));
  CHECK_NO_VAR (DECL_QUALIFIER (t));
  CHECK_NO_VAR (DECL_FIELD_BIT_OFFSET (t));
  CHECK_NO_VAR (DECL_FCONTEXT (t));
  return false;
}

/* Check presence of pointers to decls in fields of a type T.  */

static bool
mentions_vars_p_type (tree t)
{
  if (mentions_vars_p_common (t))
    return true;
  CHECK_NO_VAR (TYPE_CACHED_VALUES (t));
  CHECK_VAR (TYPE_SIZE (t));
  CHECK_VAR (TYPE_SIZE_UNIT (t));
  CHECK_NO_VAR (TYPE_ATTRIBUTES (t));
  CHECK_NO_VAR (TYPE_NAME (t));

  CHECK_VAR (TYPE_MIN_VALUE_RAW (t));
  CHECK_VAR (TYPE_MAX_VALUE_RAW (t));

  /* Accessor is for derived node types only.  */
  CHECK_NO_VAR (TYPE_LANG_SLOT_1 (t));

  CHECK_VAR (TYPE_CONTEXT (t));
  CHECK_NO_VAR (TYPE_CANONICAL (t));
  CHECK_NO_VAR (TYPE_MAIN_VARIANT (t));
  CHECK_NO_VAR (TYPE_NEXT_VARIANT (t));
  return false;
}

/* Check presence of pointers to decls in fields of a BINFO T.  */

static bool
mentions_vars_p_binfo (tree t)
{
  unsigned HOST_WIDE_INT i, n;

  if (mentions_vars_p_common (t))
    return true;
  CHECK_VAR (BINFO_VTABLE (t));
  CHECK_NO_VAR (BINFO_OFFSET (t));
  CHECK_NO_VAR (BINFO_VIRTUALS (t));
  CHECK_NO_VAR (BINFO_VPTR_FIELD (t));
  n = vec_safe_length (BINFO_BASE_ACCESSES (t));
  for (i = 0; i < n; i++)
    CHECK_NO_VAR (BINFO_BASE_ACCESS (t, i));
  /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
     and BINFO_VPTR_INDEX; these are used by C++ FE only.  */
  n = BINFO_N_BASE_BINFOS (t);
  for (i = 0; i < n; i++)
    CHECK_NO_VAR (BINFO_BASE_BINFO (t, i));
  return false;
}

/* Check presence of pointers to decls in fields of a CONSTRUCTOR T.  */

static bool
mentions_vars_p_constructor (tree t)
{
  unsigned HOST_WIDE_INT idx;
  constructor_elt *ce;

  if (mentions_vars_p_typed (t))
    return true;

  for (idx = 0; vec_safe_iterate (CONSTRUCTOR_ELTS (t), idx, &ce); idx++)
    {
      CHECK_NO_VAR (ce->index);
      CHECK_VAR (ce->value);
    }
  return false;
}

/* Check presence of pointers to decls in fields of an expression tree T.  */

static bool
mentions_vars_p_expr (tree t)
{
  int i;
  if (mentions_vars_p_typed (t))
    return true;
  for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
    CHECK_VAR (TREE_OPERAND (t, i));
  return false;
}

/* Check presence of pointers to decls in fields of an OMP_CLAUSE T.  */

static bool
mentions_vars_p_omp_clause (tree t)
{
  int i;
  if (mentions_vars_p_common (t))
    return true;
  for (i = omp_clause_num_ops[OMP_CLAUSE_CODE (t)] - 1; i >= 0; --i)
    CHECK_VAR (OMP_CLAUSE_OPERAND (t, i));
  return false;
}

/* Check presence of pointers to decls that needs later fixup in T.  */

static bool
mentions_vars_p (tree t)
{
  switch (TREE_CODE (t))
    {
    case IDENTIFIER_NODE:
      break;

    case TREE_LIST:
      CHECK_VAR (TREE_VALUE (t));
      CHECK_VAR (TREE_PURPOSE (t));
      CHECK_NO_VAR (TREE_CHAIN (t));
      break;

    case FIELD_DECL:
      return mentions_vars_p_field_decl (t);

    case LABEL_DECL:
    case CONST_DECL:
    case PARM_DECL:
    case RESULT_DECL:
    case IMPORTED_DECL:
    case NAMESPACE_DECL:
    case NAMELIST_DECL:
      return mentions_vars_p_decl_common (t);

    case VAR_DECL:
      return mentions_vars_p_decl_with_vis (t);

    case TYPE_DECL:
      return mentions_vars_p_decl_non_common (t);

    case FUNCTION_DECL:
      return mentions_vars_p_function (t);

    case TREE_BINFO:
      return mentions_vars_p_binfo (t);

    case PLACEHOLDER_EXPR:
      return mentions_vars_p_common (t);

    case BLOCK:
    case TRANSLATION_UNIT_DECL:
    case OPTIMIZATION_NODE:
    case TARGET_OPTION_NODE:
      break;

    case CONSTRUCTOR:
      return mentions_vars_p_constructor (t);

    case OMP_CLAUSE:
      return mentions_vars_p_omp_clause (t);

    default:
      if (TYPE_P (t))
	{
	  if (mentions_vars_p_type (t))
	    return true;
	}
      else if (EXPR_P (t))
	{
	  if (mentions_vars_p_expr (t))
	    return true;
	}
      else if (CONSTANT_CLASS_P (t))
	CHECK_NO_VAR (TREE_TYPE (t));
      else
	gcc_unreachable ();
    }
  return false;
}


/* Return the resolution for the decl with index INDEX from DATA_IN.  */

static enum ld_plugin_symbol_resolution
get_resolution (class data_in *data_in, unsigned index)
{
  if (data_in->globals_resolution.exists ())
    {
      ld_plugin_symbol_resolution_t ret;
      /* We can have references to not emitted functions in
	 DECL_FUNCTION_PERSONALITY at least.  So we can and have
	 to indeed return LDPR_UNKNOWN in some cases.  */
      if (data_in->globals_resolution.length () <= index)
	return LDPR_UNKNOWN;
      ret = data_in->globals_resolution[index];
      return ret;
    }
  else
    /* Delay resolution finding until decl merging.  */
    return LDPR_UNKNOWN;
}

/* We need to record resolutions until symbol table is read.  */
static void
register_resolution (struct lto_file_decl_data *file_data, tree decl,
		     enum ld_plugin_symbol_resolution resolution)
{
  bool existed;
  if (resolution == LDPR_UNKNOWN)
    return;
  if (!file_data->resolution_map)
    file_data->resolution_map
      = new hash_map<tree, ld_plugin_symbol_resolution>;
  ld_plugin_symbol_resolution_t &res
     = file_data->resolution_map->get_or_insert (decl, &existed);
  if (!existed
      || resolution == LDPR_PREVAILING_DEF_IRONLY
      || resolution == LDPR_PREVAILING_DEF
      || resolution == LDPR_PREVAILING_DEF_IRONLY_EXP)
    res = resolution;
}

/* Register DECL with the global symbol table and change its
   name if necessary to avoid name clashes for static globals across
   different files.  */

static void
lto_register_var_decl_in_symtab (class data_in *data_in, tree decl,
				 unsigned ix)
{
  tree context;

  /* Variable has file scope, not local.  */
  if (!TREE_PUBLIC (decl)
      && !((context = decl_function_context (decl))
	   && auto_var_in_fn_p (decl, context)))
    rest_of_decl_compilation (decl, 1, 0);

  /* If this variable has already been declared, queue the
     declaration for merging.  */
  if (TREE_PUBLIC (decl))
    register_resolution (data_in->file_data,
			 decl, get_resolution (data_in, ix));
}


/* Register DECL with the global symbol table and change its
   name if necessary to avoid name clashes for static globals across
   different files.  DATA_IN contains descriptors and tables for the
   file being read.  */

static void
lto_register_function_decl_in_symtab (class data_in *data_in, tree decl,
				      unsigned ix)
{
  /* If this variable has already been declared, queue the
     declaration for merging.  */
  if (TREE_PUBLIC (decl) && !DECL_ABSTRACT_P (decl))
    register_resolution (data_in->file_data,
			 decl, get_resolution (data_in, ix));
}

/* Check if T is a decl and needs register its resolution info.  */

static void
lto_maybe_register_decl (class data_in *data_in, tree t, unsigned ix)
{
  if (VAR_P (t))
    lto_register_var_decl_in_symtab (data_in, t, ix);
  else if (TREE_CODE (t) == FUNCTION_DECL
	   && !fndecl_built_in_p (t))
    lto_register_function_decl_in_symtab (data_in, t, ix);
}


/* For the type T re-materialize it in the type variant list and
   the pointer/reference-to chains.  */

static void
lto_fixup_prevailing_type (tree t)
{
  /* The following re-creates proper variant lists while fixing up
     the variant leaders.  We do not stream TYPE_NEXT_VARIANT so the
     variant list state before fixup is broken.  */

  /* If we are not our own variant leader link us into our new leaders
     variant list.  */
  if (TYPE_MAIN_VARIANT (t) != t)
    {
      tree mv = TYPE_MAIN_VARIANT (t);
      TYPE_NEXT_VARIANT (t) = TYPE_NEXT_VARIANT (mv);
      TYPE_NEXT_VARIANT (mv) = t;
    }
  else if (!TYPE_ATTRIBUTES (t))
    {
      /* The following reconstructs the pointer chains
	 of the new pointed-to type if we are a main variant.  We do
	 not stream those so they are broken before fixup.
	 Don't add it if despite being main variant it has
	 attributes (then it was created with build_distinct_type_copy).
	 Similarly don't add TYPE_REF_IS_RVALUE REFERENCE_TYPEs.
	 Don't add it if there is something in the chain already.  */
      if (TREE_CODE (t) == POINTER_TYPE)
	{
	  TYPE_NEXT_PTR_TO (t) = TYPE_POINTER_TO (TREE_TYPE (t));
	  TYPE_POINTER_TO (TREE_TYPE (t)) = t;
	}
      else if (TREE_CODE (t) == REFERENCE_TYPE && !TYPE_REF_IS_RVALUE (t))
	{
	  TYPE_NEXT_REF_TO (t) = TYPE_REFERENCE_TO (TREE_TYPE (t));
	  TYPE_REFERENCE_TO (TREE_TYPE (t)) = t;
	}
    }
}


/* We keep prevailing tree SCCs in a hashtable with manual collision
   handling (in case all hashes compare the same) and keep the colliding
   entries in the tree_scc->next chain.  */

struct tree_scc
{
  tree_scc *next;
  /* Hash of the whole SCC.  */
  hashval_t hash;
  /* Number of trees in the SCC.  */
  unsigned len;
  /* Number of possible entries into the SCC (tree nodes [0..entry_len-1]
     which share the same individual tree hash).  */
  unsigned entry_len;
  /* The members of the SCC.
     We only need to remember the first entry node candidate for prevailing
     SCCs (but of course have access to all entries for SCCs we are
     processing).
     ???  For prevailing SCCs we really only need hash and the first
     entry candidate, but that's too awkward to implement.  */
  tree entries[1];
};

struct tree_scc_hasher : nofree_ptr_hash <tree_scc>
{
  static inline hashval_t hash (const tree_scc *);
  static inline bool equal (const tree_scc *, const tree_scc *);
};

hashval_t
tree_scc_hasher::hash (const tree_scc *scc)
{
  return scc->hash;
}

bool
tree_scc_hasher::equal (const tree_scc *scc1, const tree_scc *scc2)
{
  if (scc1->hash != scc2->hash
      || scc1->len != scc2->len
      || scc1->entry_len != scc2->entry_len)
    return false;
  return true;
}

static hash_table<tree_scc_hasher> *tree_scc_hash;
static struct obstack tree_scc_hash_obstack;

static unsigned long num_merged_types;
static unsigned long num_prevailing_types;
static unsigned long num_type_scc_trees;
static unsigned long total_scc_size;
static unsigned long num_sccs_read;
static unsigned long num_unshared_trees_read;
static unsigned long total_scc_size_merged;
static unsigned long num_sccs_merged;
static unsigned long num_scc_compares;
static unsigned long num_scc_compare_collisions;


/* Compare the two entries T1 and T2 of two SCCs that are possibly equal,
   recursing through in-SCC tree edges.  Returns true if the SCCs entered
   through T1 and T2 are equal and fills in *MAP with the pairs of
   SCC entries we visited, starting with (*MAP)[0] = T1 and (*MAP)[1] = T2.  */

static bool
compare_tree_sccs_1 (tree t1, tree t2, tree **map)
{
  enum tree_code code;

  /* Mark already visited nodes.  */
  TREE_ASM_WRITTEN (t2) = 1;

  /* Push the pair onto map.  */
  (*map)[0] = t1;
  (*map)[1] = t2;
  *map = *map + 2;

  /* Compare value-fields.  */
#define compare_values(X) \
  do { \
    if (X(t1) != X(t2)) \
      return false; \
  } while (0)

  compare_values (TREE_CODE);
  code = TREE_CODE (t1);

  /* If we end up comparing translation unit decls we either forgot to mark
     some SCC as local or we compare too much.  */
  gcc_checking_assert (code != TRANSLATION_UNIT_DECL);

  if (!TYPE_P (t1))
    {
      compare_values (TREE_SIDE_EFFECTS);
      compare_values (TREE_CONSTANT);
      compare_values (TREE_READONLY);
      compare_values (TREE_PUBLIC);
    }
  compare_values (TREE_ADDRESSABLE);
  compare_values (TREE_THIS_VOLATILE);
  if (DECL_P (t1))
    compare_values (DECL_UNSIGNED);
  else if (TYPE_P (t1))
    compare_values (TYPE_UNSIGNED);
  if (TYPE_P (t1))
    compare_values (TYPE_ARTIFICIAL);
  else
    compare_values (TREE_NO_WARNING);
  compare_values (TREE_NOTHROW);
  compare_values (TREE_STATIC);
  if (code != TREE_BINFO)
    compare_values (TREE_PRIVATE);
  compare_values (TREE_PROTECTED);
  compare_values (TREE_DEPRECATED);
  if (TYPE_P (t1))
    {
      if (AGGREGATE_TYPE_P (t1))
	compare_values (TYPE_REVERSE_STORAGE_ORDER);
      else
	compare_values (TYPE_SATURATING);
      compare_values (TYPE_ADDR_SPACE);
    }
  else if (code == SSA_NAME)
    compare_values (SSA_NAME_IS_DEFAULT_DEF);

  if (CODE_CONTAINS_STRUCT (code, TS_INT_CST))
    {
      if (wi::to_wide (t1) != wi::to_wide (t2))
	return false;
    }

  if (CODE_CONTAINS_STRUCT (code, TS_REAL_CST))
    {
      /* ???  No suitable compare routine available.  */
      REAL_VALUE_TYPE r1 = TREE_REAL_CST (t1);
      REAL_VALUE_TYPE r2 = TREE_REAL_CST (t2);
      if (r1.cl != r2.cl
	  || r1.decimal != r2.decimal
	  || r1.sign != r2.sign
	  || r1.signalling != r2.signalling
	  || r1.canonical != r2.canonical
	  || r1.uexp != r2.uexp)
	return false;
      for (unsigned i = 0; i < SIGSZ; ++i)
	if (r1.sig[i] != r2.sig[i])
	  return false;
    }

  if (CODE_CONTAINS_STRUCT (code, TS_FIXED_CST))
    if (!fixed_compare (EQ_EXPR,
			TREE_FIXED_CST_PTR (t1), TREE_FIXED_CST_PTR (t2)))
      return false;

  if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
    {
      compare_values (VECTOR_CST_LOG2_NPATTERNS);
      compare_values (VECTOR_CST_NELTS_PER_PATTERN);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
    {
      compare_values (DECL_MODE);
      compare_values (DECL_NONLOCAL);
      compare_values (DECL_VIRTUAL_P);
      compare_values (DECL_IGNORED_P);
      compare_values (DECL_ABSTRACT_P);
      compare_values (DECL_ARTIFICIAL);
      compare_values (DECL_USER_ALIGN);
      compare_values (DECL_PRESERVE_P);
      compare_values (DECL_EXTERNAL);
      compare_values (DECL_NOT_GIMPLE_REG_P);
      compare_values (DECL_ALIGN);
      if (code == LABEL_DECL)
	{
	  compare_values (EH_LANDING_PAD_NR);
	  compare_values (LABEL_DECL_UID);
	}
      else if (code == FIELD_DECL)
	{
	  compare_values (DECL_PACKED);
	  compare_values (DECL_NONADDRESSABLE_P);
	  compare_values (DECL_PADDING_P);
	  compare_values (DECL_FIELD_ABI_IGNORED);
	  compare_values (DECL_FIELD_CXX_ZERO_WIDTH_BIT_FIELD);
	  compare_values (DECL_OFFSET_ALIGN);
	  compare_values (DECL_NOT_FLEXARRAY);
	}
      else if (code == VAR_DECL)
	{
	  compare_values (DECL_HAS_DEBUG_EXPR_P);
	  compare_values (DECL_NONLOCAL_FRAME);
	}
      if (code == RESULT_DECL
	  || code == PARM_DECL
	  || code == VAR_DECL)
	{
	  compare_values (DECL_BY_REFERENCE);
	  if (code == VAR_DECL
	      || code == PARM_DECL)
	    compare_values (DECL_HAS_VALUE_EXPR_P);
	}
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WRTL))
    compare_values (DECL_REGISTER);

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
    {
      compare_values (DECL_COMMON);
      compare_values (DECL_DLLIMPORT_P);
      compare_values (DECL_WEAK);
      compare_values (DECL_SEEN_IN_BIND_EXPR_P);
      compare_values (DECL_COMDAT);
      compare_values (DECL_VISIBILITY);
      compare_values (DECL_VISIBILITY_SPECIFIED);
      if (code == VAR_DECL)
	{
	  compare_values (DECL_HARD_REGISTER);
	  /* DECL_IN_TEXT_SECTION is set during final asm output only.  */
	  compare_values (DECL_IN_CONSTANT_POOL);
	}
    }

  if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
    {
      compare_values (DECL_BUILT_IN_CLASS);
      compare_values (DECL_STATIC_CONSTRUCTOR);
      compare_values (DECL_STATIC_DESTRUCTOR);
      compare_values (DECL_UNINLINABLE);
      compare_values (DECL_POSSIBLY_INLINED);
      compare_values (DECL_IS_NOVOPS);
      compare_values (DECL_IS_RETURNS_TWICE);
      compare_values (DECL_IS_MALLOC);
      compare_values (FUNCTION_DECL_DECL_TYPE);
      compare_values (DECL_DECLARED_INLINE_P);
      compare_values (DECL_STATIC_CHAIN);
      compare_values (DECL_NO_INLINE_WARNING_P);
      compare_values (DECL_NO_INSTRUMENT_FUNCTION_ENTRY_EXIT);
      compare_values (DECL_NO_LIMIT_STACK);
      compare_values (DECL_DISREGARD_INLINE_LIMITS);
      compare_values (DECL_PURE_P);
      compare_values (DECL_LOOPING_CONST_OR_PURE_P);
      compare_values (DECL_IS_REPLACEABLE_OPERATOR);
      compare_values (DECL_FINAL_P);
      compare_values (DECL_CXX_CONSTRUCTOR_P);
      compare_values (DECL_CXX_DESTRUCTOR_P);
      if (DECL_BUILT_IN_CLASS (t1) != NOT_BUILT_IN)
	compare_values (DECL_UNCHECKED_FUNCTION_CODE);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
    {
      compare_values (TYPE_MODE);
      compare_values (TYPE_NEEDS_CONSTRUCTING);
      if (RECORD_OR_UNION_TYPE_P (t1))
	{
	  compare_values (TYPE_TRANSPARENT_AGGR);
	  compare_values (TYPE_FINAL_P);
          compare_values (TYPE_CXX_ODR_P);
	}
      else if (code == ARRAY_TYPE)
	compare_values (TYPE_NONALIASED_COMPONENT);
      if (code == ARRAY_TYPE || code == INTEGER_TYPE)
        compare_values (TYPE_STRING_FLAG);
      if (AGGREGATE_TYPE_P (t1))
	compare_values (TYPE_TYPELESS_STORAGE);
      compare_values (TYPE_EMPTY_P);
      if (FUNC_OR_METHOD_TYPE_P (t1))
	compare_values (TYPE_NO_NAMED_ARGS_STDARG_P);
      if (RECORD_OR_UNION_TYPE_P (t1))
	compare_values (TYPE_INCLUDES_FLEXARRAY);
      compare_values (TYPE_PACKED);
      compare_values (TYPE_RESTRICT);
      compare_values (TYPE_USER_ALIGN);
      compare_values (TYPE_READONLY);
      compare_values (TYPE_PRECISION_RAW);
      compare_values (TYPE_ALIGN);
      /* Do not compare TYPE_ALIAS_SET.  Doing so introduce ordering issues
	 with calls to get_alias_set which may initialize it for streamed
	 in types.  */
    }

  /* We don't want to compare locations, so there is nothing do compare
     for TS_EXP.  */

  /* BLOCKs are function local and we don't merge anything there, so
     simply refuse to merge.  */
  if (CODE_CONTAINS_STRUCT (code, TS_BLOCK))
    return false;

  if (CODE_CONTAINS_STRUCT (code, TS_TRANSLATION_UNIT_DECL))
    if (strcmp (TRANSLATION_UNIT_LANGUAGE (t1),
		TRANSLATION_UNIT_LANGUAGE (t2)) != 0)
      return false;

  if (CODE_CONTAINS_STRUCT (code, TS_TARGET_OPTION))
    if (!cl_target_option_eq (TREE_TARGET_OPTION (t1), TREE_TARGET_OPTION (t2)))
      return false;

  if (CODE_CONTAINS_STRUCT (code, TS_OPTIMIZATION))
    if (!cl_optimization_option_eq (TREE_OPTIMIZATION (t1),
				    TREE_OPTIMIZATION (t2)))
      return false;

  if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
    if (vec_safe_length (BINFO_BASE_ACCESSES (t1))
	!= vec_safe_length (BINFO_BASE_ACCESSES (t2)))
      return false;

  if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
    {
      compare_values (CLOBBER_KIND);
      compare_values (CONSTRUCTOR_NELTS);
    }

  if (CODE_CONTAINS_STRUCT (code, TS_IDENTIFIER))
    if (IDENTIFIER_LENGTH (t1) != IDENTIFIER_LENGTH (t2)
	|| memcmp (IDENTIFIER_POINTER (t1), IDENTIFIER_POINTER (t2),
		   IDENTIFIER_LENGTH (t1)) != 0)
      return false;

  if (CODE_CONTAINS_STRUCT (code, TS_STRING))
    if (TREE_STRING_LENGTH (t1) != TREE_STRING_LENGTH (t2)
	|| memcmp (TREE_STRING_POINTER (t1), TREE_STRING_POINTER (t2),
		   TREE_STRING_LENGTH (t1)) != 0)
      return false;

  if (code == RAW_DATA_CST)
    if (RAW_DATA_LENGTH (t1) != RAW_DATA_LENGTH (t2)
	|| memcmp (RAW_DATA_POINTER (t1), RAW_DATA_POINTER (t2),
		   RAW_DATA_LENGTH (t1)) != 0)
      return false;

  if (code == OMP_CLAUSE)
    {
      compare_values (OMP_CLAUSE_CODE);
      switch (OMP_CLAUSE_CODE (t1))
	{
	case OMP_CLAUSE_DEFAULT:
	  compare_values (OMP_CLAUSE_DEFAULT_KIND);
	  break;
	case OMP_CLAUSE_SCHEDULE:
	  compare_values (OMP_CLAUSE_SCHEDULE_KIND);
	  break;
	case OMP_CLAUSE_DEPEND:
	  compare_values (OMP_CLAUSE_DEPEND_KIND);
	  break;
	case OMP_CLAUSE_MAP:
	  compare_values (OMP_CLAUSE_MAP_KIND);
	  break;
	case OMP_CLAUSE_PROC_BIND:
	  compare_values (OMP_CLAUSE_PROC_BIND_KIND);
	  break;
	case OMP_CLAUSE_REDUCTION:
	  compare_values (OMP_CLAUSE_REDUCTION_CODE);
	  compare_values (OMP_CLAUSE_REDUCTION_GIMPLE_INIT);
	  compare_values (OMP_CLAUSE_REDUCTION_GIMPLE_MERGE);
	  break;
	default:
	  break;
	}
    }

#undef compare_values


  /* Compare pointer fields.  */

  /* Recurse.  Search & Replaced from DFS_write_tree_body.
     Folding the early checks into the compare_tree_edges recursion
     macro makes debugging way quicker as you are able to break on
     compare_tree_sccs_1 and simply finish until a call returns false
     to spot the SCC members with the difference.  */
#define compare_tree_edges(E1, E2) \
  do { \
    tree t1_ = (E1), t2_ = (E2); \
    if (t1_ != t2_ \
	&& (!t1_ || !t2_ \
	    || !TREE_VISITED (t2_) \
	    || (!TREE_ASM_WRITTEN (t2_) \
		&& !compare_tree_sccs_1 (t1_, t2_, map)))) \
      return false; \
    /* Only non-NULL trees outside of the SCC may compare equal.  */ \
    gcc_checking_assert (t1_ != t2_ || (!t2_ || !TREE_VISITED (t2_))); \
  } while (0)

  if (CODE_CONTAINS_STRUCT (code, TS_TYPED))
    {
      if (code != IDENTIFIER_NODE)
	compare_tree_edges (TREE_TYPE (t1), TREE_TYPE (t2));
    }

  if (CODE_CONTAINS_STRUCT (code, TS_VECTOR))
    {
      /* Note that the number of elements for EXPR has already been emitted
	 in EXPR's header (see streamer_write_tree_header).  */
      unsigned int count = vector_cst_encoded_nelts (t1);
      for (unsigned int i = 0; i < count; ++i)
	compare_tree_edges (VECTOR_CST_ENCODED_ELT (t1, i),
			    VECTOR_CST_ENCODED_ELT (t2, i));
    }

  if (CODE_CONTAINS_STRUCT (code, TS_COMPLEX))
    {
      compare_tree_edges (TREE_REALPART (t1), TREE_REALPART (t2));
      compare_tree_edges (TREE_IMAGPART (t1), TREE_IMAGPART (t2));
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_MINIMAL))
    {
      compare_tree_edges (DECL_NAME (t1), DECL_NAME (t2));
      /* ???  Global decls from different TUs have non-matching
	 TRANSLATION_UNIT_DECLs.  Only consider a small set of
	 decls equivalent, we should not end up merging others.  */
      if ((code == TYPE_DECL
	   || code == NAMESPACE_DECL
	   || code == IMPORTED_DECL
	   || code == CONST_DECL
	   || (VAR_OR_FUNCTION_DECL_P (t1)
	       && (TREE_PUBLIC (t1) || DECL_EXTERNAL (t1))))
	  && DECL_FILE_SCOPE_P (t1) && DECL_FILE_SCOPE_P (t2))
	;
      else
	compare_tree_edges (DECL_CONTEXT (t1), DECL_CONTEXT (t2));
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
    {
      compare_tree_edges (DECL_SIZE (t1), DECL_SIZE (t2));
      compare_tree_edges (DECL_SIZE_UNIT (t1), DECL_SIZE_UNIT (t2));
      compare_tree_edges (DECL_ATTRIBUTES (t1), DECL_ATTRIBUTES (t2));
      compare_tree_edges (DECL_ABSTRACT_ORIGIN (t1), DECL_ABSTRACT_ORIGIN (t2));
      if ((code == VAR_DECL
	   || code == PARM_DECL)
	  && DECL_HAS_VALUE_EXPR_P (t1))
	compare_tree_edges (DECL_VALUE_EXPR (t1), DECL_VALUE_EXPR (t2));
      if (code == VAR_DECL
	  && DECL_HAS_DEBUG_EXPR_P (t1))
	compare_tree_edges (DECL_DEBUG_EXPR (t1), DECL_DEBUG_EXPR (t2));
      /* LTO specific edges.  */
      if (code != FUNCTION_DECL
	  && code != TRANSLATION_UNIT_DECL)
	compare_tree_edges (DECL_INITIAL (t1), DECL_INITIAL (t2));
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
    {
      if (code == FUNCTION_DECL)
	{
	  tree a1, a2;
	  for (a1 = DECL_ARGUMENTS (t1), a2 = DECL_ARGUMENTS (t2);
	       a1 || a2;
	       a1 = TREE_CHAIN (a1), a2 = TREE_CHAIN (a2))
	    compare_tree_edges (a1, a2);
	  compare_tree_edges (DECL_RESULT (t1), DECL_RESULT (t2));
	}
      else if (code == TYPE_DECL)
	compare_tree_edges (DECL_ORIGINAL_TYPE (t1), DECL_ORIGINAL_TYPE (t2));
    }

  if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
    {
      /* Make sure we don't inadvertently set the assembler name.  */
      if (DECL_ASSEMBLER_NAME_SET_P (t1))
	compare_tree_edges (DECL_ASSEMBLER_NAME (t1),
			    DECL_ASSEMBLER_NAME (t2));
    }

  if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
    {
      compare_tree_edges (DECL_FIELD_OFFSET (t1), DECL_FIELD_OFFSET (t2));
      compare_tree_edges (DECL_BIT_FIELD_TYPE (t1), DECL_BIT_FIELD_TYPE (t2));
      compare_tree_edges (DECL_BIT_FIELD_REPRESENTATIVE (t1),
			  DECL_BIT_FIELD_REPRESENTATIVE (t2));
      compare_tree_edges (DECL_FIELD_BIT_OFFSET (t1),
			  DECL_FIELD_BIT_OFFSET (t2));
      compare_tree_edges (DECL_FCONTEXT (t1), DECL_FCONTEXT (t2));
    }

  if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
    {
      compare_tree_edges (DECL_FUNCTION_PERSONALITY (t1),
			  DECL_FUNCTION_PERSONALITY (t2));
      compare_tree_edges (DECL_VINDEX (t1), DECL_VINDEX (t2));
      compare_tree_edges (DECL_FUNCTION_SPECIFIC_TARGET (t1),
			  DECL_FUNCTION_SPECIFIC_TARGET (t2));
      compare_tree_edges (DECL_FUNCTION_SPECIFIC_OPTIMIZATION (t1),
			  DECL_FUNCTION_SPECIFIC_OPTIMIZATION (t2));
    }

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_COMMON))
    {
      compare_tree_edges (TYPE_SIZE (t1), TYPE_SIZE (t2));
      compare_tree_edges (TYPE_SIZE_UNIT (t1), TYPE_SIZE_UNIT (t2));
      compare_tree_edges (TYPE_ATTRIBUTES (t1), TYPE_ATTRIBUTES (t2));
      compare_tree_edges (TYPE_NAME (t1), TYPE_NAME (t2));
      /* Do not compare TYPE_POINTER_TO or TYPE_REFERENCE_TO.  They will be
	 reconstructed during fixup.  */
      /* Do not compare TYPE_NEXT_VARIANT, we reconstruct the variant lists
	 during fixup.  */
      compare_tree_edges (TYPE_MAIN_VARIANT (t1), TYPE_MAIN_VARIANT (t2));
      /* ???  Global types from different TUs have non-matching
	 TRANSLATION_UNIT_DECLs.  Still merge them if they are otherwise
	 equal.  */
      if (TYPE_FILE_SCOPE_P (t1) && TYPE_FILE_SCOPE_P (t2))
	;
      else
	compare_tree_edges (TYPE_CONTEXT (t1), TYPE_CONTEXT (t2));
      /* TYPE_CANONICAL is re-computed during type merging, so do not
	 compare it here.  */
      compare_tree_edges (TYPE_STUB_DECL (t1), TYPE_STUB_DECL (t2));
    }

  if (CODE_CONTAINS_STRUCT (code, TS_TYPE_NON_COMMON))
    {
      if (code == ARRAY_TYPE)
	compare_tree_edges (TYPE_DOMAIN (t1), TYPE_DOMAIN (t2));
      else if (RECORD_OR_UNION_TYPE_P (t1))
	{
	  tree f1, f2;
	  for (f1 = TYPE_FIELDS (t1), f2 = TYPE_FIELDS (t2);
	       f1 || f2;
	       f1 = TREE_CHAIN (f1), f2 = TREE_CHAIN (f2))
	    compare_tree_edges (f1, f2);
	}
      else if (code == FUNCTION_TYPE
	       || code == METHOD_TYPE)
	compare_tree_edges (TYPE_ARG_TYPES (t1), TYPE_ARG_TYPES (t2));

      if (!POINTER_TYPE_P (t1))
	compare_tree_edges (TYPE_MIN_VALUE_RAW (t1), TYPE_MIN_VALUE_RAW (t2));
      compare_tree_edges (TYPE_MAX_VALUE_RAW (t1), TYPE_MAX_VALUE_RAW (t2));
    }

  if (CODE_CONTAINS_STRUCT (code, TS_LIST))
    {
      compare_tree_edges (TREE_PURPOSE (t1), TREE_PURPOSE (t2));
      compare_tree_edges (TREE_VALUE (t1), TREE_VALUE (t2));
      compare_tree_edges (TREE_CHAIN (t1), TREE_CHAIN (t2));
    }

  if (CODE_CONTAINS_STRUCT (code, TS_VEC))
    for (int i = 0; i < TREE_VEC_LENGTH (t1); i++)
      compare_tree_edges (TREE_VEC_ELT (t1, i), TREE_VEC_ELT (t2, i));

  if (CODE_CONTAINS_STRUCT (code, TS_EXP))
    {
      for (int i = 0; i < TREE_OPERAND_LENGTH (t1); i++)
	compare_tree_edges (TREE_OPERAND (t1, i),
			    TREE_OPERAND (t2, i));

      /* BLOCKs are function local and we don't merge anything there.  */
      if (TREE_BLOCK (t1) || TREE_BLOCK (t2))
	return false;
    }

  if (CODE_CONTAINS_STRUCT (code, TS_BINFO))
    {
      unsigned i;
      tree t;
      /* Lengths have already been compared above.  */
      FOR_EACH_VEC_ELT (*BINFO_BASE_BINFOS (t1), i, t)
	compare_tree_edges (t, BINFO_BASE_BINFO (t2, i));
      FOR_EACH_VEC_SAFE_ELT (BINFO_BASE_ACCESSES (t1), i, t)
	compare_tree_edges (t, BINFO_BASE_ACCESS (t2, i));
      compare_tree_edges (BINFO_OFFSET (t1), BINFO_OFFSET (t2));
      compare_tree_edges (BINFO_VTABLE (t1), BINFO_VTABLE (t2));
      compare_tree_edges (BINFO_VPTR_FIELD (t1), BINFO_VPTR_FIELD (t2));
      /* Do not walk BINFO_INHERITANCE_CHAIN, BINFO_SUBVTT_INDEX
	 and BINFO_VPTR_INDEX; these are used by C++ FE only.  */
    }

  if (CODE_CONTAINS_STRUCT (code, TS_CONSTRUCTOR))
    {
      unsigned i;
      tree index, value;
      /* Lengths have already been compared above.  */
      FOR_EACH_CONSTRUCTOR_ELT (CONSTRUCTOR_ELTS (t1), i, index, value)
	{
	  compare_tree_edges (index, CONSTRUCTOR_ELT (t2, i)->index);
	  compare_tree_edges (value, CONSTRUCTOR_ELT (t2, i)->value);
	}
    }

  if (code == OMP_CLAUSE)
    {
      int i;

      for (i = 0; i < omp_clause_num_ops[OMP_CLAUSE_CODE (t1)]; i++)
	compare_tree_edges (OMP_CLAUSE_OPERAND (t1, i),
			    OMP_CLAUSE_OPERAND (t2, i));
      compare_tree_edges (OMP_CLAUSE_CHAIN (t1), OMP_CLAUSE_CHAIN (t2));
    }

#undef compare_tree_edges

  return true;
}

/* Compare the tree scc SCC to the prevailing candidate PSCC, filling
   out MAP if they are equal.  */

static bool
compare_tree_sccs (tree_scc *pscc, tree_scc *scc,
		   tree *map)
{
  /* Assume SCC entry hashes are sorted after their cardinality.  Which
     means we can simply take the first n-tuple of equal hashes
     (which is recorded as entry_len) and do n SCC entry candidate
     comparisons.  */
  for (unsigned i = 0; i < pscc->entry_len; ++i)
    {
      tree *mapp = map;
      num_scc_compare_collisions++;
      if (compare_tree_sccs_1 (pscc->entries[0], scc->entries[i], &mapp))
	{
	  /* Equal - no need to reset TREE_VISITED or TREE_ASM_WRITTEN
	     on the scc as all trees will be freed.  */
	  return true;
	}
      /* Reset TREE_ASM_WRITTEN on scc for the next compare or in case
	 the SCC prevails.  */
      for (unsigned j = 0; j < scc->len; ++j)
	TREE_ASM_WRITTEN (scc->entries[j]) = 0;
    }

  return false;
}

/* QSort sort function to sort a map of two pointers after the 2nd
   pointer.  */

static int
cmp_tree (const void *p1_, const void *p2_)
{
  tree *p1 = (tree *)(const_cast<void *>(p1_));
  tree *p2 = (tree *)(const_cast<void *>(p2_));
  if (p1[1] == p2[1])
    return 0;
  return ((uintptr_t)p1[1] < (uintptr_t)p2[1]) ? -1 : 1;
}

/* New scc of size 1 containing T was streamed in from DATA_IN and not merged.
   Register it to reader cache at index FROM.  */

static void
process_dref (class data_in *data_in, tree t, unsigned from)
{
  struct streamer_tree_cache_d *cache = data_in->reader_cache;
  /* If we got a debug reference queued, see if the prevailing
     tree has a debug reference and if not, register the one
     for the tree we are about to throw away.  */
  if (dref_queue.length () == 1)
    {
      dref_entry e = dref_queue.pop ();
      gcc_assert (e.decl
		  == streamer_tree_cache_get_tree (cache, from));
      const char *sym;
      unsigned HOST_WIDE_INT off;
      if (!debug_hooks->die_ref_for_decl (t, &sym, &off))
	debug_hooks->register_external_die (t, e.sym, e.off);
    }
}

/* Try to unify the SCC with nodes FROM to FROM + LEN in CACHE and
   hash value SCC_HASH with an already recorded SCC.  Return true if
   that was successful, otherwise return false.  */

static bool
unify_scc (class data_in *data_in, unsigned from,
	   unsigned len, unsigned scc_entry_len, hashval_t scc_hash)
{
  bool unified_p = false;
  struct streamer_tree_cache_d *cache = data_in->reader_cache;
  tree_scc *scc
    = (tree_scc *) alloca (sizeof (tree_scc) + (len - 1) * sizeof (tree));
  scc->next = NULL;
  scc->hash = scc_hash;
  scc->len = len;
  scc->entry_len = scc_entry_len;
  for (unsigned i = 0; i < len; ++i)
    {
      tree t = streamer_tree_cache_get_tree (cache, from + i);
      scc->entries[i] = t;
      /* These types should be streamed as unshared.  */
      gcc_checking_assert
	 (!(TREE_CODE (t) == TRANSLATION_UNIT_DECL
	    || (VAR_OR_FUNCTION_DECL_P (t)
		&& !(TREE_PUBLIC (t) || DECL_EXTERNAL (t)))
	    || TREE_CODE (t) == LABEL_DECL
	    || (TREE_CODE (t) == NAMESPACE_DECL && !DECL_NAME (t))
	    || (TYPE_P (t)
		&& type_with_linkage_p (TYPE_MAIN_VARIANT (t))
		&& type_in_anonymous_namespace_p (TYPE_MAIN_VARIANT (t)))));
    }

  /* Look for the list of candidate SCCs to compare against.  */
  tree_scc **slot;
  slot = tree_scc_hash->find_slot_with_hash (scc, scc_hash, INSERT);
  if (*slot)
    {
      /* Try unifying against each candidate.  */
      num_scc_compares++;

      /* Set TREE_VISITED on the scc so we can easily identify tree nodes
	 outside of the scc when following tree edges.  Make sure
	 that TREE_ASM_WRITTEN is unset so we can use it as 2nd bit
	 to track whether we visited the SCC member during the compare.
	 We cannot use TREE_VISITED on the pscc members as the extended
	 scc and pscc can overlap.  */
      for (unsigned i = 0; i < scc->len; ++i)
	{
	  TREE_VISITED (scc->entries[i]) = 1;
	  gcc_checking_assert (!TREE_ASM_WRITTEN (scc->entries[i]));
	}

      tree *map = XALLOCAVEC (tree, 2 * len);
      for (tree_scc *pscc = *slot; pscc; pscc = pscc->next)
	{
	  if (!compare_tree_sccs (pscc, scc, map))
	    continue;

	  /* Found an equal SCC.  */
	  unified_p = true;
	  num_scc_compare_collisions--;
	  num_sccs_merged++;
	  total_scc_size_merged += len;

	  if (flag_checking)
	    for (unsigned i = 0; i < len; ++i)
	      {
		tree t = map[2*i+1];
		enum tree_code code = TREE_CODE (t);
		/* IDENTIFIER_NODEs should be singletons and are merged by the
		   streamer.  The others should be singletons, too, and we
		   should not merge them in any way.  */
		gcc_assert (code != TRANSLATION_UNIT_DECL
			    && code != IDENTIFIER_NODE);
	      }

	  /* Fixup the streamer cache with the prevailing nodes according
	     to the tree node mapping computed by compare_tree_sccs.  */
	  if (len == 1)
	    {
	      process_dref (data_in, pscc->entries[0], from);
	      lto_maybe_register_decl (data_in, pscc->entries[0], from);
	      streamer_tree_cache_replace_tree (cache, pscc->entries[0], from);
	    }
	  else
	    {
	      tree *map2 = XALLOCAVEC (tree, 2 * len);
	      for (unsigned i = 0; i < len; ++i)
		{
		  map2[i*2] = (tree)(uintptr_t)(from + i);
		  map2[i*2+1] = scc->entries[i];
		}
	      qsort (map2, len, 2 * sizeof (tree), cmp_tree);
	      qsort (map, len, 2 * sizeof (tree), cmp_tree);
	      for (unsigned i = 0; i < len; ++i)
		{
		  lto_maybe_register_decl (data_in, map[2*i],
					   (uintptr_t)map2[2*i]);
		  streamer_tree_cache_replace_tree (cache, map[2*i],
						    (uintptr_t)map2[2*i]);
		}
	    }

	  /* Free the tree nodes from the read SCC.  */
	  data_in->location_cache.revert_location_cache ();
	  for (unsigned i = 0; i < len; ++i)
	    {
	      if (TYPE_P (scc->entries[i]))
		num_merged_types++;
	      free_node (scc->entries[i]);
	    }

	  /* Drop DIE references.
	     ???  Do as in the size-one SCC case which involves sorting
	     the queue.  */
	  dref_queue.truncate (0);

	  break;
	}

      /* Reset TREE_VISITED if we didn't unify the SCC with another.  */
      if (!unified_p)
	for (unsigned i = 0; i < scc->len; ++i)
	  TREE_VISITED (scc->entries[i]) = 0;
    }

  /* If we didn't unify it to any candidate duplicate the relevant
     pieces to permanent storage and link it into the chain.  */
  if (!unified_p)
    {
      tree_scc *pscc
	= XOBNEWVAR (&tree_scc_hash_obstack, tree_scc, sizeof (tree_scc));
      memcpy (pscc, scc, sizeof (tree_scc));
      pscc->next = (*slot);
      *slot = pscc;
    }
  return unified_p;
}

typedef int_hash<unsigned, 0, UINT_MAX> code_id_hash;

/* Do registering necessary once new tree fully streamed in (including all
   trees it reffers to).  */

static void
process_new_tree (tree t, hash_map <code_id_hash, unsigned> *hm,
		  unsigned index, unsigned *total, class data_in *data_in)
{
  /* Reconstruct the type variant and pointer-to/reference-to
     chains.  */
  if (TYPE_P (t))
    {
      /* Map the tree types to their frequencies.  */
      if (flag_lto_dump_type_stats)
	{
	  unsigned key = (unsigned) TREE_CODE (t);
	  unsigned *countp = hm->get (key);
	  hm->put (key, countp ? (*countp) + 1 : 1);
	  (*total)++;
	}

      num_prevailing_types++;
      lto_fixup_prevailing_type (t);

      /* Compute the canonical type of all non-ODR types.
	 Delay ODR types for the end of merging process - the canonical
	 type for those can be computed using the (unique) name however
	 we want to do this only if units in other languages do not
	 contain structurally equivalent type.

	 Because SCC components are streamed in random (hash) order
	 we may have encountered the type before while registering
	 type canonical of a derived type in the same SCC.  */
      if (!TYPE_CANONICAL (t))
	{
	  if (!RECORD_OR_UNION_TYPE_P (t)
	      || !TYPE_CXX_ODR_P (t))
	    gimple_register_canonical_type (t);
	  else if (COMPLETE_TYPE_P (t))
	    vec_safe_push (types_to_register, t);
	}
      if (TYPE_MAIN_VARIANT (t) == t && odr_type_p (t))
	register_odr_type (t);
    }
  /* Link shared INTEGER_CSTs into TYPE_CACHED_VALUEs of its
     type which is also member of this SCC.  */
  if (TREE_CODE (t) == INTEGER_CST
      && !TREE_OVERFLOW (t))
    cache_integer_cst (t);
  if (!flag_ltrans)
    {
      lto_maybe_register_decl (data_in, t, index);
      /* Scan the tree for references to global functions or
	 variables and record those for later fixup.  */
      if (mentions_vars_p (t))
	vec_safe_push (tree_with_vars, t);
    }
}

/* Read all the symbols from buffer DATA, using descriptors in DECL_DATA.
   RESOLUTIONS is the set of symbols picked by the linker (read from the
   resolution file when the linker plugin is being used).  */

static void
lto_read_decls (struct lto_file_decl_data *decl_data, const void *data,
		vec<ld_plugin_symbol_resolution_t> resolutions)
{
  const struct lto_decl_header *header = (const struct lto_decl_header *) data;
  const int decl_offset = sizeof (struct lto_decl_header);
  const int main_offset = decl_offset + header->decl_state_size;
  const int string_offset = main_offset + header->main_size;
  class data_in *data_in;
  unsigned int i;
  const uint32_t *data_ptr, *data_end;
  uint32_t num_decl_states;

  lto_input_block ib_main ((const char *) data + main_offset,
			   header->main_size, decl_data);

  data_in = lto_data_in_create (decl_data, (const char *) data + string_offset,
				header->string_size, resolutions);

  /* We do not uniquify the pre-loaded cache entries, those are middle-end
     internal types that should not be merged.  */

  hash_map <code_id_hash, unsigned> hm;
  unsigned total = 0;

  /* Read the global declarations and types.  */
  while (ib_main.p < ib_main.len)
    {
      tree t;
      unsigned from = data_in->reader_cache->nodes.length ();
      /* Read and uniquify SCCs as in the input stream.  */
      enum LTO_tags tag = streamer_read_record_start (&ib_main);
      if (tag == LTO_tree_scc || tag == LTO_trees)
	{
	  unsigned len_;
	  unsigned scc_entry_len;

	  /* Because we stream in SCC order we know that all unshared trees
	     are now fully streamed.  Process them.  */
	  hashval_t scc_hash = lto_input_scc (&ib_main, data_in, &len_,
					      &scc_entry_len,
					      tag == LTO_tree_scc);
	  unsigned len = data_in->reader_cache->nodes.length () - from;
	  gcc_assert (len == len_);

	  if (tag == LTO_tree_scc)
	    {
	      total_scc_size += len;
	      num_sccs_read++;
	    }
	  else
	    num_unshared_trees_read += len;

	  /* We have the special case of size-1 SCCs that are pre-merged
	     by means of identifier and string sharing for example.
	     ???  Maybe we should avoid streaming those as SCCs.  */
	  tree first = streamer_tree_cache_get_tree (data_in->reader_cache,
						     from);
	  /* Identifier and integers are shared specially, they should never
	     go by the tree merging path.  */
	  gcc_checking_assert ((TREE_CODE (first) != IDENTIFIER_NODE
				&& (TREE_CODE (first) != INTEGER_CST
				    || TREE_OVERFLOW (first)))
			       || len != 1);

	  /* Try to unify the SCC with already existing ones.  */
	  if (!flag_ltrans && tag != LTO_trees
	      && unify_scc (data_in, from,
			    len, scc_entry_len, scc_hash))
	    continue;

	  /* Tree merging failed, mark entries in location cache as
	     permanent.  */
	  data_in->location_cache.accept_location_cache ();

	  bool seen_type = false;
	  for (unsigned i = 0; i < len; ++i)
	    {
	      tree t = streamer_tree_cache_get_tree (data_in->reader_cache,
						     from + i);
	      process_new_tree (t, &hm, from + i, &total, data_in);
	      if (TYPE_P (t))
		seen_type = true;
	    }

	  /* Register DECLs with the debuginfo machinery.  */
	  while (!dref_queue.is_empty ())
	    {
	      dref_entry e = dref_queue.pop ();
	      debug_hooks->register_external_die (e.decl, e.sym, e.off);
	    }

	  if (seen_type)
	    num_type_scc_trees += len;
	}
      else
	{
	  t = lto_input_tree_1 (&ib_main, data_in, tag, 0);
	  gcc_assert (data_in->reader_cache->nodes.length () == from + 1);
	  num_unshared_trees_read++;
	  data_in->location_cache.accept_location_cache ();
	  process_dref (data_in, t, from);
	  if (TREE_CODE (t) == IDENTIFIER_NODE
	      || (TREE_CODE (t) == INTEGER_CST
		  && !TREE_OVERFLOW (t)))
	    ;
	  else
	    {
	      lto_maybe_register_decl (data_in, t, from);
	      process_new_tree (t, &hm, from, &total, data_in);
	    }
	}
    }

  /* Dump type statistics.  */
  if (flag_lto_dump_type_stats)
    {
      fprintf (stdout, "       Type     Frequency   Percentage\n\n");
      for (hash_map<code_id_hash, unsigned>::iterator itr = hm.begin ();
	   itr != hm.end ();
	   ++itr)
	{
	  std::pair<unsigned, unsigned> p = *itr;
	  enum tree_code code = (enum tree_code) p.first;
	  fprintf (stdout, "%14s %6d %12.2f\n", get_tree_code_name (code),
		   p.second, float (p.second)/total*100);
	}
    }

  data_in->location_cache.apply_location_cache ();

  /* Read in lto_in_decl_state objects.  */
  data_ptr = (const uint32_t *) ((const char*) data + decl_offset);
  data_end
    = (const uint32_t *) ((const char*) data_ptr + header->decl_state_size);
  num_decl_states = *data_ptr++;

  gcc_assert (num_decl_states > 0);
  decl_data->global_decl_state = lto_new_in_decl_state ();
  data_ptr = lto_read_in_decl_state (data_in, data_ptr,
				     decl_data->global_decl_state);

  /* Read in per-function decl states and enter them in hash table.  */
  decl_data->function_decl_states
    = hash_table<decl_state_hasher>::create_ggc (37);

  for (i = 1; i < num_decl_states; i++)
    {
      struct lto_in_decl_state *state = lto_new_in_decl_state ();

      data_ptr = lto_read_in_decl_state (data_in, data_ptr, state);
      lto_in_decl_state **slot
	= decl_data->function_decl_states->find_slot (state, INSERT);
      gcc_assert (*slot == NULL);
      *slot = state;
    }

  if (data_ptr != data_end)
    internal_error ("bytecode stream: garbage at the end of symbols section");

  /* Set the current decl state to be the global state.  */
  decl_data->current_decl_state = decl_data->global_decl_state;

  lto_data_in_delete (data_in);
}

/* Custom version of strtoll, which is not portable.  */

static int64_t
lto_parse_hex (const char *p)
{
  int64_t ret = 0;

  for (; *p != '\0'; ++p)
    {
      char c = *p;
      unsigned char part;
      ret <<= 4;
      if (c >= '0' && c <= '9')
	part = c - '0';
      else if (c >= 'a' && c <= 'f')
	part = c - 'a' + 10;
      else if (c >= 'A' && c <= 'F')
	part = c - 'A' + 10;
      else
	internal_error ("could not parse hex number");
      ret |= part;
    }

  return ret;
}

/* Read resolution for file named FILE_NAME.  The resolution is read from
   RESOLUTION.  */

static void
lto_resolution_read (splay_tree file_ids, FILE *resolution, lto_file *file)
{
  /* We require that objects in the resolution file are in the same
     order as the lto1 command line.  */
  unsigned int name_len;
  char *obj_name;
  unsigned int num_symbols;
  unsigned int i;
  struct lto_file_decl_data *file_data;
  splay_tree_node nd = NULL;

  if (!resolution)
    return;

  name_len = strlen (file->filename);
  obj_name = XNEWVEC (char, name_len + 1);
  fscanf (resolution, " ");   /* Read white space.  */

  fread (obj_name, sizeof (char), name_len, resolution);
  obj_name[name_len] = '\0';
  if (filename_cmp (obj_name, file->filename) != 0)
    internal_error ("unexpected file name %s in linker resolution file. "
		    "Expected %s", obj_name, file->filename);
  if (file->offset != 0)
    {
      int t;
      char offset_p[17];
      int64_t offset;
      t = fscanf (resolution, "@0x%16s", offset_p);
      if (t != 1)
	internal_error ("could not parse file offset");
      offset = lto_parse_hex (offset_p);
      if (offset != file->offset)
	internal_error ("unexpected offset");
    }

  free (obj_name);

  fscanf (resolution, "%u", &num_symbols);

  for (i = 0; i < num_symbols; i++)
    {
      int t;
      unsigned index;
      unsigned HOST_WIDE_INT id;
      char r_str[27];
      enum ld_plugin_symbol_resolution r = (enum ld_plugin_symbol_resolution) 0;
      unsigned int j;
      unsigned int lto_resolution_str_len = ARRAY_SIZE (lto_resolution_str);
      res_pair rp;

      t = fscanf (resolution, "%u " HOST_WIDE_INT_PRINT_HEX_PURE
		  " %26s %*[^\n]\n", &index, &id, r_str);
      if (t != 3)
	internal_error ("invalid line in the resolution file");

      for (j = 0; j < lto_resolution_str_len; j++)
	{
	  if (strcmp (lto_resolution_str[j], r_str) == 0)
	    {
	      r = (enum ld_plugin_symbol_resolution) j;
	      /* Incremental linking together with -fwhole-program may seem
		 somewhat contradictionary (as the point of incremental linking
		 is to allow re-linking with more symbols later) but it is
		 used to build LTO kernel.  We want to hide all symbols that
		 are not explicitly marked as exported and thus turn
		 LDPR_PREVAILING_DEF_IRONLY_EXP
		 to LDPR_PREVAILING_DEF_IRONLY.  */
	      if (flag_whole_program
		  && flag_incremental_link == INCREMENTAL_LINK_NOLTO
		  && r == LDPR_PREVAILING_DEF_IRONLY_EXP)
		r = LDPR_PREVAILING_DEF_IRONLY;
	      break;
	    }
	}
      if (j == lto_resolution_str_len)
	internal_error ("invalid resolution in the resolution file");

      if (!(nd && lto_splay_tree_id_equal_p (nd->key, id)))
	{
	  nd = lto_splay_tree_lookup (file_ids, id);
	  if (nd == NULL)
	    internal_error ("resolution sub id %wx not in object file", id);
	}

      file_data = (struct lto_file_decl_data *)nd->value;
      /* The indexes are very sparse.  To save memory save them in a compact
	 format that is only unpacked later when the subfile is processed.  */
      rp.res = r;
      rp.index = index;
      file_data->respairs.safe_push (rp);
      if (file_data->max_index < index)
	file_data->max_index = index;
    }
}

/* List of file_decl_datas.  */
struct file_data_list
{
  struct lto_file_decl_data *first, *last;
};

/* Is the name for a id'ed LTO section? */

static int
lto_section_with_id (const char *name, unsigned HOST_WIDE_INT *id)
{
  const char *s;

  if (strncmp (name, section_name_prefix, strlen (section_name_prefix)))
    return 0;

  if (flag_ltrans)
    {
      *id = 0;
      return 1;
    }

  s = strrchr (name, '.');
  if (!s)
    return 0;
  /* If the section is not suffixed with an ID return.  */
  if ((size_t)(s - name) == strlen (section_name_prefix))
    return 0;
  return sscanf (s, "." HOST_WIDE_INT_PRINT_HEX_PURE, id) == 1;
}

/* Create file_data of each sub file id.  */

static int
create_subid_section_table (struct lto_section_slot *ls, splay_tree file_ids,
			    struct file_data_list *list)
{
  struct lto_section_slot s_slot, *new_slot;
  unsigned HOST_WIDE_INT id;
  splay_tree_node nd;
  void **hash_slot;
  char *new_name;
  struct lto_file_decl_data *file_data;

  if (!lto_section_with_id (ls->name, &id))
    return 1;

  /* Find hash table of sub module id.  */
  nd = lto_splay_tree_lookup (file_ids, id);
  if (nd != NULL)
    {
      file_data = (struct lto_file_decl_data *)nd->value;
    }
  else
    {
      file_data = ggc_alloc<lto_file_decl_data> ();
      memset(file_data, 0, sizeof (struct lto_file_decl_data));
      file_data->id = id;
      file_data->section_hash_table = lto_obj_create_section_hash_table ();
      lto_splay_tree_insert (file_ids, id, file_data);

      /* Maintain list in linker order.  */
      if (!list->first)
	list->first = file_data;
      if (list->last)
	list->last->next = file_data;

      list->last = file_data;
    }

  /* Copy section into sub module hash table.  */
  new_name = XDUPVEC (char, ls->name, strlen (ls->name) + 1);
  s_slot.name = new_name;
  hash_slot = htab_find_slot (file_data->section_hash_table, &s_slot, INSERT);
  gcc_assert (*hash_slot == NULL);

  new_slot = XDUP (struct lto_section_slot, ls);
  new_slot->name = new_name;
  *hash_slot = new_slot;
  return 1;
}

/* Read declarations and other initializations for a FILE_DATA.  */

static void
lto_file_finalize (struct lto_file_decl_data *file_data, lto_file *file,
		   int order)
{
  const char *data;
  size_t len;
  vec<ld_plugin_symbol_resolution_t>
	resolutions = vNULL;
  int i;
  res_pair *rp;

  /* Create vector for fast access of resolution.  We do this lazily
     to save memory.  */
  resolutions.safe_grow_cleared (file_data->max_index + 1, true);
  for (i = 0; file_data->respairs.iterate (i, &rp); i++)
    resolutions[rp->index] = rp->res;
  file_data->respairs.release ();

  file_data->renaming_hash_table = lto_create_renaming_table ();
  file_data->file_name = file->filename;
  file_data->order = order;

  /* Read and verify LTO section.  */
  data = lto_get_summary_section_data (file_data, LTO_section_lto, &len);
  if (data == NULL)
    {
      fatal_error (input_location, "bytecode stream in file %qs generated "
		   "with GCC compiler older than 10.0", file_data->file_name);
      return;
    }

  memcpy (&file_data->lto_section_header, data, sizeof (lto_section));
  lto_check_version (file_data->lto_section_header.major_version,
		     file_data->lto_section_header.minor_version,
		     file_data->file_name);

#ifdef ACCEL_COMPILER
  lto_input_mode_table (file_data);
#else
  file_data->mode_table = NULL;
  file_data->mode_bits = ceil_log2 (MAX_MACHINE_MODE);
#endif

  data = lto_get_summary_section_data (file_data, LTO_section_decls, &len);
  if (data == NULL)
    {
      internal_error ("cannot read %<LTO_section_decls%> from %s",
		      file_data->file_name);
      return;
    }
  /* Frees resolutions.  */
  lto_read_decls (file_data, data, resolutions);
  lto_free_section_data (file_data, LTO_section_decls, NULL, data, len);
}

/* Finalize FILE_DATA in FILE and increase COUNT.  */

static int
lto_create_files_from_ids (lto_file *file, struct lto_file_decl_data *file_data,
			   int *count, int order)
{
  lto_file_finalize (file_data, file, order);
  if (symtab->dump_file)
    fprintf (symtab->dump_file,
	     "Creating file %s with sub id " HOST_WIDE_INT_PRINT_HEX "\n",
	     file_data->file_name, file_data->id);
  (*count)++;
  return 0;
}

/* Generate a TREE representation for all types and external decls
   entities in FILE.

   Read all of the globals out of the file.  Then read the cgraph
   and process the .o index into the cgraph nodes so that it can open
   the .o file to load the functions and ipa information.  */

static struct lto_file_decl_data *
lto_file_read (lto_file *file, FILE *resolution_file, int *count)
{
  struct lto_file_decl_data *file_data = NULL;
  splay_tree file_ids;
  htab_t section_hash_table;
  struct lto_section_slot *section;
  struct file_data_list file_list;
  struct lto_section_list section_list;

  memset (&section_list, 0, sizeof (struct lto_section_list));
  section_hash_table = lto_obj_build_section_table (file, &section_list);

  /* Dump the details of LTO objects.  */
  if (flag_lto_dump_objects)
  {
    int i=0;
    fprintf (stdout, "\n    LTO Object Name: %s\n", file->filename);
    fprintf (stdout, "\nNo.    Offset    Size       Section Name\n\n");
    for (section = section_list.first; section != NULL; section = section->next)
      fprintf (stdout, "%2d %8" PRId64 " %8" PRIu64 "   %s\n",
	       ++i, (int64_t) section->start, (uint64_t) section->len,
	       section->name);
  }

  /* Find all sub modules in the object and put their sections into new hash
     tables in a splay tree.  */
  file_ids = lto_splay_tree_new ();
  memset (&file_list, 0, sizeof (struct file_data_list));
  for (section = section_list.first; section != NULL; section = section->next)
    create_subid_section_table (section, file_ids, &file_list);

  /* Add resolutions to file ids.  */
  lto_resolution_read (file_ids, resolution_file, file);

  /* Finalize each lto file for each submodule in the merged object.  */
  int order = 0;
  for (file_data = file_list.first; file_data != NULL;
       file_data = file_data->next)
    lto_create_files_from_ids (file, file_data, count, order++);

  splay_tree_delete (file_ids);
  htab_delete (section_hash_table);

  return file_list.first;
}

#if HAVE_MMAP_FILE && HAVE_SYSCONF && defined _SC_PAGE_SIZE
#define LTO_MMAP_IO 1
#endif

#if LTO_MMAP_IO
/* Page size of machine is used for mmap and munmap calls.  */
static size_t page_mask;
#endif

/* Get the section data of length LEN from FILENAME starting at
   OFFSET.  The data segment must be freed by the caller when the
   caller is finished.  Returns NULL if all was not well.  */

static char *
lto_read_section_data (struct lto_file_decl_data *file_data,
		       off_t offset, size_t len)
{
  char *result;
  static int fd = -1;
  static char *fd_name;
#if LTO_MMAP_IO
  size_t computed_len;
  off_t computed_offset;
  off_t diff;
#endif

  /* Keep a single-entry file-descriptor cache.  The last file we
     touched will get closed at exit.
     ???  Eventually we want to add a more sophisticated larger cache
     or rather fix function body streaming to not stream them in
     practically random order.  */
  if (fd != -1
      && filename_cmp (fd_name, file_data->file_name) != 0)
    {
      free (fd_name);
      close (fd);
      fd = -1;
    }
  if (fd == -1)
    {
      fd = open (file_data->file_name, O_RDONLY|O_BINARY);
      if (fd == -1)
	{
	  fatal_error (input_location, "Cannot open %s", file_data->file_name);
	  return NULL;
	}
      fd_name = xstrdup (file_data->file_name);
    }

#if LTO_MMAP_IO
  if (!page_mask)
    {
      size_t page_size = sysconf (_SC_PAGE_SIZE);
      page_mask = ~(page_size - 1);
    }

  computed_offset = offset & ((off_t) page_mask);
  diff = offset - computed_offset;
  if (len > (((size_t) -1) >> 1) - diff)
    {
      fatal_error (input_location, "Cannot map %s: section is too long",
		   file_data->file_name);
      return NULL;
    }
  computed_len = (size_t) diff + len;

  result = (char *) mmap (NULL, computed_len, PROT_READ, MAP_PRIVATE,
			  fd, computed_offset);
  if (result == MAP_FAILED)
    {
      fatal_error (input_location, "Cannot map %s", file_data->file_name);
      return NULL;
    }

  return result + diff;
#else
  result = (char *) xmalloc (len);
  if (lseek (fd, offset, SEEK_SET) != offset
      || read (fd, result, len) != (ssize_t) len)
    {
      free (result);
      fatal_error (input_location, "Cannot read %s", file_data->file_name);
      result = NULL;
    }
#ifdef __MINGW32__
  /* Native windows doesn't supports delayed unlink on opened file.  So
     we close file here again.  This produces higher I/O load, but at least
     it prevents to have dangling file handles preventing unlink.  */
  free (fd_name);
  fd_name = NULL;
  close (fd);
  fd = -1;
#endif
  return result;
#endif
}


/* Get the section data from FILE_DATA of SECTION_TYPE with NAME.
   NAME will be NULL unless the section type is for a function
   body.  */

static const char *
get_section_data (struct lto_file_decl_data *file_data,
		  enum lto_section_type section_type,
		  const char *name, int order,
		  size_t *len)
{
  htab_t section_hash_table = file_data->section_hash_table;
  struct lto_section_slot *f_slot;
  struct lto_section_slot s_slot;
  const char *section_name = lto_get_section_name (section_type, name,
						   order, file_data);
  char *data = NULL;

  *len = 0;
  s_slot.name = section_name;
  f_slot = (struct lto_section_slot *) htab_find (section_hash_table, &s_slot);
  if (f_slot)
    {
      data = lto_read_section_data (file_data, f_slot->start, f_slot->len);
      *len = f_slot->len;
    }

  free (const_cast<char *> (section_name));
  return data;
}


/* Free the section data from FILE_DATA of SECTION_TYPE with NAME that
   starts at OFFSET and has LEN bytes.  */

static void
free_section_data (struct lto_file_decl_data *file_data ATTRIBUTE_UNUSED,
		   enum lto_section_type section_type ATTRIBUTE_UNUSED,
		   const char *name ATTRIBUTE_UNUSED,
		   const char *offset, size_t len ATTRIBUTE_UNUSED)
{
#if LTO_MMAP_IO
  intptr_t computed_len;
  intptr_t computed_offset;
  intptr_t diff;
#endif

#if LTO_MMAP_IO
  computed_offset = ((intptr_t) offset) & page_mask;
  diff = (intptr_t) offset - computed_offset;
  computed_len = len + diff;

  munmap ((caddr_t) computed_offset, computed_len);
#else
  free (const_cast<char *> (offset));
#endif
}

static lto_file *current_lto_file;

/* If TT is a variable or function decl replace it with its
   prevailing variant.  */
#define LTO_SET_PREVAIL(tt) \
  do {\
    if ((tt) && VAR_OR_FUNCTION_DECL_P (tt) \
	&& (TREE_PUBLIC (tt) || DECL_EXTERNAL (tt))) \
      { \
	tt = lto_symtab_prevailing_decl (tt); \
	fixed = true; \
      } \
  } while (0)

/* Ensure that TT isn't a replacable var of function decl.  */
#define LTO_NO_PREVAIL(tt) \
  gcc_checking_assert (!(tt) || !VAR_OR_FUNCTION_DECL_P (tt))

/* Given a tree T replace all fields referring to variables or functions
   with their prevailing variant.  */
static void
lto_fixup_prevailing_decls (tree t)
{
  enum tree_code code = TREE_CODE (t);
  bool fixed = false;

  gcc_checking_assert (code != TREE_BINFO);
  LTO_NO_PREVAIL (TREE_TYPE (t));
  if (CODE_CONTAINS_STRUCT (code, TS_COMMON)
      /* lto_symtab_prevail_decl use TREE_CHAIN to link to the prevailing decl.
	 in the case T is a prevailed declaration we would ICE here.  */
      && !VAR_OR_FUNCTION_DECL_P (t))
    LTO_NO_PREVAIL (TREE_CHAIN (t));
  if (DECL_P (t))
    {
      LTO_NO_PREVAIL (DECL_NAME (t));
      LTO_SET_PREVAIL (DECL_CONTEXT (t));
      if (CODE_CONTAINS_STRUCT (code, TS_DECL_COMMON))
	{
	  LTO_SET_PREVAIL (DECL_SIZE (t));
	  LTO_SET_PREVAIL (DECL_SIZE_UNIT (t));
	  LTO_SET_PREVAIL (DECL_INITIAL (t));
	  LTO_NO_PREVAIL (DECL_ATTRIBUTES (t));
	  LTO_SET_PREVAIL (DECL_ABSTRACT_ORIGIN (t));
	}
      if (CODE_CONTAINS_STRUCT (code, TS_DECL_WITH_VIS))
	{
	  LTO_NO_PREVAIL (DECL_ASSEMBLER_NAME_RAW (t));
	}
      if (CODE_CONTAINS_STRUCT (code, TS_DECL_NON_COMMON))
	{
	  LTO_NO_PREVAIL (DECL_RESULT_FLD (t));
	}
      if (CODE_CONTAINS_STRUCT (code, TS_FUNCTION_DECL))
	{
	  LTO_NO_PREVAIL (DECL_ARGUMENTS (t));
	  LTO_SET_PREVAIL (DECL_FUNCTION_PERSONALITY (t));
	  LTO_NO_PREVAIL (DECL_VINDEX (t));
	}
      if (CODE_CONTAINS_STRUCT (code, TS_FIELD_DECL))
	{
	  LTO_SET_PREVAIL (DECL_FIELD_OFFSET (t));
	  LTO_NO_PREVAIL (DECL_BIT_FIELD_TYPE (t));
	  LTO_NO_PREVAIL (DECL_QUALIFIER (t));
	  LTO_NO_PREVAIL (DECL_FIELD_BIT_OFFSET (t));
	  LTO_NO_PREVAIL (DECL_FCONTEXT (t));
	}
    }
  else if (TYPE_P (t))
    {
      LTO_NO_PREVAIL (TYPE_CACHED_VALUES (t));
      LTO_SET_PREVAIL (TYPE_SIZE (t));
      LTO_SET_PREVAIL (TYPE_SIZE_UNIT (t));
      LTO_NO_PREVAIL (TYPE_ATTRIBUTES (t));
      LTO_NO_PREVAIL (TYPE_NAME (t));

      LTO_SET_PREVAIL (TYPE_MIN_VALUE_RAW (t));
      LTO_SET_PREVAIL (TYPE_MAX_VALUE_RAW (t));
      LTO_NO_PREVAIL (TYPE_LANG_SLOT_1 (t));

      LTO_SET_PREVAIL (TYPE_CONTEXT (t));

      LTO_NO_PREVAIL (TYPE_CANONICAL (t));
      LTO_NO_PREVAIL (TYPE_MAIN_VARIANT (t));
      LTO_NO_PREVAIL (TYPE_NEXT_VARIANT (t));
    }
  else if (EXPR_P (t))
    {
      int i;
      for (i = TREE_OPERAND_LENGTH (t) - 1; i >= 0; --i)
	LTO_SET_PREVAIL (TREE_OPERAND (t, i));
    }
  else if (TREE_CODE (t) == CONSTRUCTOR)
    {
      unsigned i;
      tree val;
      FOR_EACH_CONSTRUCTOR_VALUE (CONSTRUCTOR_ELTS (t), i, val)
	LTO_SET_PREVAIL (val);
    }
  else
    {
      switch (code)
	{
	case TREE_LIST:
	  LTO_SET_PREVAIL (TREE_VALUE (t));
	  LTO_SET_PREVAIL (TREE_PURPOSE (t));
	  break;
	default:
	  gcc_unreachable ();
	}
    }
  /* If we fixed nothing, then we missed something seen by
     mentions_vars_p.  */
  gcc_checking_assert (fixed);
}
#undef LTO_SET_PREVAIL
#undef LTO_NO_PREVAIL

/* Helper function of lto_fixup_decls.  Walks the var and fn streams in STATE,
   replaces var and function decls with the corresponding prevailing def.  */

static void
lto_fixup_state (struct lto_in_decl_state *state)
{
  unsigned i, si;

  /* Although we only want to replace FUNCTION_DECLs and VAR_DECLs,
     we still need to walk from all DECLs to find the reachable
     FUNCTION_DECLs and VAR_DECLs.  */
  for (si = 0; si < LTO_N_DECL_STREAMS; si++)
    {
      vec<tree, va_gc> *trees = state->streams[si];
      for (i = 0; i < vec_safe_length (trees); i++)
	{
	  tree t = (*trees)[i];
	  if (flag_checking && TYPE_P (t))
	    verify_type (t);
	  if (VAR_OR_FUNCTION_DECL_P (t)
	      && (TREE_PUBLIC (t) || DECL_EXTERNAL (t)))
	    (*trees)[i] = lto_symtab_prevailing_decl (t);
	}
    }
}

/* Fix the decls from all FILES.  Replaces each decl with the corresponding
   prevailing one.  */

static void
lto_fixup_decls (struct lto_file_decl_data **files)
{
  unsigned int i;
  tree t;

  if (tree_with_vars)
    FOR_EACH_VEC_ELT ((*tree_with_vars), i, t)
      lto_fixup_prevailing_decls (t);

  for (i = 0; files[i]; i++)
    {
      struct lto_file_decl_data *file = files[i];
      struct lto_in_decl_state *state = file->global_decl_state;
      lto_fixup_state (state);

      hash_table<decl_state_hasher>::iterator iter;
      lto_in_decl_state *elt;
      FOR_EACH_HASH_TABLE_ELEMENT (*file->function_decl_states, elt,
				   lto_in_decl_state *, iter)
	lto_fixup_state (elt);
    }
}

static GTY((length ("lto_stats.num_input_files + 1"))) struct lto_file_decl_data **all_file_decl_data;

/* Turn file datas for sub files into a single array, so that they look
   like separate files for further passes.  */

static void
lto_flatten_files (struct lto_file_decl_data **orig, int count,
		   int last_file_ix)
{
  struct lto_file_decl_data *n, *next;
  int i, k;

  lto_stats.num_input_files = count;
  all_file_decl_data
    = ggc_cleared_vec_alloc<lto_file_decl_data_ptr> (count + 1);
  /* Set the hooks so that all of the ipa passes can read in their data.  */
  lto_set_in_hooks (all_file_decl_data, get_section_data, free_section_data);
  for (i = 0, k = 0; i < last_file_ix; i++)
    {
      for (n = orig[i]; n != NULL; n = next)
	{
	  all_file_decl_data[k++] = n;
	  next = n->next;
	  n->next = NULL;
	}
    }
  all_file_decl_data[k] = NULL;
  gcc_assert (k == count);
}

/* Input file data before flattening (i.e. splitting them to subfiles to support
   incremental linking.  */
static int real_file_count;
static GTY((length ("real_file_count + 1"))) struct lto_file_decl_data **real_file_decl_data;

/* Read all the symbols from the input files FNAMES.  NFILES is the
   number of files requested in the command line.  Instantiate a
   global call graph by aggregating all the sub-graphs found in each
   file.  */

void
read_cgraph_and_symbols (unsigned nfiles, const char **fnames)
{
  unsigned int i, last_file_ix;
  FILE *resolution;
  unsigned resolution_objects = 0;
  int count = 0;
  struct lto_file_decl_data **decl_data;
  symtab_node *snode;

  symtab->initialize ();

  timevar_push (TV_IPA_LTO_DECL_IN);

#ifdef ACCEL_COMPILER
  section_name_prefix = OFFLOAD_SECTION_NAME_PREFIX;
  lto_stream_offload_p = true;
#endif

  real_file_decl_data
    = decl_data = ggc_cleared_vec_alloc<lto_file_decl_data_ptr> (nfiles + 1);
  real_file_count = nfiles;

  /* Read the resolution file.  */
  resolution = NULL;
  if (resolution_file_name)
    {
      int t;

      resolution = fopen (resolution_file_name, "r");
      if (resolution == NULL)
	fatal_error (input_location,
		     "could not open symbol resolution file: %m");

      t = fscanf (resolution, "%u", &resolution_objects);
      gcc_assert (t == 1);
    }
  symtab->state = LTO_STREAMING;

  canonical_type_hash_cache = new hash_map<const_tree, hashval_t> (251);
  gimple_canonical_types = htab_create (16381, gimple_canonical_type_hash,
					gimple_canonical_type_eq, NULL);
  gcc_obstack_init (&tree_scc_hash_obstack);
  tree_scc_hash = new hash_table<tree_scc_hasher> (4096);

  /* Register the common node types with the canonical type machinery so
     we properly share alias-sets across languages and TUs.  Do not
     expose the common nodes as type merge target - those that should be
     are already exposed so by pre-loading the LTO streamer caches.
     Do two passes - first clear TYPE_CANONICAL and then re-compute it.  */
  for (i = 0; i < itk_none; ++i)
    lto_register_canonical_types (integer_types[i], true);
  for (i = 0; i < stk_type_kind_last; ++i)
    lto_register_canonical_types (sizetype_tab[i], true);
  for (i = 0; i < TI_MAX; ++i)
    lto_register_canonical_types (global_trees[i], true);
  for (i = 0; i < itk_none; ++i)
    lto_register_canonical_types (integer_types[i], false);
  for (i = 0; i < stk_type_kind_last; ++i)
    lto_register_canonical_types (sizetype_tab[i], false);
  for (i = 0; i < TI_MAX; ++i)
    lto_register_canonical_types (global_trees[i], false);

  if (!quiet_flag)
    fprintf (stderr, "Reading object files:");

  /* Read all of the object files specified on the command line.  */
  for (i = 0, last_file_ix = 0; i < nfiles; ++i)
    {
      struct lto_file_decl_data *file_data = NULL;
      if (!quiet_flag)
	{
	  fprintf (stderr, " %s", fnames[i]);
	  fflush (stderr);
	}

      current_lto_file = lto_obj_file_open (fnames[i], false);
      if (!current_lto_file)
	break;

      file_data = lto_file_read (current_lto_file, resolution, &count);
      if (!file_data)
	{
	  lto_obj_file_close (current_lto_file);
	  free (current_lto_file);
	  current_lto_file = NULL;
	  break;
	}

      decl_data[last_file_ix++] = file_data;

      lto_obj_file_close (current_lto_file);
      free (current_lto_file);
      current_lto_file = NULL;
    }

  lto_flatten_files (decl_data, count, last_file_ix);
  lto_stats.num_input_files = count;
  ggc_free(decl_data);
  real_file_decl_data = NULL;

  lto_register_canonical_types_for_odr_types ();

  if (resolution_file_name)
    {
      /* True, since the plugin splits the archives.  */
      gcc_assert (resolution_objects == nfiles);
      fclose (resolution);
    }

  /* Show the LTO report before launching LTRANS.  */
  if (flag_lto_report || (flag_wpa && flag_lto_report_wpa))
    print_lto_report_1 ();

  /* Free gimple type merging datastructures.  */
  delete tree_scc_hash;
  tree_scc_hash = NULL;
  obstack_free (&tree_scc_hash_obstack, NULL);
  htab_delete (gimple_canonical_types);
  gimple_canonical_types = NULL;
  delete canonical_type_hash_cache;
  canonical_type_hash_cache = NULL;

  /* At this stage we know that majority of GGC memory is reachable.
     Growing the limits prevents unnecesary invocation of GGC.  */
  ggc_grow ();
  report_heap_memory_use ();

  /* Set the hooks so that all of the ipa passes can read in their data.  */
  lto_set_in_hooks (all_file_decl_data, get_section_data, free_section_data);

  timevar_pop (TV_IPA_LTO_DECL_IN);

  if (!quiet_flag)
    fprintf (stderr, "\nReading the symbol table:");

  timevar_push (TV_IPA_LTO_CGRAPH_IO);
  /* Read the symtab.  */
  input_symtab ();

  input_offload_tables (!flag_ltrans);

  /* Store resolutions into the symbol table.  */

  FOR_EACH_SYMBOL (snode)
    if (snode->externally_visible && snode->real_symbol_p ()
	&& snode->lto_file_data && snode->lto_file_data->resolution_map
	&& !(TREE_CODE (snode->decl) == FUNCTION_DECL
	     && fndecl_built_in_p (snode->decl))
	&& !(VAR_P (snode->decl) && DECL_HARD_REGISTER (snode->decl)))
      {
	ld_plugin_symbol_resolution_t *res;

	res = snode->lto_file_data->resolution_map->get (snode->decl);
	if (!res || *res == LDPR_UNKNOWN)
	  {
	    if (snode->output_to_lto_symbol_table_p ())
	      fatal_error (input_location, "missing resolution data for %s",
			   IDENTIFIER_POINTER
			     (DECL_ASSEMBLER_NAME (snode->decl)));
	  }
	/* Symbol versions are always used externally, but linker does not
	   report that correctly.
	   This is binutils PR25924.  */
	else if (snode->symver && *res == LDPR_PREVAILING_DEF_IRONLY)
	  snode->resolution = LDPR_PREVAILING_DEF_IRONLY_EXP;
	else
	  snode->resolution = *res;
      }
  for (i = 0; all_file_decl_data[i]; i++)
    if (all_file_decl_data[i]->resolution_map)
      {
	delete all_file_decl_data[i]->resolution_map;
	all_file_decl_data[i]->resolution_map = NULL;
      }

  timevar_pop (TV_IPA_LTO_CGRAPH_IO);

  if (!quiet_flag)
    fprintf (stderr, "\nMerging declarations:");

  timevar_push (TV_IPA_LTO_DECL_MERGE);
  /* Merge global decls.  In ltrans mode we read merged cgraph, we do not
     need to care about resolving symbols again, we only need to replace
     duplicated declarations read from the callgraph and from function
     sections.  */
  if (!flag_ltrans)
    {
      lto_symtab_merge_decls ();

      /* If there were errors during symbol merging bail out, we have no
	 good way to recover here.  */
      if (seen_error ())
	fatal_error (input_location,
		     "errors during merging of translation units");

      /* Fixup all decls.  */
      lto_fixup_decls (all_file_decl_data);
    }
  if (tree_with_vars)
    ggc_free (tree_with_vars);
  tree_with_vars = NULL;

  input_toplevel_asms ();

  /* During WPA we want to prevent ggc collecting by default.  Grow limits
     until after the IPA summaries are streamed in.  Basically all IPA memory
     is explcitly managed by ggc_free and ggc collect is not useful.
     Exception are the merged declarations.  */
  ggc_grow ();
  report_heap_memory_use ();

  timevar_pop (TV_IPA_LTO_DECL_MERGE);
  /* Each pass will set the appropriate timer.  */

  if (!quiet_flag)
    fprintf (stderr, "\nReading summaries:");

  /* Read the IPA summary data.  */
  if (flag_ltrans)
    ipa_read_optimization_summaries ();
  else
    ipa_read_summaries ();

  ggc_grow ();

  for (i = 0; all_file_decl_data[i]; i++)
    {
      gcc_assert (all_file_decl_data[i]->symtab_node_encoder);
      lto_symtab_encoder_delete (all_file_decl_data[i]->symtab_node_encoder);
      all_file_decl_data[i]->symtab_node_encoder = NULL;
      lto_in_decl_state *global_decl_state
	= all_file_decl_data[i]->global_decl_state;
      lto_free_function_in_decl_state (global_decl_state);
      all_file_decl_data[i]->global_decl_state = NULL;
      all_file_decl_data[i]->current_decl_state = NULL;
    }

  if (!flag_ltrans)
    {
      /* Finally merge the cgraph according to the decl merging decisions.  */
      timevar_push (TV_IPA_LTO_CGRAPH_MERGE);

      if (!quiet_flag)
	fprintf (stderr, "\nMerging symbols:");

      gcc_assert (!dump_file);
      dump_file = dump_begin (lto_link_dump_id, NULL);

      if (dump_file)
	{
	  fprintf (dump_file, "Before merging:\n");
	  symtab->dump (dump_file);
	}
      lto_symtab_merge_symbols ();
      analyze_toplevel_extended_asm ();
      /* Removal of unreachable symbols is needed to make verify_symtab to pass;
	 we are still having duplicated comdat groups containing local statics.
	 We could also just remove them while merging.  */
      symtab->remove_unreachable_nodes (dump_file);
      ggc_collect ();
      report_heap_memory_use ();

      if (dump_file)
	dump_end (lto_link_dump_id, dump_file);
      dump_file = NULL;
      timevar_pop (TV_IPA_LTO_CGRAPH_MERGE);
    }
  symtab->state = IPA_SSA;
  /* All node removals happening here are useless, because
     WPA should not stream them.  Still always perform remove_unreachable_nodes
     because we may reshape clone tree, get rid of dead masters of inline
     clones and remove symbol entries for read-only variables we keep around
     only to be able to constant fold them.  */
  if (flag_ltrans)
    {
      if (symtab->dump_file)
	 symtab->dump (symtab->dump_file);
      symtab->remove_unreachable_nodes (symtab->dump_file);
    }

  /* Indicate that the cgraph is built and ready.  */
  symtab->function_flags_ready = true;

  ggc_free (all_file_decl_data);
  all_file_decl_data = NULL;
}



/* Show various memory usage statistics related to LTO.  */
void
print_lto_report_1 (void)
{
  const char *pfx = (flag_lto) ? "LTO" : (flag_wpa) ? "WPA" : "LTRANS";
  fprintf (stderr, "%s statistics\n", pfx);

  fprintf (stderr, "[%s] read %lu unshared trees\n",
	   pfx, num_unshared_trees_read);
  fprintf (stderr, "[%s] read %lu mergeable SCCs of average size %f\n",
	   pfx, num_sccs_read, total_scc_size / (double)num_sccs_read);
  fprintf (stderr, "[%s] %lu tree bodies read in total\n", pfx,
	   total_scc_size + num_unshared_trees_read);
  if (flag_wpa && tree_scc_hash && num_sccs_read)
    {
      fprintf (stderr, "[%s] tree SCC table: size " HOST_SIZE_T_PRINT_DEC ", "
	       HOST_SIZE_T_PRINT_DEC " elements, collision ratio: %f\n", pfx,
	       (fmt_size_t) tree_scc_hash->size (),
	       (fmt_size_t) tree_scc_hash->elements (),
	       tree_scc_hash->collisions ());
      hash_table<tree_scc_hasher>::iterator hiter;
      tree_scc *scc, *max_scc = NULL;
      unsigned max_length = 0;
      FOR_EACH_HASH_TABLE_ELEMENT (*tree_scc_hash, scc, x, hiter)
	{
	  unsigned length = 0;
	  tree_scc *s = scc;
	  for (; s; s = s->next)
	    length++;
	  if (length > max_length)
	    {
	      max_length = length;
	      max_scc = scc;
	    }
	}
      fprintf (stderr, "[%s] tree SCC max chain length %u (size %u)\n",
	       pfx, max_length, max_scc->len);
      fprintf (stderr, "[%s] Compared %lu SCCs, %lu collisions (%f)\n", pfx,
	       num_scc_compares, num_scc_compare_collisions,
	       num_scc_compare_collisions / (double) num_scc_compares);
      fprintf (stderr, "[%s] Merged %lu SCCs\n", pfx, num_sccs_merged);
      fprintf (stderr, "[%s] Merged %lu tree bodies\n", pfx,
	       total_scc_size_merged);
      fprintf (stderr, "[%s] Merged %lu types\n", pfx, num_merged_types);
      fprintf (stderr, "[%s] %lu types prevailed (%lu associated trees)\n",
	       pfx, num_prevailing_types, num_type_scc_trees);
      fprintf (stderr, "[%s] GIMPLE canonical type table: size "
	       HOST_SIZE_T_PRINT_DEC ", " HOST_SIZE_T_PRINT_DEC
	       " elements, %d searches, %d collisions (ratio: %f)\n", pfx,
	       (fmt_size_t) htab_size (gimple_canonical_types),
	       (fmt_size_t) htab_elements (gimple_canonical_types),
	       gimple_canonical_types->searches,
	       gimple_canonical_types->collisions,
	       htab_collisions (gimple_canonical_types));
      fprintf (stderr, "[%s] GIMPLE canonical type pointer-map: "
	       "%lu elements, %ld searches\n", pfx,
	       num_canonical_type_hash_entries,
	       num_canonical_type_hash_queries);
    }

  print_lto_report (pfx);
}

GTY(()) tree lto_eh_personality_decl;

/* Return the LTO personality function decl.  */

tree
lto_eh_personality (void)
{
  if (!lto_eh_personality_decl)
    {
      /* Use the first personality DECL for our personality if we don't
	 support multiple ones.  This ensures that we don't artificially
	 create the need for them in a single-language program.  */
      if (first_personality_decl && !dwarf2out_do_cfi_asm ())
	lto_eh_personality_decl = first_personality_decl;
      else
	lto_eh_personality_decl = lhd_gcc_personality ();
    }

  return lto_eh_personality_decl;
}

/* Set the process name based on the LTO mode.  */

static void
lto_process_name (void)
{
  if (flag_lto)
    setproctitle (flag_incremental_link == INCREMENTAL_LINK_LTO
		  ? "lto1-inclink" : "lto1-lto");
  if (flag_wpa)
    setproctitle ("lto1-wpa");
  if (flag_ltrans)
    setproctitle ("lto1-ltrans");
}


/* Initialize the LTO front end.  */

void
lto_fe_init (void)
{
  lto_process_name ();
  lto_streamer_hooks_init ();
  lto_reader_init ();
  lto_set_in_hooks (NULL, get_section_data, free_section_data);
  memset (&lto_stats, 0, sizeof (lto_stats));
  bitmap_obstack_initialize (NULL);
  gimple_register_cfg_hooks ();
}

#include "gt-lto-lto-common.h"
