/* Write and read the cgraph to the memory mapped representation of a
   .o file.

   Copyright (C) 2009-2022 Free Software Foundation, Inc.
   Contributed by Kenneth Zadeck <zadeck@naturalbridge.com>

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "rtl.h"
#include "tree.h"
#include "gimple.h"
#include "predict.h"
#include "stringpool.h"
#include "tree-streamer.h"
#include "cgraph.h"
#include "tree-pass.h"
#include "profile.h"
#include "context.h"
#include "pass_manager.h"
#include "ipa-utils.h"
#include "omp-offload.h"
#include "omp-general.h"
#include "stringpool.h"
#include "attribs.h"
#include "alloc-pool.h"
#include "symbol-summary.h"
#include "symtab-thunks.h"
#include "symtab-clones.h"

/* True when asm nodes has been output.  */
bool asm_nodes_output = false;

static void output_cgraph_opt_summary (void);
static void input_cgraph_opt_summary (vec<symtab_node *>  nodes);

/* Number of LDPR values known to GCC.  */
#define LDPR_NUM_KNOWN (LDPR_PREVAILING_DEF_IRONLY_EXP + 1)

/* Cgraph streaming is organized as set of record whose type
   is indicated by a tag.  */
enum LTO_symtab_tags
{
  /* Must leave 0 for the stopper.  */

  /* Cgraph node without body available.  */
  LTO_symtab_unavail_node = 1,
  /* Cgraph node with function body.  */
  LTO_symtab_analyzed_node,
  /* Cgraph edges.  */
  LTO_symtab_edge,
  LTO_symtab_indirect_edge,
  LTO_symtab_variable,
  LTO_symtab_last_tag
};

/* Create a new symtab encoder.
   if FOR_INPUT, the encoder allocate only datastructures needed
   to read the symtab.  */

lto_symtab_encoder_t
lto_symtab_encoder_new (bool for_input)
{
  lto_symtab_encoder_t encoder = XCNEW (struct lto_symtab_encoder_d);

  if (!for_input)
    encoder->map = new hash_map<symtab_node *, size_t>;
  encoder->nodes.create (0);
  return encoder;
}


/* Delete ENCODER and its components.  */

void
lto_symtab_encoder_delete (lto_symtab_encoder_t encoder)
{
   encoder->nodes.release ();
   if (encoder->map)
     delete encoder->map;
   free (encoder);
}


/* Return the existing reference number of NODE in the symtab encoder in
   output block OB.  Assign a new reference if this is the first time
   NODE is encoded.  */

int
lto_symtab_encoder_encode (lto_symtab_encoder_t encoder,
			   symtab_node *node)
{
  int ref;

  if (!encoder->map)
    {
      lto_encoder_entry entry = {node, false, false, false};

      ref = encoder->nodes.length ();
      encoder->nodes.safe_push (entry);
      return ref;
    }

  size_t *slot = encoder->map->get (node);
  if (!slot || !*slot)
    {
      lto_encoder_entry entry = {node, false, false, false};
      ref = encoder->nodes.length ();
      if (!slot)
        encoder->map->put (node, ref + 1);
      encoder->nodes.safe_push (entry);
    }
  else
    ref = *slot - 1;

  return ref;
}

/* Remove NODE from encoder.  */

bool
lto_symtab_encoder_delete_node (lto_symtab_encoder_t encoder,
			        symtab_node *node)
{
  int index;
  lto_encoder_entry last_node;

  size_t *slot = encoder->map->get (node);
  if (slot == NULL || !*slot)
    return false;

  index = *slot - 1;
  gcc_checking_assert (encoder->nodes[index].node == node);

  /* Remove from vector. We do this by swapping node with the last element
     of the vector.  */
  last_node = encoder->nodes.pop ();
  if (last_node.node != node)
    {
      gcc_assert (encoder->map->put (last_node.node, index + 1));

      /* Move the last element to the original spot of NODE.  */
      encoder->nodes[index] = last_node;
    }

  /* Remove element from hash table.  */
  encoder->map->remove (node);
  return true;
}


/* Return TRUE if we should encode the body of NODE (if any).  */

bool
lto_symtab_encoder_encode_body_p (lto_symtab_encoder_t encoder,
				  struct cgraph_node *node)
{
  int index = lto_symtab_encoder_lookup (encoder, node);
  return encoder->nodes[index].body;
}

/* Specify that we encode the body of NODE in this partition.  */

static void
lto_set_symtab_encoder_encode_body (lto_symtab_encoder_t encoder,
				    struct cgraph_node *node)
{
  int index = lto_symtab_encoder_encode (encoder, node);
  gcc_checking_assert (encoder->nodes[index].node == node);
  encoder->nodes[index].body = true;
}

/* Return TRUE if we should encode initializer of NODE (if any).  */

bool
lto_symtab_encoder_encode_initializer_p (lto_symtab_encoder_t encoder,
					 varpool_node *node)
{
  int index = lto_symtab_encoder_lookup (encoder, node);
  if (index == LCC_NOT_FOUND)
    return false;
  return encoder->nodes[index].initializer;
}

/* Specify that we should encode initializer of NODE (if any).  */

static void
lto_set_symtab_encoder_encode_initializer (lto_symtab_encoder_t encoder,
					   varpool_node *node)
{
  int index = lto_symtab_encoder_lookup (encoder, node);
  encoder->nodes[index].initializer = true;
}

/* Return TRUE if NODE is in this partition.  */

bool
lto_symtab_encoder_in_partition_p (lto_symtab_encoder_t encoder,
				   symtab_node *node)
{
  int index = lto_symtab_encoder_lookup (encoder, node);
  if (index == LCC_NOT_FOUND)
    return false;
  return encoder->nodes[index].in_partition;
}

/* Specify that NODE is in this partition.  */

void
lto_set_symtab_encoder_in_partition (lto_symtab_encoder_t encoder,
				     symtab_node *node)
{
  int index = lto_symtab_encoder_encode (encoder, node);
  encoder->nodes[index].in_partition = true;
}

/* Output the cgraph EDGE to OB using ENCODER.  */

static void
lto_output_edge (struct lto_simple_output_block *ob, struct cgraph_edge *edge,
		 lto_symtab_encoder_t encoder)
{
  unsigned int uid;
  intptr_t ref;
  struct bitpack_d bp;

  if (edge->indirect_unknown_callee)
    streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
			 LTO_symtab_indirect_edge);
  else
    streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
			 LTO_symtab_edge);

  ref = lto_symtab_encoder_lookup (encoder, edge->caller);
  gcc_assert (ref != LCC_NOT_FOUND);
  streamer_write_hwi_stream (ob->main_stream, ref);

  if (!edge->indirect_unknown_callee)
    {
      ref = lto_symtab_encoder_lookup (encoder, edge->callee);
      gcc_assert (ref != LCC_NOT_FOUND);
      streamer_write_hwi_stream (ob->main_stream, ref);
    }

  edge->count.stream_out (ob->main_stream);

  bp = bitpack_create (ob->main_stream);
  uid = !edge->call_stmt ? edge->lto_stmt_uid
			 : gimple_uid (edge->call_stmt) + 1;
  bp_pack_enum (&bp, cgraph_inline_failed_t,
	        CIF_N_REASONS, edge->inline_failed);
  gcc_checking_assert (uid || edge->caller->thunk);
  bp_pack_var_len_unsigned (&bp, uid);
  bp_pack_value (&bp, edge->speculative_id, 16);
  bp_pack_value (&bp, edge->indirect_inlining_edge, 1);
  bp_pack_value (&bp, edge->speculative, 1);
  bp_pack_value (&bp, edge->call_stmt_cannot_inline_p, 1);
  gcc_assert (!edge->call_stmt_cannot_inline_p
	      || edge->inline_failed != CIF_BODY_NOT_AVAILABLE);
  bp_pack_value (&bp, edge->can_throw_external, 1);
  bp_pack_value (&bp, edge->in_polymorphic_cdtor, 1);
  if (edge->indirect_unknown_callee)
    {
      int flags = edge->indirect_info->ecf_flags;
      bp_pack_value (&bp, (flags & ECF_CONST) != 0, 1);
      bp_pack_value (&bp, (flags & ECF_PURE) != 0, 1);
      bp_pack_value (&bp, (flags & ECF_NORETURN) != 0, 1);
      bp_pack_value (&bp, (flags & ECF_MALLOC) != 0, 1);
      bp_pack_value (&bp, (flags & ECF_NOTHROW) != 0, 1);
      bp_pack_value (&bp, (flags & ECF_RETURNS_TWICE) != 0, 1);
      /* Flags that should not appear on indirect calls.  */
      gcc_assert (!(flags & (ECF_LOOPING_CONST_OR_PURE
			     | ECF_MAY_BE_ALLOCA
			     | ECF_SIBCALL
			     | ECF_LEAF
			     | ECF_NOVOPS)));

      bp_pack_value (&bp, edge->indirect_info->num_speculative_call_targets,
		     16);
    }
  streamer_write_bitpack (&bp);
}

/* Return if NODE contain references from other partitions.  */

bool
referenced_from_other_partition_p (symtab_node *node, lto_symtab_encoder_t encoder)
{
  int i;
  struct ipa_ref *ref = NULL;

  for (i = 0; node->iterate_referring (i, ref); i++)
    {
      /* Ignore references from non-offloadable nodes while streaming NODE into
	 offload LTO section.  */
      if (!ref->referring->need_lto_streaming)
	continue;

      if (ref->referring->in_other_partition
          || !lto_symtab_encoder_in_partition_p (encoder, ref->referring))
	return true;
    }
  return false;
}

/* Return true when node is reachable from other partition.  */

bool
reachable_from_other_partition_p (struct cgraph_node *node, lto_symtab_encoder_t encoder)
{
  struct cgraph_edge *e;
  if (!node->definition)
    return false;
  if (node->inlined_to)
    return false;
  for (e = node->callers; e; e = e->next_caller)
    {
      /* Ignore references from non-offloadable nodes while streaming NODE into
	 offload LTO section.  */
      if (!e->caller->need_lto_streaming)
	continue;

      if (e->caller->in_other_partition
	  || !lto_symtab_encoder_in_partition_p (encoder, e->caller))
	return true;
    }
  return false;
}

/* Return if NODE contain references from other partitions.  */

bool
referenced_from_this_partition_p (symtab_node *node,
				  lto_symtab_encoder_t encoder)
{
  int i;
  struct ipa_ref *ref = NULL;

  for (i = 0; node->iterate_referring (i, ref); i++)
    if (lto_symtab_encoder_in_partition_p (encoder, ref->referring))
      return true;
  return false;
}

/* Return true when node is reachable from other partition.  */

bool
reachable_from_this_partition_p (struct cgraph_node *node, lto_symtab_encoder_t encoder)
{
  struct cgraph_edge *e;
  for (e = node->callers; e; e = e->next_caller)
    if (lto_symtab_encoder_in_partition_p (encoder, e->caller))
      return true;
  return false;
}

/* Output the cgraph NODE to OB.  ENCODER is used to find the
   reference number of NODE->inlined_to.  SET is the set of nodes we
   are writing to the current file.  If NODE is not in SET, then NODE
   is a boundary of a cgraph_node_set and we pretend NODE just has a
   decl and no callees.  WRITTEN_DECLS is the set of FUNCTION_DECLs
   that have had their callgraph node written so far.  This is used to
   determine if NODE is a clone of a previously written node.  */

static void
lto_output_node (struct lto_simple_output_block *ob, struct cgraph_node *node,
		 lto_symtab_encoder_t encoder)
{
  unsigned int tag;
  struct bitpack_d bp;
  bool boundary_p;
  intptr_t ref;
  bool in_other_partition = false;
  struct cgraph_node *clone_of, *ultimate_clone_of;
  ipa_opt_pass_d *pass;
  int i;
  const char *comdat;
  const char *section;
  tree group;

  boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node);

  if (node->analyzed && (!boundary_p || node->alias
			 || (node->thunk && !node->inlined_to)))
    tag = LTO_symtab_analyzed_node;
  else
    tag = LTO_symtab_unavail_node;

  streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
		       tag);
  streamer_write_hwi_stream (ob->main_stream, node->order);

  /* In WPA mode, we only output part of the call-graph.  Also, we
     fake cgraph node attributes.  There are two cases that we care.

     Boundary nodes: There are nodes that are not part of SET but are
     called from within SET.  We artificially make them look like
     externally visible nodes with no function body.

     Cherry-picked nodes:  These are nodes we pulled from other
     translation units into SET during IPA-inlining.  We make them as
     local static nodes to prevent clashes with other local statics.  */
  if (boundary_p && node->analyzed
      && node->get_partitioning_class () == SYMBOL_PARTITION)
    {
      /* Inline clones cannot be part of boundary.  
	 gcc_assert (!node->inlined_to);

	 FIXME: At the moment they can be, when partition contains an inline
	 clone that is clone of inline clone from outside partition.  We can
	 reshape the clone tree and make other tree to be the root, but it
	 needs a bit extra work and will be promplty done by cgraph_remove_node
	 after reading back.  */
      in_other_partition = 1;
    }
  else if (UNLIKELY (lto_stream_offload_p
		     && lookup_attribute ("omp target device_ancestor_host",
					  DECL_ATTRIBUTES (node->decl))))
    /* This symbol is only used as argument to IFN_GOMP_TARGET_REV; this IFN
       is ignored on ACCEL_COMPILER.  Thus, mark it as in_other_partition to silence
       verify_node_partition diagnostic.  */
    in_other_partition = 1;

  clone_of = node->clone_of;
  while (clone_of
	 && (ref = lto_symtab_encoder_lookup (encoder, clone_of)) == LCC_NOT_FOUND)
    if (clone_of->prev_sibling_clone)
      clone_of = clone_of->prev_sibling_clone;
    else
      clone_of = clone_of->clone_of;

  /* See if body of the master function is output.  If not, we are seeing only
     an declaration and we do not need to pass down clone tree. */
  ultimate_clone_of = clone_of;
  while (ultimate_clone_of && ultimate_clone_of->clone_of)
    ultimate_clone_of = ultimate_clone_of->clone_of;

  if (clone_of && !lto_symtab_encoder_encode_body_p (encoder, ultimate_clone_of))
    clone_of = NULL;

  if (tag == LTO_symtab_analyzed_node)
    gcc_assert (clone_of || !node->clone_of);
  if (!clone_of)
    streamer_write_hwi_stream (ob->main_stream, LCC_NOT_FOUND);
  else
    streamer_write_hwi_stream (ob->main_stream, ref);


  lto_output_fn_decl_ref (ob->decl_state, ob->main_stream, node->decl);
  node->count.stream_out (ob->main_stream);
  streamer_write_hwi_stream (ob->main_stream, node->count_materialization_scale);

  streamer_write_hwi_stream (ob->main_stream,
			     node->ipa_transforms_to_apply.length ());
  FOR_EACH_VEC_ELT (node->ipa_transforms_to_apply, i, pass)
    streamer_write_hwi_stream (ob->main_stream, pass->static_pass_number);

  if (tag == LTO_symtab_analyzed_node)
    {
      if (node->inlined_to)
	{
	  ref = lto_symtab_encoder_lookup (encoder, node->inlined_to);
	  gcc_assert (ref != LCC_NOT_FOUND);
	}
      else
	ref = LCC_NOT_FOUND;

      streamer_write_hwi_stream (ob->main_stream, ref);
    }

  group = node->get_comdat_group ();
  if (group)
    comdat = IDENTIFIER_POINTER (group);
  else
    comdat = "";
  streamer_write_data_stream (ob->main_stream, comdat, strlen (comdat) + 1);

  if (group)
    {
      if (node->same_comdat_group)
	{
	  ref = LCC_NOT_FOUND;
	  for (struct symtab_node *n = node->same_comdat_group; 
	       ref == LCC_NOT_FOUND && n != node; n = n->same_comdat_group)
	    ref = lto_symtab_encoder_lookup (encoder, n);
	}
      else
	ref = LCC_NOT_FOUND;
      streamer_write_hwi_stream (ob->main_stream, ref);
    }

  section = node->get_section ();
  if (!section)
    section = "";

  streamer_write_hwi_stream (ob->main_stream, node->tp_first_run);

  bp = bitpack_create (ob->main_stream);
  bp_pack_value (&bp, node->local, 1);
  bp_pack_value (&bp, node->externally_visible, 1);
  bp_pack_value (&bp, node->no_reorder, 1);
  bp_pack_value (&bp, node->definition, 1);
  bp_pack_value (&bp, node->versionable, 1);
  bp_pack_value (&bp, node->can_change_signature, 1);
  bp_pack_value (&bp, node->redefined_extern_inline, 1);
  bp_pack_value (&bp, node->force_output, 1);
  bp_pack_value (&bp, node->forced_by_abi, 1);
  bp_pack_value (&bp, node->unique_name, 1);
  bp_pack_value (&bp, node->body_removed, 1);
  bp_pack_value (&bp, node->semantic_interposition, 1);
  bp_pack_value (&bp, node->implicit_section, 1);
  bp_pack_value (&bp, node->address_taken, 1);
  bp_pack_value (&bp, tag == LTO_symtab_analyzed_node
		 && node->get_partitioning_class () == SYMBOL_PARTITION
		 && (reachable_from_other_partition_p (node, encoder)
		     || referenced_from_other_partition_p (node, encoder)), 1);
  bp_pack_value (&bp, node->lowered, 1);
  bp_pack_value (&bp, in_other_partition, 1);
  bp_pack_value (&bp, node->alias, 1);
  bp_pack_value (&bp, node->transparent_alias, 1);
  bp_pack_value (&bp, node->weakref, 1);
  bp_pack_value (&bp, node->symver, 1);
  bp_pack_value (&bp, node->frequency, 2);
  bp_pack_value (&bp, node->only_called_at_startup, 1);
  bp_pack_value (&bp, node->only_called_at_exit, 1);
  bp_pack_value (&bp, node->tm_clone, 1);
  bp_pack_value (&bp, node->calls_comdat_local, 1);
  bp_pack_value (&bp, node->icf_merged, 1);
  bp_pack_value (&bp, node->nonfreeing_fn, 1);
  bp_pack_value (&bp, node->merged_comdat, 1);
  bp_pack_value (&bp, node->merged_extern_inline, 1);
  bp_pack_value (&bp, node->thunk, 1);
  bp_pack_value (&bp, node->parallelized_function, 1);
  bp_pack_value (&bp, node->declare_variant_alt, 1);
  bp_pack_value (&bp, node->calls_declare_variant_alt, 1);

  /* Stream thunk info always because we use it in
     ipa_polymorphic_call_context::ipa_polymorphic_call_context
     to properly interpret THIS pointers for thunks that has been converted
     to Gimple.  */
  struct thunk_info *thunk = node->definition ? thunk_info::get (node) : NULL;

  bp_pack_value (&bp, thunk != NULL, 1);

  bp_pack_enum (&bp, ld_plugin_symbol_resolution,
	        LDPR_NUM_KNOWN,
		/* When doing incremental link, we will get new resolution
		   info next time we process the file.  */
		flag_incremental_link ? LDPR_UNKNOWN : node->resolution);
  bp_pack_value (&bp, node->split_part, 1);
  streamer_write_bitpack (&bp);
  streamer_write_data_stream (ob->main_stream, section, strlen (section) + 1);

  streamer_write_hwi_stream (ob->main_stream, node->profile_id);
  streamer_write_hwi_stream (ob->main_stream, node->unit_id);
  if (DECL_STATIC_CONSTRUCTOR (node->decl))
    streamer_write_hwi_stream (ob->main_stream, node->get_init_priority ());
  if (DECL_STATIC_DESTRUCTOR (node->decl))
    streamer_write_hwi_stream (ob->main_stream, node->get_fini_priority ());

  if (thunk)
    thunk_info::get (node)->stream_out (ob);
}

/* Output the varpool NODE to OB. 
   If NODE is not in SET, then NODE is a boundary.  */

static void
lto_output_varpool_node (struct lto_simple_output_block *ob, varpool_node *node,
			 lto_symtab_encoder_t encoder)
{
  bool boundary_p = !lto_symtab_encoder_in_partition_p (encoder, node);
  bool encode_initializer_p
	 = (node->definition
	    && lto_symtab_encoder_encode_initializer_p (encoder, node));
  struct bitpack_d bp;
  int ref;
  const char *comdat;
  const char *section;
  tree group;

  gcc_assert (!encode_initializer_p || node->definition);
  gcc_assert (boundary_p || encode_initializer_p);

  streamer_write_enum (ob->main_stream, LTO_symtab_tags, LTO_symtab_last_tag,
		       LTO_symtab_variable);
  streamer_write_hwi_stream (ob->main_stream, node->order);
  lto_output_var_decl_ref (ob->decl_state, ob->main_stream, node->decl);
  bp = bitpack_create (ob->main_stream);
  bp_pack_value (&bp, node->externally_visible, 1);
  bp_pack_value (&bp, node->no_reorder, 1);
  bp_pack_value (&bp, node->force_output, 1);
  bp_pack_value (&bp, node->forced_by_abi, 1);
  bp_pack_value (&bp, node->unique_name, 1);
  bp_pack_value (&bp,
		 node->body_removed
		 || (!encode_initializer_p && !node->alias && node->definition),
		 1);
  bp_pack_value (&bp, node->semantic_interposition, 1);
  bp_pack_value (&bp, node->implicit_section, 1);
  bp_pack_value (&bp, node->writeonly, 1);
  bp_pack_value (&bp, node->definition && (encode_initializer_p || node->alias),
		 1);
  bp_pack_value (&bp, node->alias, 1);
  bp_pack_value (&bp, node->transparent_alias, 1);
  bp_pack_value (&bp, node->weakref, 1);
  bp_pack_value (&bp, node->symver, 1);
  bp_pack_value (&bp, node->analyzed && (!boundary_p || node->alias), 1);
  gcc_assert (node->definition || !node->analyzed);
  /* Constant pool initializers can be de-unified into individual ltrans units.
     FIXME: Alternatively at -Os we may want to avoid generating for them the local
     labels and share them across LTRANS partitions.  */
  if (node->get_partitioning_class () != SYMBOL_PARTITION)
    {
      bp_pack_value (&bp, 0, 1);  /* used_from_other_parition.  */
      bp_pack_value (&bp, 0, 1);  /* in_other_partition.  */
    }
  else
    {
      bp_pack_value (&bp, node->definition
		     && referenced_from_other_partition_p (node, encoder), 1);
      bp_pack_value (&bp, node->analyzed
		     && boundary_p && !DECL_EXTERNAL (node->decl), 1);
	  /* in_other_partition.  */
    }
  bp_pack_value (&bp, node->tls_model, 3);
  bp_pack_value (&bp, node->used_by_single_function, 1);
  bp_pack_value (&bp, node->dynamically_initialized, 1);
  streamer_write_bitpack (&bp);

  group = node->get_comdat_group ();
  if (group)
    comdat = IDENTIFIER_POINTER (group);
  else
    comdat = "";
  streamer_write_data_stream (ob->main_stream, comdat, strlen (comdat) + 1);

  if (group)
    {
      if (node->same_comdat_group)
	{
	  ref = LCC_NOT_FOUND;
	  for (struct symtab_node *n = node->same_comdat_group; 
	       ref == LCC_NOT_FOUND && n != node; n = n->same_comdat_group)
	    ref = lto_symtab_encoder_lookup (encoder, n);
	}
      else
	ref = LCC_NOT_FOUND;
      streamer_write_hwi_stream (ob->main_stream, ref);
    }

  section = node->get_section ();
  if (!section)
    section = "";
  streamer_write_data_stream (ob->main_stream, section, strlen (section) + 1);

  streamer_write_enum (ob->main_stream, ld_plugin_symbol_resolution,
		       LDPR_NUM_KNOWN, node->resolution);
}

/* Output the varpool NODE to OB. 
   If NODE is not in SET, then NODE is a boundary.  */

static void
lto_output_ref (struct lto_simple_output_block *ob, struct ipa_ref *ref,
		lto_symtab_encoder_t encoder)
{
  struct bitpack_d bp;
  int nref;
  int uid = !ref->stmt ? ref->lto_stmt_uid : gimple_uid (ref->stmt) + 1;
  struct cgraph_node *node;

  bp = bitpack_create (ob->main_stream);
  bp_pack_value (&bp, ref->use, 3);
  bp_pack_value (&bp, ref->speculative, 1);
  streamer_write_bitpack (&bp);
  nref = lto_symtab_encoder_lookup (encoder, ref->referred);
  gcc_assert (nref != LCC_NOT_FOUND);
  streamer_write_hwi_stream (ob->main_stream, nref);
  
  node = dyn_cast <cgraph_node *> (ref->referring);
  if (node)
    {
      if (ref->stmt)
	uid = gimple_uid (ref->stmt) + 1;
      streamer_write_hwi_stream (ob->main_stream, uid);
      bp_pack_value (&bp, ref->speculative_id, 16);
      streamer_write_bitpack (&bp);
    }
}

/* Stream out profile_summary to OB.  */

static void
output_profile_summary (struct lto_simple_output_block *ob)
{
  if (profile_info)
    {
      /* We do not output num and run_max, they are not used by
         GCC profile feedback and they are difficult to merge from multiple
         units.  */
      unsigned runs = (profile_info->runs);
      streamer_write_uhwi_stream (ob->main_stream, runs);

      /* IPA-profile computes hot bb threshold based on cumulated
	 whole program profile.  We need to stream it down to ltrans.  */
       if (flag_wpa)
         streamer_write_gcov_count_stream (ob->main_stream,
					   get_hot_bb_threshold ());
    }
  else
    streamer_write_uhwi_stream (ob->main_stream, 0);
}

/* Output all callees or indirect outgoing edges.  EDGE must be the first such
   edge.  */

static void
output_outgoing_cgraph_edges (struct cgraph_edge *edge,
			      struct lto_simple_output_block *ob,
			      lto_symtab_encoder_t encoder)
{
  if (!edge)
    return;

  /* Output edges in backward direction, so the reconstructed callgraph match
     and it is easy to associate call sites in the IPA pass summaries.  */
  while (edge->next_callee)
    edge = edge->next_callee;
  for (; edge; edge = edge->prev_callee)
    lto_output_edge (ob, edge, encoder);
}

/* Output the part of the cgraph in SET.  */

static void
output_refs (lto_symtab_encoder_t encoder)
{
  struct lto_simple_output_block *ob;
  int count;
  struct ipa_ref *ref;

  ob = lto_create_simple_output_block (LTO_section_refs);

  for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
    {
      symtab_node *node = lto_symtab_encoder_deref (encoder, i);

      /* IPA_REF_ALIAS references are always preserved
	 in the boundary.  Alias node can't have other references and
	 can be always handled as if it's not in the boundary.  */
      if (!node->alias && !lto_symtab_encoder_in_partition_p (encoder, node))
	continue;

      count = node->ref_list.nreferences ();
      if (count)
	{
	  streamer_write_gcov_count_stream (ob->main_stream, count);
	  streamer_write_uhwi_stream (ob->main_stream,
				     lto_symtab_encoder_lookup (encoder, node));
	  for (int i = 0; node->iterate_reference (i, ref); i++)
	    lto_output_ref (ob, ref, encoder);
	}
      if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
	if (cnode->declare_variant_alt)
	  omp_lto_output_declare_variant_alt (ob, cnode, encoder);
    }

  streamer_write_uhwi_stream (ob->main_stream, 0);

  lto_destroy_simple_output_block (ob);
}

/* Add NODE into encoder as well as nodes it is cloned from.
   Do it in a way so clones appear first.  */

static void
add_node_to (lto_symtab_encoder_t encoder, struct cgraph_node *node,
	     bool include_body)
{
  if (node->clone_of)
    add_node_to (encoder, node->clone_of, include_body);
  else if (include_body)
    lto_set_symtab_encoder_encode_body (encoder, node);
  lto_symtab_encoder_encode (encoder, node);
}

/* Add all references in NODE to encoders.  */

static void
create_references (lto_symtab_encoder_t encoder, symtab_node *node)
{
  int i;
  struct ipa_ref *ref = NULL;
  for (i = 0; node->iterate_reference (i, ref); i++)
    if (is_a <cgraph_node *> (ref->referred))
      add_node_to (encoder, dyn_cast <cgraph_node *> (ref->referred), false);
    else
      lto_symtab_encoder_encode (encoder, ref->referred);
}

/* Select what needs to be streamed out.  In regular lto mode stream everything.
   In offload lto mode stream only nodes marked as offloadable.  */
void
select_what_to_stream (void)
{
  struct symtab_node *snode;
  FOR_EACH_SYMBOL (snode)
    snode->need_lto_streaming = !lto_stream_offload_p || snode->offloadable;
}

/* Find all symbols we want to stream into given partition and insert them
   to encoders.

   The function actually replaces IN_ENCODER by new one.  The reason is that
   streaming code needs clone's origin to be streamed before clone.  This
   means that we need to insert the nodes in specific order.  This order is
   ignored by the partitioning logic earlier.  */

lto_symtab_encoder_t 
compute_ltrans_boundary (lto_symtab_encoder_t in_encoder)
{
  struct cgraph_edge *edge;
  int i;
  lto_symtab_encoder_t encoder;
  lto_symtab_encoder_iterator lsei;
  hash_set<void *> reachable_call_targets;

  encoder = lto_symtab_encoder_new (false);

  /* Go over all entries in the IN_ENCODER and duplicate them to
     ENCODER. At the same time insert masters of clones so
     every master appears before clone.  */
  for (lsei = lsei_start_function_in_partition (in_encoder);
       !lsei_end_p (lsei); lsei_next_function_in_partition (&lsei))
    {
      struct cgraph_node *node = lsei_cgraph_node (lsei);
      if (!node->need_lto_streaming)
	continue;
      add_node_to (encoder, node, true);
      lto_set_symtab_encoder_in_partition (encoder, node);
      create_references (encoder, node);
    }
  for (lsei = lsei_start_variable_in_partition (in_encoder);
       !lsei_end_p (lsei); lsei_next_variable_in_partition (&lsei))
    {
      varpool_node *vnode = lsei_varpool_node (lsei);

      if (!vnode->need_lto_streaming)
	continue;
      lto_set_symtab_encoder_in_partition (encoder, vnode);
      lto_set_symtab_encoder_encode_initializer (encoder, vnode);
      create_references (encoder, vnode);
    }
  /* Pickle in also the initializer of all referenced readonly variables
     to help folding.  Constant pool variables are not shared, so we must
     pickle those too.  */
  for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
    {
      symtab_node *node = lto_symtab_encoder_deref (encoder, i);
      if (varpool_node *vnode = dyn_cast <varpool_node *> (node))
	{
	  if (!lto_symtab_encoder_encode_initializer_p (encoder,
							vnode)
	      && (((vnode->ctor_useable_for_folding_p ()
		   && (!DECL_VIRTUAL_P (vnode->decl)
		       || !flag_wpa
		       || flag_ltrans_devirtualize)))))
	    {
	      lto_set_symtab_encoder_encode_initializer (encoder, vnode);
	      create_references (encoder, vnode);
	    }
       }
    }

  /* Go over all the nodes again to include callees that are not in
     SET.  */
  for (lsei = lsei_start_function_in_partition (encoder);
       !lsei_end_p (lsei); lsei_next_function_in_partition (&lsei))
    {
      struct cgraph_node *node = lsei_cgraph_node (lsei);
      for (edge = node->callees; edge; edge = edge->next_callee)
	{
	  struct cgraph_node *callee = edge->callee;
	  if (!lto_symtab_encoder_in_partition_p (encoder, callee))
	    {
	      /* We should have moved all the inlines.  */
	      gcc_assert (!callee->inlined_to);
	      add_node_to (encoder, callee, false);
	    }
	}
      /* Add all possible targets for late devirtualization.  */
      if (flag_ltrans_devirtualize || !flag_wpa)
	for (edge = node->indirect_calls; edge; edge = edge->next_callee)
	  if (edge->indirect_info->polymorphic)
	    {
	      unsigned int i;
	      void *cache_token;
	      bool final;
	      vec <cgraph_node *>targets
		= possible_polymorphic_call_targets
		    (edge, &final, &cache_token);
	      if (!reachable_call_targets.add (cache_token))
		{
		  for (i = 0; i < targets.length (); i++)
		    {
		      struct cgraph_node *callee = targets[i];

		      /* Adding an external declarations into the unit serves
			 no purpose and just increases its boundary.  */
		      if (callee->definition
			  && !lto_symtab_encoder_in_partition_p
			       (encoder, callee))
			{
			  gcc_assert (!callee->inlined_to);
			  add_node_to (encoder, callee, false);
			}
		    }
		}
	    }
    }
  /* Be sure to also insert alias targert and thunk callees.  These needs
     to stay to aid local calling conventions.  */
  for (i = 0; i < lto_symtab_encoder_size (encoder); i++)
    {
      symtab_node *node = lto_symtab_encoder_deref (encoder, i);
      cgraph_node *cnode = dyn_cast <cgraph_node *> (node);

      if (node->alias && node->analyzed)
	create_references (encoder, node);
      if (cnode
	  && cnode->thunk && !cnode->inlined_to)
	add_node_to (encoder, cnode->callees->callee, false);
      while (node->transparent_alias && node->analyzed)
	{
	  node = node->get_alias_target ();
	  if (is_a <cgraph_node *> (node))
	    add_node_to (encoder, dyn_cast <cgraph_node *> (node),
			 false);
	  else
	    lto_symtab_encoder_encode (encoder, node);
	}
    }
  lto_symtab_encoder_delete (in_encoder);
  return encoder;
}

/* Output the part of the symtab in SET and VSET.  */

void
output_symtab (void)
{
  struct cgraph_node *node;
  struct lto_simple_output_block *ob;
  int i, n_nodes;
  lto_symtab_encoder_t encoder;

  if (flag_wpa)
    output_cgraph_opt_summary ();

  ob = lto_create_simple_output_block (LTO_section_symtab_nodes);

  output_profile_summary (ob);

  /* An encoder for cgraph nodes should have been created by
     ipa_write_summaries_1.  */
  gcc_assert (ob->decl_state->symtab_node_encoder);
  encoder = ob->decl_state->symtab_node_encoder;

  /* Write out the nodes.  We must first output a node and then its clones,
     otherwise at a time reading back the node there would be nothing to clone
     from.  */
  n_nodes = lto_symtab_encoder_size (encoder);
  for (i = 0; i < n_nodes; i++)
    {
      symtab_node *node = lto_symtab_encoder_deref (encoder, i);
      if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
        lto_output_node (ob, cnode, encoder);
      else
	lto_output_varpool_node (ob, dyn_cast<varpool_node *> (node), encoder);
    }

  /* Go over the nodes in SET again to write edges.  */
  for (int i = 0; i < lto_symtab_encoder_size (encoder); i++)
    {
      node = dyn_cast <cgraph_node *> (lto_symtab_encoder_deref (encoder, i));
      if (node
	  && ((node->thunk && !node->inlined_to)
	      || lto_symtab_encoder_in_partition_p (encoder, node)))
	{
	  output_outgoing_cgraph_edges (node->callees, ob, encoder);
	  output_outgoing_cgraph_edges (node->indirect_calls, ob, encoder);
	}
    }

  streamer_write_uhwi_stream (ob->main_stream, 0);

  lto_destroy_simple_output_block (ob);

  /* Emit toplevel asms.
     When doing WPA we must output every asm just once.  Since we do not partition asm
     nodes at all, output them to first output.  This is kind of hack, but should work
     well.  */
  if (!asm_nodes_output)
    {
      asm_nodes_output = true;
      lto_output_toplevel_asms ();
    }

  output_refs (encoder);
}

/* Return identifier encoded in IB as a plain string.  */

static tree
read_identifier (class lto_input_block *ib)
{
  unsigned int len = strnlen (ib->data + ib->p, ib->len - ib->p - 1);
  tree id;

  if (ib->data[ib->p + len])
    lto_section_overrun (ib);
  if (!len)
    {
      ib->p++;
      return NULL;
    }
  id = get_identifier (ib->data + ib->p);
  ib->p += len + 1;
  return id;
}

/* Return string encoded in IB, NULL if string is empty.  */

static const char *
read_string (class lto_input_block *ib)
{
  unsigned int len = strnlen (ib->data + ib->p, ib->len - ib->p - 1);
  const char *str;

  if (ib->data[ib->p + len])
    lto_section_overrun (ib);
  if (!len)
    {
      ib->p++;
      return NULL;
    }
  str = ib->data + ib->p;
  ib->p += len + 1;
  return str;
}

/* Output function/variable tables that will allow libgomp to look up offload
   target code.
   OFFLOAD_FUNCS is filled in expand_omp_target, OFFLOAD_VARS is filled in
   varpool_node::get_create.  In WHOPR (partitioned) mode during the WPA stage
   both OFFLOAD_FUNCS and OFFLOAD_VARS are filled by input_offload_tables.  */

void
output_offload_tables (void)
{
  bool output_requires = (flag_openmp
			  && (omp_requires_mask & OMP_REQUIRES_TARGET_USED) != 0);
  if (vec_safe_is_empty (offload_funcs) && vec_safe_is_empty (offload_vars)
      && !output_requires)
    return;

  struct lto_simple_output_block *ob
    = lto_create_simple_output_block (LTO_section_offload_table);

  for (unsigned i = 0; i < vec_safe_length (offload_funcs); i++)
    {
      symtab_node *node = symtab_node::get ((*offload_funcs)[i]);
      if (!node)
	continue;
      node->force_output = true;
      streamer_write_enum (ob->main_stream, LTO_symtab_tags,
			   LTO_symtab_last_tag, LTO_symtab_unavail_node);
      lto_output_fn_decl_ref (ob->decl_state, ob->main_stream,
			      (*offload_funcs)[i]);
    }

  for (unsigned i = 0; i < vec_safe_length (offload_vars); i++)
    {
      symtab_node *node = symtab_node::get ((*offload_vars)[i]);
      if (!node)
	continue;
      node->force_output = true;
      streamer_write_enum (ob->main_stream, LTO_symtab_tags,
			   LTO_symtab_last_tag, LTO_symtab_variable);
      lto_output_var_decl_ref (ob->decl_state, ob->main_stream,
			       (*offload_vars)[i]);
    }

  if (output_requires)
    {
      HOST_WIDE_INT val = ((HOST_WIDE_INT) omp_requires_mask
			   & (OMP_REQUIRES_UNIFIED_ADDRESS
			      | OMP_REQUIRES_UNIFIED_SHARED_MEMORY
			      | OMP_REQUIRES_REVERSE_OFFLOAD
			      | OMP_REQUIRES_TARGET_USED));
      /* (Mis)use LTO_symtab_edge for this variable.  */
      streamer_write_enum (ob->main_stream, LTO_symtab_tags,
			   LTO_symtab_last_tag, LTO_symtab_edge);
      streamer_write_hwi_stream (ob->main_stream, val);
    }

  streamer_write_uhwi_stream (ob->main_stream, 0);
  lto_destroy_simple_output_block (ob);

  /* In WHOPR mode during the WPA stage the joint offload tables need to be
     streamed to one partition only.  That's why we free offload_funcs and
     offload_vars after the first call of output_offload_tables.  */
  if (flag_wpa)
    {
      vec_free (offload_funcs);
      vec_free (offload_vars);
    }
}

/* Verify the partitioning of NODE.  */

static inline void
verify_node_partition (symtab_node *node)
{
  if (flag_ltrans)
    return;

#ifdef ACCEL_COMPILER
  if (node->in_other_partition)
    {
      if (TREE_CODE (node->decl) == FUNCTION_DECL)
	{
	  if (lookup_attribute ("omp target device_ancestor_host",
				DECL_ATTRIBUTES (node->decl)) != NULL)
	    return;
	  error_at (DECL_SOURCE_LOCATION (node->decl),
		    "function %qs has been referenced in offloaded code but"
		    " hasn%'t been marked to be included in the offloaded code",
		    node->name ());
	}
      else if (VAR_P (node->decl))
	error_at (DECL_SOURCE_LOCATION (node->decl),
		  "variable %qs has been referenced in offloaded code but"
		  " hasn%'t been marked to be included in the offloaded code",
		  node->name ());
      else
	gcc_unreachable ();
    }
#else
  gcc_assert (!node->in_other_partition
	      && !node->used_from_other_partition);
#endif
}

/* Overwrite the information in NODE based on FILE_DATA, TAG, FLAGS,
   STACK_SIZE, SELF_TIME and SELF_SIZE.  This is called either to initialize
   NODE or to replace the values in it, for instance because the first
   time we saw it, the function body was not available but now it
   is.  BP is a bitpack with all the bitflags for NODE read from the
   stream.  Initialize HAS_THUNK_INFO to indicate if thunk info should
   be streamed in.  */

static void
input_overwrite_node (struct lto_file_decl_data *file_data,
		      struct cgraph_node *node,
		      enum LTO_symtab_tags tag,
		      struct bitpack_d *bp, bool *has_thunk_info)
{
  node->aux = (void *) tag;
  node->lto_file_data = file_data;

  node->local = bp_unpack_value (bp, 1);
  node->externally_visible = bp_unpack_value (bp, 1);
  node->no_reorder = bp_unpack_value (bp, 1);
  node->definition = bp_unpack_value (bp, 1);
  node->versionable = bp_unpack_value (bp, 1);
  node->can_change_signature = bp_unpack_value (bp, 1);
  node->redefined_extern_inline = bp_unpack_value (bp, 1);
  node->force_output = bp_unpack_value (bp, 1);
  node->forced_by_abi = bp_unpack_value (bp, 1);
  node->unique_name = bp_unpack_value (bp, 1);
  node->body_removed = bp_unpack_value (bp, 1);
  node->semantic_interposition = bp_unpack_value (bp, 1);
  node->implicit_section = bp_unpack_value (bp, 1);
  node->address_taken = bp_unpack_value (bp, 1);
  node->used_from_other_partition = bp_unpack_value (bp, 1);
  node->lowered = bp_unpack_value (bp, 1);
  node->analyzed = tag == LTO_symtab_analyzed_node;
  node->in_other_partition = bp_unpack_value (bp, 1);
  if (node->in_other_partition
      /* Avoid updating decl when we are seeing just inline clone.
	 When inlining function that has functions already inlined into it,
	 we produce clones of inline clones.

	 WPA partitioning might put each clone into different unit and
	 we might end up streaming inline clone from other partition
	 to support clone we are interested in. */
      && (!node->clone_of
	  || node->clone_of->decl != node->decl))
    {
      DECL_EXTERNAL (node->decl) = 1;
      TREE_STATIC (node->decl) = 0;
    }
  node->alias = bp_unpack_value (bp, 1);
  node->transparent_alias = bp_unpack_value (bp, 1);
  node->weakref = bp_unpack_value (bp, 1);
  node->symver = bp_unpack_value (bp, 1);
  node->frequency = (enum node_frequency)bp_unpack_value (bp, 2);
  node->only_called_at_startup = bp_unpack_value (bp, 1);
  node->only_called_at_exit = bp_unpack_value (bp, 1);
  node->tm_clone = bp_unpack_value (bp, 1);
  node->calls_comdat_local = bp_unpack_value (bp, 1);
  node->icf_merged = bp_unpack_value (bp, 1);
  node->nonfreeing_fn = bp_unpack_value (bp, 1);
  node->merged_comdat = bp_unpack_value (bp, 1);
  node->merged_extern_inline = bp_unpack_value (bp, 1);
  node->thunk = bp_unpack_value (bp, 1);
  node->parallelized_function = bp_unpack_value (bp, 1);
  node->declare_variant_alt = bp_unpack_value (bp, 1);
  node->calls_declare_variant_alt = bp_unpack_value (bp, 1);
  *has_thunk_info = bp_unpack_value (bp, 1);
  node->resolution = bp_unpack_enum (bp, ld_plugin_symbol_resolution,
				     LDPR_NUM_KNOWN);
  node->split_part = bp_unpack_value (bp, 1);
  verify_node_partition (node);
}

/* Return string alias is alias of.  */

static tree
get_alias_symbol (tree decl)
{
  tree alias = lookup_attribute ("alias", DECL_ATTRIBUTES (decl));
  return get_identifier (TREE_STRING_POINTER
			  (TREE_VALUE (TREE_VALUE (alias))));
}

/* Read a node from input_block IB.  TAG is the node's tag just read.
   Return the node read or overwriten.  */

static struct cgraph_node *
input_node (struct lto_file_decl_data *file_data,
	    class lto_input_block *ib,
	    enum LTO_symtab_tags tag,
	    vec<symtab_node *> nodes)
{
  gcc::pass_manager *passes = g->get_passes ();
  tree fn_decl;
  struct cgraph_node *node;
  struct bitpack_d bp;
  int ref = LCC_NOT_FOUND, ref2 = LCC_NOT_FOUND;
  int clone_ref;
  int order;
  int i, count;
  tree group;
  const char *section;
  order = streamer_read_hwi (ib) + file_data->order_base;
  clone_ref = streamer_read_hwi (ib);
  bool has_thunk_info;

  fn_decl = lto_input_fn_decl_ref (ib, file_data);

  if (clone_ref != LCC_NOT_FOUND)
    {
      node = dyn_cast<cgraph_node *> (nodes[clone_ref])->create_clone (fn_decl,
	profile_count::uninitialized (), false,
	vNULL, false, NULL, NULL);
    }
  else
    {
      /* Declaration of functions can be already merged with a declaration
	 from other input file.  We keep cgraph unmerged until after streaming
	 of ipa passes is done.  Alays forcingly create a fresh node.  */
      node = symtab->create_empty ();
      node->decl = fn_decl;
      if (lookup_attribute ("ifunc", DECL_ATTRIBUTES (fn_decl)))
	node->ifunc_resolver = 1;
      node->register_symbol ();
    }

  node->order = order;
  if (order >= symtab->order)
    symtab->order = order + 1;

  node->count = profile_count::stream_in (ib);
  node->count_materialization_scale = streamer_read_hwi (ib);

  count = streamer_read_hwi (ib);
  node->ipa_transforms_to_apply = vNULL;
  for (i = 0; i < count; i++)
    {
      opt_pass *pass;
      int pid = streamer_read_hwi (ib);

      gcc_assert (pid < passes->passes_by_id_size);
      pass = passes->passes_by_id[pid];
      node->ipa_transforms_to_apply.safe_push ((ipa_opt_pass_d *) pass);
    }

  if (tag == LTO_symtab_analyzed_node)
    ref = streamer_read_hwi (ib);

  group = read_identifier (ib);
  if (group)
    ref2 = streamer_read_hwi (ib);

  /* Make sure that we have not read this node before.  Nodes that
     have already been read will have their tag stored in the 'aux'
     field.  Since built-in functions can be referenced in multiple
     functions, they are expected to be read more than once.  */
  if (node->aux && !fndecl_built_in_p (node->decl))
    internal_error ("bytecode stream: found multiple instances of cgraph "
		    "node with uid %d", node->get_uid ());

  node->tp_first_run = streamer_read_uhwi (ib);

  bp = streamer_read_bitpack (ib);

  input_overwrite_node (file_data, node, tag, &bp, &has_thunk_info);

  /* Store a reference for now, and fix up later to be a pointer.  */
  node->inlined_to = (cgraph_node *) (intptr_t) ref;

  if (group)
    {
      node->set_comdat_group (group);
      /* Store a reference for now, and fix up later to be a pointer.  */
      node->same_comdat_group = (symtab_node *) (intptr_t) ref2;
    }
  else
    node->same_comdat_group = (symtab_node *) (intptr_t) LCC_NOT_FOUND;
  section = read_string (ib);
  if (section)
    node->set_section_for_node (section);

  if (node->alias && !node->analyzed && node->weakref)
    node->alias_target = get_alias_symbol (node->decl);
  node->profile_id = streamer_read_hwi (ib);
  node->unit_id = streamer_read_hwi (ib) + file_data->unit_base;
  if (symtab->max_unit < node->unit_id)
    symtab->max_unit = node->unit_id;
  if (DECL_STATIC_CONSTRUCTOR (node->decl))
    node->set_init_priority (streamer_read_hwi (ib));
  if (DECL_STATIC_DESTRUCTOR (node->decl))
    node->set_fini_priority (streamer_read_hwi (ib));

  if (has_thunk_info)
    thunk_info::get_create (node)->stream_in (ib);

  return node;
}

/* Read a node from input_block IB.  TAG is the node's tag just read.
   Return the node read or overwriten.  */

static varpool_node *
input_varpool_node (struct lto_file_decl_data *file_data,
		    class lto_input_block *ib)
{
  tree var_decl;
  varpool_node *node;
  struct bitpack_d bp;
  int ref = LCC_NOT_FOUND;
  int order;
  tree group;
  const char *section;

  order = streamer_read_hwi (ib) + file_data->order_base;
  var_decl = lto_input_var_decl_ref (ib, file_data);

  /* Declaration of functions can be already merged with a declaration
     from other input file.  We keep cgraph unmerged until after streaming
     of ipa passes is done.  Alays forcingly create a fresh node.  */
  node = varpool_node::create_empty ();
  node->decl = var_decl;
  node->register_symbol ();

  node->order = order;
  if (order >= symtab->order)
    symtab->order = order + 1;
  node->lto_file_data = file_data;

  bp = streamer_read_bitpack (ib);
  node->externally_visible = bp_unpack_value (&bp, 1);
  node->no_reorder = bp_unpack_value (&bp, 1);
  node->force_output = bp_unpack_value (&bp, 1);
  node->forced_by_abi = bp_unpack_value (&bp, 1);
  node->unique_name = bp_unpack_value (&bp, 1);
  node->body_removed = bp_unpack_value (&bp, 1);
  node->semantic_interposition = bp_unpack_value (&bp, 1);
  node->implicit_section = bp_unpack_value (&bp, 1);
  node->writeonly = bp_unpack_value (&bp, 1);
  node->definition = bp_unpack_value (&bp, 1);
  node->alias = bp_unpack_value (&bp, 1);
  node->transparent_alias = bp_unpack_value (&bp, 1);
  node->weakref = bp_unpack_value (&bp, 1);
  node->symver = bp_unpack_value (&bp, 1);
  node->analyzed = bp_unpack_value (&bp, 1);
  node->used_from_other_partition = bp_unpack_value (&bp, 1);
  node->in_other_partition = bp_unpack_value (&bp, 1);
  if (node->in_other_partition)
    {
      DECL_EXTERNAL (node->decl) = 1;
      TREE_STATIC (node->decl) = 0;
    }
  if (node->alias && !node->analyzed && node->weakref)
    node->alias_target = get_alias_symbol (node->decl);
  node->tls_model = (enum tls_model)bp_unpack_value (&bp, 3);
  node->used_by_single_function = (enum tls_model)bp_unpack_value (&bp, 1);
  node->dynamically_initialized = bp_unpack_value (&bp, 1);
  group = read_identifier (ib);
  if (group)
    {
      node->set_comdat_group (group);
      ref = streamer_read_hwi (ib);
      /* Store a reference for now, and fix up later to be a pointer.  */
      node->same_comdat_group = (symtab_node *) (intptr_t) ref;
    }
  else
    node->same_comdat_group = (symtab_node *) (intptr_t) LCC_NOT_FOUND;
  section = read_string (ib);
  if (section)
    node->set_section_for_node (section);
  node->resolution = streamer_read_enum (ib, ld_plugin_symbol_resolution,
					        LDPR_NUM_KNOWN);
  verify_node_partition (node);
  return node;
}

/* Read a node from input_block IB.  TAG is the node's tag just read.
   Return the node read or overwriten.  */

static void
input_ref (class lto_input_block *ib,
	   symtab_node *referring_node,
	   vec<symtab_node *> nodes)
{
  symtab_node *node = NULL;
  struct bitpack_d bp;
  enum ipa_ref_use use;
  bool speculative;
  struct ipa_ref *ref;

  bp = streamer_read_bitpack (ib);
  use = (enum ipa_ref_use) bp_unpack_value (&bp, 3);
  speculative = (enum ipa_ref_use) bp_unpack_value (&bp, 1);
  node = nodes[streamer_read_hwi (ib)];
  ref = referring_node->create_reference (node, use);
  ref->speculative = speculative;
  if (is_a <cgraph_node *> (referring_node))
    {
      ref->lto_stmt_uid = streamer_read_hwi (ib);
      bp = streamer_read_bitpack (ib);
      ref->speculative_id = bp_unpack_value (&bp, 16);
    }
}

/* Read an edge from IB.  NODES points to a vector of previously read nodes for
   decoding caller and callee of the edge to be read.  If INDIRECT is true, the
   edge being read is indirect (in the sense that it has
   indirect_unknown_callee set).  */

static void
input_edge (class lto_input_block *ib, vec<symtab_node *> nodes,
	    bool indirect)
{
  struct cgraph_node *caller, *callee;
  struct cgraph_edge *edge;
  unsigned int stmt_id, speculative_id;
  profile_count count;
  cgraph_inline_failed_t inline_failed;
  struct bitpack_d bp;
  int ecf_flags = 0;

  caller = dyn_cast<cgraph_node *> (nodes[streamer_read_hwi (ib)]);
  if (caller == NULL || caller->decl == NULL_TREE)
    internal_error ("bytecode stream: no caller found while reading edge");

  if (!indirect)
    {
      callee = dyn_cast<cgraph_node *> (nodes[streamer_read_hwi (ib)]);
      if (callee == NULL || callee->decl == NULL_TREE)
	internal_error ("bytecode stream: no callee found while reading edge");
    }
  else
    callee = NULL;

  count = profile_count::stream_in (ib);

  bp = streamer_read_bitpack (ib);
  inline_failed = bp_unpack_enum (&bp, cgraph_inline_failed_t, CIF_N_REASONS);
  stmt_id = bp_unpack_var_len_unsigned (&bp);
  speculative_id = bp_unpack_value (&bp, 16);

  if (indirect)
    edge = caller->create_indirect_edge (NULL, 0, count);
  else
    edge = caller->create_edge (callee, NULL, count);

  edge->indirect_inlining_edge = bp_unpack_value (&bp, 1);
  edge->speculative = bp_unpack_value (&bp, 1);
  edge->lto_stmt_uid = stmt_id;
  edge->speculative_id = speculative_id;
  edge->inline_failed = inline_failed;
  edge->call_stmt_cannot_inline_p = bp_unpack_value (&bp, 1);
  edge->can_throw_external = bp_unpack_value (&bp, 1);
  edge->in_polymorphic_cdtor = bp_unpack_value (&bp, 1);
  if (indirect)
    {
      if (bp_unpack_value (&bp, 1))
	ecf_flags |= ECF_CONST;
      if (bp_unpack_value (&bp, 1))
	ecf_flags |= ECF_PURE;
      if (bp_unpack_value (&bp, 1))
	ecf_flags |= ECF_NORETURN;
      if (bp_unpack_value (&bp, 1))
	ecf_flags |= ECF_MALLOC;
      if (bp_unpack_value (&bp, 1))
	ecf_flags |= ECF_NOTHROW;
      if (bp_unpack_value (&bp, 1))
	ecf_flags |= ECF_RETURNS_TWICE;
      edge->indirect_info->ecf_flags = ecf_flags;

      edge->indirect_info->num_speculative_call_targets
	= bp_unpack_value (&bp, 16);
    }
}


/* Read a cgraph from IB using the info in FILE_DATA.  */

static vec<symtab_node *> 
input_cgraph_1 (struct lto_file_decl_data *file_data,
		class lto_input_block *ib)
{
  enum LTO_symtab_tags tag;
  vec<symtab_node *> nodes = vNULL;
  symtab_node *node;
  unsigned i;

  tag = streamer_read_enum (ib, LTO_symtab_tags, LTO_symtab_last_tag);
  file_data->order_base = symtab->order;
  file_data->unit_base = symtab->max_unit + 1;
  while (tag)
    {
      if (tag == LTO_symtab_edge)
        input_edge (ib, nodes, false);
      else if (tag == LTO_symtab_indirect_edge)
        input_edge (ib, nodes, true);
      else if (tag == LTO_symtab_variable)
        {
	  node = input_varpool_node (file_data, ib);
          nodes.safe_push (node);
	  lto_symtab_encoder_encode (file_data->symtab_node_encoder, node);
        }
      else
	{
	  node = input_node (file_data, ib, tag, nodes);
	  if (node == NULL || node->decl == NULL_TREE)
	    internal_error ("bytecode stream: found empty cgraph node");
	  nodes.safe_push (node);
	  lto_symtab_encoder_encode (file_data->symtab_node_encoder, node);
	}

      tag = streamer_read_enum (ib, LTO_symtab_tags, LTO_symtab_last_tag);
    }

  lto_input_toplevel_asms (file_data, file_data->order_base);

  /* AUX pointers should be all non-zero for function nodes read from the stream.  */
  if (flag_checking)
    {
      FOR_EACH_VEC_ELT (nodes, i, node)
	gcc_assert (node->aux || !is_a <cgraph_node *> (node));
    }
  FOR_EACH_VEC_ELT (nodes, i, node)
    {
      int ref;
      if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
	{
	  ref = (int) (intptr_t) cnode->inlined_to;

	  /* We share declaration of builtins, so we may read same node twice.  */
	  if (!node->aux)
	    continue;
	  node->aux = NULL;

	  /* Fixup inlined_to from reference to pointer.  */
	  if (ref != LCC_NOT_FOUND)
	    dyn_cast<cgraph_node *> (node)->inlined_to
	      = dyn_cast<cgraph_node *> (nodes[ref]);
	  else
	    cnode->inlined_to = NULL;
	}

      ref = (int) (intptr_t) node->same_comdat_group;

      /* Fixup same_comdat_group from reference to pointer.  */
      if (ref != LCC_NOT_FOUND)
	node->same_comdat_group = nodes[ref];
      else
	node->same_comdat_group = NULL;
    }
  FOR_EACH_VEC_ELT (nodes, i, node)
    node->aux = is_a <cgraph_node *> (node) ? (void *)1 : NULL;
  return nodes;
}

/* Input ipa_refs.  */

static void
input_refs (class lto_input_block *ib,
	    vec<symtab_node *> nodes)
{
  int count;
  int idx;
  while (true)
    {
      symtab_node *node;
      count = streamer_read_uhwi (ib);
      if (!count)
	break;
      idx = streamer_read_uhwi (ib);
      node = nodes[idx];
      while (count)
	{
	  input_ref (ib, node, nodes);
	  count--;
	}
      if (cgraph_node *cnode = dyn_cast <cgraph_node *> (node))
	if (cnode->declare_variant_alt)
	  omp_lto_input_declare_variant_alt (ib, cnode, nodes);
    }
}
	    
/* Input profile_info from IB.  */
static void
input_profile_summary (class lto_input_block *ib,
		       struct lto_file_decl_data *file_data)
{
  unsigned int runs = streamer_read_uhwi (ib);
  if (runs)
    {
      file_data->profile_info.runs = runs;

      /* IPA-profile computes hot bb threshold based on cumulated
	 whole program profile.  We need to stream it down to ltrans.  */
      if (flag_ltrans)
	set_hot_bb_threshold (streamer_read_gcov_count (ib));
    }

}

/* Rescale profile summaries to the same number of runs in the whole unit.  */

static void
merge_profile_summaries (struct lto_file_decl_data **file_data_vec)
{
  struct lto_file_decl_data *file_data;
  unsigned int j;
  gcov_unsigned_t max_runs = 0;
  struct cgraph_node *node;
  struct cgraph_edge *edge;

  /* Find unit with maximal number of runs.  If we ever get serious about
     roundoff errors, we might also consider computing smallest common
     multiply.  */
  for (j = 0; (file_data = file_data_vec[j]) != NULL; j++)
    if (max_runs < file_data->profile_info.runs)
      max_runs = file_data->profile_info.runs;

  if (!max_runs)
    return;

  /* Simple overflow check.  We probably don't need to support that many train
     runs. Such a large value probably imply data corruption anyway.  */
  if (max_runs > INT_MAX / REG_BR_PROB_BASE)
    {
      sorry ("At most %i profile runs is supported. Perhaps corrupted profile?",
	     INT_MAX / REG_BR_PROB_BASE);
      return;
    }

  profile_info = XCNEW (gcov_summary);
  profile_info->runs = max_runs;

  /* If merging already happent at WPA time, we are done.  */
  if (flag_ltrans)
    return;

  /* Now compute count_materialization_scale of each node.
     During LTRANS we already have values of count_materialization_scale
     computed, so just update them.  */
  FOR_EACH_FUNCTION (node)
    if (node->lto_file_data
	&& node->lto_file_data->profile_info.runs)
      {
	int scale;

	scale = RDIV (node->count_materialization_scale * max_runs,
                      node->lto_file_data->profile_info.runs);
	node->count_materialization_scale = scale;
	if (scale < 0)
	  fatal_error (input_location, "Profile information in %s corrupted",
		       file_data->file_name);

	if (scale == REG_BR_PROB_BASE)
	  continue;
	for (edge = node->callees; edge; edge = edge->next_callee)
	  if (edge->count.ipa ().nonzero_p ())
	    edge->count = edge->count.apply_scale (scale, REG_BR_PROB_BASE);
	for (edge = node->indirect_calls; edge; edge = edge->next_callee)
	  if (edge->count.ipa ().nonzero_p ())
	    edge->count = edge->count.apply_scale (scale, REG_BR_PROB_BASE);
	if (node->count.ipa ().nonzero_p ())
	  node->count = node->count.apply_scale (scale, REG_BR_PROB_BASE);
      }
}

/* Input and merge the symtab from each of the .o files passed to
   lto1.  */

void
input_symtab (void)
{
  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
  struct lto_file_decl_data *file_data;
  unsigned int j = 0;
  struct cgraph_node *node;

  while ((file_data = file_data_vec[j++]))
    {
      const char *data;
      size_t len;
      class lto_input_block *ib;
      vec<symtab_node *> nodes;

      ib = lto_create_simple_input_block (file_data, LTO_section_symtab_nodes,
					  &data, &len);
      if (!ib) 
	fatal_error (input_location,
		     "cannot find LTO cgraph in %s", file_data->file_name);
      input_profile_summary (ib, file_data);
      file_data->symtab_node_encoder = lto_symtab_encoder_new (true);
      nodes = input_cgraph_1 (file_data, ib);
      lto_destroy_simple_input_block (file_data, LTO_section_symtab_nodes,
				      ib, data, len);

      ib = lto_create_simple_input_block (file_data, LTO_section_refs,
					  &data, &len);
      if (!ib)
	fatal_error (input_location, "cannot find LTO section refs in %s",
		     file_data->file_name);
      input_refs (ib, nodes);
      lto_destroy_simple_input_block (file_data, LTO_section_refs,
				      ib, data, len);
      if (flag_ltrans)
	input_cgraph_opt_summary (nodes);
      nodes.release ();
    }

  merge_profile_summaries (file_data_vec);

  /* Clear out the aux field that was used to store enough state to
     tell which nodes should be overwritten.  */
  FOR_EACH_FUNCTION (node)
    {
      /* Some nodes may have been created by cgraph_node.  This
	 happens when the callgraph contains nested functions.  If the
	 node for the parent function was never emitted to the gimple
	 file, cgraph_node will create a node for it when setting the
	 context of the nested function.  */
      if (node->lto_file_data)
	node->aux = NULL;
    }
}

static void
omp_requires_to_name (char *buf, size_t size, HOST_WIDE_INT requires_mask)
{
  char *end = buf + size, *p = buf;
  if (requires_mask & GOMP_REQUIRES_UNIFIED_ADDRESS)
    p += snprintf (p, end - p, "unified_address");
  if (requires_mask & GOMP_REQUIRES_UNIFIED_SHARED_MEMORY)
    p += snprintf (p, end - p, "%sunified_shared_memory",
		   (p == buf ? "" : ", "));
  if (requires_mask & GOMP_REQUIRES_REVERSE_OFFLOAD)
    p += snprintf (p, end - p, "%sreverse_offload",
		   (p == buf ? "" : ", "));
}

/* Input function/variable tables that will allow libgomp to look up offload
   target code, and store them into OFFLOAD_FUNCS and OFFLOAD_VARS.  */

void
input_offload_tables (bool do_force_output)
{
  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
  struct lto_file_decl_data *file_data;
  unsigned int j = 0;
  const char *requires_fn = NULL;
  tree requires_decl = NULL_TREE;

  omp_requires_mask = (omp_requires) 0;

  while ((file_data = file_data_vec[j++]))
    {
      const char *data;
      size_t len;
      class lto_input_block *ib
	= lto_create_simple_input_block (file_data, LTO_section_offload_table,
					 &data, &len);
      if (!ib)
	continue;

      tree tmp_decl = NULL_TREE;
      enum LTO_symtab_tags tag
	= streamer_read_enum (ib, LTO_symtab_tags, LTO_symtab_last_tag);
      while (tag)
	{
	  if (tag == LTO_symtab_unavail_node)
	    {
	      tree fn_decl
		= lto_input_fn_decl_ref (ib, file_data);
	      vec_safe_push (offload_funcs, fn_decl);

	      /* Prevent IPA from removing fn_decl as unreachable, since there
		 may be no refs from the parent function to child_fn in offload
		 LTO mode.  */
	      if (do_force_output)
		cgraph_node::get (fn_decl)->mark_force_output ();
	      tmp_decl = fn_decl;
	    }
	  else if (tag == LTO_symtab_variable)
	    {
	      tree var_decl
		= lto_input_var_decl_ref (ib, file_data);
	      vec_safe_push (offload_vars, var_decl);

	      /* Prevent IPA from removing var_decl as unused, since there
		 may be no refs to var_decl in offload LTO mode.  */
	      if (do_force_output)
		varpool_node::get (var_decl)->force_output = 1;
	      tmp_decl = var_decl;
	    }
	  else if (tag == LTO_symtab_edge)
	    {
	      static bool error_emitted = false;
	      HOST_WIDE_INT val = streamer_read_hwi (ib);

	      if (omp_requires_mask == 0)
		{
		  omp_requires_mask = (omp_requires) val;
		  requires_decl = tmp_decl;
		  requires_fn = file_data->file_name;
		}
	      else if (omp_requires_mask != val && !error_emitted)
		{
		  const char *fn1 = requires_fn;
		  if (requires_decl != NULL_TREE)
		    {
		      while (DECL_CONTEXT (requires_decl) != NULL_TREE
			     && TREE_CODE (requires_decl) != TRANSLATION_UNIT_DECL)
			requires_decl = DECL_CONTEXT (requires_decl);
		      if (requires_decl != NULL_TREE)
			fn1 = IDENTIFIER_POINTER (DECL_NAME (requires_decl));
		    }

		  const char *fn2 = file_data->file_name;
		  if (tmp_decl != NULL_TREE)
		    {
		      while (DECL_CONTEXT (tmp_decl) != NULL_TREE
			     && TREE_CODE (tmp_decl) != TRANSLATION_UNIT_DECL)
			tmp_decl = DECL_CONTEXT (tmp_decl);
		      if (tmp_decl != NULL_TREE)
			fn2 = IDENTIFIER_POINTER (DECL_NAME (tmp_decl));
		    }
		  if (fn1 == fn2)
		    {
		      fn1 = requires_fn;
		      fn2 = file_data->file_name;
		    }

		  char buf1[sizeof ("unified_address, unified_shared_memory, "
				    "reverse_offload")];
		  char buf2[sizeof ("unified_address, unified_shared_memory, "
				    "reverse_offload")];
		  omp_requires_to_name (buf2, sizeof (buf2),
					val != OMP_REQUIRES_TARGET_USED
					? val
					: (HOST_WIDE_INT) omp_requires_mask);
		  if (val != OMP_REQUIRES_TARGET_USED
		      && omp_requires_mask != OMP_REQUIRES_TARGET_USED)
		    {
		      omp_requires_to_name (buf1, sizeof (buf1),
					    omp_requires_mask);
		      error ("OpenMP %<requires%> directive with non-identical "
			     "clauses in multiple compilation units: %qs vs. "
			     "%qs", buf1, buf2);
		      inform (UNKNOWN_LOCATION, "%qs has %qs", fn1, buf1);
		      inform (UNKNOWN_LOCATION, "%qs has %qs", fn2, buf2);
		    }
		  else
		    {
		      error ("OpenMP %<requires%> directive with %qs specified "
			     "only in some compilation units", buf2);
		      inform (UNKNOWN_LOCATION, "%qs has %qs",
			      val != OMP_REQUIRES_TARGET_USED ? fn2 : fn1,
			      buf2);
		      inform (UNKNOWN_LOCATION, "but %qs has not",
			      val != OMP_REQUIRES_TARGET_USED ? fn1 : fn2);
		    }
		  error_emitted = true;
		}
	    }
	  else
	    fatal_error (input_location,
			 "invalid offload table in %s", file_data->file_name);

	  tag = streamer_read_enum (ib, LTO_symtab_tags, LTO_symtab_last_tag);
	}

      lto_destroy_simple_input_block (file_data, LTO_section_offload_table,
				      ib, data, len);
    }
#ifdef ACCEL_COMPILER
  char *omp_requires_file = getenv ("GCC_OFFLOAD_OMP_REQUIRES_FILE");
  if (omp_requires_file == NULL || omp_requires_file[0] == '\0')
    fatal_error (input_location, "GCC_OFFLOAD_OMP_REQUIRES_FILE unset");
  FILE *f = fopen (omp_requires_file, "wb");
  if (!f)
    fatal_error (input_location, "Cannot open omp_requires file %qs",
		 omp_requires_file);
  uint32_t req_mask = omp_requires_mask;
  fwrite (&req_mask, sizeof (req_mask), 1, f);
  fclose (f);
#endif
}

/* True when we need optimization summary for NODE.  */

static int
output_cgraph_opt_summary_p (struct cgraph_node *node)
{
  if (node->clone_of || node->former_clone_of)
    return true;
  clone_info *info = clone_info::get (node);
  return info && (info->tree_map || info->param_adjustments);
}

/* Output optimization summary for EDGE to OB.  */
static void
output_edge_opt_summary (struct output_block *ob ATTRIBUTE_UNUSED,
			 struct cgraph_edge *edge ATTRIBUTE_UNUSED)
{
}

/* Output optimization summary for NODE to OB.  */

static void
output_node_opt_summary (struct output_block *ob,
			 struct cgraph_node *node,
			 lto_symtab_encoder_t encoder)
{
  struct ipa_replace_map *map;
  int i;
  struct cgraph_edge *e;

  /* TODO: Should this code be moved to ipa-param-manipulation?  */
  struct bitpack_d bp;
  bp = bitpack_create (ob->main_stream);
  clone_info *info = clone_info::get (node);
  
  bp_pack_value (&bp, (info && info->param_adjustments != NULL), 1);
  streamer_write_bitpack (&bp);
  if (ipa_param_adjustments *adjustments
		 = info ? info->param_adjustments : NULL)
    {
      streamer_write_uhwi (ob, vec_safe_length (adjustments->m_adj_params));
      ipa_adjusted_param *adj;
      FOR_EACH_VEC_SAFE_ELT (adjustments->m_adj_params, i, adj)
	{
	  bp = bitpack_create (ob->main_stream);
	  bp_pack_value (&bp, adj->base_index, IPA_PARAM_MAX_INDEX_BITS);
	  bp_pack_value (&bp, adj->prev_clone_index, IPA_PARAM_MAX_INDEX_BITS);
	  bp_pack_value (&bp, adj->op, 2);
	  bp_pack_value (&bp, adj->param_prefix_index, 2);
	  bp_pack_value (&bp, adj->prev_clone_adjustment, 1);
	  bp_pack_value (&bp, adj->reverse, 1);
	  bp_pack_value (&bp, adj->user_flag, 1);
	  streamer_write_bitpack (&bp);
	  if (adj->op == IPA_PARAM_OP_SPLIT
	      || adj->op == IPA_PARAM_OP_NEW)
	    {
	      stream_write_tree (ob, adj->type, true);
	      if (adj->op == IPA_PARAM_OP_SPLIT)
		{
		  stream_write_tree (ob, adj->alias_ptr_type, true);
		  streamer_write_uhwi (ob, adj->unit_offset);
		}
	    }
	}
      streamer_write_hwi (ob, adjustments->m_always_copy_start);
      bp = bitpack_create (ob->main_stream);
      bp_pack_value (&bp, info->param_adjustments->m_skip_return, 1);
      streamer_write_bitpack (&bp);
    }

  streamer_write_uhwi (ob, info ? vec_safe_length (info->tree_map) : 0);
  if (info)
    FOR_EACH_VEC_SAFE_ELT (info->tree_map, i, map)
      {
	streamer_write_uhwi (ob, map->parm_num);
	gcc_assert (EXPR_LOCATION (map->new_tree) == UNKNOWN_LOCATION);
	stream_write_tree (ob, map->new_tree, true);
      }

  if (lto_symtab_encoder_in_partition_p (encoder, node))
    {
      for (e = node->callees; e; e = e->next_callee)
	output_edge_opt_summary (ob, e);
      for (e = node->indirect_calls; e; e = e->next_callee)
	output_edge_opt_summary (ob, e);
    }
}

/* Output optimization summaries stored in callgraph.
   At the moment it is the clone info structure.  */

static void
output_cgraph_opt_summary (void)
{
  int i, n_nodes;
  lto_symtab_encoder_t encoder;
  struct output_block *ob = create_output_block (LTO_section_cgraph_opt_sum);
  unsigned count = 0;

  ob->symbol = NULL;
  encoder = ob->decl_state->symtab_node_encoder;
  n_nodes = lto_symtab_encoder_size (encoder);
  for (i = 0; i < n_nodes; i++)
    {
      symtab_node *node = lto_symtab_encoder_deref (encoder, i);
      cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
      if (cnode && output_cgraph_opt_summary_p (cnode))
	count++;
    }
  streamer_write_uhwi (ob, count);
  for (i = 0; i < n_nodes; i++)
    {
      symtab_node *node = lto_symtab_encoder_deref (encoder, i);
      cgraph_node *cnode = dyn_cast <cgraph_node *> (node);
      if (cnode && output_cgraph_opt_summary_p (cnode))
	{
	  streamer_write_uhwi (ob, i);
	  output_node_opt_summary (ob, cnode, encoder);
	}
    }
  produce_asm (ob, NULL);
  destroy_output_block (ob);
}

/* Input optimisation summary of EDGE.  */

static void
input_edge_opt_summary (struct cgraph_edge *edge ATTRIBUTE_UNUSED,
			class lto_input_block *ib_main ATTRIBUTE_UNUSED)
{
}

/* Input optimisation summary of NODE.  */

static void
input_node_opt_summary (struct cgraph_node *node,
			class lto_input_block *ib_main,
			class data_in *data_in)
{
  int i;
  int count;
  struct cgraph_edge *e;

  /* TODO: Should this code be moved to ipa-param-manipulation?  */
  struct bitpack_d bp;
  bp = streamer_read_bitpack (ib_main);
  bool have_adjustments = bp_unpack_value (&bp, 1);
  clone_info *info = clone_info::get_create (node);

  if (have_adjustments)
    {
      count = streamer_read_uhwi (ib_main);
      vec<ipa_adjusted_param, va_gc> *new_params = NULL;
      for (i = 0; i < count; i++)
	{
	  ipa_adjusted_param adj;
	  memset (&adj, 0, sizeof (adj));
	  bp = streamer_read_bitpack (ib_main);
	  adj.base_index = bp_unpack_value (&bp, IPA_PARAM_MAX_INDEX_BITS);
	  adj.prev_clone_index
	    = bp_unpack_value (&bp, IPA_PARAM_MAX_INDEX_BITS);
	  adj.op = (enum ipa_parm_op) bp_unpack_value (&bp, 2);
	  adj.param_prefix_index = bp_unpack_value (&bp, 2);
	  adj.prev_clone_adjustment = bp_unpack_value (&bp, 1);
	  adj.reverse = bp_unpack_value (&bp, 1);
	  adj.user_flag = bp_unpack_value (&bp, 1);
	  if (adj.op == IPA_PARAM_OP_SPLIT
	      || adj.op == IPA_PARAM_OP_NEW)
	    {
	      adj.type = stream_read_tree (ib_main, data_in);
	      if (adj.op == IPA_PARAM_OP_SPLIT)
		{
		  adj.alias_ptr_type = stream_read_tree (ib_main, data_in);
		  adj.unit_offset = streamer_read_uhwi (ib_main);
		}
	    }
	  vec_safe_push (new_params, adj);
	}
      int always_copy_start = streamer_read_hwi (ib_main);
      bp = streamer_read_bitpack (ib_main);
      bool skip_return = bp_unpack_value (&bp, 1);
      info->param_adjustments
	= (new (ggc_alloc <ipa_param_adjustments> ())
	   ipa_param_adjustments (new_params, always_copy_start, skip_return));
    }

  count = streamer_read_uhwi (ib_main);
  for (i = 0; i < count; i++)
    {
      struct ipa_replace_map *map = ggc_alloc<ipa_replace_map> ();

      vec_safe_push (info->tree_map, map);
      map->parm_num = streamer_read_uhwi (ib_main);
      map->new_tree = stream_read_tree (ib_main, data_in);
    }
  for (e = node->callees; e; e = e->next_callee)
    input_edge_opt_summary (e, ib_main);
  for (e = node->indirect_calls; e; e = e->next_callee)
    input_edge_opt_summary (e, ib_main);
}

/* Read section in file FILE_DATA of length LEN with data DATA.  */

static void
input_cgraph_opt_section (struct lto_file_decl_data *file_data,
			  const char *data, size_t len,
			  vec<symtab_node *> nodes)
{
  const struct lto_function_header *header =
    (const struct lto_function_header *) data;
  const int cfg_offset = sizeof (struct lto_function_header);
  const int main_offset = cfg_offset + header->cfg_size;
  const int string_offset = main_offset + header->main_size;
  class data_in *data_in;
  unsigned int i;
  unsigned int count;

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

  data_in =
    lto_data_in_create (file_data, (const char *) data + string_offset,
			header->string_size, vNULL);
  count = streamer_read_uhwi (&ib_main);

  for (i = 0; i < count; i++)
    {
      int ref = streamer_read_uhwi (&ib_main);
      input_node_opt_summary (dyn_cast<cgraph_node *> (nodes[ref]),
			      &ib_main, data_in);
    }
  lto_free_section_data (file_data, LTO_section_cgraph_opt_sum, NULL, data,
			 len);
  lto_data_in_delete (data_in);
}

/* Input optimization summary of cgraph.  */

static void
input_cgraph_opt_summary (vec<symtab_node *> nodes)
{
  struct lto_file_decl_data **file_data_vec = lto_get_file_decl_data ();
  struct lto_file_decl_data *file_data;
  unsigned int j = 0;

  while ((file_data = file_data_vec[j++]))
    {
      size_t len;
      const char *data
	= lto_get_summary_section_data (file_data, LTO_section_cgraph_opt_sum,
					&len);
      if (data)
	input_cgraph_opt_section (file_data, data, len, nodes);
    }
}
