/* Manipulation of formal and actual parameters of functions and function
   calls.
   Copyright (C) 2017-2022 Free Software Foundation, 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 "backend.h"
#include "tree.h"
#include "gimple.h"
#include "ssa.h"
#include "cgraph.h"
#include "fold-const.h"
#include "tree-eh.h"
#include "stor-layout.h"
#include "gimplify.h"
#include "gimple-iterator.h"
#include "gimplify-me.h"
#include "tree-cfg.h"
#include "tree-dfa.h"
#include "ipa-param-manipulation.h"
#include "print-tree.h"
#include "gimple-pretty-print.h"
#include "builtins.h"
#include "tree-ssa.h"
#include "tree-inline.h"
#include "alloc-pool.h"
#include "symbol-summary.h"
#include "symtab-clones.h"
#include "tree-phinodes.h"
#include "cfgexpand.h"
#include "attribs.h"


/* Actual prefixes of different newly synthetized parameters.  Keep in sync
   with IPA_PARAM_PREFIX_* defines.  */

static const char *ipa_param_prefixes[IPA_PARAM_PREFIX_COUNT]
  = {"SYNTH",
     "ISRA",
     "simd",
     "mask"};

/* Names of parameters for dumping.  Keep in sync with enum ipa_parm_op.  */

static const char *ipa_param_op_names[IPA_PARAM_PREFIX_COUNT]
  = {"IPA_PARAM_OP_UNDEFINED",
     "IPA_PARAM_OP_COPY",
     "IPA_PARAM_OP_NEW",
     "IPA_PARAM_OP_SPLIT"};

/* Structure to hold declarations representing pass-through IPA-SRA splits.  In
   essence, it tells new index for a combination of original index and
   offset.  */

struct pass_through_split_map
{
  /* Original argument index.  */
  unsigned base_index;
  /* Offset of the split part in the original argument.  */
  unsigned unit_offset;
  /* Index of the split part in the call statement - where clone
     materialization put it.  */
  int new_index;
};

/* Information about some call statements that needs to be conveyed from clone
   materialization to edge redirection. */

class ipa_edge_modification_info
{
 public:
  ipa_edge_modification_info ()
    {}

  /* Mapping of original argument indices to where those arguments sit in the
     call statement now or to a negative index if they were removed.  */
  auto_vec<int> index_map;
  /* Information about ISRA replacements put into the call statement at the
     clone materialization stages.  */
  auto_vec<pass_through_split_map> pass_through_map;
  /* Necessary adjustment to ipa_param_adjustments::m_always_copy_start when
     redirecting the call.  */
  int always_copy_delta = 0;
};

/* Class for storing and retrieving summaries about cal statement
   modifications.  */

class ipa_edge_modification_sum
  : public call_summary <ipa_edge_modification_info *>
{
 public:
  ipa_edge_modification_sum (symbol_table *table)
    : call_summary<ipa_edge_modification_info *> (table)
  {
  }

  /* Hook that is called by summary when an edge is duplicated.  */

  virtual void duplicate (cgraph_edge *,
			  cgraph_edge *,
			  ipa_edge_modification_info *old_info,
			  ipa_edge_modification_info *new_info)
  {
    new_info->index_map.safe_splice (old_info->index_map);
    new_info->pass_through_map.safe_splice (old_info->pass_through_map);
    new_info->always_copy_delta = old_info->always_copy_delta;
  }
};

/* Call summary to store information about edges which have had their arguments
   partially modified already.  */

static ipa_edge_modification_sum *ipa_edge_modifications;

/* Fail compilation if CS has any summary associated with it in
   ipa_edge_modifications.  */

DEBUG_FUNCTION void
ipa_verify_edge_has_no_modifications (cgraph_edge *cs)
{
  gcc_assert (!ipa_edge_modifications || !ipa_edge_modifications->get (cs));
}

/* Fill an empty vector ARGS with PARM_DECLs representing formal parameters of
   FNDECL.  The function should not be called during LTO WPA phase except for
   thunks (or functions with bodies streamed in). */

void
push_function_arg_decls (vec<tree> *args, tree fndecl)
{
  int count;
  tree parm;

  /* Safety check that we do not attempt to use the function in WPA, except
     when the function is a thunk and then we have DECL_ARGUMENTS or when we
     have already explicitely loaded its body.  */
  gcc_assert (!flag_wpa
	      || DECL_ARGUMENTS (fndecl)
	      || gimple_has_body_p (fndecl));
  count = 0;
  for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
    count++;

  args->reserve_exact (count);
  for (parm = DECL_ARGUMENTS (fndecl); parm; parm = DECL_CHAIN (parm))
    args->quick_push (parm);
}

/* Fill an empty vector TYPES with trees representing formal parameters of
   function type FNTYPE.  */

void
push_function_arg_types (vec<tree> *types, tree fntype)
{
  int count = 0;
  tree t;

  for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
    count++;

  types->reserve_exact (count);
  for (t = TYPE_ARG_TYPES (fntype); t; t = TREE_CHAIN (t))
    types->quick_push (TREE_VALUE (t));
}

/* Dump the adjustments in the vector ADJUSTMENTS to dump_file in a human
   friendly way, assuming they are meant to be applied to FNDECL.  */

void
ipa_dump_adjusted_parameters (FILE *f,
			      vec<ipa_adjusted_param, va_gc> *adj_params)
{
  unsigned i, len = vec_safe_length (adj_params);
  bool first = true;

  if (!len)
    return;

  fprintf (f, "    IPA adjusted parameters: ");
  for (i = 0; i < len; i++)
    {
      struct ipa_adjusted_param *apm;
      apm = &(*adj_params)[i];

      if (!first)
	fprintf (f, "                             ");
      else
	first = false;

      fprintf (f, "%i. %s %s", i, ipa_param_op_names[apm->op],
	       apm->prev_clone_adjustment ? "prev_clone_adjustment " : "");
      switch (apm->op)
	{
	case IPA_PARAM_OP_UNDEFINED:
	  break;

	case IPA_PARAM_OP_COPY:
	  fprintf (f, ", base_index: %u", apm->base_index);
	  fprintf (f, ", prev_clone_index: %u", apm->prev_clone_index);
	  break;

	case IPA_PARAM_OP_SPLIT:
	  fprintf (f, ", offset: %u", apm->unit_offset);
	  /* fall-through */
	case IPA_PARAM_OP_NEW:
	  fprintf (f, ", base_index: %u", apm->base_index);
	  fprintf (f, ", prev_clone_index: %u", apm->prev_clone_index);
	  print_node_brief (f, ", type: ", apm->type, 0);
	  print_node_brief (f, ", alias type: ", apm->alias_ptr_type, 0);
	  fprintf (f, " prefix: %s",
		   ipa_param_prefixes[apm->param_prefix_index]);
	  if (apm->reverse)
	    fprintf (f, ", reverse");
	  break;
	}
      fprintf (f, "\n");
    }
}

/* Fill NEW_TYPES with types of a function after its current OTYPES have been
   modified as described in ADJ_PARAMS.  When USE_PREV_INDICES is true, use
   prev_clone_index from ADJ_PARAMS as opposed to base_index when the parameter
   is false.  */

static void
fill_vector_of_new_param_types (vec<tree> *new_types, vec<tree> *otypes,
				vec<ipa_adjusted_param, va_gc> *adj_params,
				bool use_prev_indices)
{
  unsigned adj_len = vec_safe_length (adj_params);
  new_types->reserve_exact (adj_len);
  for (unsigned i = 0; i < adj_len ; i++)
    {
      ipa_adjusted_param *apm = &(*adj_params)[i];
      if (apm->op == IPA_PARAM_OP_COPY)
	{
	  unsigned index
	    = use_prev_indices ? apm->prev_clone_index : apm->base_index;
	  /* The following needs to be handled gracefully because of type
	     mismatches.  This happens with LTO but apparently also in Fortran
	     with -fcoarray=lib -O2 -lcaf_single -latomic.  */
	  if (index >= otypes->length ())
	    continue;
	  new_types->quick_push ((*otypes)[index]);
	}
      else if (apm->op == IPA_PARAM_OP_NEW
	       || apm->op == IPA_PARAM_OP_SPLIT)
	{
	  tree ntype = apm->type;
	  if (is_gimple_reg_type (ntype)
	      && TYPE_MODE (ntype) != BLKmode)
	    {
	      unsigned malign = GET_MODE_ALIGNMENT (TYPE_MODE (ntype));
	      if (TYPE_ALIGN (ntype) != malign)
		ntype = build_aligned_type (ntype, malign);
	    }
	  new_types->quick_push (ntype);
	}
      else
	gcc_unreachable ();
    }
}

/* Return false if given attribute should prevent type adjustments.  */

bool
ipa_param_adjustments::type_attribute_allowed_p (tree name)
{
  if ((is_attribute_p ("fn spec", name) && flag_ipa_modref)
      || is_attribute_p ("access", name)
      || is_attribute_p ("returns_nonnull", name)
      || is_attribute_p ("assume_aligned", name)
      || is_attribute_p ("nocf_check", name)
      || is_attribute_p ("warn_unused_result", name))
    return true;
  return false;
}

/* Return true if attribute should be dropped if parameter changed.  */

static bool
drop_type_attribute_if_params_changed_p (tree name)
{
  if (is_attribute_p ("fn spec", name)
      || is_attribute_p ("access", name))
    return true;
  return false;
}

/* Build and return a function type just like ORIG_TYPE but with parameter
   types given in NEW_PARAM_TYPES - which can be NULL if, but only if,
   ORIG_TYPE itself has NULL TREE_ARG_TYPEs.  If METHOD2FUNC is true, also make
   it a FUNCTION_TYPE instead of FUNCTION_TYPE.
   If ARG_MODIFIED is true drop attributes that are no longer up to date.  */

static tree
build_adjusted_function_type (tree orig_type, vec<tree> *new_param_types,
			      bool method2func, bool skip_return,
			      bool args_modified)
{
  tree new_arg_types = NULL;
  if (TYPE_ARG_TYPES (orig_type))
    {
      gcc_checking_assert (new_param_types);
      bool last_parm_void = (TREE_VALUE (tree_last (TYPE_ARG_TYPES (orig_type)))
			     == void_type_node);
      unsigned len = new_param_types->length ();
      for (unsigned i = 0; i < len; i++)
	new_arg_types = tree_cons (NULL_TREE, (*new_param_types)[i],
				   new_arg_types);

      tree new_reversed = nreverse (new_arg_types);
      if (last_parm_void)
	{
	  if (new_reversed)
	    TREE_CHAIN (new_arg_types) = void_list_node;
	  else
	    new_reversed = void_list_node;
	}
      new_arg_types = new_reversed;
    }

  /* Use build_distinct_type_copy to preserve as much as possible from original
     type (debug info, attribute lists etc.).  The one exception is
     METHOD_TYPEs which must have THIS argument and when we are asked to remove
     it, we need to build new FUNCTION_TYPE instead.  */
  tree new_type = NULL;
  if (method2func)
    {
      tree ret_type;
      if (skip_return)
	ret_type = void_type_node;
      else
	ret_type = TREE_TYPE (orig_type);

      new_type
	= build_distinct_type_copy (build_function_type (ret_type,
							 new_arg_types));
      TYPE_CONTEXT (new_type) = TYPE_CONTEXT (orig_type);
    }
  else
    {
      new_type = build_distinct_type_copy (orig_type);
      TYPE_ARG_TYPES (new_type) = new_arg_types;
      if (skip_return)
	TREE_TYPE (new_type) = void_type_node;
    }
  if (args_modified && TYPE_ATTRIBUTES (new_type))
    {
      tree t = TYPE_ATTRIBUTES (new_type);
      tree *last = &TYPE_ATTRIBUTES (new_type);
      TYPE_ATTRIBUTES (new_type) = NULL;
      for (;t; t = TREE_CHAIN (t))
	if (!drop_type_attribute_if_params_changed_p
		(get_attribute_name (t)))
	  {
	    *last = copy_node (t);
	    TREE_CHAIN (*last) = NULL;
	    last = &TREE_CHAIN (*last);
	  }
    }

  return new_type;
}

/* Return the maximum index in any IPA_PARAM_OP_COPY adjustment or -1 if there
   is none.  */

int
ipa_param_adjustments::get_max_base_index ()
{
  unsigned adj_len = vec_safe_length (m_adj_params);
  int max_index = -1;
  for (unsigned i = 0; i < adj_len ; i++)
    {
      ipa_adjusted_param *apm = &(*m_adj_params)[i];
      if (apm->op == IPA_PARAM_OP_COPY
	  && max_index < apm->base_index)
	max_index = apm->base_index;
    }
  return max_index;
}


/* Fill SURVIVING_PARAMS with an array of bools where each one says whether a
   parameter that originally was at that position still survives in the given
   clone or is removed/replaced.  If the final array is smaller than an index
   of an original parameter, that parameter also did not survive.  That a
   parameter survives does not mean it has the same index as before.  */

void
ipa_param_adjustments::get_surviving_params (vec<bool> *surviving_params)
{
  unsigned adj_len = vec_safe_length (m_adj_params);
  int max_index = get_max_base_index ();

  if (max_index < 0)
    return;
  surviving_params->reserve_exact (max_index + 1);
  surviving_params->quick_grow_cleared (max_index + 1);
  for (unsigned i = 0; i < adj_len ; i++)
    {
      ipa_adjusted_param *apm = &(*m_adj_params)[i];
      if (apm->op == IPA_PARAM_OP_COPY)
	(*surviving_params)[apm->base_index] = true;
    }
}

/* Fill NEW_INDICES with new indices of each surviving parameter or -1 for
   those which do not survive.  Any parameter outside of lenght of the vector
   does not survive.  There is currently no support for a parameter to be
   copied to two distinct new parameters.  */

void
ipa_param_adjustments::get_updated_indices (vec<int> *new_indices)
{
  unsigned adj_len = vec_safe_length (m_adj_params);
  int max_index = get_max_base_index ();

  if (max_index < 0)
    return;
  unsigned res_len = max_index + 1;
  new_indices->reserve_exact (res_len);
  for (unsigned i = 0; i < res_len ; i++)
    new_indices->quick_push (-1);
  for (unsigned i = 0; i < adj_len ; i++)
    {
      ipa_adjusted_param *apm = &(*m_adj_params)[i];
      if (apm->op == IPA_PARAM_OP_COPY)
	(*new_indices)[apm->base_index] = i;
    }
}

/* If a parameter with original INDEX has survived intact, return its new
   index.  Otherwise return -1.  In that case, if it has been split and there
   is a new parameter representing a portion at unit OFFSET for which a value
   of a TYPE can be substituted, store its new index into SPLIT_INDEX,
   otherwise store -1 there.  */
int
ipa_param_adjustments::get_updated_index_or_split (int index,
						   unsigned unit_offset,
						   tree type, int *split_index)
{
  unsigned adj_len = vec_safe_length (m_adj_params);
  for (unsigned i = 0; i < adj_len ; i++)
    {
      ipa_adjusted_param *apm = &(*m_adj_params)[i];
      if (apm->base_index != index)
	continue;
      if (apm->op == IPA_PARAM_OP_COPY)
	return i;
      if (apm->op == IPA_PARAM_OP_SPLIT
	  && apm->unit_offset == unit_offset)
	{
	  if (useless_type_conversion_p (apm->type, type))
	    *split_index = i;
	  else
	    *split_index = -1;
	  return -1;
	}
    }

  *split_index = -1;
  return -1;
}

/* Return the original index for the given new parameter index.  Return a
   negative number if not available.  */

int
ipa_param_adjustments::get_original_index (int newidx)
{
  const ipa_adjusted_param *adj = &(*m_adj_params)[newidx];
  if (adj->op != IPA_PARAM_OP_COPY)
    return -1;
  return adj->base_index;
}

/* Return true if the first parameter (assuming there was one) survives the
   transformation intact and remains the first one.  */

bool
ipa_param_adjustments::first_param_intact_p ()
{
  return (!vec_safe_is_empty (m_adj_params)
	  && (*m_adj_params)[0].op == IPA_PARAM_OP_COPY
	  && (*m_adj_params)[0].base_index == 0);
}

/* Return true if we have to change what has formerly been a method into a
   function.  */

bool
ipa_param_adjustments::method2func_p (tree orig_type)
{
  return ((TREE_CODE (orig_type) == METHOD_TYPE) && !first_param_intact_p ());
}

/* Given function type OLD_TYPE, return a new type derived from it after
   performing all atored modifications.  TYPE_ORIGINAL_P should be true when
   OLD_TYPE refers to the type before any IPA transformations, as opposed to a
   type that can be an intermediate one in between various IPA
   transformations.  */

tree
ipa_param_adjustments::build_new_function_type (tree old_type,
						bool type_original_p)
{
  auto_vec<tree,16> new_param_types, *new_param_types_p;
  if (prototype_p (old_type))
    {
      auto_vec<tree, 16> otypes;
      push_function_arg_types (&otypes, old_type);
      fill_vector_of_new_param_types (&new_param_types, &otypes, m_adj_params,
				      !type_original_p);
      new_param_types_p = &new_param_types;
    }
  else
    new_param_types_p = NULL;

  /* Check if any params type cares about are modified.  In this case will
     need to drop some type attributes.  */
  bool modified = false;
  size_t index = 0;
  if (m_adj_params)
    for (tree t = TYPE_ARG_TYPES (old_type);
	 t && (int)index < m_always_copy_start && !modified;
	 t = TREE_CHAIN (t), index++)
      if (index >= m_adj_params->length ()
	  || get_original_index (index) != (int)index)
	modified = true;


  return build_adjusted_function_type (old_type, new_param_types_p,
				       method2func_p (old_type), m_skip_return,
				       modified);
}

/* Build variant of function decl ORIG_DECL which has no return value if
   M_SKIP_RETURN is true and, if ORIG_DECL's types or parameters is known, has
   this type adjusted as indicated in M_ADJ_PARAMS. Arguments from
   DECL_ARGUMENTS list are not processed now, since they are linked by
   TREE_CHAIN directly and not accessible in LTO during WPA.  The caller is
   responsible for eliminating them when clones are properly materialized.  */

tree
ipa_param_adjustments::adjust_decl (tree orig_decl)
{
  tree new_decl = copy_node (orig_decl);
  tree orig_type = TREE_TYPE (orig_decl);
  if (prototype_p (orig_type)
      || (m_skip_return && !VOID_TYPE_P (TREE_TYPE (orig_type))))
    {
      tree new_type = build_new_function_type (orig_type, false);
      TREE_TYPE (new_decl) = new_type;
    }
  if (method2func_p (orig_type))
    DECL_VINDEX (new_decl) = NULL_TREE;

  /* When signature changes, we need to clear builtin info.  */
  if (fndecl_built_in_p (new_decl))
    set_decl_built_in_function (new_decl, NOT_BUILT_IN, 0);

  DECL_VIRTUAL_P (new_decl) = 0;
  DECL_LANG_SPECIFIC (new_decl) = NULL;

  /* Drop MALLOC attribute for a void function.  */
  if (m_skip_return)
    DECL_IS_MALLOC (new_decl) = 0;

  return new_decl;
}

/* Wrapper around get_base_ref_and_offset for cases interesting for IPA-SRA
   transformations.  Return true if EXPR has an interesting form and fill in
   *BASE_P and *UNIT_OFFSET_P with the appropriate info.  */

static bool
isra_get_ref_base_and_offset (tree expr, tree *base_p, unsigned *unit_offset_p)
{
  HOST_WIDE_INT offset, size;
  bool reverse;
  tree base
    = get_ref_base_and_extent_hwi (expr, &offset, &size, &reverse);
  if (!base || size < 0)
    return false;

  if ((offset % BITS_PER_UNIT) != 0)
    return false;

  if (TREE_CODE (base) == MEM_REF)
    {
      poly_int64 plmoff = mem_ref_offset (base).force_shwi ();
      HOST_WIDE_INT moff;
      bool is_cst = plmoff.is_constant (&moff);
      if (!is_cst)
	return false;
      offset += moff * BITS_PER_UNIT;
      base = TREE_OPERAND (base, 0);
    }

  if (offset < 0 || (offset / BITS_PER_UNIT) > UINT_MAX)
    return false;

  *base_p = base;
  *unit_offset_p = offset / BITS_PER_UNIT;
  return true;
}

/* Modify actual arguments of a function call in statement currently belonging
   to CS, and make it call CS->callee->decl.  Return the new statement that
   replaced the old one.  When invoked, cfun and current_function_decl have to
   be set to the caller.  */

gcall *
ipa_param_adjustments::modify_call (cgraph_edge *cs,
				    bool update_references)
{
  gcall *stmt = cs->call_stmt;
  tree callee_decl = cs->callee->decl;

  ipa_edge_modification_info *mod_info
    = ipa_edge_modifications ? ipa_edge_modifications->get (cs) : NULL;
  if (mod_info && symtab->dump_file)
    {
      fprintf (symtab->dump_file, "Information about pre-exiting "
	       "modifications.\n  Index map:");
      unsigned idx_len = mod_info->index_map.length ();
      for (unsigned i = 0; i < idx_len; i++)
	fprintf (symtab->dump_file, " %i", mod_info->index_map[i]);
      fprintf (symtab->dump_file, "\n  Pass-through split map: ");
      unsigned ptm_len = mod_info->pass_through_map.length ();
      for (unsigned i = 0; i < ptm_len; i++)
	fprintf (symtab->dump_file,
		 " (base_index: %u, offset: %u, new_index: %i)",
		 mod_info->pass_through_map[i].base_index,
		 mod_info->pass_through_map[i].unit_offset,
		 mod_info->pass_through_map[i].new_index);
      fprintf (symtab->dump_file, "\n  Always-copy delta: %i\n",
	       mod_info->always_copy_delta);
    }

  unsigned len = vec_safe_length (m_adj_params);
  auto_vec<tree, 16> vargs (len);
  unsigned old_nargs = gimple_call_num_args (stmt);
  unsigned orig_nargs = mod_info ? mod_info->index_map.length () : old_nargs;
  auto_vec<bool, 16> kept (old_nargs);
  kept.quick_grow_cleared (old_nargs);

  cgraph_node *current_node = cgraph_node::get (current_function_decl);
  if (update_references)
    current_node->remove_stmt_references (stmt);

  gimple_stmt_iterator gsi = gsi_for_stmt (stmt);
  gimple_stmt_iterator prev_gsi = gsi;
  gsi_prev (&prev_gsi);
  for (unsigned i = 0; i < len; i++)
    {
      ipa_adjusted_param *apm = &(*m_adj_params)[i];
      if (apm->op == IPA_PARAM_OP_COPY)
	{
	  int index = apm->base_index;
	  if ((unsigned) index >= orig_nargs)
	    /* Can happen if the original call has argument mismatch,
	       ignore.  */
	    continue;
	  if (mod_info)
	    {
	      index = mod_info->index_map[apm->base_index];
	      gcc_assert (index >= 0);
	    }

	  tree arg = gimple_call_arg (stmt, index);

	  vargs.quick_push (arg);
	  kept[index] = true;
	  continue;
	}

      /* At the moment the only user of IPA_PARAM_OP_NEW modifies calls itself.
	 If we ever want to support it during WPA IPA stage, we'll need a
	 mechanism to call into the IPA passes that introduced them.  Currently
	 we simply mandate that IPA infrastructure understands all argument
	 modifications.  Remember, edge redirection/modification is done only
	 once, not in steps for each pass modifying the callee like clone
	 materialization.  */
      gcc_assert (apm->op == IPA_PARAM_OP_SPLIT);

      /* We have to handle pass-through changes differently using the map
	 clone materialziation might have left behind.  */
      tree repl = NULL_TREE;
      unsigned ptm_len = mod_info ? mod_info->pass_through_map.length () : 0;
      for (unsigned j = 0; j < ptm_len; j++)
	if (mod_info->pass_through_map[j].base_index == apm->base_index
	    && mod_info->pass_through_map[j].unit_offset == apm->unit_offset)
	  {
	    int repl_idx = mod_info->pass_through_map[j].new_index;
	    gcc_assert (repl_idx >= 0);
	    repl = gimple_call_arg (stmt, repl_idx);
	    break;
	  }
      if (repl)
	{
	  vargs.quick_push (repl);
	  continue;
	}

      int index = apm->base_index;
      if ((unsigned) index >= orig_nargs)
	/* Can happen if the original call has argument mismatch, ignore.  */
	continue;
      if (mod_info)
	{
	  index = mod_info->index_map[apm->base_index];
	  gcc_assert (index >= 0);
	}
      tree base = gimple_call_arg (stmt, index);

      /* We create a new parameter out of the value of the old one, we can
	 do the following kind of transformations:

	 - A scalar passed by reference, potentially as a part of a larger
	 aggregate, is converted to a scalar passed by value.

	 - A part of an aggregate is passed instead of the whole aggregate.  */

      location_t loc = gimple_location (stmt);
      tree off;
      bool deref_base = false;
      unsigned int deref_align = 0;
      if (TREE_CODE (base) != ADDR_EXPR
	  && is_gimple_reg_type (TREE_TYPE (base)))
	{
	  /* Detect type mismatches in calls in invalid programs and make a
	     poor attempt to gracefully convert them so that we don't ICE.  */
	  if (!POINTER_TYPE_P (TREE_TYPE (base)))
	    base = force_value_to_type (ptr_type_node, base);

	  off = build_int_cst (apm->alias_ptr_type, apm->unit_offset);
	}
      else
	{
	  bool addrof;
	  if (TREE_CODE (base) == ADDR_EXPR)
	    {
	      base = TREE_OPERAND (base, 0);
	      addrof = true;
	    }
	  else
	    addrof = false;

	  tree prev_base = base;
	  poly_int64 base_offset;
	  base = get_addr_base_and_unit_offset (base, &base_offset);

	  /* Aggregate arguments can have non-invariant addresses.  */
	  if (!base)
	    {
	      base = build_fold_addr_expr (prev_base);
	      off = build_int_cst (apm->alias_ptr_type, apm->unit_offset);
	    }
	  else if (TREE_CODE (base) == MEM_REF)
	    {
	      if (!addrof)
		{
		  deref_base = true;
		  deref_align = TYPE_ALIGN (TREE_TYPE (base));
		}
	      off = build_int_cst (apm->alias_ptr_type,
				   base_offset + apm->unit_offset);
	      off = int_const_binop (PLUS_EXPR, TREE_OPERAND (base, 1),
				     off);
	      base = TREE_OPERAND (base, 0);
	    }
	  else
	    {
	      off = build_int_cst (apm->alias_ptr_type,
				   base_offset + apm->unit_offset);
	      base = build_fold_addr_expr (base);
	    }
	}

      tree type = apm->type;
      unsigned int align;
      unsigned HOST_WIDE_INT misalign;

      if (deref_base)
	{
	  align = deref_align;
	  misalign = 0;
	}
      else
	{
	  get_pointer_alignment_1 (base, &align, &misalign);
	  /* All users must make sure that we can be optimistic when it
	     comes to alignment in this case (by inspecting the final users
	     of these new parameters).  */
	  if (TYPE_ALIGN (type) > align)
	    align = TYPE_ALIGN (type);
	}
      misalign
	+= (offset_int::from (wi::to_wide (off), SIGNED).to_short_addr ()
	    * BITS_PER_UNIT);
      misalign = misalign & (align - 1);
      if (misalign != 0)
	align = least_bit_hwi (misalign);
      if (align < TYPE_ALIGN (type))
	type = build_aligned_type (type, align);
      base = force_gimple_operand_gsi (&gsi, base,
				       true, NULL, true, GSI_SAME_STMT);
      tree expr = fold_build2_loc (loc, MEM_REF, type, base, off);
      REF_REVERSE_STORAGE_ORDER (expr) = apm->reverse;
      /* If expr is not a valid gimple call argument emit
	 a load into a temporary.  */
      if (is_gimple_reg_type (TREE_TYPE (expr)))
	{
	  gimple *tem = gimple_build_assign (NULL_TREE, expr);
	  if (gimple_in_ssa_p (cfun))
	    {
	      gimple_set_vuse (tem, gimple_vuse (stmt));
	      expr = make_ssa_name (TREE_TYPE (expr), tem);
	    }
	  else
	    expr = create_tmp_reg (TREE_TYPE (expr));
	  gimple_assign_set_lhs (tem, expr);
	  gsi_insert_before (&gsi, tem, GSI_SAME_STMT);
	}
      vargs.quick_push (expr);
    }

  if (m_always_copy_start >= 0)
    {
      int always_copy_start = m_always_copy_start;
      if (mod_info)
	{
	  always_copy_start += mod_info->always_copy_delta;
	  gcc_assert (always_copy_start >= 0);
	}
      for (unsigned i = always_copy_start; i < old_nargs; i++)
	vargs.safe_push (gimple_call_arg (stmt, i));
    }

  /* For optimized away parameters, add on the caller side
     before the call
     DEBUG D#X => parm_Y(D)
     stmts and associate D#X with parm in decl_debug_args_lookup
     vector to say for debug info that if parameter parm had been passed,
     it would have value parm_Y(D).  */
  tree old_decl = gimple_call_fndecl (stmt);
  if (MAY_HAVE_DEBUG_BIND_STMTS && old_decl && callee_decl)
    {
      vec<tree, va_gc> **debug_args = NULL;
      unsigned i = 0;
      cgraph_node *callee_node = cgraph_node::get (callee_decl);

      /* FIXME: we don't seem to be able to insert debug args before clone
	 is materialized.  Materializing them early leads to extra memory
	 use.  */
      if (callee_node->clone_of)
	callee_node->get_untransformed_body ();
      for (tree old_parm = DECL_ARGUMENTS (old_decl);
	   old_parm && i < old_nargs && ((int) i) < m_always_copy_start;
	   old_parm = DECL_CHAIN (old_parm), i++)
	{
	  if (!is_gimple_reg (old_parm) || kept[i])
	    continue;
	  tree arg;
	  if (mod_info)
	    {
	      if (mod_info->index_map[i] < 0)
		continue;
	      arg = gimple_call_arg (stmt, mod_info->index_map[i]);
	    }
	  else
	    arg = gimple_call_arg (stmt, i);

	  tree origin = DECL_ORIGIN (old_parm);
	  if (!useless_type_conversion_p (TREE_TYPE (origin), TREE_TYPE (arg)))
	    {
	      if (!fold_convertible_p (TREE_TYPE (origin), arg))
		continue;
	      tree rhs1;
	      if (TREE_CODE (arg) == SSA_NAME
		  && gimple_assign_cast_p (SSA_NAME_DEF_STMT (arg))
		  && (rhs1
		      = gimple_assign_rhs1 (SSA_NAME_DEF_STMT (arg)))
		  && useless_type_conversion_p (TREE_TYPE (origin),
						TREE_TYPE (rhs1)))
		arg = rhs1;
	      else
		arg = fold_convert_loc (gimple_location (stmt),
					TREE_TYPE (origin), arg);
	    }
	  if (debug_args == NULL)
	    debug_args = decl_debug_args_insert (callee_decl);
	  unsigned int ix;
	  tree ddecl = NULL_TREE;
	  for (ix = 0; vec_safe_iterate (*debug_args, ix, &ddecl); ix += 2)
	    if (ddecl == origin)
	      {
		ddecl = (**debug_args)[ix + 1];
		break;
	      }
	  if (ddecl == NULL)
	    {
	      ddecl = build_debug_expr_decl (TREE_TYPE (origin));
	      /* FIXME: Is setting the mode really necessary? */
	      SET_DECL_MODE (ddecl, DECL_MODE (origin));

	      vec_safe_push (*debug_args, origin);
	      vec_safe_push (*debug_args, ddecl);
	    }
	  gimple *def_temp = gimple_build_debug_bind (ddecl,
						      unshare_expr (arg), stmt);
	  gsi_insert_before (&gsi, def_temp, GSI_SAME_STMT);
	}
    }

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "replacing stmt:");
      print_gimple_stmt (dump_file, gsi_stmt (gsi), 0);
    }

  gcall *new_stmt = gimple_build_call_vec (callee_decl, vargs);

  tree ssa_to_remove = NULL;
  if (tree lhs = gimple_call_lhs (stmt))
    {
      if (!m_skip_return)
	gimple_call_set_lhs (new_stmt, lhs);
      else if (TREE_CODE (lhs) == SSA_NAME)
	{
	  /* LHS should now by a default-def SSA.  Unfortunately default-def
	     SSA_NAMEs need a backing variable (or at least some code examining
	     SSAs assumes it is non-NULL).  So we either have to re-use the
	     decl we have at hand or introdice a new one.  */
	  tree repl = create_tmp_var (TREE_TYPE (lhs), "removed_return");
	  repl = get_or_create_ssa_default_def (cfun, repl);
	  SSA_NAME_IS_DEFAULT_DEF (repl) = true;
	  imm_use_iterator ui;
	  use_operand_p use_p;
	  gimple *using_stmt;
	  FOR_EACH_IMM_USE_STMT (using_stmt, ui, lhs)
	    {
	      FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
		{
		  SET_USE (use_p, repl);
		}
	      update_stmt (using_stmt);
	    }
	  ssa_to_remove = lhs;
	}
    }

  gimple_set_block (new_stmt, gimple_block (stmt));
  if (gimple_has_location (stmt))
    gimple_set_location (new_stmt, gimple_location (stmt));
  gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
  gimple_call_copy_flags (new_stmt, stmt);
  if (gimple_in_ssa_p (cfun))
    gimple_move_vops (new_stmt, stmt);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "with stmt:");
      print_gimple_stmt (dump_file, new_stmt, 0);
      fprintf (dump_file, "\n");
    }
  gsi_replace (&gsi, new_stmt, true);
  if (ssa_to_remove)
    release_ssa_name (ssa_to_remove);
  if (update_references)
    do
      {
	current_node->record_stmt_references (gsi_stmt (gsi));
	gsi_prev (&gsi);
      }
    while (gsi_stmt (gsi) != gsi_stmt (prev_gsi));

  if (mod_info)
    ipa_edge_modifications->remove (cs);
  return new_stmt;
}

/* Dump information contained in the object in textual form to F.  */

void
ipa_param_adjustments::dump (FILE *f)
{
  fprintf (f, "    m_always_copy_start: %i\n", m_always_copy_start);
  ipa_dump_adjusted_parameters (f, m_adj_params);
  if (m_skip_return)
    fprintf (f, "    Will SKIP return.\n");
}

/* Dump information contained in the object in textual form to stderr.  */

void
ipa_param_adjustments::debug ()
{
  dump (stderr);
}

/* Register that REPLACEMENT should replace parameter described in APM.  */

void
ipa_param_body_adjustments::register_replacement (ipa_adjusted_param *apm,
						  tree replacement)
{
  gcc_checking_assert (apm->op == IPA_PARAM_OP_SPLIT
		       || apm->op == IPA_PARAM_OP_NEW);
  gcc_checking_assert (!apm->prev_clone_adjustment);
  ipa_param_body_replacement psr;
  psr.base = m_oparms[apm->prev_clone_index];
  psr.repl = replacement;
  psr.dummy = NULL_TREE;
  psr.unit_offset = apm->unit_offset;
  m_replacements.safe_push (psr);
}

/* Copy or not, as appropriate given m_id and decl context, a pre-existing
   PARM_DECL T so that it can be included in the parameters of the modified
   function.  */

tree
ipa_param_body_adjustments::carry_over_param (tree t)
{
  tree new_parm;
  if (m_id)
    {
      new_parm = remap_decl (t, m_id);
      if (TREE_CODE (new_parm) != PARM_DECL)
	new_parm = m_id->copy_decl (t, m_id);
    }
  else if (DECL_CONTEXT (t) != m_fndecl)
    {
      new_parm = copy_node (t);
      DECL_CONTEXT (new_parm) = m_fndecl;
    }
  else
    new_parm = t;
  return new_parm;
}

/* Populate m_dead_stmts given that DEAD_PARAM is going to be removed without
   any replacement or splitting.  REPL is the replacement VAR_SECL to base any
   remaining uses of a removed parameter on.  Push all removed SSA names that
   are used within debug statements to DEBUGSTACK.  */

void
ipa_param_body_adjustments::mark_dead_statements (tree dead_param,
						  vec<tree> *debugstack)
{
  /* Current IPA analyses which remove unused parameters never remove a
     non-gimple register ones which have any use except as parameters in other
     calls, so we can safely leve them as they are.  */
  if (!is_gimple_reg (dead_param))
    return;
  tree parm_ddef = ssa_default_def (m_id->src_cfun, dead_param);
  if (!parm_ddef || has_zero_uses (parm_ddef))
    return;

  auto_vec<tree, 4> stack;
  hash_set<tree> used_in_debug;
  m_dead_ssas.add (parm_ddef);
  stack.safe_push (parm_ddef);
  while (!stack.is_empty ())
    {
      imm_use_iterator imm_iter;
      use_operand_p use_p;
      tree t = stack.pop ();

      insert_decl_map (m_id, t, error_mark_node);
      FOR_EACH_IMM_USE_FAST (use_p, imm_iter, t)
	{
	  gimple *stmt = USE_STMT (use_p);

	  /* Calls containing dead arguments cannot be deleted,
	     modify_call_stmt will instead remove just the argument later on.
	     If isra_track_scalar_value_uses in ipa-sra.cc is extended to look
	     through const functions, we will need to do so here too.  */
	  if (is_gimple_call (stmt)
	      || (m_id->blocks_to_copy
		  && !bitmap_bit_p (m_id->blocks_to_copy,
				    gimple_bb (stmt)->index)))
	    continue;

	  if (is_gimple_debug (stmt))
	    {
	      m_dead_stmts.add (stmt);
	      gcc_assert (gimple_debug_bind_p (stmt));
	      if (!used_in_debug.contains (t))
		{
		  used_in_debug.add (t);
		  debugstack->safe_push (t);
		}
	    }
	  else if (gimple_code (stmt) == GIMPLE_PHI)
	    {
	      gphi *phi = as_a <gphi *> (stmt);
	      int ix = PHI_ARG_INDEX_FROM_USE (use_p);

	      if (!m_id->blocks_to_copy
		  || bitmap_bit_p (m_id->blocks_to_copy,
				   gimple_phi_arg_edge (phi, ix)->src->index))
		{
		  m_dead_stmts.add (phi);
		  tree res = gimple_phi_result (phi);
		  if (!m_dead_ssas.add (res))
		    stack.safe_push (res);
		}
	    }
	  else if (is_gimple_assign (stmt))
	    {
	      m_dead_stmts.add (stmt);
	      if (!gimple_clobber_p (stmt))
		{
		  tree lhs = gimple_assign_lhs (stmt);
		  gcc_assert (TREE_CODE (lhs) == SSA_NAME);
		  if (!m_dead_ssas.add (lhs))
		    stack.safe_push (lhs);
		}
	    }
	  else
	    /* IPA-SRA does not analyze other types of statements.  */
	    gcc_unreachable ();
	}
    }

  if (!MAY_HAVE_DEBUG_STMTS)
    {
      gcc_assert (debugstack->is_empty ());
      return;
    }

  tree dp_ddecl = build_debug_expr_decl (TREE_TYPE (dead_param));
  /* FIXME: Is setting the mode really necessary? */
  SET_DECL_MODE (dp_ddecl, DECL_MODE (dead_param));
  m_dead_ssa_debug_equiv.put (parm_ddef, dp_ddecl);
}

/* Callback to walk_tree.  If REMAP is an SSA_NAME that is present in hash_map
   passed in DATA, replace it with unshared version of what it was mapped to.
   If an SSA argument would be remapped to NULL, the whole operation needs to
   abort which is signaled by returning error_mark_node.  */

static tree
replace_with_mapped_expr (tree *remap, int *walk_subtrees, void *data)
{
  if (TYPE_P (*remap))
    {
      *walk_subtrees = 0;
      return 0;
    }
  if (TREE_CODE (*remap) != SSA_NAME)
    return 0;

  *walk_subtrees = 0;

  hash_map<tree, tree> *equivs = (hash_map<tree, tree> *) data;
  if (tree *p = equivs->get (*remap))
    {
      if (!*p)
	return error_mark_node;
      *remap = unshare_expr (*p);
    }
  return 0;
}

/* Replace all occurances of SSAs in m_dead_ssa_debug_equiv in t with what they
   are mapped to.  */

void
ipa_param_body_adjustments::remap_with_debug_expressions (tree *t)
{
  /* If *t is an SSA_NAME which should have its debug statements reset, it is
     mapped to NULL in the hash_map.

     It is perhaps simpler to handle the SSA_NAME cases directly and only
     invoke walk_tree on more complex expressions.  When
     remap_with_debug_expressions is called from tree-inline.cc, a to-be-reset
     SSA_NAME can be an operand to such expressions and the entire debug
     variable we are remapping should be reset.  This is signaled by walk_tree
     returning error_mark_node and done by setting *t to NULL.  */
  if (TREE_CODE (*t) == SSA_NAME)
    {
      if (tree *p = m_dead_ssa_debug_equiv.get (*t))
	*t = *p;
    }
  else if (walk_tree (t, replace_with_mapped_expr,
		      &m_dead_ssa_debug_equiv, NULL) == error_mark_node)
    *t = NULL_TREE;
}

/* For an SSA_NAME DEAD_SSA which is about to be DCEd because it is based on a
   useless parameter, prepare an expression that should represent it in
   debug_binds in the cloned function and add a mapping from DEAD_SSA to
   m_dead_ssa_debug_equiv.  That mapping is to NULL when the associated
   debug_statement has to be reset instead.  In such case return false,
   ottherwise return true.  If DEAD_SSA comes from a basic block which is not
   about to be copied, ignore it and return true.  */

bool
ipa_param_body_adjustments::prepare_debug_expressions (tree dead_ssa)
{
  gcc_checking_assert (m_dead_ssas.contains (dead_ssa));
  if (tree *d = m_dead_ssa_debug_equiv.get (dead_ssa))
    return (*d != NULL_TREE);

  gcc_assert (!SSA_NAME_IS_DEFAULT_DEF (dead_ssa));
  gimple *def = SSA_NAME_DEF_STMT (dead_ssa);
  if (m_id->blocks_to_copy
      && !bitmap_bit_p (m_id->blocks_to_copy, gimple_bb (def)->index))
    return true;

  if (gimple_code (def) == GIMPLE_PHI)
    {
      /* In theory, we could ignore all SSAs coming from BBs not in
	 m_id->blocks_to_copy but at the time of the writing this code that
	 should never really be the case because only fnsplit uses that bitmap,
	 so don't bother.  */
      tree value = degenerate_phi_result (as_a <gphi *> (def));
      if (!value
	  || (m_dead_ssas.contains (value)
	      && !prepare_debug_expressions (value)))
	{
	  m_dead_ssa_debug_equiv.put (dead_ssa, NULL_TREE);
	  return false;
	}

      gcc_assert (TREE_CODE (value) == SSA_NAME);
      tree *d = m_dead_ssa_debug_equiv.get (value);
      m_dead_ssa_debug_equiv.put (dead_ssa, *d);
      return true;
    }

  bool lost = false;
  use_operand_p use_p;
  ssa_op_iter oi;
  FOR_EACH_PHI_OR_STMT_USE (use_p, def, oi, SSA_OP_USE)
    {
      tree use = USE_FROM_PTR (use_p);
      if (m_dead_ssas.contains (use)
	  && !prepare_debug_expressions (use))
	{
	  lost = true;
	  break;
	}
    }

  if (lost)
    {
      m_dead_ssa_debug_equiv.put (dead_ssa, NULL_TREE);
      return false;
    }

  if (is_gimple_assign (def))
    {
      gcc_assert (!gimple_clobber_p (def));
      if (gimple_assign_copy_p (def)
	  && TREE_CODE (gimple_assign_rhs1 (def)) == SSA_NAME)
	{
	  tree d = *m_dead_ssa_debug_equiv.get (gimple_assign_rhs1 (def));
	  gcc_assert (d);
	  m_dead_ssa_debug_equiv.put (dead_ssa, d);
	  return true;
	}

      tree val
	= unshare_expr_without_location (gimple_assign_rhs_to_tree (def));
      remap_with_debug_expressions (&val);

      tree vexpr = build_debug_expr_decl (TREE_TYPE (val));
      m_dead_stmt_debug_equiv.put (def, val);
      m_dead_ssa_debug_equiv.put (dead_ssa, vexpr);
      return true;
    }
  else
    gcc_unreachable ();
}

/* Common initialization performed by all ipa_param_body_adjustments
   constructors.  OLD_FNDECL is the declaration we take original arguments
   from, (it may be the same as M_FNDECL).  VARS, if non-NULL, is a pointer to
   a chained list of new local variables.  TREE_MAP is the IPA-CP produced
   mapping of trees to constants.

   The function is rather long but it really onlu initializes all data members
   of the class.  It creates new param DECLs, finds their new types,   */

void
ipa_param_body_adjustments::common_initialization (tree old_fndecl,
						   tree *vars,
						   vec<ipa_replace_map *,
						       va_gc> *tree_map)
{
  push_function_arg_decls (&m_oparms, old_fndecl);
  auto_vec<tree,16> otypes;
  if (TYPE_ARG_TYPES (TREE_TYPE (old_fndecl)) != NULL_TREE)
    push_function_arg_types (&otypes, TREE_TYPE (old_fndecl));
  else
    {
      auto_vec<tree,16> oparms;
      push_function_arg_decls (&oparms, old_fndecl);
      unsigned ocount = oparms.length ();
      otypes.reserve_exact (ocount);
      for (unsigned i = 0; i < ocount; i++)
	otypes.quick_push (TREE_TYPE (oparms[i]));
    }
  fill_vector_of_new_param_types (&m_new_types, &otypes, m_adj_params, true);

  auto_vec<bool, 16> kept;
  kept.reserve_exact (m_oparms.length ());
  kept.quick_grow_cleared (m_oparms.length ());
  auto_vec<bool, 16> split;
  split.reserve_exact (m_oparms.length ());
  split.quick_grow_cleared (m_oparms.length ());

  unsigned adj_len = vec_safe_length (m_adj_params);
  m_method2func = ((TREE_CODE (TREE_TYPE (m_fndecl)) == METHOD_TYPE)
		   && (adj_len == 0
		       || (*m_adj_params)[0].op != IPA_PARAM_OP_COPY
		       || (*m_adj_params)[0].base_index != 0));

  /* The main job of the this function is to go over the vector of adjusted
     parameters and create declarations or find corresponding old ones and push
     them to m_new_decls.  For IPA-SRA replacements it also creates
     corresponding m_id->dst_node->clone.performed_splits entries.  */

  m_new_decls.reserve_exact (adj_len);
  for (unsigned i = 0; i < adj_len ; i++)
    {
      ipa_adjusted_param *apm = &(*m_adj_params)[i];
      unsigned prev_index = apm->prev_clone_index;
      tree new_parm;
      if (apm->op == IPA_PARAM_OP_COPY
	  || apm->prev_clone_adjustment)
	{
	  kept[prev_index] = true;
	  new_parm = carry_over_param (m_oparms[prev_index]);
	  m_new_decls.quick_push (new_parm);
	}
      else if (apm->op == IPA_PARAM_OP_NEW
	       || apm->op == IPA_PARAM_OP_SPLIT)
	{
	  tree new_type = m_new_types[i];
	  gcc_checking_assert (new_type);
	  new_parm = build_decl (UNKNOWN_LOCATION, PARM_DECL, NULL_TREE,
				 new_type);
	  const char *prefix = ipa_param_prefixes[apm->param_prefix_index];
	  DECL_NAME (new_parm) = create_tmp_var_name (prefix);
	  DECL_ARTIFICIAL (new_parm) = 1;
	  DECL_ARG_TYPE (new_parm) = new_type;
	  DECL_CONTEXT (new_parm) = m_fndecl;
	  TREE_USED (new_parm) = 1;
	  DECL_IGNORED_P (new_parm) = 1;
	  layout_decl (new_parm, 0);
	  m_new_decls.quick_push (new_parm);

	  if (apm->op == IPA_PARAM_OP_SPLIT)
	    {
	      m_split_modifications_p = true;
	      split[prev_index] = true;
	      register_replacement (apm, new_parm);
	    }
        }
      else
	gcc_unreachable ();
    }

  if (tree_map)
    {
      /* Do not treat parameters which were replaced with a constant as
	 completely vanished.  */
      auto_vec <int, 16> index_mapping;
      bool need_remap = false;

      if (m_id)
	{
	  clone_info *cinfo = clone_info::get (m_id->src_node);
	  if (cinfo && cinfo->param_adjustments)
	    {
	      cinfo->param_adjustments->get_updated_indices (&index_mapping);
	      need_remap = true;
	    }
	}

      for (unsigned i = 0; i < tree_map->length (); i++)
	{
	  int parm_num = (*tree_map)[i]->parm_num;
	  gcc_assert (parm_num >= 0);
	  if (need_remap)
	    parm_num = index_mapping[parm_num];
	  kept[parm_num] = true;
	}
    }

  /* As part of body modifications, we will also have to replace remaining uses
     of remaining uses of removed PARM_DECLs (which do not however use the
     initial value) with their VAR_DECL copies.

     We do this differently with and without m_id.  With m_id, we rely on its
     mapping and create a replacement straight away.  Without it, we have our
     own mechanism for which we have to populate m_removed_decls vector.  Just
     don't mix them, that is why you should not call
     replace_removed_params_ssa_names or perform_cfun_body_modifications when
     you construct with ID not equal to NULL.  */

  auto_vec<tree, 8> ssas_to_process_debug;
  unsigned op_len = m_oparms.length ();
  for (unsigned i = 0; i < op_len; i++)
    if (!kept[i])
      {
	if (m_id)
	  {
	    gcc_assert (!m_id->decl_map->get (m_oparms[i]));
	    tree var = copy_decl_to_var (m_oparms[i], m_id);
	    insert_decl_map (m_id, m_oparms[i], var);
	    /* Declare this new variable.  */
	    DECL_CHAIN (var) = *vars;
	    *vars = var;

	    /* If this is not a split but a real removal, init hash sets
	       that will guide what not to copy to the new body.  */
	    if (!split[i])
	      mark_dead_statements (m_oparms[i], &ssas_to_process_debug);
	    if (MAY_HAVE_DEBUG_STMTS
		&& is_gimple_reg (m_oparms[i]))
	      m_reset_debug_decls.safe_push (m_oparms[i]);
	  }
	else
	  {
	    m_removed_decls.safe_push (m_oparms[i]);
	    m_removed_map.put (m_oparms[i], m_removed_decls.length () - 1);
	    if (MAY_HAVE_DEBUG_STMTS
		&& !kept[i]
		&& is_gimple_reg (m_oparms[i]))
	      m_reset_debug_decls.safe_push (m_oparms[i]);
	  }
      }

  while (!ssas_to_process_debug.is_empty ())
    prepare_debug_expressions (ssas_to_process_debug.pop ());
}

/* Constructor of ipa_param_body_adjustments from a simple list of
   modifications to parameters listed in ADJ_PARAMS which will prepare ground
   for modification of parameters of fndecl.  Return value of the function will
   not be removed and the object will assume it does not run as a part of
   tree-function_versioning.  */

ipa_param_body_adjustments
::ipa_param_body_adjustments (vec<ipa_adjusted_param, va_gc> *adj_params,
			      tree fndecl)
  : m_adj_params (adj_params), m_adjustments (NULL), m_reset_debug_decls (),
    m_split_modifications_p (false), m_dead_stmts (), m_dead_ssas (),
    m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (), m_fndecl (fndecl),
    m_id (NULL), m_oparms (), m_new_decls (), m_new_types (), m_replacements (),
    m_removed_decls (), m_removed_map (), m_method2func (false)
{
  common_initialization (fndecl, NULL, NULL);
}

/* Constructor of ipa_param_body_adjustments from ipa_param_adjustments in
   ADJUSTMENTS which will prepare ground for modification of parameters of
   fndecl.  The object will assume it does not run as a part of
   tree-function_versioning.  */

ipa_param_body_adjustments
::ipa_param_body_adjustments (ipa_param_adjustments *adjustments,
			      tree fndecl)
  : m_adj_params (adjustments->m_adj_params), m_adjustments (adjustments),
    m_reset_debug_decls (), m_split_modifications_p (false), m_dead_stmts (),
    m_dead_ssas (), m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (),
    m_fndecl (fndecl), m_id (NULL), m_oparms (), m_new_decls (),
    m_new_types (), m_replacements (), m_removed_decls (), m_removed_map (),
    m_method2func (false)
{
  common_initialization (fndecl, NULL, NULL);
}

/* Constructor of ipa_param_body_adjustments which sets it up as a part of
   running tree_function_versioning.  Planned modifications to the function are
   in ADJUSTMENTS.  FNDECL designates the new function clone which is being
   modified.  OLD_FNDECL is the function of which FNDECL is a clone (and which
   at the time of invocation still share DECL_ARGUMENTS).  ID is the
   copy_body_data structure driving the wholy body copying process.  VARS is a
   pointer to the head of the list of new local variables, TREE_MAP is the map
   that drives tree substitution in the cloning process.  */

ipa_param_body_adjustments
::ipa_param_body_adjustments (ipa_param_adjustments *adjustments,
			      tree fndecl, tree old_fndecl,
			      copy_body_data *id, tree *vars,
			      vec<ipa_replace_map *, va_gc> *tree_map)
  : m_adj_params (adjustments->m_adj_params), m_adjustments (adjustments),
    m_reset_debug_decls (), m_split_modifications_p (false), m_dead_stmts (),
    m_dead_ssas (), m_dead_ssa_debug_equiv (), m_dead_stmt_debug_equiv (),
    m_fndecl (fndecl), m_id (id), m_oparms (), m_new_decls (), m_new_types (),
    m_replacements (), m_removed_decls (), m_removed_map (),
    m_method2func (false)
{
  common_initialization (old_fndecl, vars, tree_map);
}

/* Chain new param decls up and return them.  */

tree
ipa_param_body_adjustments::get_new_param_chain ()
{
  tree result;
  tree *link = &result;

  unsigned len = vec_safe_length (m_adj_params);
  for (unsigned i = 0; i < len; i++)
    {
      tree new_decl = m_new_decls[i];
      *link = new_decl;
      link = &DECL_CHAIN (new_decl);
    }
  *link = NULL_TREE;
  return result;
}

/* Modify the function parameters FNDECL and its type according to the plan in
   ADJUSTMENTS.  This function needs to be called when the decl has not already
   been processed with ipa_param_adjustments::adjust_decl, otherwise just
   seting DECL_ARGUMENTS to whatever get_new_param_chain will do is enough.  */

void
ipa_param_body_adjustments::modify_formal_parameters ()
{
  tree orig_type = TREE_TYPE (m_fndecl);
  DECL_ARGUMENTS (m_fndecl) = get_new_param_chain ();

  /* When signature changes, we need to clear builtin info.  */
  if (fndecl_built_in_p (m_fndecl))
    set_decl_built_in_function (m_fndecl, NOT_BUILT_IN, 0);

  bool modified = false;
  size_t index = 0;
  if (m_adj_params)
    for (tree t = TYPE_ARG_TYPES (orig_type);
	 t && !modified;
	 t = TREE_CHAIN (t), index++)
      if (index >= m_adj_params->length ()
	  || (*m_adj_params)[index].op != IPA_PARAM_OP_COPY
	  || (*m_adj_params)[index].base_index != index)
	modified = true;

  /* At this point, removing return value is only implemented when going
     through tree_function_versioning, not when modifying function body
     directly.  */
  gcc_assert (!m_adjustments || !m_adjustments->m_skip_return);
  tree new_type = build_adjusted_function_type (orig_type, &m_new_types,
						m_method2func, false, modified);

  TREE_TYPE (m_fndecl) = new_type;
  DECL_VIRTUAL_P (m_fndecl) = 0;
  DECL_LANG_SPECIFIC (m_fndecl) = NULL;
  if (m_method2func)
    DECL_VINDEX (m_fndecl) = NULL_TREE;
}

/* Given BASE and UNIT_OFFSET, find the corresponding record among replacement
   structures.  */

ipa_param_body_replacement *
ipa_param_body_adjustments::lookup_replacement_1 (tree base,
						  unsigned unit_offset)
{
  unsigned int len = m_replacements.length ();
  for (unsigned i = 0; i < len; i++)
    {
      ipa_param_body_replacement *pbr = &m_replacements[i];

      if (pbr->base == base
	  && (pbr->unit_offset == unit_offset))
	return pbr;
    }
  return NULL;
}

/* Given BASE and UNIT_OFFSET, find the corresponding replacement expression
   and return it, assuming it is known it does not hold value by reference or
   in reverse storage order.  */

tree
ipa_param_body_adjustments::lookup_replacement (tree base, unsigned unit_offset)
{
  ipa_param_body_replacement *pbr = lookup_replacement_1 (base, unit_offset);
  if (!pbr)
    return NULL;
  return pbr->repl;
}

/* If T is an SSA_NAME, return NULL if it is not a default def or
   return its base variable if it is.  If IGNORE_DEFAULT_DEF is true,
   the base variable is always returned, regardless if it is a default
   def.  Return T if it is not an SSA_NAME.  */

static tree
get_ssa_base_param (tree t, bool ignore_default_def)
{
  if (TREE_CODE (t) == SSA_NAME)
    {
      if (ignore_default_def || SSA_NAME_IS_DEFAULT_DEF (t))
	return SSA_NAME_VAR (t);
      else
	return NULL_TREE;
    }
  return t;
}

/* Given an expression, return the structure describing how it should be
   replaced if it accesses a part of a split parameter or NULL otherwise.

   Do not free the result, it will be deallocated when the object is destroyed.

   If IGNORE_DEFAULT_DEF is cleared, consider only SSA_NAMEs of PARM_DECLs
   which are default definitions, if set, consider all SSA_NAMEs of
   PARM_DECLs.  */

ipa_param_body_replacement *
ipa_param_body_adjustments::get_expr_replacement (tree expr,
						  bool ignore_default_def)
{
  tree base;
  unsigned unit_offset;

  if (!isra_get_ref_base_and_offset (expr, &base, &unit_offset))
    return NULL;

  base = get_ssa_base_param (base, ignore_default_def);
  if (!base || TREE_CODE (base) != PARM_DECL)
    return NULL;
  return lookup_replacement_1 (base, unit_offset);
}

/* Given OLD_DECL, which is a PARM_DECL of a parameter that is being removed
   (which includes it being split or replaced), return a new variable that
   should be used for any SSA names that will remain in the function that
   previously belonged to OLD_DECL.  */

tree
ipa_param_body_adjustments::get_replacement_ssa_base (tree old_decl)
{
  unsigned *idx = m_removed_map.get (old_decl);
  if (!idx)
    return NULL;

  tree repl;
  if (TREE_CODE (m_removed_decls[*idx]) == PARM_DECL)
    {
      gcc_assert (m_removed_decls[*idx] == old_decl);
      repl = copy_var_decl (old_decl, DECL_NAME (old_decl),
			    TREE_TYPE (old_decl));
      m_removed_decls[*idx] = repl;
    }
  else
    repl = m_removed_decls[*idx];
  return repl;
}

/* If OLD_NAME, which is being defined by statement STMT, is an SSA_NAME of a
   parameter which is to be removed because its value is not used, create a new
   SSA_NAME relating to a replacement VAR_DECL, replace all uses of the
   original with it and return it.  If there is no need to re-map, return NULL.
   ADJUSTMENTS is a pointer to a vector of IPA-SRA adjustments.  */

tree
ipa_param_body_adjustments::replace_removed_params_ssa_names (tree old_name,
							      gimple *stmt)
{
  gcc_assert (!m_id);
  if (TREE_CODE (old_name) != SSA_NAME)
    return NULL;

  tree decl = SSA_NAME_VAR (old_name);
  if (decl == NULL_TREE
      || TREE_CODE (decl) != PARM_DECL)
    return NULL;

  tree repl = get_replacement_ssa_base (decl);
  if (!repl)
    return NULL;

  tree new_name = make_ssa_name (repl, stmt);
  SSA_NAME_OCCURS_IN_ABNORMAL_PHI (new_name)
    = SSA_NAME_OCCURS_IN_ABNORMAL_PHI (old_name);

  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "replacing an SSA name of a removed param ");
      print_generic_expr (dump_file, old_name);
      fprintf (dump_file, " with ");
      print_generic_expr (dump_file, new_name);
      fprintf (dump_file, "\n");
    }

  replace_uses_by (old_name, new_name);
  return new_name;
}

/* If the expression *EXPR_P should be replaced, do so.  CONVERT specifies
   whether the function should care about type incompatibility of the current
   and new expressions.  If it is false, the function will leave
   incompatibility issues to the caller - note that when the function
   encounters a BIT_FIELD_REF, IMAGPART_EXPR or REALPART_EXPR, it will modify
   their bases instead of the expressions themselves and then also performs any
   necessary conversions.  */

bool
ipa_param_body_adjustments::modify_expression (tree *expr_p, bool convert)
{
  tree expr = *expr_p;

  if (TREE_CODE (expr) == BIT_FIELD_REF
      || TREE_CODE (expr) == IMAGPART_EXPR
      || TREE_CODE (expr) == REALPART_EXPR)
    {
      expr_p = &TREE_OPERAND (expr, 0);
      expr = *expr_p;
      convert = true;
    }

  ipa_param_body_replacement *pbr = get_expr_replacement (expr, false);
  if (!pbr)
    return false;

  tree repl = pbr->repl;
  if (dump_file && (dump_flags & TDF_DETAILS))
    {
      fprintf (dump_file, "About to replace expr ");
      print_generic_expr (dump_file, expr);
      fprintf (dump_file, " with ");
      print_generic_expr (dump_file, repl);
      fprintf (dump_file, "\n");
    }

  if (convert && !useless_type_conversion_p (TREE_TYPE (expr),
					     TREE_TYPE (repl)))
    {
      tree vce = build1 (VIEW_CONVERT_EXPR, TREE_TYPE (expr), repl);
      *expr_p = vce;
    }
  else
    *expr_p = repl;
  return true;
}

/* If the assignment statement STMT contains any expressions that need to
   replaced with a different one as noted by ADJUSTMENTS, do so.  Handle any
   potential type incompatibilities.  If any conversion sttements have to be
   pre-pended to STMT, they will be added to EXTRA_STMTS.  Return true iff the
   statement was modified.  */

bool
ipa_param_body_adjustments::modify_assignment (gimple *stmt,
					       gimple_seq *extra_stmts)
{
  tree *lhs_p, *rhs_p;
  bool any;

  if (!gimple_assign_single_p (stmt))
    return false;

  rhs_p = gimple_assign_rhs1_ptr (stmt);
  lhs_p = gimple_assign_lhs_ptr (stmt);

  any = modify_expression (lhs_p, false);
  any |= modify_expression (rhs_p, false);
  if (any
      && !useless_type_conversion_p (TREE_TYPE (*lhs_p), TREE_TYPE (*rhs_p)))
    {
      if (TREE_CODE (*rhs_p) == CONSTRUCTOR)
	{
	  /* V_C_Es of constructors can cause trouble (PR 42714).  */
	  if (is_gimple_reg_type (TREE_TYPE (*lhs_p)))
	    *rhs_p = build_zero_cst (TREE_TYPE (*lhs_p));
	  else
	    *rhs_p = build_constructor (TREE_TYPE (*lhs_p),
					NULL);
	}
      else
	{
	  tree new_rhs = fold_build1_loc (gimple_location (stmt),
					  VIEW_CONVERT_EXPR, TREE_TYPE (*lhs_p),
					  *rhs_p);
	  tree tmp = force_gimple_operand (new_rhs, extra_stmts, true,
					   NULL_TREE);
	  gimple_assign_set_rhs1 (stmt, tmp);
	}
      return true;
    }

  return any;
}

/* Record information about what modifications to call arguments have already
   been done by clone materialization into a summary describing CS.  The
   information is stored in NEW_INDEX_MAP, NEW_PT_MAP and NEW_ALWAYS_COPY_DELTA
   and correspond to equivalent fields in ipa_edge_modification_info.  Return
   the edge summary.  */

static ipa_edge_modification_info *
record_argument_state_1 (cgraph_edge *cs, const vec<int> &new_index_map,
			 const vec<pass_through_split_map> &new_pt_map,
			 int new_always_copy_delta)

{
  ipa_edge_modification_info *sum = ipa_edge_modifications->get_create (cs);

  unsigned len = sum->pass_through_map.length ();
  for (unsigned i = 0; i < len; i++)
    {
      unsigned oldnew = sum->pass_through_map[i].new_index;
      sum->pass_through_map[i].new_index = new_index_map[oldnew];
    }

  len = sum->index_map.length ();
  if (len > 0)
    {
      unsigned nptlen = new_pt_map.length ();
      for (unsigned j = 0; j < nptlen; j++)
	{
	  int inverse = -1;
	  for (unsigned i = 0; i < len ; i++)
	    if ((unsigned) sum->index_map[i] == new_pt_map[j].base_index)
	    {
	      inverse = i;
	      break;
	    }
	  gcc_assert (inverse >= 0);
	  pass_through_split_map ptm_item;

	  ptm_item.base_index = inverse;
	  ptm_item.unit_offset = new_pt_map[j].unit_offset;
	  ptm_item.new_index = new_pt_map[j].new_index;
	  sum->pass_through_map.safe_push (ptm_item);
	}

      for (unsigned i = 0; i < len; i++)
	{
	  int idx = sum->index_map[i];
	  if (idx < 0)
	    continue;
	  sum->index_map[i] = new_index_map[idx];
	}
    }
  else
    {
      sum->pass_through_map.safe_splice (new_pt_map);
      sum->index_map.safe_splice (new_index_map);
    }
  sum->always_copy_delta += new_always_copy_delta;
  return sum;
}

/* Record information about what modifications to call arguments have already
   been done by clone materialization into a summary of an edge describing the
   call in this clone and all its clones.  NEW_INDEX_MAP, NEW_PT_MAP and
   NEW_ALWAYS_COPY_DELTA have the same meaning as record_argument_state_1.

   In order to associate the info with the right edge summaries, we need
   address of the ORIG_STMT in the function from which we are cloning (because
   the edges have not yet been re-assigned to the new statement that has just
   been created) and ID, the structure governing function body copying.  */

static void
record_argument_state (copy_body_data *id, gimple *orig_stmt,
		       const vec<int> &new_index_map,
		       const vec<pass_through_split_map> &new_pt_map,
		       int new_always_copy_delta)
{
  if (!ipa_edge_modifications)
    ipa_edge_modifications = new ipa_edge_modification_sum (symtab);

  struct cgraph_node *this_node = id->dst_node;
  ipa_edge_modification_info *first_sum = NULL;
  cgraph_edge *cs = this_node->get_edge (orig_stmt);
  if (cs)
    first_sum = record_argument_state_1 (cs, new_index_map, new_pt_map,
					 new_always_copy_delta);
  else
    gcc_assert (this_node->clones);

  if (!this_node->clones)
    return;
  for (cgraph_node *subclone = this_node->clones; subclone != this_node;)
    {
      cs = subclone->get_edge (orig_stmt);
      if (cs)
	{
	  if (!first_sum)
	    first_sum = record_argument_state_1 (cs, new_index_map, new_pt_map,
						 new_always_copy_delta);
	  else
	    {
	      ipa_edge_modification_info *s2
		= ipa_edge_modifications->get_create (cs);
	      s2->index_map.truncate (0);
	      s2->index_map.safe_splice (first_sum->index_map);
	      s2->pass_through_map.truncate (0);
	      s2->pass_through_map.safe_splice (first_sum->pass_through_map);
	      s2->always_copy_delta = first_sum->always_copy_delta;
	    }
	}
      else
	gcc_assert (subclone->clones);

      if (subclone->clones)
	subclone = subclone->clones;
      else if (subclone->next_sibling_clone)
	subclone = subclone->next_sibling_clone;
      else
	{
	  while (subclone != this_node && !subclone->next_sibling_clone)
	    subclone = subclone->clone_of;
	  if (subclone != this_node)
	    subclone = subclone->next_sibling_clone;
	}
    }
}

/* If the call statement pointed at by STMT_P contains any expressions that
   need to replaced with a different one as noted by ADJUSTMENTS, do so.  f the
   statement needs to be rebuilt, do so.  Return true if any modifications have
   been performed.  ORIG_STMT, if not NULL, is the original statement in the
   function that is being cloned from, which at this point can be used to look
   up call_graph edges.

   If the method is invoked as a part of IPA clone materialization and if any
   parameter split is pass-through, i.e. it applies to the functin that is
   being modified and also to the callee of the statement, replace the
   parameter passed to old callee with all of the replacement a callee might
   possibly want and record the performed argument modifications in
   ipa_edge_modifications.  Likewise if any argument has already been left out
   because it is not necessary.  */

bool
ipa_param_body_adjustments::modify_call_stmt (gcall **stmt_p,
					      gimple *orig_stmt)
{
  auto_vec <unsigned, 4> pass_through_args;
  auto_vec <unsigned, 4> pass_through_pbr_indices;
  auto_vec <HOST_WIDE_INT, 4> pass_through_offsets;
  gcall *stmt = *stmt_p;
  unsigned nargs = gimple_call_num_args (stmt);
  bool recreate = false;

  for (unsigned i = 0; i < gimple_call_num_args (stmt); i++)
    {
      tree t = gimple_call_arg (stmt, i);
      gcc_assert (TREE_CODE (t) != BIT_FIELD_REF
		  && TREE_CODE (t) != IMAGPART_EXPR
		  && TREE_CODE (t) != REALPART_EXPR);

      if (TREE_CODE (t) == SSA_NAME
	  && m_dead_ssas.contains (t))
	recreate = true;

      if (!m_split_modifications_p)
	continue;

      tree base;
      unsigned agg_arg_offset;
      if (!isra_get_ref_base_and_offset (t, &base, &agg_arg_offset))
	continue;

      bool by_ref = false;
      if (TREE_CODE (base) == SSA_NAME)
	{
	  if (!SSA_NAME_IS_DEFAULT_DEF (base))
	    continue;
	  base = SSA_NAME_VAR (base);
	  gcc_checking_assert (base);
	  by_ref = true;
	}
      if (TREE_CODE (base) != PARM_DECL)
	continue;

      bool base_among_replacements = false;
      unsigned j, repl_list_len = m_replacements.length ();
      for (j = 0; j < repl_list_len; j++)
	{
	  ipa_param_body_replacement *pbr = &m_replacements[j];
	  if (pbr->base == base)
	    {
	      base_among_replacements = true;
	      break;
	    }
	}
      if (!base_among_replacements)
	continue;

      /* We still have to distinguish between an end-use that we have to
	 transform now and a pass-through, which happens in the following
	 two cases.  */

      /* TODO: After we adjust ptr_parm_has_nonarg_uses to also consider
	 &MEM_REF[ssa_name + offset], we will also have to detect that case
	 here.    */

      if (TREE_CODE (t) == SSA_NAME
	  && SSA_NAME_IS_DEFAULT_DEF (t)
	  && SSA_NAME_VAR (t)
	  && TREE_CODE (SSA_NAME_VAR (t)) == PARM_DECL)
	{
	  /* This must be a by_reference pass-through.  */
	  recreate = true;
	  gcc_assert (POINTER_TYPE_P (TREE_TYPE (t)));
	  pass_through_args.safe_push (i);
	  pass_through_pbr_indices.safe_push (j);
	  pass_through_offsets.safe_push (agg_arg_offset);
	}
      else if (!by_ref && AGGREGATE_TYPE_P (TREE_TYPE (t)))
	{
	  /* Currently IPA-SRA guarantees the aggregate access type
	     exactly matches in this case.  So if it does not match, it is
	     a pass-through argument that will be sorted out at edge
	     redirection time.  */
	  ipa_param_body_replacement *pbr
	    = lookup_replacement_1 (base, agg_arg_offset);

	  if (!pbr
	      || (TYPE_MAIN_VARIANT (TREE_TYPE (t))
		  != TYPE_MAIN_VARIANT (TREE_TYPE (pbr->repl))))
	    {
	      recreate = true;
	      pass_through_args.safe_push (i);
	      pass_through_pbr_indices.safe_push (j);
	      pass_through_offsets.safe_push (agg_arg_offset);
	    }
	}
    }

  if (!recreate)
    {
      /* No need to rebuild the statement, let's just modify arguments
	 and the LHS if/as appropriate.  */
      bool modified = false;
      for (unsigned i = 0; i < nargs; i++)
	{
	  tree *t = gimple_call_arg_ptr (stmt, i);
	  modified |= modify_expression (t, true);
	}
      if (gimple_call_lhs (stmt))
	{
	  tree *t = gimple_call_lhs_ptr (stmt);
	  modified |= modify_expression (t, false);
	}
      return modified;
    }

  auto_vec<int, 16> index_map;
  auto_vec<pass_through_split_map, 4> pass_through_map;
  auto_vec<tree, 16> vargs;
  int always_copy_delta = 0;
  unsigned pt_idx = 0;
  int new_arg_idx = 0;
  for (unsigned i = 0; i < nargs; i++)
    {
      if (pt_idx < pass_through_args.length ()
	  && i == pass_through_args[pt_idx])
	{
	  unsigned j = pass_through_pbr_indices[pt_idx];
	  unsigned agg_arg_offset = pass_through_offsets[pt_idx];
	  pt_idx++;
	  always_copy_delta--;
	  tree base = m_replacements[j].base;

	  /* In order to be put into SSA form, we have to push all replacements
	     pertaining to this parameter as parameters to the call statement.
	     Edge redirection will need to use edge summary to weed out the
	     unnecessary ones.  */
	  unsigned repl_list_len = m_replacements.length ();
	  for (; j < repl_list_len; j++)
	    {
	      if (m_replacements[j].base != base)
		break;
	      if (m_replacements[j].unit_offset < agg_arg_offset)
		continue;
	      pass_through_split_map pt_map;
	      pt_map.base_index = i;
	      pt_map.unit_offset
		= m_replacements[j].unit_offset - agg_arg_offset;
	      pt_map.new_index = new_arg_idx;
	      pass_through_map.safe_push (pt_map);
	      vargs.safe_push (m_replacements[j].repl);
	      new_arg_idx++;
	      always_copy_delta++;
	    }
	  index_map.safe_push (-1);
	}
      else
	{
	  tree t = gimple_call_arg (stmt, i);
	  if (TREE_CODE (t) == SSA_NAME
	      && m_dead_ssas.contains (t))
	    {
	      always_copy_delta--;
	      index_map.safe_push (-1);
	    }
	  else
	    {
	      modify_expression (&t, true);
	      vargs.safe_push (t);
	      index_map.safe_push (new_arg_idx);
	      new_arg_idx++;
	    }
	}
    }

  gcall *new_stmt = gimple_build_call_vec (gimple_call_fn (stmt), vargs);
  if (gimple_has_location (stmt))
    gimple_set_location (new_stmt, gimple_location (stmt));
  gimple_call_set_chain (new_stmt, gimple_call_chain (stmt));
  gimple_call_copy_flags (new_stmt, stmt);
  if (tree lhs = gimple_call_lhs (stmt))
    {
      modify_expression (&lhs, false);
      /* Avoid adjusting SSA_NAME_DEF_STMT of a SSA lhs, SSA names
	 have not yet been remapped.  */
      *gimple_call_lhs_ptr (new_stmt) = lhs;
    }
  *stmt_p = new_stmt;

  if (orig_stmt)
    record_argument_state (m_id, orig_stmt, index_map, pass_through_map,
			   always_copy_delta);
  return true;
}

/* If the statement STMT contains any expressions that need to replaced with a
   different one as noted by ADJUSTMENTS, do so.  Handle any potential type
   incompatibilities.  If any conversion sttements have to be pre-pended to
   STMT, they will be added to EXTRA_STMTS.  Return true iff the statement was
   modified.  */

bool
ipa_param_body_adjustments::modify_gimple_stmt (gimple **stmt,
						gimple_seq *extra_stmts,
						gimple *orig_stmt)
{
  bool modified = false;
  tree *t;

  switch (gimple_code (*stmt))
    {
    case GIMPLE_RETURN:
      t = gimple_return_retval_ptr (as_a <greturn *> (*stmt));
      if (m_adjustments && m_adjustments->m_skip_return)
	*t = NULL_TREE;
      else if (*t != NULL_TREE)
	modified |= modify_expression (t, true);
      break;

    case GIMPLE_ASSIGN:
      modified |= modify_assignment (*stmt, extra_stmts);
      break;

    case GIMPLE_CALL:
      modified |= modify_call_stmt ((gcall **) stmt, orig_stmt);
      break;

    case GIMPLE_ASM:
      {
	gasm *asm_stmt = as_a <gasm *> (*stmt);
	for (unsigned i = 0; i < gimple_asm_ninputs (asm_stmt); i++)
	  {
	    t = &TREE_VALUE (gimple_asm_input_op (asm_stmt, i));
	    modified |= modify_expression (t, true);
	  }
	for (unsigned i = 0; i < gimple_asm_noutputs (asm_stmt); i++)
	  {
	    t = &TREE_VALUE (gimple_asm_output_op (asm_stmt, i));
	    modified |= modify_expression (t, false);
	  }
      }
      break;

    default:
      break;
    }
  return modified;
}


/* Traverse body of the current function and perform the requested adjustments
   on its statements.  Return true iff the CFG has been changed.  */

bool
ipa_param_body_adjustments::modify_cfun_body ()
{
  bool cfg_changed = false;
  basic_block bb;

  FOR_EACH_BB_FN (bb, cfun)
    {
      gimple_stmt_iterator gsi;

      for (gsi = gsi_start_phis (bb); !gsi_end_p (gsi); gsi_next (&gsi))
	{
	  gphi *phi = as_a <gphi *> (gsi_stmt (gsi));
	  tree new_lhs, old_lhs = gimple_phi_result (phi);
	  new_lhs = replace_removed_params_ssa_names (old_lhs, phi);
	  if (new_lhs)
	    {
	      gimple_phi_set_result (phi, new_lhs);
	      release_ssa_name (old_lhs);
	    }
	}

      gsi = gsi_start_bb (bb);
      while (!gsi_end_p (gsi))
	{
	  gimple *stmt = gsi_stmt (gsi);
	  gimple *stmt_copy = stmt;
	  gimple_seq extra_stmts = NULL;
	  bool modified = modify_gimple_stmt (&stmt, &extra_stmts, NULL);
	  if (stmt != stmt_copy)
	    {
	      gcc_checking_assert (modified);
	      gsi_replace (&gsi, stmt, false);
	    }
	  if (!gimple_seq_empty_p (extra_stmts))
	    gsi_insert_seq_before (&gsi, extra_stmts, GSI_SAME_STMT);

	  def_operand_p defp;
	  ssa_op_iter iter;
	  FOR_EACH_SSA_DEF_OPERAND (defp, stmt, iter, SSA_OP_DEF)
	    {
	      tree old_def = DEF_FROM_PTR (defp);
	      if (tree new_def = replace_removed_params_ssa_names (old_def,
								   stmt))
		{
		  SET_DEF (defp, new_def);
		  release_ssa_name (old_def);
		  modified = true;
		}
	    }

	  if (modified)
	    {
	      update_stmt (stmt);
	      if (maybe_clean_eh_stmt (stmt)
		  && gimple_purge_dead_eh_edges (gimple_bb (stmt)))
		cfg_changed = true;
	    }
	  gsi_next (&gsi);
	}
    }

  return cfg_changed;
}

/* Call gimple_debug_bind_reset_value on all debug statements describing
   gimple register parameters that are being removed or replaced.  */

void
ipa_param_body_adjustments::reset_debug_stmts ()
{
  int i, len;
  gimple_stmt_iterator *gsip = NULL, gsi;

  if (MAY_HAVE_DEBUG_STMTS && single_succ_p (ENTRY_BLOCK_PTR_FOR_FN (cfun)))
    {
      gsi = gsi_after_labels (single_succ (ENTRY_BLOCK_PTR_FOR_FN (cfun)));
      gsip = &gsi;
    }
  len = m_reset_debug_decls.length ();
  for (i = 0; i < len; i++)
    {
      imm_use_iterator ui;
      gimple *stmt;
      gdebug *def_temp;
      tree name, vexpr, copy = NULL_TREE;
      use_operand_p use_p;
      tree decl = m_reset_debug_decls[i];

      gcc_checking_assert (is_gimple_reg (decl));
      name = ssa_default_def (cfun, decl);
      vexpr = NULL;
      if (name)
	FOR_EACH_IMM_USE_STMT (stmt, ui, name)
	  {
	    if (gimple_clobber_p (stmt))
	      {
		gimple_stmt_iterator cgsi = gsi_for_stmt (stmt);
		unlink_stmt_vdef (stmt);
		gsi_remove (&cgsi, true);
		release_defs (stmt);
		continue;
	      }
	    /* All other users must have been removed by function body
	       modification.  */
	    gcc_assert (is_gimple_debug (stmt));
	    if (vexpr == NULL && gsip != NULL)
	      {
		vexpr = build_debug_expr_decl (TREE_TYPE (name));
		/* FIXME: Is setting the mode really necessary? */
		SET_DECL_MODE (vexpr, DECL_MODE (decl));
		def_temp = gimple_build_debug_source_bind (vexpr, decl, NULL);
		gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
	      }
	    if (vexpr)
	      {
		FOR_EACH_IMM_USE_ON_STMT (use_p, ui)
		  SET_USE (use_p, vexpr);
	      }
	    else
	      gimple_debug_bind_reset_value (stmt);
	    update_stmt (stmt);
	  }
      /* Create a VAR_DECL for debug info purposes.  */
      if (!DECL_IGNORED_P (decl))
	{
	  copy = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
			     VAR_DECL, DECL_NAME (decl),
			     TREE_TYPE (decl));
	  if (DECL_PT_UID_SET_P (decl))
	    SET_DECL_PT_UID (copy, DECL_PT_UID (decl));
	  TREE_ADDRESSABLE (copy) = TREE_ADDRESSABLE (decl);
	  TREE_READONLY (copy) = TREE_READONLY (decl);
	  TREE_THIS_VOLATILE (copy) = TREE_THIS_VOLATILE (decl);
	  DECL_NOT_GIMPLE_REG_P (copy) = DECL_NOT_GIMPLE_REG_P (decl);
	  DECL_ARTIFICIAL (copy) = DECL_ARTIFICIAL (decl);
	  DECL_IGNORED_P (copy) = DECL_IGNORED_P (decl);
	  DECL_ABSTRACT_ORIGIN (copy) = DECL_ORIGIN (decl);
	  DECL_SEEN_IN_BIND_EXPR_P (copy) = 1;
	  SET_DECL_RTL (copy, 0);
	  TREE_USED (copy) = 1;
	  DECL_CONTEXT (copy) = current_function_decl;
	  add_local_decl (cfun, copy);
	  DECL_CHAIN (copy)
	    = BLOCK_VARS (DECL_INITIAL (current_function_decl));
	  BLOCK_VARS (DECL_INITIAL (current_function_decl)) = copy;
	}
      if (gsip != NULL && copy && target_for_debug_bind (decl))
	{
	  gcc_assert (TREE_CODE (decl) == PARM_DECL);
	  if (vexpr)
	    def_temp = gimple_build_debug_bind (copy, vexpr, NULL);
	  else
	    def_temp = gimple_build_debug_source_bind (copy, decl,
						       NULL);
	  gsi_insert_before (gsip, def_temp, GSI_SAME_STMT);
	}
    }
}

/* Perform all necessary body changes to change signature, body and debug info
   of fun according to adjustments passed at construction.  Return true if CFG
   was changed in any way.  The main entry point for modification of standalone
   functions that is not part of IPA clone materialization.  */

bool
ipa_param_body_adjustments::perform_cfun_body_modifications ()
{
  bool cfg_changed;
  modify_formal_parameters ();
  cfg_changed = modify_cfun_body ();
  reset_debug_stmts ();

  return cfg_changed;
}


/* Deallocate summaries which otherwise stay alive until the end of
   compilation.  */

void
ipa_edge_modifications_finalize ()
{
  if (!ipa_edge_modifications)
    return;
  delete ipa_edge_modifications;
  ipa_edge_modifications = NULL;
}


