/* Emit RTL for the GCC expander.
   Copyright (C) 1987-2024 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/>.  */


/* Middle-to-low level generation of rtx code and insns.

   This file contains support functions for creating rtl expressions
   and manipulating them in the doubly-linked chain of insns.

   The patterns of the insns are created by machine-dependent
   routines in insn-emit.cc, which is generated automatically from
   the machine description.  These routines make the individual rtx's
   of the pattern with `gen_rtx_fmt_ee' and others in genrtl.[ch],
   which are automatically generated from rtl.def; what is machine
   dependent is the kind of rtx's they make and what arguments they
   use.  */

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "memmodel.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "df.h"
#include "tm_p.h"
#include "stringpool.h"
#include "insn-config.h"
#include "regs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "diagnostic-core.h"
#include "alias.h"
#include "fold-const.h"
#include "varasm.h"
#include "cfgrtl.h"
#include "tree-eh.h"
#include "explow.h"
#include "expr.h"
#include "builtins.h"
#include "rtl-iter.h"
#include "stor-layout.h"
#include "opts.h"
#include "optabs.h"
#include "predict.h"
#include "rtx-vector-builder.h"
#include "gimple.h"
#include "gimple-ssa.h"
#include "gimplify.h"

struct target_rtl default_target_rtl;
#if SWITCHABLE_TARGET
struct target_rtl *this_target_rtl = &default_target_rtl;
#endif

#define initial_regno_reg_rtx (this_target_rtl->x_initial_regno_reg_rtx)

/* Commonly used modes.  */

scalar_int_mode byte_mode;	/* Mode whose width is BITS_PER_UNIT.  */
scalar_int_mode word_mode;	/* Mode whose width is BITS_PER_WORD.  */
scalar_int_mode ptr_mode;	/* Mode whose width is POINTER_SIZE.  */

/* Datastructures maintained for currently processed function in RTL form.  */

struct rtl_data x_rtl;

/* Indexed by pseudo register number, gives the rtx for that pseudo.
   Allocated in parallel with regno_pointer_align.
   FIXME: We could put it into emit_status struct, but gengtype is not able to deal
   with length attribute nested in top level structures.  */

rtx * regno_reg_rtx;

/* This is *not* reset after each function.  It gives each CODE_LABEL
   in the entire compilation a unique label number.  */

static GTY(()) int label_num = 1;

/* We record floating-point CONST_DOUBLEs in each floating-point mode for
   the values of 0, 1, and 2.  For the integer entries and VOIDmode, we
   record a copy of const[012]_rtx and constm1_rtx.  CONSTM1_RTX
   is set only for MODE_INT and MODE_VECTOR_INT modes.  */

rtx const_tiny_rtx[4][(int) MAX_MACHINE_MODE];

rtx const_true_rtx;

REAL_VALUE_TYPE dconst0;
REAL_VALUE_TYPE dconst1;
REAL_VALUE_TYPE dconst2;
REAL_VALUE_TYPE dconstm0;
REAL_VALUE_TYPE dconstm1;
REAL_VALUE_TYPE dconsthalf;
REAL_VALUE_TYPE dconstinf;
REAL_VALUE_TYPE dconstninf;

/* Record fixed-point constant 0 and 1.  */
FIXED_VALUE_TYPE fconst0[MAX_FCONST0];
FIXED_VALUE_TYPE fconst1[MAX_FCONST1];

/* We make one copy of (const_int C) where C is in
   [- MAX_SAVED_CONST_INT, MAX_SAVED_CONST_INT]
   to save space during the compilation and simplify comparisons of
   integers.  */

rtx const_int_rtx[MAX_SAVED_CONST_INT * 2 + 1];

/* Standard pieces of rtx, to be substituted directly into things.  */
rtx pc_rtx;
rtx ret_rtx;
rtx simple_return_rtx;

/* Marker used for denoting an INSN, which should never be accessed (i.e.,
   this pointer should normally never be dereferenced), but is required to be
   distinct from NULL_RTX.  Currently used by peephole2 pass.  */
rtx_insn *invalid_insn_rtx;

/* A hash table storing CONST_INTs whose absolute value is greater
   than MAX_SAVED_CONST_INT.  */

struct const_int_hasher : ggc_cache_ptr_hash<rtx_def>
{
  typedef HOST_WIDE_INT compare_type;

  static hashval_t hash (rtx i);
  static bool equal (rtx i, HOST_WIDE_INT h);
};

static GTY ((cache)) hash_table<const_int_hasher> *const_int_htab;

struct const_wide_int_hasher : ggc_cache_ptr_hash<rtx_def>
{
  static hashval_t hash (rtx x);
  static bool equal (rtx x, rtx y);
};

static GTY ((cache)) hash_table<const_wide_int_hasher> *const_wide_int_htab;

struct const_poly_int_hasher : ggc_cache_ptr_hash<rtx_def>
{
  typedef std::pair<machine_mode, poly_wide_int_ref> compare_type;

  static hashval_t hash (rtx x);
  static bool equal (rtx x, const compare_type &y);
};

static GTY ((cache)) hash_table<const_poly_int_hasher> *const_poly_int_htab;

/* A hash table storing register attribute structures.  */
struct reg_attr_hasher : ggc_cache_ptr_hash<reg_attrs>
{
  static hashval_t hash (reg_attrs *x);
  static bool equal (reg_attrs *a, reg_attrs *b);
};

static GTY ((cache)) hash_table<reg_attr_hasher> *reg_attrs_htab;

/* A hash table storing all CONST_DOUBLEs.  */
struct const_double_hasher : ggc_cache_ptr_hash<rtx_def>
{
  static hashval_t hash (rtx x);
  static bool equal (rtx x, rtx y);
};

static GTY ((cache)) hash_table<const_double_hasher> *const_double_htab;

/* A hash table storing all CONST_FIXEDs.  */
struct const_fixed_hasher : ggc_cache_ptr_hash<rtx_def>
{
  static hashval_t hash (rtx x);
  static bool equal (rtx x, rtx y);
};

static GTY ((cache)) hash_table<const_fixed_hasher> *const_fixed_htab;

#define cur_insn_uid (crtl->emit.x_cur_insn_uid)
#define cur_debug_insn_uid (crtl->emit.x_cur_debug_insn_uid)
#define first_label_num (crtl->emit.x_first_label_num)

static void set_used_decls (tree);
static void mark_label_nuses (rtx);
#if TARGET_SUPPORTS_WIDE_INT
static rtx lookup_const_wide_int (rtx);
#endif
static rtx lookup_const_double (rtx);
static rtx lookup_const_fixed (rtx);
static rtx gen_const_vector (machine_mode, int);
static void copy_rtx_if_shared_1 (rtx *orig);

/* Probability of the conditional branch currently proceeded by try_split.  */
profile_probability split_branch_probability;

/* Returns a hash code for X (which is a really a CONST_INT).  */

hashval_t
const_int_hasher::hash (rtx x)
{
  return (hashval_t) INTVAL (x);
}

/* Returns true if the value represented by X (which is really a
   CONST_INT) is the same as that given by Y (which is really a
   HOST_WIDE_INT *).  */

bool
const_int_hasher::equal (rtx x, HOST_WIDE_INT y)
{
  return (INTVAL (x) == y);
}

#if TARGET_SUPPORTS_WIDE_INT
/* Returns a hash code for X (which is a really a CONST_WIDE_INT).  */

hashval_t
const_wide_int_hasher::hash (rtx x)
{
  int i;
  unsigned HOST_WIDE_INT hash = 0;
  const_rtx xr = x;

  for (i = 0; i < CONST_WIDE_INT_NUNITS (xr); i++)
    hash += CONST_WIDE_INT_ELT (xr, i);

  return (hashval_t) hash;
}

/* Returns true if the value represented by X (which is really a
   CONST_WIDE_INT) is the same as that given by Y (which is really a
   CONST_WIDE_INT).  */

bool
const_wide_int_hasher::equal (rtx x, rtx y)
{
  int i;
  const_rtx xr = x;
  const_rtx yr = y;
  if (CONST_WIDE_INT_NUNITS (xr) != CONST_WIDE_INT_NUNITS (yr))
    return false;

  for (i = 0; i < CONST_WIDE_INT_NUNITS (xr); i++)
    if (CONST_WIDE_INT_ELT (xr, i) != CONST_WIDE_INT_ELT (yr, i))
      return false;

  return true;
}
#endif

/* Returns a hash code for CONST_POLY_INT X.  */

hashval_t
const_poly_int_hasher::hash (rtx x)
{
  inchash::hash h;
  h.add_int (GET_MODE (x));
  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    h.add_wide_int (CONST_POLY_INT_COEFFS (x)[i]);
  return h.end ();
}

/* Returns true if CONST_POLY_INT X is an rtx representation of Y.  */

bool
const_poly_int_hasher::equal (rtx x, const compare_type &y)
{
  if (GET_MODE (x) != y.first)
    return false;
  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    if (CONST_POLY_INT_COEFFS (x)[i] != y.second.coeffs[i])
      return false;
  return true;
}

/* Returns a hash code for X (which is really a CONST_DOUBLE).  */
hashval_t
const_double_hasher::hash (rtx x)
{
  const_rtx const value = x;
  hashval_t h;

  if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (value) == VOIDmode)
    h = CONST_DOUBLE_LOW (value) ^ CONST_DOUBLE_HIGH (value);
  else
    {
      h = real_hash (CONST_DOUBLE_REAL_VALUE (value));
      /* MODE is used in the comparison, so it should be in the hash.  */
      h ^= GET_MODE (value);
    }
  return h;
}

/* Returns true if the value represented by X (really a ...)
   is the same as that represented by Y (really a ...) */
bool
const_double_hasher::equal (rtx x, rtx y)
{
  const_rtx const a = x, b = y;

  if (GET_MODE (a) != GET_MODE (b))
    return false;
  if (TARGET_SUPPORTS_WIDE_INT == 0 && GET_MODE (a) == VOIDmode)
    return (CONST_DOUBLE_LOW (a) == CONST_DOUBLE_LOW (b)
	    && CONST_DOUBLE_HIGH (a) == CONST_DOUBLE_HIGH (b));
  else
    return real_identical (CONST_DOUBLE_REAL_VALUE (a),
			   CONST_DOUBLE_REAL_VALUE (b));
}

/* Returns a hash code for X (which is really a CONST_FIXED).  */

hashval_t
const_fixed_hasher::hash (rtx x)
{
  const_rtx const value = x;
  hashval_t h;

  h = fixed_hash (CONST_FIXED_VALUE (value));
  /* MODE is used in the comparison, so it should be in the hash.  */
  h ^= GET_MODE (value);
  return h;
}

/* Returns true if the value represented by X is the same as that
   represented by Y.  */

bool
const_fixed_hasher::equal (rtx x, rtx y)
{
  const_rtx const a = x, b = y;

  if (GET_MODE (a) != GET_MODE (b))
    return false;
  return fixed_identical (CONST_FIXED_VALUE (a), CONST_FIXED_VALUE (b));
}

/* Return true if the given memory attributes are equal.  */

bool
mem_attrs_eq_p (const class mem_attrs *p, const class mem_attrs *q)
{
  if (p == q)
    return true;
  if (!p || !q)
    return false;
  return (p->alias == q->alias
	  && p->offset_known_p == q->offset_known_p
	  && (!p->offset_known_p || known_eq (p->offset, q->offset))
	  && p->size_known_p == q->size_known_p
	  && (!p->size_known_p || known_eq (p->size, q->size))
	  && p->align == q->align
	  && p->addrspace == q->addrspace
	  && (p->expr == q->expr
	      || (p->expr != NULL_TREE && q->expr != NULL_TREE
		  && operand_equal_p (p->expr, q->expr, 0))));
}

/* Set MEM's memory attributes so that they are the same as ATTRS.  */

static void
set_mem_attrs (rtx mem, mem_attrs *attrs)
{
  /* If everything is the default, we can just clear the attributes.  */
  if (mem_attrs_eq_p (attrs, mode_mem_attrs[(int) GET_MODE (mem)]))
    {
      MEM_ATTRS (mem) = 0;
      return;
    }

  if (!MEM_ATTRS (mem)
      || !mem_attrs_eq_p (attrs, MEM_ATTRS (mem)))
    {
      MEM_ATTRS (mem) = ggc_alloc<mem_attrs> ();
      memcpy (MEM_ATTRS (mem), attrs, sizeof (mem_attrs));
    }
}

/* Returns a hash code for X (which is a really a reg_attrs *).  */

hashval_t
reg_attr_hasher::hash (reg_attrs *x)
{
  const reg_attrs *const p = x;

  inchash::hash h;
  h.add_ptr (p->decl);
  h.add_poly_hwi (p->offset);
  return h.end ();
}

/* Returns true if the value represented by X  is the same as that given by
   Y.  */

bool
reg_attr_hasher::equal (reg_attrs *x, reg_attrs *y)
{
  const reg_attrs *const p = x;
  const reg_attrs *const q = y;

  return (p->decl == q->decl && known_eq (p->offset, q->offset));
}
/* Allocate a new reg_attrs structure and insert it into the hash table if
   one identical to it is not already in the table.  We are doing this for
   MEM of mode MODE.  */

static reg_attrs *
get_reg_attrs (tree decl, poly_int64 offset)
{
  reg_attrs attrs;

  /* If everything is the default, we can just return zero.  */
  if (decl == 0 && known_eq (offset, 0))
    return 0;

  attrs.decl = decl;
  attrs.offset = offset;

  reg_attrs **slot = reg_attrs_htab->find_slot (&attrs, INSERT);
  if (*slot == 0)
    {
      *slot = ggc_alloc<reg_attrs> ();
      memcpy (*slot, &attrs, sizeof (reg_attrs));
    }

  return *slot;
}


#if !HAVE_blockage
/* Generate an empty ASM_INPUT, which is used to block attempts to schedule,
   and to block register equivalences to be seen across this insn.  */

rtx
gen_blockage (void)
{
  rtx x = gen_rtx_ASM_INPUT (VOIDmode, "");
  MEM_VOLATILE_P (x) = true;
  return x;
}
#endif


/* Set the mode and register number of X to MODE and REGNO.  */

void
set_mode_and_regno (rtx x, machine_mode mode, unsigned int regno)
{
  unsigned int nregs = (HARD_REGISTER_NUM_P (regno)
			? hard_regno_nregs (regno, mode)
			: 1);
  PUT_MODE_RAW (x, mode);
  set_regno_raw (x, regno, nregs);
}

/* Initialize a fresh REG rtx with mode MODE and register REGNO.  */

rtx
init_raw_REG (rtx x, machine_mode mode, unsigned int regno)
{
  set_mode_and_regno (x, mode, regno);
  REG_ATTRS (x) = NULL;
  ORIGINAL_REGNO (x) = regno;
  return x;
}

/* Generate a new REG rtx.  Make sure ORIGINAL_REGNO is set properly, and
   don't attempt to share with the various global pieces of rtl (such as
   frame_pointer_rtx).  */

rtx
gen_raw_REG (machine_mode mode, unsigned int regno)
{
  rtx x = rtx_alloc (REG MEM_STAT_INFO);
  init_raw_REG (x, mode, regno);
  return x;
}

/* There are some RTL codes that require special attention; the generation
   functions do the raw handling.  If you add to this list, modify
   special_rtx in gengenrtl.cc as well.  */

rtx_expr_list *
gen_rtx_EXPR_LIST (machine_mode mode, rtx expr, rtx expr_list)
{
  return as_a <rtx_expr_list *> (gen_rtx_fmt_ee (EXPR_LIST, mode, expr,
						 expr_list));
}

rtx_insn_list *
gen_rtx_INSN_LIST (machine_mode mode, rtx insn, rtx insn_list)
{
  return as_a <rtx_insn_list *> (gen_rtx_fmt_ue (INSN_LIST, mode, insn,
						 insn_list));
}

rtx_insn *
gen_rtx_INSN (machine_mode mode, rtx_insn *prev_insn, rtx_insn *next_insn,
	      basic_block bb, rtx pattern, int location, int code,
	      rtx reg_notes)
{
  return as_a <rtx_insn *> (gen_rtx_fmt_uuBeiie (INSN, mode,
						 prev_insn, next_insn,
						 bb, pattern, location, code,
						 reg_notes));
}

rtx
gen_rtx_CONST_INT (machine_mode mode ATTRIBUTE_UNUSED, HOST_WIDE_INT arg)
{
  if (arg >= - MAX_SAVED_CONST_INT && arg <= MAX_SAVED_CONST_INT)
    return const_int_rtx[arg + MAX_SAVED_CONST_INT];

#if STORE_FLAG_VALUE != 1 && STORE_FLAG_VALUE != -1
  if (const_true_rtx && arg == STORE_FLAG_VALUE)
    return const_true_rtx;
#endif

  /* Look up the CONST_INT in the hash table.  */
  rtx *slot = const_int_htab->find_slot_with_hash (arg, (hashval_t) arg,
						   INSERT);
  if (*slot == 0)
    *slot = gen_rtx_raw_CONST_INT (VOIDmode, arg);

  return *slot;
}

rtx
gen_int_mode (poly_int64 c, machine_mode mode)
{
  c = trunc_int_for_mode (c, mode);
  if (c.is_constant ())
    return GEN_INT (c.coeffs[0]);
  unsigned int prec = GET_MODE_PRECISION (as_a <scalar_mode> (mode));
  return immed_wide_int_const (poly_wide_int::from (c, prec, SIGNED), mode);
}

/* CONST_DOUBLEs might be created from pairs of integers, or from
   REAL_VALUE_TYPEs.  Also, their length is known only at run time,
   so we cannot use gen_rtx_raw_CONST_DOUBLE.  */

/* Determine whether REAL, a CONST_DOUBLE, already exists in the
   hash table.  If so, return its counterpart; otherwise add it
   to the hash table and return it.  */
static rtx
lookup_const_double (rtx real)
{
  rtx *slot = const_double_htab->find_slot (real, INSERT);
  if (*slot == 0)
    *slot = real;

  return *slot;
}

/* Return a CONST_DOUBLE rtx for a floating-point value specified by
   VALUE in mode MODE.  */
rtx
const_double_from_real_value (REAL_VALUE_TYPE value, machine_mode mode)
{
  rtx real = rtx_alloc (CONST_DOUBLE);
  PUT_MODE (real, mode);

  real->u.rv = value;

  return lookup_const_double (real);
}

/* Determine whether FIXED, a CONST_FIXED, already exists in the
   hash table.  If so, return its counterpart; otherwise add it
   to the hash table and return it.  */

static rtx
lookup_const_fixed (rtx fixed)
{
  rtx *slot = const_fixed_htab->find_slot (fixed, INSERT);
  if (*slot == 0)
    *slot = fixed;

  return *slot;
}

/* Return a CONST_FIXED rtx for a fixed-point value specified by
   VALUE in mode MODE.  */

rtx
const_fixed_from_fixed_value (FIXED_VALUE_TYPE value, machine_mode mode)
{
  rtx fixed = rtx_alloc (CONST_FIXED);
  PUT_MODE (fixed, mode);

  fixed->u.fv = value;

  return lookup_const_fixed (fixed);
}

#if TARGET_SUPPORTS_WIDE_INT == 0
/* Constructs double_int from rtx CST.  */

double_int
rtx_to_double_int (const_rtx cst)
{
  double_int r;

  if (CONST_INT_P (cst))
      r = double_int::from_shwi (INTVAL (cst));
  else if (CONST_DOUBLE_AS_INT_P (cst))
    {
      r.low = CONST_DOUBLE_LOW (cst);
      r.high = CONST_DOUBLE_HIGH (cst);
    }
  else
    gcc_unreachable ();
  
  return r;
}
#endif

#if TARGET_SUPPORTS_WIDE_INT
/* Determine whether CONST_WIDE_INT WINT already exists in the hash table.
   If so, return its counterpart; otherwise add it to the hash table and
   return it.  */

static rtx
lookup_const_wide_int (rtx wint)
{
  rtx *slot = const_wide_int_htab->find_slot (wint, INSERT);
  if (*slot == 0)
    *slot = wint;

  return *slot;
}
#endif

/* Return an rtx constant for V, given that the constant has mode MODE.
   The returned rtx will be a CONST_INT if V fits, otherwise it will be
   a CONST_DOUBLE (if !TARGET_SUPPORTS_WIDE_INT) or a CONST_WIDE_INT
   (if TARGET_SUPPORTS_WIDE_INT).  */

static rtx
immed_wide_int_const_1 (const wide_int_ref &v, machine_mode mode)
{
  unsigned int len = v.get_len ();
  /* Not scalar_int_mode because we also allow pointer bound modes.  */
  unsigned int prec = GET_MODE_PRECISION (as_a <scalar_mode> (mode));

  /* Allow truncation but not extension since we do not know if the
     number is signed or unsigned.  */
  gcc_assert (prec <= v.get_precision ());

  if (len < 2 || prec <= HOST_BITS_PER_WIDE_INT)
    return gen_int_mode (v.elt (0), mode);

#if TARGET_SUPPORTS_WIDE_INT
  {
    unsigned int i;
    rtx value;
    unsigned int blocks_needed
      = (prec + HOST_BITS_PER_WIDE_INT - 1) / HOST_BITS_PER_WIDE_INT;

    if (len > blocks_needed)
      len = blocks_needed;

    value = const_wide_int_alloc (len);

    /* It is so tempting to just put the mode in here.  Must control
       myself ... */
    PUT_MODE (value, VOIDmode);
    CWI_PUT_NUM_ELEM (value, len);

    for (i = 0; i < len; i++)
      CONST_WIDE_INT_ELT (value, i) = v.elt (i);

    return lookup_const_wide_int (value);
  }
#else
  return immed_double_const (v.elt (0), v.elt (1), mode);
#endif
}

#if TARGET_SUPPORTS_WIDE_INT == 0
/* Return a CONST_DOUBLE or CONST_INT for a value specified as a pair
   of ints: I0 is the low-order word and I1 is the high-order word.
   For values that are larger than HOST_BITS_PER_DOUBLE_INT, the
   implied upper bits are copies of the high bit of i1.  The value
   itself is neither signed nor unsigned.  Do not use this routine for
   non-integer modes; convert to REAL_VALUE_TYPE and use
   const_double_from_real_value.  */

rtx
immed_double_const (HOST_WIDE_INT i0, HOST_WIDE_INT i1, machine_mode mode)
{
  rtx value;
  unsigned int i;

  /* There are the following cases (note that there are no modes with
     HOST_BITS_PER_WIDE_INT < GET_MODE_BITSIZE (mode) < HOST_BITS_PER_DOUBLE_INT):

     1) If GET_MODE_BITSIZE (mode) <= HOST_BITS_PER_WIDE_INT, then we use
	gen_int_mode.
     2) If the value of the integer fits into HOST_WIDE_INT anyway
        (i.e., i1 consists only from copies of the sign bit, and sign
	of i0 and i1 are the same), then we return a CONST_INT for i0.
     3) Otherwise, we create a CONST_DOUBLE for i0 and i1.  */
  scalar_mode smode;
  if (is_a <scalar_mode> (mode, &smode)
      && GET_MODE_BITSIZE (smode) <= HOST_BITS_PER_WIDE_INT)
    return gen_int_mode (i0, mode);

  /* If this integer fits in one word, return a CONST_INT.  */
  if ((i1 == 0 && i0 >= 0) || (i1 == ~0 && i0 < 0))
    return GEN_INT (i0);

  /* We use VOIDmode for integers.  */
  value = rtx_alloc (CONST_DOUBLE);
  PUT_MODE (value, VOIDmode);

  CONST_DOUBLE_LOW (value) = i0;
  CONST_DOUBLE_HIGH (value) = i1;

  for (i = 2; i < (sizeof CONST_DOUBLE_FORMAT - 1); i++)
    XWINT (value, i) = 0;

  return lookup_const_double (value);
}
#endif

/* Return an rtx representation of C in mode MODE.  */

rtx
immed_wide_int_const (const poly_wide_int_ref &c, machine_mode mode)
{
  if (c.is_constant ())
    return immed_wide_int_const_1 (c.coeffs[0], mode);

  /* Not scalar_int_mode because we also allow pointer bound modes.  */
  unsigned int prec = GET_MODE_PRECISION (as_a <scalar_mode> (mode));

  /* Allow truncation but not extension since we do not know if the
     number is signed or unsigned.  */
  gcc_assert (prec <= c.coeffs[0].get_precision ());
  poly_wide_int newc = poly_wide_int::from (c, prec, SIGNED);

  /* See whether we already have an rtx for this constant.  */
  inchash::hash h;
  h.add_int (mode);
  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    h.add_wide_int (newc.coeffs[i]);
  const_poly_int_hasher::compare_type typed_value (mode, newc);
  rtx *slot = const_poly_int_htab->find_slot_with_hash (typed_value,
							h.end (), INSERT);
  rtx x = *slot;
  if (x)
    return x;

  /* Create a new rtx.  There's a choice to be made here between installing
     the actual mode of the rtx or leaving it as VOIDmode (for consistency
     with CONST_INT).  In practice the handling of the codes is different
     enough that we get no benefit from using VOIDmode, and various places
     assume that VOIDmode implies CONST_INT.  Using the real mode seems like
     the right long-term direction anyway.  */
  typedef trailing_wide_ints<NUM_POLY_INT_COEFFS> twi;
  size_t extra_size = twi::extra_size (prec);
  x = rtx_alloc_v (CONST_POLY_INT,
		   sizeof (struct const_poly_int_def) + extra_size);
  PUT_MODE (x, mode);
  CONST_POLY_INT_COEFFS (x).set_precision (prec);
  for (unsigned int i = 0; i < NUM_POLY_INT_COEFFS; ++i)
    CONST_POLY_INT_COEFFS (x)[i] = newc.coeffs[i];

  *slot = x;
  return x;
}

rtx
gen_rtx_REG (machine_mode mode, unsigned int regno)
{
  /* In case the MD file explicitly references the frame pointer, have
     all such references point to the same frame pointer.  This is
     used during frame pointer elimination to distinguish the explicit
     references to these registers from pseudos that happened to be
     assigned to them.

     If we have eliminated the frame pointer or arg pointer, we will
     be using it as a normal register, for example as a spill
     register.  In such cases, we might be accessing it in a mode that
     is not Pmode and therefore cannot use the pre-allocated rtx.

     Also don't do this when we are making new REGs in reload, since
     we don't want to get confused with the real pointers.  */

  if (mode == Pmode && !reload_in_progress && !lra_in_progress)
    {
      if (regno == FRAME_POINTER_REGNUM
	  && (!reload_completed || frame_pointer_needed))
	return frame_pointer_rtx;

      if (!HARD_FRAME_POINTER_IS_FRAME_POINTER
	  && regno == HARD_FRAME_POINTER_REGNUM
	  && (!reload_completed || frame_pointer_needed))
	return hard_frame_pointer_rtx;
#if !HARD_FRAME_POINTER_IS_ARG_POINTER
      if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
	  && regno == ARG_POINTER_REGNUM)
	return arg_pointer_rtx;
#endif
#ifdef RETURN_ADDRESS_POINTER_REGNUM
      if (regno == RETURN_ADDRESS_POINTER_REGNUM)
	return return_address_pointer_rtx;
#endif
      if (regno == (unsigned) PIC_OFFSET_TABLE_REGNUM
	  && PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
	  && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
	return pic_offset_table_rtx;
      if (regno == STACK_POINTER_REGNUM)
	return stack_pointer_rtx;
    }

#if 0
  /* If the per-function register table has been set up, try to re-use
     an existing entry in that table to avoid useless generation of RTL.

     This code is disabled for now until we can fix the various backends
     which depend on having non-shared hard registers in some cases.   Long
     term we want to re-enable this code as it can significantly cut down
     on the amount of useless RTL that gets generated.

     We'll also need to fix some code that runs after reload that wants to
     set ORIGINAL_REGNO.  */

  if (cfun
      && cfun->emit
      && regno_reg_rtx
      && regno < FIRST_PSEUDO_REGISTER
      && reg_raw_mode[regno] == mode)
    return regno_reg_rtx[regno];
#endif

  return gen_raw_REG (mode, regno);
}

rtx
gen_rtx_MEM (machine_mode mode, rtx addr)
{
  rtx rt = gen_rtx_raw_MEM (mode, addr);

  /* This field is not cleared by the mere allocation of the rtx, so
     we clear it here.  */
  MEM_ATTRS (rt) = 0;

  return rt;
}

/* Generate a memory referring to non-trapping constant memory.  */

rtx
gen_const_mem (machine_mode mode, rtx addr)
{
  rtx mem = gen_rtx_MEM (mode, addr);
  MEM_READONLY_P (mem) = 1;
  MEM_NOTRAP_P (mem) = 1;
  return mem;
}

/* Generate a MEM referring to fixed portions of the frame, e.g., register
   save areas.  */

rtx
gen_frame_mem (machine_mode mode, rtx addr)
{
  rtx mem = gen_rtx_MEM (mode, addr);
  MEM_NOTRAP_P (mem) = 1;
  set_mem_alias_set (mem, get_frame_alias_set ());
  return mem;
}

/* Generate a MEM referring to a temporary use of the stack, not part
    of the fixed stack frame.  For example, something which is pushed
    by a target splitter.  */
rtx
gen_tmp_stack_mem (machine_mode mode, rtx addr)
{
  rtx mem = gen_rtx_MEM (mode, addr);
  MEM_NOTRAP_P (mem) = 1;
  if (!cfun->calls_alloca)
    set_mem_alias_set (mem, get_frame_alias_set ());
  return mem;
}

/* We want to create (subreg:OMODE (obj:IMODE) OFFSET).  Return true if
   this construct would be valid, and false otherwise.  */

bool
validate_subreg (machine_mode omode, machine_mode imode,
		 const_rtx reg, poly_uint64 offset)
{
  poly_uint64 isize = GET_MODE_SIZE (imode);
  poly_uint64 osize = GET_MODE_SIZE (omode);

  /* The sizes must be ordered, so that we know whether the subreg
     is partial, paradoxical or complete.  */
  if (!ordered_p (isize, osize))
    return false;

  /* All subregs must be aligned.  */
  if (!multiple_p (offset, osize))
    return false;

  /* The subreg offset cannot be outside the inner object.  */
  if (maybe_ge (offset, isize))
    return false;

  poly_uint64 regsize = REGMODE_NATURAL_SIZE (imode);

  /* ??? This should not be here.  Temporarily continue to allow word_mode
     subregs of anything.  The most common offender is (subreg:SI (reg:DF)).
     Generally, backends are doing something sketchy but it'll take time to
     fix them all.  */
  if (omode == word_mode)
    ;
  /* ??? Similarly, e.g. with (subreg:DF (reg:TI)).  Though store_bit_field
     is the culprit here, and not the backends.  */
  else if (known_ge (osize, regsize) && known_ge (isize, osize))
    ;
  /* Allow component subregs of complex and vector.  Though given the below
     extraction rules, it's not always clear what that means.  */
  else if ((COMPLEX_MODE_P (imode) || VECTOR_MODE_P (imode))
	   && GET_MODE_INNER (imode) == omode)
    ;
  /* ??? x86 sse code makes heavy use of *paradoxical* vector subregs,
     i.e. (subreg:V4SF (reg:SF) 0) or (subreg:V4SF (reg:V2SF) 0).  This
     surely isn't the cleanest way to represent this.  It's questionable
     if this ought to be represented at all -- why can't this all be hidden
     in post-reload splitters that make arbitrarily mode changes to the
     registers themselves.  */
  else if (VECTOR_MODE_P (omode)
	   && GET_MODE_UNIT_SIZE (omode) == GET_MODE_UNIT_SIZE (imode))
    ;
  /* Subregs involving floating point modes are not allowed to
     change size unless it's an insert into a complex mode.
     Therefore (subreg:DI (reg:DF) 0) and (subreg:CS (reg:SF) 0) are fine, but
     (subreg:SI (reg:DF) 0) isn't.  */
  else if ((FLOAT_MODE_P (imode) || FLOAT_MODE_P (omode))
	   && !COMPLEX_MODE_P (omode))
    {
      if (! (known_eq (isize, osize)
	     /* LRA can use subreg to store a floating point value in
		an integer mode.  Although the floating point and the
		integer modes need the same number of hard registers,
		the size of floating point mode can be less than the
		integer mode.  LRA also uses subregs for a register
		should be used in different mode in on insn.  */
	     || lra_in_progress))
	return false;
    }

  /* Paradoxical subregs must have offset zero.  */
  if (maybe_gt (osize, isize))
    return known_eq (offset, 0U);

  /* This is a normal subreg.  Verify that the offset is representable.  */

  /* For hard registers, we already have most of these rules collected in
     subreg_offset_representable_p.  */
  if (reg && REG_P (reg) && HARD_REGISTER_P (reg))
    {
      unsigned int regno = REGNO (reg);

      if ((COMPLEX_MODE_P (imode) || VECTOR_MODE_P (imode))
	  && GET_MODE_INNER (imode) == omode)
	;
      else if (!REG_CAN_CHANGE_MODE_P (regno, imode, omode))
	return false;

      return subreg_offset_representable_p (regno, imode, offset, omode);
    }
  /* Do not allow SUBREG with stricter alignment than the inner MEM.  */
  else if (reg && MEM_P (reg) && STRICT_ALIGNMENT
	   && MEM_ALIGN (reg) < GET_MODE_ALIGNMENT (omode))
    return false;

  /* The outer size must be ordered wrt the register size, otherwise
     we wouldn't know at compile time how many registers the outer
     mode occupies.  */
  if (!ordered_p (osize, regsize))
    return false;

  /* For pseudo registers, we want most of the same checks.  Namely:

     Assume that the pseudo register will be allocated to hard registers
     that can hold REGSIZE bytes each.  If OSIZE is not a multiple of REGSIZE,
     the remainder must correspond to the lowpart of the containing hard
     register.  If BYTES_BIG_ENDIAN, the lowpart is at the highest offset,
     otherwise it is at the lowest offset.

     Given that we've already checked the mode and offset alignment,
     we only have to check subblock subregs here.  */
  if (maybe_lt (osize, regsize)
      && ! (lra_in_progress && (FLOAT_MODE_P (imode) || FLOAT_MODE_P (omode))))
    {
      /* It is invalid for the target to pick a register size for a mode
	 that isn't ordered wrt to the size of that mode.  */
      poly_uint64 block_size = ordered_min (isize, regsize);
      unsigned int start_reg;
      poly_uint64 offset_within_reg;
      if (!can_div_trunc_p (offset, block_size, &start_reg, &offset_within_reg)
	  || (BYTES_BIG_ENDIAN
	      ? maybe_ne (offset_within_reg, block_size - osize)
	      : maybe_ne (offset_within_reg, 0U)))
	return false;
    }
  return true;
}

rtx
gen_rtx_SUBREG (machine_mode mode, rtx reg, poly_uint64 offset)
{
  gcc_assert (validate_subreg (mode, GET_MODE (reg), reg, offset));
  return gen_rtx_raw_SUBREG (mode, reg, offset);
}

/* Generate a SUBREG representing the least-significant part of REG if MODE
   is smaller than mode of REG, otherwise paradoxical SUBREG.  */

rtx
gen_lowpart_SUBREG (machine_mode mode, rtx reg)
{
  machine_mode inmode;

  inmode = GET_MODE (reg);
  if (inmode == VOIDmode)
    inmode = mode;
  return gen_rtx_SUBREG (mode, reg,
			 subreg_lowpart_offset (mode, inmode));
}

rtx
gen_rtx_VAR_LOCATION (machine_mode mode, tree decl, rtx loc,
		      enum var_init_status status)
{
  rtx x = gen_rtx_fmt_te (VAR_LOCATION, mode, decl, loc);
  PAT_VAR_LOCATION_STATUS (x) = status;
  return x;
}


/* Create an rtvec and stores within it the RTXen passed in the arguments.  */

rtvec
gen_rtvec (int n, ...)
{
  int i;
  rtvec rt_val;
  va_list p;

  va_start (p, n);

  /* Don't allocate an empty rtvec...  */
  if (n == 0)
    {
      va_end (p);
      return NULL_RTVEC;
    }

  rt_val = rtvec_alloc (n);

  for (i = 0; i < n; i++)
    rt_val->elem[i] = va_arg (p, rtx);

  va_end (p);
  return rt_val;
}

rtvec
gen_rtvec_v (int n, rtx *argp)
{
  int i;
  rtvec rt_val;

  /* Don't allocate an empty rtvec...  */
  if (n == 0)
    return NULL_RTVEC;

  rt_val = rtvec_alloc (n);

  for (i = 0; i < n; i++)
    rt_val->elem[i] = *argp++;

  return rt_val;
}

rtvec
gen_rtvec_v (int n, rtx_insn **argp)
{
  int i;
  rtvec rt_val;

  /* Don't allocate an empty rtvec...  */
  if (n == 0)
    return NULL_RTVEC;

  rt_val = rtvec_alloc (n);

  for (i = 0; i < n; i++)
    rt_val->elem[i] = *argp++;

  return rt_val;
}


/* Return the number of bytes between the start of an OUTER_MODE
   in-memory value and the start of an INNER_MODE in-memory value,
   given that the former is a lowpart of the latter.  It may be a
   paradoxical lowpart, in which case the offset will be negative
   on big-endian targets.  */

poly_int64
byte_lowpart_offset (machine_mode outer_mode,
		     machine_mode inner_mode)
{
  if (paradoxical_subreg_p (outer_mode, inner_mode))
    return -subreg_lowpart_offset (inner_mode, outer_mode);
  else
    return subreg_lowpart_offset (outer_mode, inner_mode);
}

/* Return the offset of (subreg:OUTER_MODE (mem:INNER_MODE X) OFFSET)
   from address X.  For paradoxical big-endian subregs this is a
   negative value, otherwise it's the same as OFFSET.  */

poly_int64
subreg_memory_offset (machine_mode outer_mode, machine_mode inner_mode,
		      poly_uint64 offset)
{
  if (paradoxical_subreg_p (outer_mode, inner_mode))
    {
      gcc_assert (known_eq (offset, 0U));
      return -subreg_lowpart_offset (inner_mode, outer_mode);
    }
  return offset;
}

/* As above, but return the offset that existing subreg X would have
   if SUBREG_REG (X) were stored in memory.  The only significant thing
   about the current SUBREG_REG is its mode.  */

poly_int64
subreg_memory_offset (const_rtx x)
{
  return subreg_memory_offset (GET_MODE (x), GET_MODE (SUBREG_REG (x)),
			       SUBREG_BYTE (x));
}

/* Generate a REG rtx for a new pseudo register of mode MODE.
   This pseudo is assigned the next sequential register number.  */

rtx
gen_reg_rtx (machine_mode mode)
{
  rtx val;
  unsigned int align = GET_MODE_ALIGNMENT (mode);

  gcc_assert (can_create_pseudo_p ());

  /* If a virtual register with bigger mode alignment is generated,
     increase stack alignment estimation because it might be spilled
     to stack later.  */
  if (SUPPORTS_STACK_ALIGNMENT
      && crtl->stack_alignment_estimated < align
      && !crtl->stack_realign_processed)
    {
      unsigned int min_align = MINIMUM_ALIGNMENT (NULL, mode, align);
      if (crtl->stack_alignment_estimated < min_align)
	crtl->stack_alignment_estimated = min_align;
    }

  if (generating_concat_p
      && (GET_MODE_CLASS (mode) == MODE_COMPLEX_FLOAT
	  || GET_MODE_CLASS (mode) == MODE_COMPLEX_INT))
    {
      /* For complex modes, don't make a single pseudo.
	 Instead, make a CONCAT of two pseudos.
	 This allows noncontiguous allocation of the real and imaginary parts,
	 which makes much better code.  Besides, allocating DCmode
	 pseudos overstrains reload on some machines like the 386.  */
      rtx realpart, imagpart;
      machine_mode partmode = GET_MODE_INNER (mode);

      realpart = gen_reg_rtx (partmode);
      imagpart = gen_reg_rtx (partmode);
      return gen_rtx_CONCAT (mode, realpart, imagpart);
    }

  /* Do not call gen_reg_rtx with uninitialized crtl.  */
  gcc_assert (crtl->emit.regno_pointer_align_length);

  crtl->emit.ensure_regno_capacity ();
  gcc_assert (reg_rtx_no < crtl->emit.regno_pointer_align_length);

  val = gen_raw_REG (mode, reg_rtx_no);
  regno_reg_rtx[reg_rtx_no++] = val;
  return val;
}

/* Make sure m_regno_pointer_align, and regno_reg_rtx are large
   enough to have elements in the range 0 <= idx <= reg_rtx_no.  */

void
emit_status::ensure_regno_capacity ()
{
  int old_size = regno_pointer_align_length;

  if (reg_rtx_no < old_size)
    return;

  int new_size = old_size * 2;
  while (reg_rtx_no >= new_size)
    new_size *= 2;

  char *tmp = XRESIZEVEC (char, regno_pointer_align, new_size);
  memset (tmp + old_size, 0, new_size - old_size);
  regno_pointer_align = (unsigned char *) tmp;

  rtx *new1 = GGC_RESIZEVEC (rtx, regno_reg_rtx, new_size);
  memset (new1 + old_size, 0, (new_size - old_size) * sizeof (rtx));
  regno_reg_rtx = new1;

  crtl->emit.regno_pointer_align_length = new_size;
}

/* Return TRUE if REG is a PARM_DECL, FALSE otherwise.  */

bool
reg_is_parm_p (rtx reg)
{
  tree decl;

  gcc_assert (REG_P (reg));
  decl = REG_EXPR (reg);
  return (decl && TREE_CODE (decl) == PARM_DECL);
}

/* Update NEW with the same attributes as REG, but with OFFSET added
   to the REG_OFFSET.  */

static void
update_reg_offset (rtx new_rtx, rtx reg, poly_int64 offset)
{
  REG_ATTRS (new_rtx) = get_reg_attrs (REG_EXPR (reg),
				       REG_OFFSET (reg) + offset);
}

/* Generate a register with same attributes as REG, but with OFFSET
   added to the REG_OFFSET.  */

rtx
gen_rtx_REG_offset (rtx reg, machine_mode mode, unsigned int regno,
		    poly_int64 offset)
{
  /* Use gen_raw_REG rather than gen_rtx_REG, because otherwise we'd
     overwrite REG_ATTRS (and in the callers often ORIGINAL_REGNO too)
     of the shared REG rtxes like stack_pointer_rtx etc.  This should
     happen only for SUBREGs from DEBUG_INSNs, RA should ensure
     multi-word registers don't overlap the special registers like
     stack pointer.  */
  rtx new_rtx = gen_raw_REG (mode, regno);

  update_reg_offset (new_rtx, reg, offset);
  return new_rtx;
}

/* Generate a new pseudo-register with the same attributes as REG, but
   with OFFSET added to the REG_OFFSET.  */

rtx
gen_reg_rtx_offset (rtx reg, machine_mode mode, int offset)
{
  rtx new_rtx = gen_reg_rtx (mode);

  update_reg_offset (new_rtx, reg, offset);
  return new_rtx;
}

/* Adjust REG in-place so that it has mode MODE.  It is assumed that the
   new register is a (possibly paradoxical) lowpart of the old one.  */

void
adjust_reg_mode (rtx reg, machine_mode mode)
{
  update_reg_offset (reg, reg, byte_lowpart_offset (mode, GET_MODE (reg)));
  PUT_MODE (reg, mode);
}

/* Copy REG's attributes from X, if X has any attributes.  If REG and X
   have different modes, REG is a (possibly paradoxical) lowpart of X.  */

void
set_reg_attrs_from_value (rtx reg, rtx x)
{
  poly_int64 offset;
  bool can_be_reg_pointer = true;

  /* Don't call mark_reg_pointer for incompatible pointer sign
     extension.  */
  while (GET_CODE (x) == SIGN_EXTEND
	 || GET_CODE (x) == ZERO_EXTEND
	 || GET_CODE (x) == TRUNCATE
	 || (GET_CODE (x) == SUBREG && subreg_lowpart_p (x)))
    {
#if defined(POINTERS_EXTEND_UNSIGNED)
      if (((GET_CODE (x) == SIGN_EXTEND && POINTERS_EXTEND_UNSIGNED)
	   || (GET_CODE (x) == ZERO_EXTEND && ! POINTERS_EXTEND_UNSIGNED)
	   || (paradoxical_subreg_p (x)
	       && ! (SUBREG_PROMOTED_VAR_P (x)
		     && SUBREG_CHECK_PROMOTED_SIGN (x,
						    POINTERS_EXTEND_UNSIGNED))))
	  && !targetm.have_ptr_extend ())
	can_be_reg_pointer = false;
#endif
      x = XEXP (x, 0);
    }

  /* Hard registers can be reused for multiple purposes within the same
     function, so setting REG_ATTRS, REG_POINTER and REG_POINTER_ALIGN
     on them is wrong.  */
  if (HARD_REGISTER_P (reg))
    return;

  offset = byte_lowpart_offset (GET_MODE (reg), GET_MODE (x));
  if (MEM_P (x))
    {
      if (MEM_OFFSET_KNOWN_P (x))
	REG_ATTRS (reg) = get_reg_attrs (MEM_EXPR (x),
					 MEM_OFFSET (x) + offset);
      if (can_be_reg_pointer && MEM_POINTER (x))
	mark_reg_pointer (reg, 0);
    }
  else if (REG_P (x))
    {
      if (REG_ATTRS (x))
	update_reg_offset (reg, x, offset);
      if (can_be_reg_pointer && REG_POINTER (x))
	mark_reg_pointer (reg, REGNO_POINTER_ALIGN (REGNO (x)));
    }
}

/* Generate a REG rtx for a new pseudo register, copying the mode
   and attributes from X.  */

rtx
gen_reg_rtx_and_attrs (rtx x)
{
  rtx reg = gen_reg_rtx (GET_MODE (x));
  set_reg_attrs_from_value (reg, x);
  return reg;
}

/* Set the register attributes for registers contained in PARM_RTX.
   Use needed values from memory attributes of MEM.  */

void
set_reg_attrs_for_parm (rtx parm_rtx, rtx mem)
{
  if (REG_P (parm_rtx))
    set_reg_attrs_from_value (parm_rtx, mem);
  else if (GET_CODE (parm_rtx) == PARALLEL)
    {
      /* Check for a NULL entry in the first slot, used to indicate that the
	 parameter goes both on the stack and in registers.  */
      int i = XEXP (XVECEXP (parm_rtx, 0, 0), 0) ? 0 : 1;
      for (; i < XVECLEN (parm_rtx, 0); i++)
	{
	  rtx x = XVECEXP (parm_rtx, 0, i);
	  if (REG_P (XEXP (x, 0)))
	    REG_ATTRS (XEXP (x, 0))
	      = get_reg_attrs (MEM_EXPR (mem),
			       INTVAL (XEXP (x, 1)));
	}
    }
}

/* Set the REG_ATTRS for registers in value X, given that X represents
   decl T.  */

void
set_reg_attrs_for_decl_rtl (tree t, rtx x)
{
  if (!t)
    return;
  tree tdecl = t;
  if (GET_CODE (x) == SUBREG)
    {
      gcc_assert (subreg_lowpart_p (x));
      x = SUBREG_REG (x);
    }
  if (REG_P (x))
    REG_ATTRS (x)
      = get_reg_attrs (t, byte_lowpart_offset (GET_MODE (x),
					       DECL_P (tdecl)
					       ? DECL_MODE (tdecl)
					       : TYPE_MODE (TREE_TYPE (tdecl))));
  if (GET_CODE (x) == CONCAT)
    {
      if (REG_P (XEXP (x, 0)))
        REG_ATTRS (XEXP (x, 0)) = get_reg_attrs (t, 0);
      if (REG_P (XEXP (x, 1)))
	REG_ATTRS (XEXP (x, 1))
	  = get_reg_attrs (t, GET_MODE_UNIT_SIZE (GET_MODE (XEXP (x, 0))));
    }
  if (GET_CODE (x) == PARALLEL)
    {
      int i, start;

      /* Check for a NULL entry, used to indicate that the parameter goes
	 both on the stack and in registers.  */
      if (XEXP (XVECEXP (x, 0, 0), 0))
	start = 0;
      else
	start = 1;

      for (i = start; i < XVECLEN (x, 0); i++)
	{
	  rtx y = XVECEXP (x, 0, i);
	  if (REG_P (XEXP (y, 0)))
	    REG_ATTRS (XEXP (y, 0)) = get_reg_attrs (t, INTVAL (XEXP (y, 1)));
	}
    }
}

/* Assign the RTX X to declaration T.  */

void
set_decl_rtl (tree t, rtx x)
{
  DECL_WRTL_CHECK (t)->decl_with_rtl.rtl = x;
  if (x)
    set_reg_attrs_for_decl_rtl (t, x);
}

/* Assign the RTX X to parameter declaration T.  BY_REFERENCE_P is true
   if the ABI requires the parameter to be passed by reference.  */

void
set_decl_incoming_rtl (tree t, rtx x, bool by_reference_p)
{
  DECL_INCOMING_RTL (t) = x;
  if (x && !by_reference_p)
    set_reg_attrs_for_decl_rtl (t, x);
}

/* Identify REG (which may be a CONCAT) as a user register.  */

void
mark_user_reg (rtx reg)
{
  if (GET_CODE (reg) == CONCAT)
    {
      REG_USERVAR_P (XEXP (reg, 0)) = 1;
      REG_USERVAR_P (XEXP (reg, 1)) = 1;
    }
  else
    {
      gcc_assert (REG_P (reg));
      REG_USERVAR_P (reg) = 1;
    }
}

/* Identify REG as a probable pointer register and show its alignment
   as ALIGN, if nonzero.  */

void
mark_reg_pointer (rtx reg, int align)
{
  if (! REG_POINTER (reg))
    {
      REG_POINTER (reg) = 1;

      if (align)
	REGNO_POINTER_ALIGN (REGNO (reg)) = align;
    }
  else if (align && align < REGNO_POINTER_ALIGN (REGNO (reg)))
    /* We can no-longer be sure just how aligned this pointer is.  */
    REGNO_POINTER_ALIGN (REGNO (reg)) = align;
}

/* Return 1 plus largest pseudo reg number used in the current function.  */

int
max_reg_num (void)
{
  return reg_rtx_no;
}

/* Return 1 + the largest label number used so far in the current function.  */

int
max_label_num (void)
{
  return label_num;
}

/* Return first label number used in this function (if any were used).  */

int
get_first_label_num (void)
{
  return first_label_num;
}

/* If the rtx for label was created during the expansion of a nested
   function, then first_label_num won't include this label number.
   Fix this now so that array indices work later.  */

void
maybe_set_first_label_num (rtx_code_label *x)
{
  if (CODE_LABEL_NUMBER (x) < first_label_num)
    first_label_num = CODE_LABEL_NUMBER (x);
}

/* For use by the RTL function loader, when mingling with normal
   functions.
   Ensure that label_num is greater than the label num of X, to avoid
   duplicate labels in the generated assembler.  */

void
maybe_set_max_label_num (rtx_code_label *x)
{
  if (CODE_LABEL_NUMBER (x) >= label_num)
    label_num = CODE_LABEL_NUMBER (x) + 1;
}


/* Return a value representing some low-order bits of X, where the number
   of low-order bits is given by MODE.  Note that no conversion is done
   between floating-point and fixed-point values, rather, the bit
   representation is returned.

   This function handles the cases in common between gen_lowpart, below,
   and two variants in cse.cc and combine.cc.  These are the cases that can
   be safely handled at all points in the compilation.

   If this is not a case we can handle, return 0.  */

rtx
gen_lowpart_common (machine_mode mode, rtx x)
{
  poly_uint64 msize = GET_MODE_SIZE (mode);
  machine_mode innermode;

  /* Unfortunately, this routine doesn't take a parameter for the mode of X,
     so we have to make one up.  Yuk.  */
  innermode = GET_MODE (x);
  if (CONST_INT_P (x)
      && known_le (msize * BITS_PER_UNIT,
		   (unsigned HOST_WIDE_INT) HOST_BITS_PER_WIDE_INT))
    innermode = int_mode_for_size (HOST_BITS_PER_WIDE_INT, 0).require ();
  else if (innermode == VOIDmode)
    innermode = int_mode_for_size (HOST_BITS_PER_DOUBLE_INT, 0).require ();

  gcc_assert (innermode != VOIDmode && innermode != BLKmode);

  if (innermode == mode)
    return x;

  /* The size of the outer and inner modes must be ordered.  */
  poly_uint64 xsize = GET_MODE_SIZE (innermode);
  if (!ordered_p (msize, xsize))
    return 0;

  if (SCALAR_FLOAT_MODE_P (mode))
    {
      /* Don't allow paradoxical FLOAT_MODE subregs.  */
      if (maybe_gt (msize, xsize))
	return 0;
    }
  else
    {
      /* MODE must occupy no more of the underlying registers than X.  */
      poly_uint64 regsize = REGMODE_NATURAL_SIZE (innermode);
      unsigned int mregs, xregs;
      if (!can_div_away_from_zero_p (msize, regsize, &mregs)
	  || !can_div_away_from_zero_p (xsize, regsize, &xregs)
	  || mregs > xregs)
	return 0;
    }

  scalar_int_mode int_mode, int_innermode, from_mode;
  if ((GET_CODE (x) == ZERO_EXTEND || GET_CODE (x) == SIGN_EXTEND)
      && is_a <scalar_int_mode> (mode, &int_mode)
      && is_a <scalar_int_mode> (innermode, &int_innermode)
      && is_a <scalar_int_mode> (GET_MODE (XEXP (x, 0)), &from_mode))
    {
      /* If we are getting the low-order part of something that has been
	 sign- or zero-extended, we can either just use the object being
	 extended or make a narrower extension.  If we want an even smaller
	 piece than the size of the object being extended, call ourselves
	 recursively.

	 This case is used mostly by combine and cse.  */

      if (from_mode == int_mode)
	return XEXP (x, 0);
      else if (GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (from_mode))
	return gen_lowpart_common (int_mode, XEXP (x, 0));
      else if (GET_MODE_SIZE (int_mode) < GET_MODE_SIZE (int_innermode))
	return gen_rtx_fmt_e (GET_CODE (x), int_mode, XEXP (x, 0));
    }
  else if (GET_CODE (x) == SUBREG || REG_P (x)
	   || GET_CODE (x) == CONCAT || GET_CODE (x) == CONST_VECTOR
	   || CONST_DOUBLE_AS_FLOAT_P (x) || CONST_SCALAR_INT_P (x)
	   || CONST_POLY_INT_P (x))
    return lowpart_subreg (mode, x, innermode);

  /* Otherwise, we can't do this.  */
  return 0;
}

rtx
gen_highpart (machine_mode mode, rtx x)
{
  poly_uint64 msize = GET_MODE_SIZE (mode);
  rtx result;

  /* This case loses if X is a subreg.  To catch bugs early,
     complain if an invalid MODE is used even in other cases.  */
  gcc_assert (known_le (msize, (unsigned int) UNITS_PER_WORD)
	      || known_eq (msize, GET_MODE_UNIT_SIZE (GET_MODE (x))));

  /* gen_lowpart_common handles a lot of special cases due to needing to handle
     paradoxical subregs; it only calls simplify_gen_subreg when certain that
     it will produce something meaningful.  The only case we need to handle
     specially here is MEM.  */
  if (MEM_P (x))
    {
      poly_int64 offset = subreg_highpart_offset (mode, GET_MODE (x));
      return adjust_address (x, mode, offset);
    }

  result = simplify_gen_subreg (mode, x, GET_MODE (x),
				subreg_highpart_offset (mode, GET_MODE (x)));
  /* Since we handle MEM directly above, we should never get a MEM back
     from simplify_gen_subreg.  */
  gcc_assert (result && !MEM_P (result));

  return result;
}

/* Like gen_highpart, but accept mode of EXP operand in case EXP can
   be VOIDmode constant.  */
rtx
gen_highpart_mode (machine_mode outermode, machine_mode innermode, rtx exp)
{
  if (GET_MODE (exp) != VOIDmode)
    {
      gcc_assert (GET_MODE (exp) == innermode);
      return gen_highpart (outermode, exp);
    }
  return simplify_gen_subreg (outermode, exp, innermode,
			      subreg_highpart_offset (outermode, innermode));
}

/* Return the SUBREG_BYTE for a lowpart subreg whose outer mode has
   OUTER_BYTES bytes and whose inner mode has INNER_BYTES bytes.  */

poly_uint64
subreg_size_lowpart_offset (poly_uint64 outer_bytes, poly_uint64 inner_bytes)
{
  gcc_checking_assert (ordered_p (outer_bytes, inner_bytes));
  if (maybe_gt (outer_bytes, inner_bytes))
    /* Paradoxical subregs always have a SUBREG_BYTE of 0.  */
    return 0;

  if (BYTES_BIG_ENDIAN && WORDS_BIG_ENDIAN)
    return inner_bytes - outer_bytes;
  else if (!BYTES_BIG_ENDIAN && !WORDS_BIG_ENDIAN)
    return 0;
  else
    return subreg_size_offset_from_lsb (outer_bytes, inner_bytes, 0);
}

/* Return the SUBREG_BYTE for a highpart subreg whose outer mode has
   OUTER_BYTES bytes and whose inner mode has INNER_BYTES bytes.  */

poly_uint64
subreg_size_highpart_offset (poly_uint64 outer_bytes, poly_uint64 inner_bytes)
{
  gcc_assert (known_ge (inner_bytes, outer_bytes));

  if (BYTES_BIG_ENDIAN && WORDS_BIG_ENDIAN)
    return 0;
  else if (!BYTES_BIG_ENDIAN && !WORDS_BIG_ENDIAN)
    return inner_bytes - outer_bytes;
  else
    return subreg_size_offset_from_lsb (outer_bytes, inner_bytes,
					(inner_bytes - outer_bytes)
					* BITS_PER_UNIT);
}

/* Return true iff X, assumed to be a SUBREG,
   refers to the least significant part of its containing reg.
   If X is not a SUBREG, always return true (it is its own low part!).  */

bool
subreg_lowpart_p (const_rtx x)
{
  if (GET_CODE (x) != SUBREG)
    return true;
  else if (GET_MODE (SUBREG_REG (x)) == VOIDmode)
    return false;

  return known_eq (subreg_lowpart_offset (GET_MODE (x),
					  GET_MODE (SUBREG_REG (x))),
		   SUBREG_BYTE (x));
}

/* Return subword OFFSET of operand OP.
   The word number, OFFSET, is interpreted as the word number starting
   at the low-order address.  OFFSET 0 is the low-order word if not
   WORDS_BIG_ENDIAN, otherwise it is the high-order word.

   If we cannot extract the required word, we return zero.  Otherwise,
   an rtx corresponding to the requested word will be returned.

   VALIDATE_ADDRESS is nonzero if the address should be validated.  Before
   reload has completed, a valid address will always be returned.  After
   reload, if a valid address cannot be returned, we return zero.

   If VALIDATE_ADDRESS is zero, we simply form the required address; validating
   it is the responsibility of the caller.

   MODE is the mode of OP in case it is a CONST_INT.

   ??? This is still rather broken for some cases.  The problem for the
   moment is that all callers of this thing provide no 'goal mode' to
   tell us to work with.  This exists because all callers were written
   in a word based SUBREG world.
   Now use of this function can be deprecated by simplify_subreg in most
   cases.
 */

rtx
operand_subword (rtx op, poly_uint64 offset, int validate_address,
		 machine_mode mode)
{
  if (mode == VOIDmode)
    mode = GET_MODE (op);

  gcc_assert (mode != VOIDmode);

  /* If OP is narrower than a word, fail.  */
  if (mode != BLKmode
      && maybe_lt (GET_MODE_SIZE (mode), UNITS_PER_WORD))
    return 0;

  /* If we want a word outside OP, return zero.  */
  if (mode != BLKmode
      && maybe_gt ((offset + 1) * UNITS_PER_WORD, GET_MODE_SIZE (mode)))
    return const0_rtx;

  /* Form a new MEM at the requested address.  */
  if (MEM_P (op))
    {
      rtx new_rtx = adjust_address_nv (op, word_mode, offset * UNITS_PER_WORD);

      if (! validate_address)
	return new_rtx;

      else if (reload_completed)
	{
	  if (! strict_memory_address_addr_space_p (word_mode,
						    XEXP (new_rtx, 0),
						    MEM_ADDR_SPACE (op)))
	    return 0;
	}
      else
	return replace_equiv_address (new_rtx, XEXP (new_rtx, 0));
    }

  /* Rest can be handled by simplify_subreg.  */
  return simplify_gen_subreg (word_mode, op, mode, (offset * UNITS_PER_WORD));
}

/* Similar to `operand_subword', but never return 0.  If we can't
   extract the required subword, put OP into a register and try again.
   The second attempt must succeed.  We always validate the address in
   this case.

   MODE is the mode of OP, in case it is CONST_INT.  */

rtx
operand_subword_force (rtx op, poly_uint64 offset, machine_mode mode)
{
  rtx result = operand_subword (op, offset, 1, mode);

  if (result)
    return result;

  if (mode != BLKmode && mode != VOIDmode)
    {
      /* If this is a register which cannot be accessed by words, copy it
	 to a pseudo register.  */
      if (REG_P (op))
	op = copy_to_reg (op);
      else
	op = force_reg (mode, op);
    }

  result = operand_subword (op, offset, 1, mode);
  gcc_assert (result);

  return result;
}

mem_attrs::mem_attrs ()
  : expr (NULL_TREE),
    offset (0),
    size (0),
    alias (0),
    align (0),
    addrspace (ADDR_SPACE_GENERIC),
    offset_known_p (false),
    size_known_p (false)
{}

/* Returns true if both MEM_EXPR can be considered equal
   and false otherwise.  */

bool
mem_expr_equal_p (const_tree expr1, const_tree expr2)
{
  if (expr1 == expr2)
    return true;

  if (! expr1 || ! expr2)
    return false;

  if (TREE_CODE (expr1) != TREE_CODE (expr2))
    return false;

  return operand_equal_p (expr1, expr2, 0);
}

/* Return OFFSET if XEXP (MEM, 0) - OFFSET is known to be ALIGN
   bits aligned for 0 <= OFFSET < ALIGN / BITS_PER_UNIT, or
   -1 if not known.  */

int
get_mem_align_offset (rtx mem, unsigned int align)
{
  tree expr;
  poly_uint64 offset;

  /* This function can't use
     if (!MEM_EXPR (mem) || !MEM_OFFSET_KNOWN_P (mem)
	 || (MAX (MEM_ALIGN (mem),
	          MAX (align, get_object_alignment (MEM_EXPR (mem))))
	     < align))
       return -1;
     else
       return (- MEM_OFFSET (mem)) & (align / BITS_PER_UNIT - 1);
     for two reasons:
     - COMPONENT_REFs in MEM_EXPR can have NULL first operand,
       for <variable>.  get_inner_reference doesn't handle it and
       even if it did, the alignment in that case needs to be determined
       from DECL_FIELD_CONTEXT's TYPE_ALIGN.
     - it would do suboptimal job for COMPONENT_REFs, even if MEM_EXPR
       isn't sufficiently aligned, the object it is in might be.  */
  gcc_assert (MEM_P (mem));
  expr = MEM_EXPR (mem);
  if (expr == NULL_TREE || !MEM_OFFSET_KNOWN_P (mem))
    return -1;

  offset = MEM_OFFSET (mem);
  if (DECL_P (expr))
    {
      if (DECL_ALIGN (expr) < align)
	return -1;
    }
  else if (INDIRECT_REF_P (expr))
    {
      if (TYPE_ALIGN (TREE_TYPE (expr)) < (unsigned int) align)
	return -1;
    }
  else if (TREE_CODE (expr) == COMPONENT_REF)
    {
      while (1)
	{
	  tree inner = TREE_OPERAND (expr, 0);
	  tree field = TREE_OPERAND (expr, 1);
	  tree byte_offset = component_ref_field_offset (expr);
	  tree bit_offset = DECL_FIELD_BIT_OFFSET (field);

	  poly_uint64 suboffset;
	  if (!byte_offset
	      || !poly_int_tree_p (byte_offset, &suboffset)
	      || !tree_fits_uhwi_p (bit_offset))
	    return -1;

	  offset += suboffset;
	  offset += tree_to_uhwi (bit_offset) / BITS_PER_UNIT;

	  if (inner == NULL_TREE)
	    {
	      if (TYPE_ALIGN (DECL_FIELD_CONTEXT (field))
		  < (unsigned int) align)
		return -1;
	      break;
	    }
	  else if (DECL_P (inner))
	    {
	      if (DECL_ALIGN (inner) < align)
		return -1;
	      break;
	    }
	  else if (TREE_CODE (inner) != COMPONENT_REF)
	    return -1;
	  expr = inner;
	}
    }
  else
    return -1;

  HOST_WIDE_INT misalign;
  if (!known_misalignment (offset, align / BITS_PER_UNIT, &misalign))
    return -1;
  return misalign;
}

/* Given REF (a MEM) and T, either the type of X or the expression
   corresponding to REF, set the memory attributes.  OBJECTP is nonzero
   if we are making a new object of this type.  BITPOS is nonzero if
   there is an offset outstanding on T that will be applied later.  */

void
set_mem_attributes_minus_bitpos (rtx ref, tree t, int objectp,
				 poly_int64 bitpos)
{
  poly_int64 apply_bitpos = 0;
  tree type;
  class mem_attrs attrs, *defattrs, *refattrs;
  addr_space_t as;

  /* It can happen that type_for_mode was given a mode for which there
     is no language-level type.  In which case it returns NULL, which
     we can see here.  */
  if (t == NULL_TREE)
    return;

  type = TYPE_P (t) ? t : TREE_TYPE (t);
  if (type == error_mark_node)
    return;

  /* If we have already set DECL_RTL = ref, get_alias_set will get the
     wrong answer, as it assumes that DECL_RTL already has the right alias
     info.  Callers should not set DECL_RTL until after the call to
     set_mem_attributes.  */
  gcc_assert (!DECL_P (t) || ref != DECL_RTL_IF_SET (t));

  /* Get the alias set from the expression or type (perhaps using a
     front-end routine) and use it.  */
  attrs.alias = get_alias_set (t);

  MEM_VOLATILE_P (ref) |= TYPE_VOLATILE (type);
  MEM_POINTER (ref) = POINTER_TYPE_P (type);

  /* Default values from pre-existing memory attributes if present.  */
  refattrs = MEM_ATTRS (ref);
  if (refattrs)
    {
      /* ??? Can this ever happen?  Calling this routine on a MEM that
	 already carries memory attributes should probably be invalid.  */
      attrs.expr = refattrs->expr;
      attrs.offset_known_p = refattrs->offset_known_p;
      attrs.offset = refattrs->offset;
      attrs.size_known_p = refattrs->size_known_p;
      attrs.size = refattrs->size;
      attrs.align = refattrs->align;
    }

  /* Otherwise, default values from the mode of the MEM reference.  */
  else
    {
      defattrs = mode_mem_attrs[(int) GET_MODE (ref)];
      gcc_assert (!defattrs->expr);
      gcc_assert (!defattrs->offset_known_p);

      /* Respect mode size.  */
      attrs.size_known_p = defattrs->size_known_p;
      attrs.size = defattrs->size;
      /* ??? Is this really necessary?  We probably should always get
	 the size from the type below.  */

      /* Respect mode alignment for STRICT_ALIGNMENT targets if T is a type;
         if T is an object, always compute the object alignment below.  */
      if (TYPE_P (t))
	attrs.align = defattrs->align;
      else
	attrs.align = BITS_PER_UNIT;
      /* ??? If T is a type, respecting mode alignment may *also* be wrong
	 e.g. if the type carries an alignment attribute.  Should we be
	 able to simply always use TYPE_ALIGN?  */
    }

  /* We can set the alignment from the type if we are making an object or if
     this is an INDIRECT_REF.  */
  if (objectp || TREE_CODE (t) == INDIRECT_REF)
    attrs.align = MAX (attrs.align, TYPE_ALIGN (type));

  /* If the size is known, we can set that.  */
  tree new_size = TYPE_SIZE_UNIT (type);

  /* The address-space is that of the type.  */
  as = TYPE_ADDR_SPACE (type);

  /* If T is not a type, we may be able to deduce some more information about
     the expression.  */
  if (! TYPE_P (t))
    {
      tree base;

      if (TREE_THIS_VOLATILE (t))
	MEM_VOLATILE_P (ref) = 1;

      /* Now remove any conversions: they don't change what the underlying
	 object is.  Likewise for SAVE_EXPR.  */
      while (CONVERT_EXPR_P (t)
	     || TREE_CODE (t) == VIEW_CONVERT_EXPR
	     || TREE_CODE (t) == SAVE_EXPR)
	t = TREE_OPERAND (t, 0);

      /* Note whether this expression can trap.  */
      MEM_NOTRAP_P (ref) = !tree_could_trap_p (t);

      base = get_base_address (t);
      if (base)
	{
	  if (DECL_P (base)
	      && TREE_READONLY (base)
	      && (TREE_STATIC (base) || DECL_EXTERNAL (base))
	      && !TREE_THIS_VOLATILE (base))
	    MEM_READONLY_P (ref) = 1;

	  /* Mark static const strings readonly as well.  */
	  if (TREE_CODE (base) == STRING_CST
	      && TREE_READONLY (base)
	      && TREE_STATIC (base))
	    MEM_READONLY_P (ref) = 1;

	  /* Address-space information is on the base object.  */
	  if (TREE_CODE (base) == MEM_REF
	      || TREE_CODE (base) == TARGET_MEM_REF)
	    as = TYPE_ADDR_SPACE (TREE_TYPE (TREE_TYPE (TREE_OPERAND (base,
								      0))));
	  else
	    as = TYPE_ADDR_SPACE (TREE_TYPE (base));
	}

      /* If this expression uses it's parent's alias set, mark it such
	 that we won't change it.  */
      if (component_uses_parent_alias_set_from (t) != NULL_TREE)
	MEM_KEEP_ALIAS_SET_P (ref) = 1;

      /* If this is a decl, set the attributes of the MEM from it.  */
      if (DECL_P (t))
	{
	  attrs.expr = t;
	  attrs.offset_known_p = true;
	  attrs.offset = 0;
	  apply_bitpos = bitpos;
	  new_size = DECL_SIZE_UNIT (t);
	}

      /* ???  If we end up with a constant or a descriptor do not
	 record a MEM_EXPR.  */
      else if (CONSTANT_CLASS_P (t)
	       || TREE_CODE (t) == CONSTRUCTOR)
	;

      /* If this is a field reference, record it.  */
      else if (TREE_CODE (t) == COMPONENT_REF)
	{
	  attrs.expr = t;
	  attrs.offset_known_p = true;
	  attrs.offset = 0;
	  apply_bitpos = bitpos;
	  if (DECL_BIT_FIELD (TREE_OPERAND (t, 1)))
	    new_size = DECL_SIZE_UNIT (TREE_OPERAND (t, 1));
	}

      /* Else record it.  */
      else
	{
	  gcc_assert (handled_component_p (t)
		      || TREE_CODE (t) == MEM_REF
		      || TREE_CODE (t) == TARGET_MEM_REF);
	  attrs.expr = t;
	  attrs.offset_known_p = true;
	  attrs.offset = 0;
	  apply_bitpos = bitpos;
	}

      /* If this is a reference based on a partitioned decl replace the
	 base with a MEM_REF of the pointer representative we created
	 during stack slot partitioning.  */
      if (attrs.expr
	  && VAR_P (base)
	  && ! is_global_var (base)
	  && cfun->gimple_df->decls_to_pointers != NULL)
	{
	  tree *namep = cfun->gimple_df->decls_to_pointers->get (base);
	  if (namep)
	    {
	      attrs.expr = unshare_expr (attrs.expr);
	      tree *orig_base = &attrs.expr;
	      while (handled_component_p (*orig_base))
		orig_base = &TREE_OPERAND (*orig_base, 0);
	      if (TREE_CODE (*orig_base) == MEM_REF
		  || TREE_CODE (*orig_base) == TARGET_MEM_REF)
		TREE_OPERAND (*orig_base, 0) = *namep;
	      else
		{
		  tree aptrt = reference_alias_ptr_type (*orig_base);
		  *orig_base = build2 (MEM_REF, TREE_TYPE (*orig_base),
				       *namep, build_int_cst (aptrt, 0));
		}
	    }
	}

      /* Compute the alignment.  */
      unsigned int obj_align;
      unsigned HOST_WIDE_INT obj_bitpos;
      get_object_alignment_1 (t, &obj_align, &obj_bitpos);
      unsigned int diff_align = known_alignment (obj_bitpos - bitpos);
      if (diff_align != 0)
	obj_align = MIN (obj_align, diff_align);
      attrs.align = MAX (attrs.align, obj_align);
    }

  poly_uint64 const_size;
  if (poly_int_tree_p (new_size, &const_size))
    {
      attrs.size_known_p = true;
      attrs.size = const_size;
    }

  /* If we modified OFFSET based on T, then subtract the outstanding
     bit position offset.  Similarly, increase the size of the accessed
     object to contain the negative offset.  */
  if (maybe_ne (apply_bitpos, 0))
    {
      gcc_assert (attrs.offset_known_p);
      poly_int64 bytepos = bits_to_bytes_round_down (apply_bitpos);
      attrs.offset -= bytepos;
      if (attrs.size_known_p)
	attrs.size += bytepos;
    }

  /* Now set the attributes we computed above.  */
  attrs.addrspace = as;
  set_mem_attrs (ref, &attrs);
}

void
set_mem_attributes (rtx ref, tree t, int objectp)
{
  set_mem_attributes_minus_bitpos (ref, t, objectp, 0);
}

/* Set the alias set of MEM to SET.  */

void
set_mem_alias_set (rtx mem, alias_set_type set)
{
  /* If the new and old alias sets don't conflict, something is wrong.  */
  gcc_checking_assert (alias_sets_conflict_p (set, MEM_ALIAS_SET (mem)));
  mem_attrs attrs (*get_mem_attrs (mem));
  attrs.alias = set;
  set_mem_attrs (mem, &attrs);
}

/* Set the address space of MEM to ADDRSPACE (target-defined).  */

void
set_mem_addr_space (rtx mem, addr_space_t addrspace)
{
  mem_attrs attrs (*get_mem_attrs (mem));
  attrs.addrspace = addrspace;
  set_mem_attrs (mem, &attrs);
}

/* Set the alignment of MEM to ALIGN bits.  */

void
set_mem_align (rtx mem, unsigned int align)
{
  mem_attrs attrs (*get_mem_attrs (mem));
  attrs.align = align;
  set_mem_attrs (mem, &attrs);
}

/* Set the expr for MEM to EXPR.  */

void
set_mem_expr (rtx mem, tree expr)
{
  mem_attrs attrs (*get_mem_attrs (mem));
  attrs.expr = expr;
  set_mem_attrs (mem, &attrs);
}

/* Set the offset of MEM to OFFSET.  */

void
set_mem_offset (rtx mem, poly_int64 offset)
{
  mem_attrs attrs (*get_mem_attrs (mem));
  attrs.offset_known_p = true;
  attrs.offset = offset;
  set_mem_attrs (mem, &attrs);
}

/* Clear the offset of MEM.  */

void
clear_mem_offset (rtx mem)
{
  mem_attrs attrs (*get_mem_attrs (mem));
  attrs.offset_known_p = false;
  set_mem_attrs (mem, &attrs);
}

/* Set the size of MEM to SIZE.  */

void
set_mem_size (rtx mem, poly_int64 size)
{
  mem_attrs attrs (*get_mem_attrs (mem));
  attrs.size_known_p = true;
  attrs.size = size;
  set_mem_attrs (mem, &attrs);
}

/* Clear the size of MEM.  */

void
clear_mem_size (rtx mem)
{
  mem_attrs attrs (*get_mem_attrs (mem));
  attrs.size_known_p = false;
  set_mem_attrs (mem, &attrs);
}

/* Return a memory reference like MEMREF, but with its mode changed to MODE
   and its address changed to ADDR.  (VOIDmode means don't change the mode.
   NULL for ADDR means don't change the address.)  VALIDATE is nonzero if the
   returned memory location is required to be valid.  INPLACE is true if any
   changes can be made directly to MEMREF or false if MEMREF must be treated
   as immutable.

   The memory attributes are not changed.  */

static rtx
change_address_1 (rtx memref, machine_mode mode, rtx addr, int validate,
		  bool inplace)
{
  addr_space_t as;
  rtx new_rtx;

  gcc_assert (MEM_P (memref));
  as = MEM_ADDR_SPACE (memref);
  if (mode == VOIDmode)
    mode = GET_MODE (memref);
  if (addr == 0)
    addr = XEXP (memref, 0);
  if (mode == GET_MODE (memref) && addr == XEXP (memref, 0)
      && (!validate || memory_address_addr_space_p (mode, addr, as)))
    return memref;

  /* Don't validate address for LRA.  LRA can make the address valid
     by itself in most efficient way.  */
  if (validate && !lra_in_progress)
    {
      if (reload_in_progress || reload_completed)
	gcc_assert (memory_address_addr_space_p (mode, addr, as));
      else
	addr = memory_address_addr_space (mode, addr, as);
    }

  if (rtx_equal_p (addr, XEXP (memref, 0)) && mode == GET_MODE (memref))
    return memref;

  if (inplace)
    {
      XEXP (memref, 0) = addr;
      return memref;
    }

  new_rtx = gen_rtx_MEM (mode, addr);
  MEM_COPY_ATTRIBUTES (new_rtx, memref);
  return new_rtx;
}

/* Like change_address_1 with VALIDATE nonzero, but we are not saying in what
   way we are changing MEMREF, so we only preserve the alias set.  */

rtx
change_address (rtx memref, machine_mode mode, rtx addr)
{
  rtx new_rtx = change_address_1 (memref, mode, addr, 1, false);
  machine_mode mmode = GET_MODE (new_rtx);
  class mem_attrs *defattrs;

  mem_attrs attrs (*get_mem_attrs (memref));
  defattrs = mode_mem_attrs[(int) mmode];
  attrs.expr = NULL_TREE;
  attrs.offset_known_p = false;
  attrs.size_known_p = defattrs->size_known_p;
  attrs.size = defattrs->size;
  attrs.align = defattrs->align;

  /* If there are no changes, just return the original memory reference.  */
  if (new_rtx == memref)
    {
      if (mem_attrs_eq_p (get_mem_attrs (memref), &attrs))
	return new_rtx;

      new_rtx = gen_rtx_MEM (mmode, XEXP (memref, 0));
      MEM_COPY_ATTRIBUTES (new_rtx, memref);
    }

  set_mem_attrs (new_rtx, &attrs);
  return new_rtx;
}

/* Return a memory reference like MEMREF, but with its mode changed
   to MODE and its address offset by OFFSET bytes.  If VALIDATE is
   nonzero, the memory address is forced to be valid.
   If ADJUST_ADDRESS is zero, OFFSET is only used to update MEM_ATTRS
   and the caller is responsible for adjusting MEMREF base register.
   If ADJUST_OBJECT is zero, the underlying object associated with the
   memory reference is left unchanged and the caller is responsible for
   dealing with it.  Otherwise, if the new memory reference is outside
   the underlying object, even partially, then the object is dropped.
   SIZE, if nonzero, is the size of an access in cases where MODE
   has no inherent size.  */

rtx
adjust_address_1 (rtx memref, machine_mode mode, poly_int64 offset,
		  int validate, int adjust_address, int adjust_object,
		  poly_int64 size)
{
  rtx addr = XEXP (memref, 0);
  rtx new_rtx;
  scalar_int_mode address_mode;
  class mem_attrs attrs (*get_mem_attrs (memref)), *defattrs;
  unsigned HOST_WIDE_INT max_align;
#ifdef POINTERS_EXTEND_UNSIGNED
  scalar_int_mode pointer_mode
    = targetm.addr_space.pointer_mode (attrs.addrspace);
#endif

  /* VOIDmode means no mode change for change_address_1.  */
  if (mode == VOIDmode)
    mode = GET_MODE (memref);

  /* Take the size of non-BLKmode accesses from the mode.  */
  defattrs = mode_mem_attrs[(int) mode];
  if (defattrs->size_known_p)
    size = defattrs->size;

  /* If there are no changes, just return the original memory reference.  */
  if (mode == GET_MODE (memref)
      && known_eq (offset, 0)
      && (known_eq (size, 0)
	  || (attrs.size_known_p && known_eq (attrs.size, size)))
      && (!validate || memory_address_addr_space_p (mode, addr,
						    attrs.addrspace)))
    return memref;

  /* ??? Prefer to create garbage instead of creating shared rtl.
     This may happen even if offset is nonzero -- consider
     (plus (plus reg reg) const_int) -- so do this always.  */
  addr = copy_rtx (addr);

  /* Convert a possibly large offset to a signed value within the
     range of the target address space.  */
  address_mode = get_address_mode (memref);
  offset = trunc_int_for_mode (offset, address_mode);

  if (adjust_address)
    {
      /* If MEMREF is a LO_SUM and the offset is within the alignment of the
	 object, we can merge it into the LO_SUM.  */
      if (GET_MODE (memref) != BLKmode
	  && GET_CODE (addr) == LO_SUM
	  && known_in_range_p (offset,
			       0, (GET_MODE_ALIGNMENT (GET_MODE (memref))
				   / BITS_PER_UNIT)))
	addr = gen_rtx_LO_SUM (address_mode, XEXP (addr, 0),
			       plus_constant (address_mode,
					      XEXP (addr, 1), offset));
#ifdef POINTERS_EXTEND_UNSIGNED
      /* If MEMREF is a ZERO_EXTEND from pointer_mode and the offset is valid
	 in that mode, we merge it into the ZERO_EXTEND.  We take advantage of
	 the fact that pointers are not allowed to overflow.  */
      else if (POINTERS_EXTEND_UNSIGNED > 0
	       && GET_CODE (addr) == ZERO_EXTEND
	       && GET_MODE (XEXP (addr, 0)) == pointer_mode
	       && known_eq (trunc_int_for_mode (offset, pointer_mode), offset))
	addr = gen_rtx_ZERO_EXTEND (address_mode,
				    plus_constant (pointer_mode,
						   XEXP (addr, 0), offset));
#endif
      else
	addr = plus_constant (address_mode, addr, offset);
    }

  new_rtx = change_address_1 (memref, mode, addr, validate, false);

  /* If the address is a REG, change_address_1 rightfully returns memref,
     but this would destroy memref's MEM_ATTRS.  */
  if (new_rtx == memref && maybe_ne (offset, 0))
    new_rtx = copy_rtx (new_rtx);

  /* Conservatively drop the object if we don't know where we start from.  */
  if (adjust_object && (!attrs.offset_known_p || !attrs.size_known_p))
    {
      attrs.expr = NULL_TREE;
      attrs.alias = 0;
    }

  /* Compute the new values of the memory attributes due to this adjustment.
     We add the offsets and update the alignment.  */
  if (attrs.offset_known_p)
    {
      attrs.offset += offset;

      /* Drop the object if the new left end is not within its bounds.  */
      if (adjust_object && maybe_lt (attrs.offset, 0))
	{
	  attrs.expr = NULL_TREE;
	  attrs.alias = 0;
	}
    }

  /* Compute the new alignment by taking the MIN of the alignment and the
     lowest-order set bit in OFFSET, but don't change the alignment if OFFSET
     if zero.  */
  if (maybe_ne (offset, 0))
    {
      max_align = known_alignment (offset) * BITS_PER_UNIT;
      attrs.align = MIN (attrs.align, max_align);
    }

  if (maybe_ne (size, 0))
    {
      /* Drop the object if the new right end is not within its bounds.  */
      if (adjust_object && maybe_gt (offset + size, attrs.size))
	{
	  attrs.expr = NULL_TREE;
	  attrs.alias = 0;
	}
      attrs.size_known_p = true;
      attrs.size = size;
    }
  else if (attrs.size_known_p)
    {
      gcc_assert (!adjust_object);
      attrs.size -= offset;
      /* ??? The store_by_pieces machinery generates negative sizes,
	 so don't assert for that here.  */
    }

  set_mem_attrs (new_rtx, &attrs);

  return new_rtx;
}

/* Return a memory reference like MEMREF, but with its mode changed
   to MODE and its address changed to ADDR, which is assumed to be
   MEMREF offset by OFFSET bytes.  If VALIDATE is
   nonzero, the memory address is forced to be valid.  */

rtx
adjust_automodify_address_1 (rtx memref, machine_mode mode, rtx addr,
			     poly_int64 offset, int validate)
{
  memref = change_address_1 (memref, VOIDmode, addr, validate, false);
  return adjust_address_1 (memref, mode, offset, validate, 0, 0, 0);
}

/* Return a memory reference like MEMREF, but whose address is changed by
   adding OFFSET, an RTX, to it.  POW2 is the highest power of two factor
   known to be in OFFSET (possibly 1).  */

rtx
offset_address (rtx memref, rtx offset, unsigned HOST_WIDE_INT pow2)
{
  rtx new_rtx, addr = XEXP (memref, 0);
  machine_mode address_mode;
  class mem_attrs *defattrs;

  mem_attrs attrs (*get_mem_attrs (memref));
  address_mode = get_address_mode (memref);
  new_rtx = simplify_gen_binary (PLUS, address_mode, addr, offset);

  /* At this point we don't know _why_ the address is invalid.  It
     could have secondary memory references, multiplies or anything.

     However, if we did go and rearrange things, we can wind up not
     being able to recognize the magic around pic_offset_table_rtx.
     This stuff is fragile, and is yet another example of why it is
     bad to expose PIC machinery too early.  */
  if (! memory_address_addr_space_p (GET_MODE (memref), new_rtx,
				     attrs.addrspace)
      && GET_CODE (addr) == PLUS
      && XEXP (addr, 0) == pic_offset_table_rtx)
    {
      addr = force_reg (GET_MODE (addr), addr);
      new_rtx = simplify_gen_binary (PLUS, address_mode, addr, offset);
    }

  update_temp_slot_address (XEXP (memref, 0), new_rtx);
  new_rtx = change_address_1 (memref, VOIDmode, new_rtx, 1, false);

  /* If there are no changes, just return the original memory reference.  */
  if (new_rtx == memref)
    return new_rtx;

  /* Update the alignment to reflect the offset.  Reset the offset, which
     we don't know.  */
  defattrs = mode_mem_attrs[(int) GET_MODE (new_rtx)];
  attrs.offset_known_p = false;
  attrs.size_known_p = defattrs->size_known_p;
  attrs.size = defattrs->size;
  attrs.align = MIN (attrs.align, pow2 * BITS_PER_UNIT);
  set_mem_attrs (new_rtx, &attrs);
  return new_rtx;
}

/* Return a memory reference like MEMREF, but with its address changed to
   ADDR.  The caller is asserting that the actual piece of memory pointed
   to is the same, just the form of the address is being changed, such as
   by putting something into a register.  INPLACE is true if any changes
   can be made directly to MEMREF or false if MEMREF must be treated as
   immutable.  */

rtx
replace_equiv_address (rtx memref, rtx addr, bool inplace)
{
  /* change_address_1 copies the memory attribute structure without change
     and that's exactly what we want here.  */
  update_temp_slot_address (XEXP (memref, 0), addr);
  return change_address_1 (memref, VOIDmode, addr, 1, inplace);
}

/* Likewise, but the reference is not required to be valid.  */

rtx
replace_equiv_address_nv (rtx memref, rtx addr, bool inplace)
{
  return change_address_1 (memref, VOIDmode, addr, 0, inplace);
}


/* Emit insns to reload VALUE into a new register.  VALUE is an
   auto-increment or auto-decrement RTX whose operand is a register or
   memory location; so reloading involves incrementing that location.

   INC_AMOUNT is the number to increment or decrement by (always
   positive and ignored for POST_MODIFY/PRE_MODIFY).

   Return a pseudo containing the result.  */
rtx
address_reload_context::emit_autoinc (rtx value, poly_int64 inc_amount)
{
  /* Since we're going to call recog, and might be called within recog,
     we need to ensure we save and restore recog_data.  */
  recog_data_saver recog_save;

  /* REG or MEM to be copied and incremented.  */
  rtx incloc = XEXP (value, 0);

  const rtx_code code = GET_CODE (value);
  const bool post_p
    = code == POST_DEC || code == POST_INC || code == POST_MODIFY;

  bool plus_p = true;
  rtx inc;
  if (code == PRE_MODIFY || code == POST_MODIFY)
    {
      gcc_assert (GET_CODE (XEXP (value, 1)) == PLUS
		  || GET_CODE (XEXP (value, 1)) == MINUS);
      gcc_assert (rtx_equal_p (XEXP (XEXP (value, 1), 0), XEXP (value, 0)));
      plus_p = GET_CODE (XEXP (value, 1)) == PLUS;
      inc = XEXP (XEXP (value, 1), 1);
    }
  else
    {
      if (code == PRE_DEC || code == POST_DEC)
	inc_amount = -inc_amount;

      inc = gen_int_mode (inc_amount, GET_MODE (value));
    }

  rtx result;
  if (!post_p && REG_P (incloc))
    result = incloc;
  else
    {
      result = get_reload_reg ();
      /* First copy the location to the result register.  */
      emit_insn (gen_move_insn (result, incloc));
    }

  /* See if we can directly increment INCLOC.  */
  rtx_insn *last = get_last_insn ();
  rtx_insn *add_insn = emit_insn (plus_p
				  ? gen_add2_insn (incloc, inc)
				  : gen_sub2_insn (incloc, inc));
  const int icode = recog_memoized (add_insn);
  if (icode >= 0)
    {
      if (!post_p && result != incloc)
	emit_insn (gen_move_insn (result, incloc));
      return result;
    }
  delete_insns_since (last);

  /* If couldn't do the increment directly, must increment in RESULT.
     The way we do this depends on whether this is pre- or
     post-increment.  For pre-increment, copy INCLOC to the reload
     register, increment it there, then save back.  */
  if (!post_p)
    {
      if (incloc != result)
	emit_insn (gen_move_insn (result, incloc));
      if (plus_p)
	emit_insn (gen_add2_insn (result, inc));
      else
	emit_insn (gen_sub2_insn (result, inc));
      if (incloc != result)
	emit_insn (gen_move_insn (incloc, result));
    }
  else
    {
      /* Post-increment.

	 Because this might be a jump insn or a compare, and because
	 RESULT may not be available after the insn in an input
	 reload, we must do the incrementing before the insn being
	 reloaded for.

	 We have already copied INCLOC to RESULT.  Increment the copy in
	 RESULT, save that back, then decrement RESULT so it has
	 the original value.  */
      if (plus_p)
	emit_insn (gen_add2_insn (result, inc));
      else
	emit_insn (gen_sub2_insn (result, inc));
      emit_insn (gen_move_insn (incloc, result));
      /* Restore non-modified value for the result.  We prefer this
	 way because it does not require an additional hard
	 register.  */
      if (plus_p)
	{
	  poly_int64 offset;
	  if (poly_int_rtx_p (inc, &offset))
	    emit_insn (gen_add2_insn (result,
				      gen_int_mode (-offset,
						    GET_MODE (result))));
	  else
	    emit_insn (gen_sub2_insn (result, inc));
	}
      else
	emit_insn (gen_add2_insn (result, inc));
    }
  return result;
}

/* Return a memory reference like MEM, but with the address reloaded into a
   pseudo register.  */

rtx
force_reload_address (rtx mem)
{
  rtx addr = XEXP (mem, 0);
  if (GET_RTX_CLASS (GET_CODE (addr)) == RTX_AUTOINC)
    {
      const auto size = GET_MODE_SIZE (GET_MODE (mem));
      addr = address_reload_context ().emit_autoinc (addr, size);
    }
  else
    addr = force_reg (Pmode, addr);

  return replace_equiv_address (mem, addr);
}

/* Return a memory reference like MEMREF, but with its mode widened to
   MODE and offset by OFFSET.  This would be used by targets that e.g.
   cannot issue QImode memory operations and have to use SImode memory
   operations plus masking logic.  */

rtx
widen_memory_access (rtx memref, machine_mode mode, poly_int64 offset)
{
  rtx new_rtx = adjust_address_1 (memref, mode, offset, 1, 1, 0, 0);
  poly_uint64 size = GET_MODE_SIZE (mode);

  /* If there are no changes, just return the original memory reference.  */
  if (new_rtx == memref)
    return new_rtx;

  mem_attrs attrs (*get_mem_attrs (new_rtx));

  /* If we don't know what offset we were at within the expression, then
     we can't know if we've overstepped the bounds.  */
  if (! attrs.offset_known_p)
    attrs.expr = NULL_TREE;

  while (attrs.expr)
    {
      if (TREE_CODE (attrs.expr) == COMPONENT_REF)
	{
	  tree field = TREE_OPERAND (attrs.expr, 1);
	  tree offset = component_ref_field_offset (attrs.expr);

	  if (! DECL_SIZE_UNIT (field))
	    {
	      attrs.expr = NULL_TREE;
	      break;
	    }

	  /* Is the field at least as large as the access?  If so, ok,
	     otherwise strip back to the containing structure.  */
	  if (poly_int_tree_p (DECL_SIZE_UNIT (field))
	      && known_ge (wi::to_poly_offset (DECL_SIZE_UNIT (field)), size)
	      && known_ge (attrs.offset, 0))
	    break;

	  poly_uint64 suboffset;
	  if (!poly_int_tree_p (offset, &suboffset))
	    {
	      attrs.expr = NULL_TREE;
	      break;
	    }

	  attrs.expr = TREE_OPERAND (attrs.expr, 0);
	  attrs.offset += suboffset;
	  attrs.offset += (tree_to_uhwi (DECL_FIELD_BIT_OFFSET (field))
			   / BITS_PER_UNIT);
	}
      /* Similarly for the decl.  */
      else if (DECL_P (attrs.expr)
	       && DECL_SIZE_UNIT (attrs.expr)
	       && poly_int_tree_p (DECL_SIZE_UNIT (attrs.expr))
	       && known_ge (wi::to_poly_offset (DECL_SIZE_UNIT (attrs.expr)),
			   size)
	       && known_ge (attrs.offset, 0))
	break;
      else
	{
	  /* The widened memory access overflows the expression, which means
	     that it could alias another expression.  Zap it.  */
	  attrs.expr = NULL_TREE;
	  break;
	}
    }

  if (! attrs.expr)
    attrs.offset_known_p = false;

  /* The widened memory may alias other stuff, so zap the alias set.  */
  /* ??? Maybe use get_alias_set on any remaining expression.  */
  attrs.alias = 0;
  attrs.size_known_p = true;
  attrs.size = size;
  set_mem_attrs (new_rtx, &attrs);
  return new_rtx;
}

/* A fake decl that is used as the MEM_EXPR of spill slots.  */
static GTY(()) tree spill_slot_decl;

tree
get_spill_slot_decl (bool force_build_p)
{
  tree d = spill_slot_decl;
  rtx rd;

  if (d || !force_build_p)
    return d;

  d = build_decl (DECL_SOURCE_LOCATION (current_function_decl),
		  VAR_DECL, get_identifier ("%sfp"), void_type_node);
  DECL_ARTIFICIAL (d) = 1;
  DECL_IGNORED_P (d) = 1;
  TREE_USED (d) = 1;
  spill_slot_decl = d;

  rd = gen_rtx_MEM (BLKmode, frame_pointer_rtx);
  MEM_NOTRAP_P (rd) = 1;
  mem_attrs attrs (*mode_mem_attrs[(int) BLKmode]);
  attrs.alias = new_alias_set ();
  attrs.expr = d;
  set_mem_attrs (rd, &attrs);
  SET_DECL_RTL (d, rd);

  return d;
}

/* Given MEM, a result from assign_stack_local, fill in the memory
   attributes as appropriate for a register allocator spill slot.
   These slots are not aliasable by other memory.  We arrange for
   them all to use a single MEM_EXPR, so that the aliasing code can
   work properly in the case of shared spill slots.  */

void
set_mem_attrs_for_spill (rtx mem)
{
  rtx addr;

  mem_attrs attrs (*get_mem_attrs (mem));
  attrs.expr = get_spill_slot_decl (true);
  attrs.alias = MEM_ALIAS_SET (DECL_RTL (attrs.expr));
  attrs.addrspace = ADDR_SPACE_GENERIC;

  /* We expect the incoming memory to be of the form:
	(mem:MODE (plus (reg sfp) (const_int offset)))
     with perhaps the plus missing for offset = 0.  */
  addr = XEXP (mem, 0);
  attrs.offset_known_p = true;
  strip_offset (addr, &attrs.offset);

  set_mem_attrs (mem, &attrs);
  MEM_NOTRAP_P (mem) = 1;
}

/* Return a newly created CODE_LABEL rtx with a unique label number.  */

rtx_code_label *
gen_label_rtx (void)
{
  return as_a <rtx_code_label *> (
	    gen_rtx_CODE_LABEL (VOIDmode, NULL_RTX, NULL_RTX,
				NULL, label_num++, NULL));
}

/* For procedure integration.  */

/* Install new pointers to the first and last insns in the chain.
   Also, set cur_insn_uid to one higher than the last in use.
   Used for an inline-procedure after copying the insn chain.  */

void
set_new_first_and_last_insn (rtx_insn *first, rtx_insn *last)
{
  rtx_insn *insn;

  set_first_insn (first);
  set_last_insn (last);
  cur_insn_uid = 0;

  if (param_min_nondebug_insn_uid || MAY_HAVE_DEBUG_INSNS)
    {
      int debug_count = 0;

      cur_insn_uid = param_min_nondebug_insn_uid - 1;
      cur_debug_insn_uid = 0;

      for (insn = first; insn; insn = NEXT_INSN (insn))
	if (INSN_UID (insn) < param_min_nondebug_insn_uid)
	  cur_debug_insn_uid = MAX (cur_debug_insn_uid, INSN_UID (insn));
	else
	  {
	    cur_insn_uid = MAX (cur_insn_uid, INSN_UID (insn));
	    if (DEBUG_INSN_P (insn))
	      debug_count++;
	  }

      if (debug_count)
	cur_debug_insn_uid = param_min_nondebug_insn_uid + debug_count;
      else
	cur_debug_insn_uid++;
    }
  else
    for (insn = first; insn; insn = NEXT_INSN (insn))
      cur_insn_uid = MAX (cur_insn_uid, INSN_UID (insn));

  cur_insn_uid++;
}

/* Go through all the RTL insn bodies and copy any invalid shared
   structure.  This routine should only be called once.  */

static void
unshare_all_rtl_1 (rtx_insn *insn)
{
  /* Unshare just about everything else.  */
  unshare_all_rtl_in_chain (insn);

  /* Make sure the addresses of stack slots found outside the insn chain
     (such as, in DECL_RTL of a variable) are not shared
     with the insn chain.

     This special care is necessary when the stack slot MEM does not
     actually appear in the insn chain.  If it does appear, its address
     is unshared from all else at that point.  */
  unsigned int i;
  rtx temp;
  FOR_EACH_VEC_SAFE_ELT (stack_slot_list, i, temp)
    (*stack_slot_list)[i] = copy_rtx_if_shared (temp);
}

/* Go through all the RTL insn bodies and copy any invalid shared
   structure, again.  This is a fairly expensive thing to do so it
   should be done sparingly.  */

void
unshare_all_rtl_again (rtx_insn *insn)
{
  rtx_insn *p;
  tree decl;

  for (p = insn; p; p = NEXT_INSN (p))
    if (INSN_P (p))
      {
	reset_used_flags (PATTERN (p));
	reset_used_flags (REG_NOTES (p));
	if (CALL_P (p))
	  reset_used_flags (CALL_INSN_FUNCTION_USAGE (p));
      }

  /* Make sure that virtual stack slots are not shared.  */
  set_used_decls (DECL_INITIAL (cfun->decl));

  /* Make sure that virtual parameters are not shared.  */
  for (decl = DECL_ARGUMENTS (cfun->decl); decl; decl = DECL_CHAIN (decl))
    set_used_flags (DECL_RTL (decl));

  rtx temp;
  unsigned int i;
  FOR_EACH_VEC_SAFE_ELT (stack_slot_list, i, temp)
    reset_used_flags (temp);

  unshare_all_rtl_1 (insn);
}

void
unshare_all_rtl (void)
{
  unshare_all_rtl_1 (get_insns ());

  for (tree decl = DECL_ARGUMENTS (cfun->decl); decl; decl = DECL_CHAIN (decl))
    {
      if (DECL_RTL_SET_P (decl))
	SET_DECL_RTL (decl, copy_rtx_if_shared (DECL_RTL (decl)));
      DECL_INCOMING_RTL (decl) = copy_rtx_if_shared (DECL_INCOMING_RTL (decl));
    }
}


/* Check that ORIG is not marked when it should not be and mark ORIG as in use,
   Recursively does the same for subexpressions.  */

static void
verify_rtx_sharing (rtx orig, rtx insn)
{
  rtx x = orig;
  int i;
  enum rtx_code code;
  const char *format_ptr;

  if (x == 0)
    return;

  code = GET_CODE (x);

  /* These types may be freely shared.  */

  switch (code)
    {
    case REG:
    case DEBUG_EXPR:
    case VALUE:
    CASE_CONST_ANY:
    case SYMBOL_REF:
    case LABEL_REF:
    case CODE_LABEL:
    case PC:
    case RETURN:
    case SIMPLE_RETURN:
    case SCRATCH:
      /* SCRATCH must be shared because they represent distinct values.  */
      return;
    case CLOBBER:
      /* Share clobbers of hard registers, but do not share pseudo reg
         clobbers or clobbers of hard registers that originated as pseudos.
         This is needed to allow safe register renaming.  */
      if (REG_P (XEXP (x, 0))
	  && HARD_REGISTER_NUM_P (REGNO (XEXP (x, 0)))
	  && HARD_REGISTER_NUM_P (ORIGINAL_REGNO (XEXP (x, 0))))
	return;
      break;

    case CONST:
      if (shared_const_p (orig))
	return;
      break;

    case MEM:
      /* A MEM is allowed to be shared if its address is constant.  */
      if (CONSTANT_ADDRESS_P (XEXP (x, 0))
	  || reload_completed || reload_in_progress)
	return;

      break;

    default:
      break;
    }

  /* This rtx may not be shared.  If it has already been seen,
     replace it with a copy of itself.  */
  if (flag_checking && RTX_FLAG (x, used))
    {
      error ("invalid rtl sharing found in the insn");
      debug_rtx (insn);
      error ("shared rtx");
      debug_rtx (x);
      internal_error ("internal consistency failure");
    }
  gcc_assert (!RTX_FLAG (x, used));

  RTX_FLAG (x, used) = 1;

  /* Now scan the subexpressions recursively.  */

  format_ptr = GET_RTX_FORMAT (code);

  for (i = 0; i < GET_RTX_LENGTH (code); i++)
    {
      switch (*format_ptr++)
	{
	case 'e':
	  verify_rtx_sharing (XEXP (x, i), insn);
	  break;

	case 'E':
	  if (XVEC (x, i) != NULL)
	    {
	      int j;
	      int len = XVECLEN (x, i);

	      for (j = 0; j < len; j++)
		{
		  /* We allow sharing of ASM_OPERANDS inside single
		     instruction.  */
		  if (j && GET_CODE (XVECEXP (x, i, j)) == SET
		      && (GET_CODE (SET_SRC (XVECEXP (x, i, j)))
			  == ASM_OPERANDS))
		    verify_rtx_sharing (SET_DEST (XVECEXP (x, i, j)), insn);
		  else
		    verify_rtx_sharing (XVECEXP (x, i, j), insn);
		}
	    }
	  break;
	}
    }
}

/* Reset used-flags for INSN.  */

static void
reset_insn_used_flags (rtx insn)
{
  gcc_assert (INSN_P (insn));
  reset_used_flags (PATTERN (insn));
  reset_used_flags (REG_NOTES (insn));
  if (CALL_P (insn))
    reset_used_flags (CALL_INSN_FUNCTION_USAGE (insn));
}

/* Go through all the RTL insn bodies and clear all the USED bits.  */

static void
reset_all_used_flags (void)
{
  rtx_insn *p;

  for (p = get_insns (); p; p = NEXT_INSN (p))
    if (INSN_P (p))
      {
	rtx pat = PATTERN (p);
	if (GET_CODE (pat) != SEQUENCE)
	  reset_insn_used_flags (p);
	else
	  {
	    gcc_assert (REG_NOTES (p) == NULL);
	    for (int i = 0; i < XVECLEN (pat, 0); i++)
	      {
		rtx insn = XVECEXP (pat, 0, i);
		if (INSN_P (insn))
		  reset_insn_used_flags (insn);
	      }
	  }
      }
}

/* Verify sharing in INSN.  */

static void
verify_insn_sharing (rtx insn)
{
  gcc_assert (INSN_P (insn));
  verify_rtx_sharing (PATTERN (insn), insn);
  verify_rtx_sharing (REG_NOTES (insn), insn);
  if (CALL_P (insn))
    verify_rtx_sharing (CALL_INSN_FUNCTION_USAGE (insn), insn);
}

/* Go through all the RTL insn bodies and check that there is no unexpected
   sharing in between the subexpressions.  */

DEBUG_FUNCTION void
verify_rtl_sharing (void)
{
  rtx_insn *p;

  timevar_push (TV_VERIFY_RTL_SHARING);

  reset_all_used_flags ();

  for (p = get_insns (); p; p = NEXT_INSN (p))
    if (INSN_P (p))
      {
	rtx pat = PATTERN (p);
	if (GET_CODE (pat) != SEQUENCE)
	  verify_insn_sharing (p);
	else
	  for (int i = 0; i < XVECLEN (pat, 0); i++)
	      {
		rtx insn = XVECEXP (pat, 0, i);
		if (INSN_P (insn))
		  verify_insn_sharing (insn);
	      }
      }

  reset_all_used_flags ();

  timevar_pop (TV_VERIFY_RTL_SHARING);
}

/* Go through all the RTL insn bodies and copy any invalid shared structure.
   Assumes the mark bits are cleared at entry.  */

void
unshare_all_rtl_in_chain (rtx_insn *insn)
{
  for (; insn; insn = NEXT_INSN (insn))
    if (INSN_P (insn))
      {
	PATTERN (insn) = copy_rtx_if_shared (PATTERN (insn));
	REG_NOTES (insn) = copy_rtx_if_shared (REG_NOTES (insn));
	if (CALL_P (insn))
	  CALL_INSN_FUNCTION_USAGE (insn)
	    = copy_rtx_if_shared (CALL_INSN_FUNCTION_USAGE (insn));
      }
}

/* Go through all virtual stack slots of a function and mark them as
   shared.  We never replace the DECL_RTLs themselves with a copy,
   but expressions mentioned into a DECL_RTL cannot be shared with
   expressions in the instruction stream.

   Note that reload may convert pseudo registers into memories in-place.
   Pseudo registers are always shared, but MEMs never are.  Thus if we
   reset the used flags on MEMs in the instruction stream, we must set
   them again on MEMs that appear in DECL_RTLs.  */

static void
set_used_decls (tree blk)
{
  tree t;

  /* Mark decls.  */
  for (t = BLOCK_VARS (blk); t; t = DECL_CHAIN (t))
    if (DECL_RTL_SET_P (t))
      set_used_flags (DECL_RTL (t));

  /* Now process sub-blocks.  */
  for (t = BLOCK_SUBBLOCKS (blk); t; t = BLOCK_CHAIN (t))
    set_used_decls (t);
}

/* Mark ORIG as in use, and return a copy of it if it was already in use.
   Recursively does the same for subexpressions.  Uses
   copy_rtx_if_shared_1 to reduce stack space.  */

rtx
copy_rtx_if_shared (rtx orig)
{
  copy_rtx_if_shared_1 (&orig);
  return orig;
}

/* Mark *ORIG1 as in use, and set it to a copy of it if it was already in
   use.  Recursively does the same for subexpressions.  */

static void
copy_rtx_if_shared_1 (rtx *orig1)
{
  rtx x;
  int i;
  enum rtx_code code;
  rtx *last_ptr;
  const char *format_ptr;
  int copied = 0;
  int length;

  /* Repeat is used to turn tail-recursion into iteration.  */
repeat:
  x = *orig1;

  if (x == 0)
    return;

  code = GET_CODE (x);

  /* These types may be freely shared.  */

  switch (code)
    {
    case REG:
    case DEBUG_EXPR:
    case VALUE:
    CASE_CONST_ANY:
    case SYMBOL_REF:
    case LABEL_REF:
    case CODE_LABEL:
    case PC:
    case RETURN:
    case SIMPLE_RETURN:
    case SCRATCH:
      /* SCRATCH must be shared because they represent distinct values.  */
      return;
    case CLOBBER:
      /* Share clobbers of hard registers, but do not share pseudo reg
         clobbers or clobbers of hard registers that originated as pseudos.
         This is needed to allow safe register renaming.  */
      if (REG_P (XEXP (x, 0))
	  && HARD_REGISTER_NUM_P (REGNO (XEXP (x, 0)))
	  && HARD_REGISTER_NUM_P (ORIGINAL_REGNO (XEXP (x, 0))))
	return;
      break;

    case CONST:
      if (shared_const_p (x))
	return;
      break;

    case DEBUG_INSN:
    case INSN:
    case JUMP_INSN:
    case CALL_INSN:
    case NOTE:
    case BARRIER:
      /* The chain of insns is not being copied.  */
      return;

    default:
      break;
    }

  /* This rtx may not be shared.  If it has already been seen,
     replace it with a copy of itself.  */

  if (RTX_FLAG (x, used))
    {
      x = shallow_copy_rtx (x);
      copied = 1;
    }
  RTX_FLAG (x, used) = 1;

  /* Now scan the subexpressions recursively.
     We can store any replaced subexpressions directly into X
     since we know X is not shared!  Any vectors in X
     must be copied if X was copied.  */

  format_ptr = GET_RTX_FORMAT (code);
  length = GET_RTX_LENGTH (code);
  last_ptr = NULL;

  for (i = 0; i < length; i++)
    {
      switch (*format_ptr++)
	{
	case 'e':
          if (last_ptr)
            copy_rtx_if_shared_1 (last_ptr);
	  last_ptr = &XEXP (x, i);
	  break;

	case 'E':
	  if (XVEC (x, i) != NULL)
	    {
	      int j;
	      int len = XVECLEN (x, i);

              /* Copy the vector iff I copied the rtx and the length
		 is nonzero.  */
	      if (copied && len > 0)
		XVEC (x, i) = gen_rtvec_v (len, XVEC (x, i)->elem);

              /* Call recursively on all inside the vector.  */
	      for (j = 0; j < len; j++)
                {
		  if (last_ptr)
		    copy_rtx_if_shared_1 (last_ptr);
                  last_ptr = &XVECEXP (x, i, j);
                }
	    }
	  break;
	}
    }
  *orig1 = x;
  if (last_ptr)
    {
      orig1 = last_ptr;
      goto repeat;
    }
}

/* Set the USED bit in X and its non-shareable subparts to FLAG.  */

static void
mark_used_flags (rtx x, int flag)
{
  int i, j;
  enum rtx_code code;
  const char *format_ptr;
  int length;

  /* Repeat is used to turn tail-recursion into iteration.  */
repeat:
  if (x == 0)
    return;

  code = GET_CODE (x);

  /* These types may be freely shared so we needn't do any resetting
     for them.  */

  switch (code)
    {
    case REG:
    case DEBUG_EXPR:
    case VALUE:
    CASE_CONST_ANY:
    case SYMBOL_REF:
    case CODE_LABEL:
    case PC:
    case RETURN:
    case SIMPLE_RETURN:
      return;

    case DEBUG_INSN:
    case INSN:
    case JUMP_INSN:
    case CALL_INSN:
    case NOTE:
    case LABEL_REF:
    case BARRIER:
      /* The chain of insns is not being copied.  */
      return;

    default:
      break;
    }

  RTX_FLAG (x, used) = flag;

  format_ptr = GET_RTX_FORMAT (code);
  length = GET_RTX_LENGTH (code);

  for (i = 0; i < length; i++)
    {
      switch (*format_ptr++)
	{
	case 'e':
          if (i == length-1)
            {
              x = XEXP (x, i);
	      goto repeat;
            }
	  mark_used_flags (XEXP (x, i), flag);
	  break;

	case 'E':
	  for (j = 0; j < XVECLEN (x, i); j++)
	    mark_used_flags (XVECEXP (x, i, j), flag);
	  break;
	}
    }
}

/* Clear all the USED bits in X to allow copy_rtx_if_shared to be used
   to look for shared sub-parts.  */

void
reset_used_flags (rtx x)
{
  mark_used_flags (x, 0);
}

/* Set all the USED bits in X to allow copy_rtx_if_shared to be used
   to look for shared sub-parts.  */

void
set_used_flags (rtx x)
{
  mark_used_flags (x, 1);
}

/* Copy X if necessary so that it won't be altered by changes in OTHER.
   Return X or the rtx for the pseudo reg the value of X was copied into.
   OTHER must be valid as a SET_DEST.  */

rtx
make_safe_from (rtx x, rtx other)
{
  while (1)
    switch (GET_CODE (other))
      {
      case SUBREG:
	other = SUBREG_REG (other);
	break;
      case STRICT_LOW_PART:
      case SIGN_EXTEND:
      case ZERO_EXTEND:
	other = XEXP (other, 0);
	break;
      default:
	goto done;
      }
 done:
  if ((MEM_P (other)
       && ! CONSTANT_P (x)
       && !REG_P (x)
       && GET_CODE (x) != SUBREG)
      || (REG_P (other)
	  && (REGNO (other) < FIRST_PSEUDO_REGISTER
	      || reg_mentioned_p (other, x))))
    {
      rtx temp = gen_reg_rtx (GET_MODE (x));
      emit_move_insn (temp, x);
      return temp;
    }
  return x;
}

/* Emission of insns (adding them to the doubly-linked list).  */

/* Return the last insn emitted, even if it is in a sequence now pushed.  */

rtx_insn *
get_last_insn_anywhere (void)
{
  struct sequence_stack *seq;
  for (seq = get_current_sequence (); seq; seq = seq->next)
    if (seq->last != 0)
      return seq->last;
  return 0;
}

/* Return the first nonnote insn emitted in current sequence or current
   function.  This routine looks inside SEQUENCEs.  */

rtx_insn *
get_first_nonnote_insn (void)
{
  rtx_insn *insn = get_insns ();

  if (insn)
    {
      if (NOTE_P (insn))
	for (insn = next_insn (insn);
	     insn && NOTE_P (insn);
	     insn = next_insn (insn))
	  continue;
      else
	{
	  if (NONJUMP_INSN_P (insn)
	      && GET_CODE (PATTERN (insn)) == SEQUENCE)
	    insn = as_a <rtx_sequence *> (PATTERN (insn))->insn (0);
	}
    }

  return insn;
}

/* Return the last nonnote insn emitted in current sequence or current
   function.  This routine looks inside SEQUENCEs.  */

rtx_insn *
get_last_nonnote_insn (void)
{
  rtx_insn *insn = get_last_insn ();

  if (insn)
    {
      if (NOTE_P (insn))
	for (insn = previous_insn (insn);
	     insn && NOTE_P (insn);
	     insn = previous_insn (insn))
	  continue;
      else
	{
	  if (NONJUMP_INSN_P (insn))
	    if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
	      insn = seq->insn (seq->len () - 1);
	}
    }

  return insn;
}

/* Return the number of actual (non-debug) insns emitted in this
   function.  */

int
get_max_insn_count (void)
{
  int n = cur_insn_uid;

  /* The table size must be stable across -g, to avoid codegen
     differences due to debug insns, and not be affected by
     -fmin-insn-uid, to avoid excessive table size and to simplify
     debugging of -fcompare-debug failures.  */
  if (cur_debug_insn_uid > param_min_nondebug_insn_uid)
    n -= cur_debug_insn_uid;
  else
    n -= param_min_nondebug_insn_uid;

  return n;
}


/* Return the next insn.  If it is a SEQUENCE, return the first insn
   of the sequence.  */

rtx_insn *
next_insn (rtx_insn *insn)
{
  if (insn)
    {
      insn = NEXT_INSN (insn);
      if (insn && NONJUMP_INSN_P (insn)
	  && GET_CODE (PATTERN (insn)) == SEQUENCE)
	insn = as_a <rtx_sequence *> (PATTERN (insn))->insn (0);
    }

  return insn;
}

/* Return the previous insn.  If it is a SEQUENCE, return the last insn
   of the sequence.  */

rtx_insn *
previous_insn (rtx_insn *insn)
{
  if (insn)
    {
      insn = PREV_INSN (insn);
      if (insn && NONJUMP_INSN_P (insn))
	if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
	  insn = seq->insn (seq->len () - 1);
    }

  return insn;
}

/* Return the next insn after INSN that is not a NOTE.  This routine does not
   look inside SEQUENCEs.  */

rtx_insn *
next_nonnote_insn (rtx_insn *insn)
{
  while (insn)
    {
      insn = NEXT_INSN (insn);
      if (insn == 0 || !NOTE_P (insn))
	break;
    }

  return insn;
}

/* Return the next insn after INSN that is not a DEBUG_INSN.  This
   routine does not look inside SEQUENCEs.  */

rtx_insn *
next_nondebug_insn (rtx_insn *insn)
{
  while (insn)
    {
      insn = NEXT_INSN (insn);
      if (insn == 0 || !DEBUG_INSN_P (insn))
	break;
    }

  return insn;
}

/* Return the previous insn before INSN that is not a NOTE.  This routine does
   not look inside SEQUENCEs.  */

rtx_insn *
prev_nonnote_insn (rtx_insn *insn)
{
  while (insn)
    {
      insn = PREV_INSN (insn);
      if (insn == 0 || !NOTE_P (insn))
	break;
    }

  return insn;
}

/* Return the previous insn before INSN that is not a DEBUG_INSN.
   This routine does not look inside SEQUENCEs.  */

rtx_insn *
prev_nondebug_insn (rtx_insn *insn)
{
  while (insn)
    {
      insn = PREV_INSN (insn);
      if (insn == 0 || !DEBUG_INSN_P (insn))
	break;
    }

  return insn;
}

/* Return the next insn after INSN that is not a NOTE nor DEBUG_INSN.
   This routine does not look inside SEQUENCEs.  */

rtx_insn *
next_nonnote_nondebug_insn (rtx_insn *insn)
{
  while (insn)
    {
      insn = NEXT_INSN (insn);
      if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn)))
	break;
    }

  return insn;
}

/* Return the next insn after INSN that is not a NOTE nor DEBUG_INSN,
   but stop the search before we enter another basic block.  This
   routine does not look inside SEQUENCEs.  */

rtx_insn *
next_nonnote_nondebug_insn_bb (rtx_insn *insn)
{
  while (insn)
    {
      insn = NEXT_INSN (insn);
      if (insn == 0)
	break;
      if (DEBUG_INSN_P (insn))
	continue;
      if (!NOTE_P (insn))
	break;
      if (NOTE_INSN_BASIC_BLOCK_P (insn))
	return NULL;
    }

  return insn;
}

/* Return the previous insn before INSN that is not a NOTE nor DEBUG_INSN.
   This routine does not look inside SEQUENCEs.  */

rtx_insn *
prev_nonnote_nondebug_insn (rtx_insn *insn)
{
  while (insn)
    {
      insn = PREV_INSN (insn);
      if (insn == 0 || (!NOTE_P (insn) && !DEBUG_INSN_P (insn)))
	break;
    }

  return insn;
}

/* Return the previous insn before INSN that is not a NOTE nor
   DEBUG_INSN, but stop the search before we enter another basic
   block.  This routine does not look inside SEQUENCEs.  */

rtx_insn *
prev_nonnote_nondebug_insn_bb (rtx_insn *insn)
{
  while (insn)
    {
      insn = PREV_INSN (insn);
      if (insn == 0)
	break;
      if (DEBUG_INSN_P (insn))
	continue;
      if (!NOTE_P (insn))
	break;
      if (NOTE_INSN_BASIC_BLOCK_P (insn))
	return NULL;
    }

  return insn;
}

/* Return the next INSN, CALL_INSN, JUMP_INSN or DEBUG_INSN after INSN;
   or 0, if there is none.  This routine does not look inside
   SEQUENCEs.  */

rtx_insn *
next_real_insn (rtx_insn *insn)
{
  while (insn)
    {
      insn = NEXT_INSN (insn);
      if (insn == 0 || INSN_P (insn))
	break;
    }

  return insn;
}

/* Return the last INSN, CALL_INSN, JUMP_INSN or DEBUG_INSN before INSN;
   or 0, if there is none.  This routine does not look inside
   SEQUENCEs.  */

rtx_insn *
prev_real_insn (rtx_insn *insn)
{
  while (insn)
    {
      insn = PREV_INSN (insn);
      if (insn == 0 || INSN_P (insn))
	break;
    }

  return insn;
}

/* Return the next INSN, CALL_INSN or JUMP_INSN after INSN;
   or 0, if there is none.  This routine does not look inside
   SEQUENCEs.  */

rtx_insn *
next_real_nondebug_insn (rtx uncast_insn)
{
  rtx_insn *insn = safe_as_a <rtx_insn *> (uncast_insn);

  while (insn)
    {
      insn = NEXT_INSN (insn);
      if (insn == 0 || NONDEBUG_INSN_P (insn))
	break;
    }

  return insn;
}

/* Return the last INSN, CALL_INSN or JUMP_INSN before INSN;
   or 0, if there is none.  This routine does not look inside
   SEQUENCEs.  */

rtx_insn *
prev_real_nondebug_insn (rtx_insn *insn)
{
  while (insn)
    {
      insn = PREV_INSN (insn);
      if (insn == 0 || NONDEBUG_INSN_P (insn))
	break;
    }

  return insn;
}

/* Return the last CALL_INSN in the current list, or 0 if there is none.
   This routine does not look inside SEQUENCEs.  */

rtx_call_insn *
last_call_insn (void)
{
  rtx_insn *insn;

  for (insn = get_last_insn ();
       insn && !CALL_P (insn);
       insn = PREV_INSN (insn))
    ;

  return safe_as_a <rtx_call_insn *> (insn);
}

bool
active_insn_p (const rtx_insn *insn)
{
  return (CALL_P (insn) || JUMP_P (insn)
	  || JUMP_TABLE_DATA_P (insn) /* FIXME */
	  || (NONJUMP_INSN_P (insn)
	      && (! reload_completed
		  || (GET_CODE (PATTERN (insn)) != USE
		      && GET_CODE (PATTERN (insn)) != CLOBBER))));
}

/* Find the next insn after INSN that really does something.  This routine
   does not look inside SEQUENCEs.  After reload this also skips over
   standalone USE and CLOBBER insn.  */

rtx_insn *
next_active_insn (rtx_insn *insn)
{
  while (insn)
    {
      insn = NEXT_INSN (insn);
      if (insn == 0 || active_insn_p (insn))
	break;
    }

  return insn;
}

/* Find the last insn before INSN that really does something.  This routine
   does not look inside SEQUENCEs.  After reload this also skips over
   standalone USE and CLOBBER insn.  */

rtx_insn *
prev_active_insn (rtx_insn *insn)
{
  while (insn)
    {
      insn = PREV_INSN (insn);
      if (insn == 0 || active_insn_p (insn))
	break;
    }

  return insn;
}

/* Find a RTX_AUTOINC class rtx which matches DATA.  */

static int
find_auto_inc (const_rtx x, const_rtx reg)
{
  subrtx_iterator::array_type array;
  FOR_EACH_SUBRTX (iter, array, x, NONCONST)
    {
      const_rtx x = *iter;
      if (GET_RTX_CLASS (GET_CODE (x)) == RTX_AUTOINC
	  && rtx_equal_p (reg, XEXP (x, 0)))
	return true;
    }
  return false;
}

/* Increment the label uses for all labels present in rtx.  */

static void
mark_label_nuses (rtx x)
{
  enum rtx_code code;
  int i, j;
  const char *fmt;

  code = GET_CODE (x);
  if (code == LABEL_REF && LABEL_P (label_ref_label (x)))
    LABEL_NUSES (label_ref_label (x))++;

  fmt = GET_RTX_FORMAT (code);
  for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
    {
      if (fmt[i] == 'e')
	mark_label_nuses (XEXP (x, i));
      else if (fmt[i] == 'E')
	for (j = XVECLEN (x, i) - 1; j >= 0; j--)
	  mark_label_nuses (XVECEXP (x, i, j));
    }
}


/* Try splitting insns that can be split for better scheduling.
   PAT is the pattern which might split.
   TRIAL is the insn providing PAT.
   LAST is nonzero if we should return the last insn of the sequence produced.

   If this routine succeeds in splitting, it returns the first or last
   replacement insn depending on the value of LAST.  Otherwise, it
   returns TRIAL.  If the insn to be returned can be split, it will be.  */

rtx_insn *
try_split (rtx pat, rtx_insn *trial, int last)
{
  rtx_insn *before, *after;
  rtx note;
  rtx_insn *seq, *tem;
  profile_probability probability;
  rtx_insn *insn_last, *insn;
  int njumps = 0;
  rtx_insn *call_insn = NULL;

  if (any_condjump_p (trial)
      && (note = find_reg_note (trial, REG_BR_PROB, 0)))
    split_branch_probability
      = profile_probability::from_reg_br_prob_note (XINT (note, 0));
  else
    split_branch_probability = profile_probability::uninitialized ();

  probability = split_branch_probability;

  seq = split_insns (pat, trial);

  split_branch_probability = profile_probability::uninitialized ();

  if (!seq)
    return trial;

  int split_insn_count = 0;
  /* Avoid infinite loop if any insn of the result matches
     the original pattern.  */
  insn_last = seq;
  while (1)
    {
      if (INSN_P (insn_last)
	  && rtx_equal_p (PATTERN (insn_last), pat))
	return trial;
      split_insn_count++;
      if (!NEXT_INSN (insn_last))
	break;
      insn_last = NEXT_INSN (insn_last);
    }

  /* We're not good at redistributing frame information if
     the split occurs before reload or if it results in more
     than one insn.  */
  if (RTX_FRAME_RELATED_P (trial))
    {
      if (!reload_completed || split_insn_count != 1)
        return trial;

      rtx_insn *new_insn = seq;
      rtx_insn *old_insn = trial;
      copy_frame_info_to_split_insn (old_insn, new_insn);
    }

  /* We will be adding the new sequence to the function.  The splitters
     may have introduced invalid RTL sharing, so unshare the sequence now.  */
  unshare_all_rtl_in_chain (seq);

  /* Mark labels and copy flags.  */
  for (insn = insn_last; insn ; insn = PREV_INSN (insn))
    {
      if (JUMP_P (insn))
	{
	  if (JUMP_P (trial))
	    CROSSING_JUMP_P (insn) = CROSSING_JUMP_P (trial);
	  mark_jump_label (PATTERN (insn), insn, 0);
	  njumps++;
	  if (probability.initialized_p ()
	      && any_condjump_p (insn)
	      && !find_reg_note (insn, REG_BR_PROB, 0))
	    {
	      /* We can preserve the REG_BR_PROB notes only if exactly
		 one jump is created, otherwise the machine description
		 is responsible for this step using
		 split_branch_probability variable.  */
	      gcc_assert (njumps == 1);
	      add_reg_br_prob_note (insn, probability);
	    }
	}
    }

  /* If we are splitting a CALL_INSN, look for the CALL_INSN
     in SEQ and copy any additional information across.  */
  if (CALL_P (trial))
    {
      for (insn = insn_last; insn ; insn = PREV_INSN (insn))
	if (CALL_P (insn))
	  {
	    gcc_assert (call_insn == NULL_RTX);
	    call_insn = insn;

	    /* Add the old CALL_INSN_FUNCTION_USAGE to whatever the
	       target may have explicitly specified.  */
	    rtx *p = &CALL_INSN_FUNCTION_USAGE (insn);
	    while (*p)
	      p = &XEXP (*p, 1);
	    *p = CALL_INSN_FUNCTION_USAGE (trial);

	    /* If the old call was a sibling call, the new one must
	       be too.  */
	    SIBLING_CALL_P (insn) = SIBLING_CALL_P (trial);
	  }
    }

  /* Copy notes, particularly those related to the CFG.  */
  for (note = REG_NOTES (trial); note; note = XEXP (note, 1))
    {
      switch (REG_NOTE_KIND (note))
	{
	case REG_EH_REGION:
	  copy_reg_eh_region_note_backward (note, insn_last, NULL);
	  break;

	case REG_NORETURN:
	case REG_SETJMP:
	case REG_TM:
	case REG_CALL_NOCF_CHECK:
	case REG_CALL_ARG_LOCATION:
	  for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
	    {
	      if (CALL_P (insn))
		add_reg_note (insn, REG_NOTE_KIND (note), XEXP (note, 0));
	    }
	  break;

	case REG_NON_LOCAL_GOTO:
	case REG_LABEL_TARGET:
	  for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
	    {
	      if (JUMP_P (insn))
		add_reg_note (insn, REG_NOTE_KIND (note), XEXP (note, 0));
	    }
	  break;

	case REG_INC:
	  if (!AUTO_INC_DEC)
	    break;

	  for (insn = insn_last; insn != NULL_RTX; insn = PREV_INSN (insn))
	    {
	      rtx reg = XEXP (note, 0);
	      if (!FIND_REG_INC_NOTE (insn, reg)
		  && find_auto_inc (PATTERN (insn), reg))
		add_reg_note (insn, REG_INC, reg);
	    }
	  break;

	case REG_ARGS_SIZE:
	  fixup_args_size_notes (NULL, insn_last, get_args_size (note));
	  break;

	case REG_CALL_DECL:
	case REG_UNTYPED_CALL:
	  gcc_assert (call_insn != NULL_RTX);
	  add_reg_note (call_insn, REG_NOTE_KIND (note), XEXP (note, 0));
	  break;

	default:
	  break;
	}
    }

  /* If there are LABELS inside the split insns increment the
     usage count so we don't delete the label.  */
  if (INSN_P (trial))
    {
      insn = insn_last;
      while (insn != NULL_RTX)
	{
	  /* JUMP_P insns have already been "marked" above.  */
	  if (NONJUMP_INSN_P (insn))
	    mark_label_nuses (PATTERN (insn));

	  insn = PREV_INSN (insn);
	}
    }

  before = PREV_INSN (trial);
  after = NEXT_INSN (trial);

  emit_insn_after_setloc (seq, trial, INSN_LOCATION (trial));

  delete_insn (trial);

  /* Recursively call try_split for each new insn created; by the
     time control returns here that insn will be fully split, so
     set LAST and continue from the insn after the one returned.
     We can't use next_active_insn here since AFTER may be a note.
     Ignore deleted insns, which can be occur if not optimizing.  */
  for (tem = NEXT_INSN (before); tem != after; tem = NEXT_INSN (tem))
    if (! tem->deleted () && INSN_P (tem))
      tem = try_split (PATTERN (tem), tem, 1);

  /* Return either the first or the last insn, depending on which was
     requested.  */
  return last
    ? (after ? PREV_INSN (after) : get_last_insn ())
    : NEXT_INSN (before);
}

/* Make and return an INSN rtx, initializing all its slots.
   Store PATTERN in the pattern slots.  */

rtx_insn *
make_insn_raw (rtx pattern)
{
  rtx_insn *insn;

  insn = as_a <rtx_insn *> (rtx_alloc (INSN));

  INSN_UID (insn) = cur_insn_uid++;
  PATTERN (insn) = pattern;
  INSN_CODE (insn) = -1;
  REG_NOTES (insn) = NULL;
  INSN_LOCATION (insn) = curr_insn_location ();
  BLOCK_FOR_INSN (insn) = NULL;

#ifdef ENABLE_RTL_CHECKING
  if (insn
      && INSN_P (insn)
      && (returnjump_p (insn)
	  || (GET_CODE (insn) == SET
	      && SET_DEST (insn) == pc_rtx)))
    {
      warning (0, "ICE: %<emit_insn%> used where %<emit_jump_insn%> needed:");
      debug_rtx (insn);
    }
#endif

  return insn;
}

/* Like `make_insn_raw' but make a DEBUG_INSN instead of an insn.  */

static rtx_insn *
make_debug_insn_raw (rtx pattern)
{
  rtx_debug_insn *insn;

  insn = as_a <rtx_debug_insn *> (rtx_alloc (DEBUG_INSN));
  INSN_UID (insn) = cur_debug_insn_uid++;
  if (cur_debug_insn_uid > param_min_nondebug_insn_uid)
    INSN_UID (insn) = cur_insn_uid++;

  PATTERN (insn) = pattern;
  INSN_CODE (insn) = -1;
  REG_NOTES (insn) = NULL;
  INSN_LOCATION (insn) = curr_insn_location ();
  BLOCK_FOR_INSN (insn) = NULL;

  return insn;
}

/* Like `make_insn_raw' but make a JUMP_INSN instead of an insn.  */

static rtx_insn *
make_jump_insn_raw (rtx pattern)
{
  rtx_jump_insn *insn;

  insn = as_a <rtx_jump_insn *> (rtx_alloc (JUMP_INSN));
  INSN_UID (insn) = cur_insn_uid++;

  PATTERN (insn) = pattern;
  INSN_CODE (insn) = -1;
  REG_NOTES (insn) = NULL;
  JUMP_LABEL (insn) = NULL;
  INSN_LOCATION (insn) = curr_insn_location ();
  BLOCK_FOR_INSN (insn) = NULL;

  return insn;
}

/* Like `make_insn_raw' but make a CALL_INSN instead of an insn.  */

static rtx_insn *
make_call_insn_raw (rtx pattern)
{
  rtx_call_insn *insn;

  insn = as_a <rtx_call_insn *> (rtx_alloc (CALL_INSN));
  INSN_UID (insn) = cur_insn_uid++;

  PATTERN (insn) = pattern;
  INSN_CODE (insn) = -1;
  REG_NOTES (insn) = NULL;
  CALL_INSN_FUNCTION_USAGE (insn) = NULL;
  INSN_LOCATION (insn) = curr_insn_location ();
  BLOCK_FOR_INSN (insn) = NULL;

  return insn;
}

/* Like `make_insn_raw' but make a NOTE instead of an insn.  */

static rtx_note *
make_note_raw (enum insn_note subtype)
{
  /* Some notes are never created this way at all.  These notes are
     only created by patching out insns.  */
  gcc_assert (subtype != NOTE_INSN_DELETED_LABEL
	      && subtype != NOTE_INSN_DELETED_DEBUG_LABEL);

  rtx_note *note = as_a <rtx_note *> (rtx_alloc (NOTE));
  INSN_UID (note) = cur_insn_uid++;
  NOTE_KIND (note) = subtype;
  BLOCK_FOR_INSN (note) = NULL;
  memset (&NOTE_DATA (note), 0, sizeof (NOTE_DATA (note)));
  return note;
}

/* Add INSN to the end of the doubly-linked list, between PREV and NEXT.
   INSN may be any object that can appear in the chain: INSN_P and NOTE_P objects,
   but also BARRIERs and JUMP_TABLE_DATAs.  PREV and NEXT may be NULL.  */

static inline void
link_insn_into_chain (rtx_insn *insn, rtx_insn *prev, rtx_insn *next)
{
  SET_PREV_INSN (insn) = prev;
  SET_NEXT_INSN (insn) = next;
  if (prev != NULL)
    {
      SET_NEXT_INSN (prev) = insn;
      if (NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
	{
	  rtx_sequence *sequence = as_a <rtx_sequence *> (PATTERN (prev));
	  SET_NEXT_INSN (sequence->insn (sequence->len () - 1)) = insn;
	}
    }
  if (next != NULL)
    {
      SET_PREV_INSN (next) = insn;
      if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE)
	{
	  rtx_sequence *sequence = as_a <rtx_sequence *> (PATTERN (next));
	  SET_PREV_INSN (sequence->insn (0)) = insn;
	}
    }

  if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
    {
      rtx_sequence *sequence = as_a <rtx_sequence *> (PATTERN (insn));
      SET_PREV_INSN (sequence->insn (0)) = prev;
      SET_NEXT_INSN (sequence->insn (sequence->len () - 1)) = next;
    }
}

/* Add INSN to the end of the doubly-linked list.
   INSN may be an INSN, JUMP_INSN, CALL_INSN, CODE_LABEL, BARRIER or NOTE.  */

void
add_insn (rtx_insn *insn)
{
  rtx_insn *prev = get_last_insn ();
  link_insn_into_chain (insn, prev, NULL);
  if (get_insns () == NULL)
    set_first_insn (insn);
  set_last_insn (insn);
}

/* Add INSN into the doubly-linked list after insn AFTER.  */

static void
add_insn_after_nobb (rtx_insn *insn, rtx_insn *after)
{
  rtx_insn *next = NEXT_INSN (after);

  gcc_assert (!optimize || !after->deleted ());

  link_insn_into_chain (insn, after, next);

  if (next == NULL)
    {
      struct sequence_stack *seq;

      for (seq = get_current_sequence (); seq; seq = seq->next)
	if (after == seq->last)
	  {
	    seq->last = insn;
	    break;
	  }
    }
}

/* Add INSN into the doubly-linked list before insn BEFORE.  */

static void
add_insn_before_nobb (rtx_insn *insn, rtx_insn *before)
{
  rtx_insn *prev = PREV_INSN (before);

  gcc_assert (!optimize || !before->deleted ());

  link_insn_into_chain (insn, prev, before);

  if (prev == NULL)
    {
      struct sequence_stack *seq;

      for (seq = get_current_sequence (); seq; seq = seq->next)
	if (before == seq->first)
	  {
	    seq->first = insn;
	    break;
	  }

      gcc_assert (seq);
    }
}

/* Like add_insn_after_nobb, but try to set BLOCK_FOR_INSN.
   If BB is NULL, an attempt is made to infer the bb from before.

   This and the next function should be the only functions called
   to insert an insn once delay slots have been filled since only
   they know how to update a SEQUENCE. */

void
add_insn_after (rtx_insn *insn, rtx_insn *after, basic_block bb)
{
  add_insn_after_nobb (insn, after);
  if (!BARRIER_P (after)
      && !BARRIER_P (insn)
      && (bb = BLOCK_FOR_INSN (after)))
    {
      set_block_for_insn (insn, bb);
      if (INSN_P (insn))
	df_insn_rescan (insn);
      /* Should not happen as first in the BB is always
	 either NOTE or LABEL.  */
      if (BB_END (bb) == after
	  /* Avoid clobbering of structure when creating new BB.  */
	  && !BARRIER_P (insn)
	  && !NOTE_INSN_BASIC_BLOCK_P (insn))
	BB_END (bb) = insn;
    }
}

/* Like add_insn_before_nobb, but try to set BLOCK_FOR_INSN.
   If BB is NULL, an attempt is made to infer the bb from before.

   This and the previous function should be the only functions called
   to insert an insn once delay slots have been filled since only
   they know how to update a SEQUENCE. */

void
add_insn_before (rtx_insn *insn, rtx_insn *before, basic_block bb)
{
  add_insn_before_nobb (insn, before);

  if (!bb
      && !BARRIER_P (before)
      && !BARRIER_P (insn))
    bb = BLOCK_FOR_INSN (before);

  if (bb)
    {
      set_block_for_insn (insn, bb);
      if (INSN_P (insn))
	df_insn_rescan (insn);
      /* Should not happen as first in the BB is always either NOTE or
	 LABEL.  */
      gcc_assert (BB_HEAD (bb) != insn
		  /* Avoid clobbering of structure when creating new BB.  */
		  || BARRIER_P (insn)
		  || NOTE_INSN_BASIC_BLOCK_P (insn));
    }
}

/* Replace insn with an deleted instruction note.  */

void
set_insn_deleted (rtx_insn *insn)
{
  if (INSN_P (insn))
    df_insn_delete (insn);
  PUT_CODE (insn, NOTE);
  NOTE_KIND (insn) = NOTE_INSN_DELETED;
}


/* Unlink INSN from the insn chain.

   This function knows how to handle sequences.
   
   This function does not invalidate data flow information associated with
   INSN (i.e. does not call df_insn_delete).  That makes this function
   usable for only disconnecting an insn from the chain, and re-emit it
   elsewhere later.

   To later insert INSN elsewhere in the insn chain via add_insn and
   similar functions, PREV_INSN and NEXT_INSN must be nullified by
   the caller.  Nullifying them here breaks many insn chain walks.

   To really delete an insn and related DF information, use delete_insn.  */

void
remove_insn (rtx_insn *insn)
{
  rtx_insn *next = NEXT_INSN (insn);
  rtx_insn *prev = PREV_INSN (insn);
  basic_block bb;

  if (prev)
    {
      SET_NEXT_INSN (prev) = next;
      if (NONJUMP_INSN_P (prev) && GET_CODE (PATTERN (prev)) == SEQUENCE)
	{
	  rtx_sequence *sequence = as_a <rtx_sequence *> (PATTERN (prev));
	  SET_NEXT_INSN (sequence->insn (sequence->len () - 1)) = next;
	}
    }
  else
    {
      struct sequence_stack *seq;

      for (seq = get_current_sequence (); seq; seq = seq->next)
	if (insn == seq->first)
	  {
	    seq->first = next;
	    break;
	  }

      gcc_assert (seq);
    }

  if (next)
    {
      SET_PREV_INSN (next) = prev;
      if (NONJUMP_INSN_P (next) && GET_CODE (PATTERN (next)) == SEQUENCE)
	{
	  rtx_sequence *sequence = as_a <rtx_sequence *> (PATTERN (next));
	  SET_PREV_INSN (sequence->insn (0)) = prev;
	}
    }
  else
    {
      struct sequence_stack *seq;

      for (seq = get_current_sequence (); seq; seq = seq->next)
	if (insn == seq->last)
	  {
	    seq->last = prev;
	    break;
	  }

      gcc_assert (seq);
    }

  /* Fix up basic block boundaries, if necessary.  */
  if (!BARRIER_P (insn)
      && (bb = BLOCK_FOR_INSN (insn)))
    {
      if (BB_HEAD (bb) == insn)
	{
	  /* Never ever delete the basic block note without deleting whole
	     basic block.  */
	  gcc_assert (!NOTE_P (insn));
	  BB_HEAD (bb) = next;
	}
      if (BB_END (bb) == insn)
	BB_END (bb) = prev;
    }
}

/* Append CALL_FUSAGE to the CALL_INSN_FUNCTION_USAGE for CALL_INSN.  */

void
add_function_usage_to (rtx call_insn, rtx call_fusage)
{
  gcc_assert (call_insn && CALL_P (call_insn));

  /* Put the register usage information on the CALL.  If there is already
     some usage information, put ours at the end.  */
  if (CALL_INSN_FUNCTION_USAGE (call_insn))
    {
      rtx link;

      for (link = CALL_INSN_FUNCTION_USAGE (call_insn); XEXP (link, 1) != 0;
	   link = XEXP (link, 1))
	;

      XEXP (link, 1) = call_fusage;
    }
  else
    CALL_INSN_FUNCTION_USAGE (call_insn) = call_fusage;
}

/* Delete all insns made since FROM.
   FROM becomes the new last instruction.  */

void
delete_insns_since (rtx_insn *from)
{
  if (from == 0)
    set_first_insn (0);
  else
    SET_NEXT_INSN (from) = 0;
  set_last_insn (from);
}

/* This function is deprecated, please use sequences instead.

   Move a consecutive bunch of insns to a different place in the chain.
   The insns to be moved are those between FROM and TO.
   They are moved to a new position after the insn AFTER.
   AFTER must not be FROM or TO or any insn in between.

   This function does not know about SEQUENCEs and hence should not be
   called after delay-slot filling has been done.  */

void
reorder_insns_nobb (rtx_insn *from, rtx_insn *to, rtx_insn *after)
{
  if (flag_checking)
    {
      for (rtx_insn *x = from; x != to; x = NEXT_INSN (x))
	gcc_assert (after != x);
      gcc_assert (after != to);
    }

  /* Splice this bunch out of where it is now.  */
  if (PREV_INSN (from))
    SET_NEXT_INSN (PREV_INSN (from)) = NEXT_INSN (to);
  if (NEXT_INSN (to))
    SET_PREV_INSN (NEXT_INSN (to)) = PREV_INSN (from);
  if (get_last_insn () == to)
    set_last_insn (PREV_INSN (from));
  if (get_insns () == from)
    set_first_insn (NEXT_INSN (to));

  /* Make the new neighbors point to it and it to them.  */
  if (NEXT_INSN (after))
    SET_PREV_INSN (NEXT_INSN (after)) = to;

  SET_NEXT_INSN (to) = NEXT_INSN (after);
  SET_PREV_INSN (from) = after;
  SET_NEXT_INSN (after) = from;
  if (after == get_last_insn ())
    set_last_insn (to);
}

/* Same as function above, but take care to update BB boundaries.  */
void
reorder_insns (rtx_insn *from, rtx_insn *to, rtx_insn *after)
{
  rtx_insn *prev = PREV_INSN (from);
  basic_block bb, bb2;

  reorder_insns_nobb (from, to, after);

  if (!BARRIER_P (after)
      && (bb = BLOCK_FOR_INSN (after)))
    {
      rtx_insn *x;
      df_set_bb_dirty (bb);

      if (!BARRIER_P (from)
	  && (bb2 = BLOCK_FOR_INSN (from)))
	{
	  if (BB_END (bb2) == to)
	    BB_END (bb2) = prev;
	  df_set_bb_dirty (bb2);
	}

      if (BB_END (bb) == after)
	BB_END (bb) = to;

      for (x = from; x != NEXT_INSN (to); x = NEXT_INSN (x))
	if (!BARRIER_P (x))
	  df_insn_change_bb (x, bb);
    }
}


/* Emit insn(s) of given code and pattern
   at a specified place within the doubly-linked list.

   All of the emit_foo global entry points accept an object
   X which is either an insn list or a PATTERN of a single
   instruction.

   There are thus a few canonical ways to generate code and
   emit it at a specific place in the instruction stream.  For
   example, consider the instruction named SPOT and the fact that
   we would like to emit some instructions before SPOT.  We might
   do it like this:

	start_sequence ();
	... emit the new instructions ...
	insns_head = get_insns ();
	end_sequence ();

	emit_insn_before (insns_head, SPOT);

   It used to be common to generate SEQUENCE rtl instead, but that
   is a relic of the past which no longer occurs.  The reason is that
   SEQUENCE rtl results in much fragmented RTL memory since the SEQUENCE
   generated would almost certainly die right after it was created.  */

static rtx_insn *
emit_pattern_before_noloc (rtx x, rtx_insn *before, rtx_insn *last,
			   basic_block bb,
                           rtx_insn *(*make_raw) (rtx))
{
  rtx_insn *insn;

  gcc_assert (before);

  if (x == NULL_RTX)
    return last;

  switch (GET_CODE (x))
    {
    case DEBUG_INSN:
    case INSN:
    case JUMP_INSN:
    case CALL_INSN:
    case CODE_LABEL:
    case BARRIER:
    case NOTE:
      insn = as_a <rtx_insn *> (x);
      while (insn)
	{
	  rtx_insn *next = NEXT_INSN (insn);
	  add_insn_before (insn, before, bb);
	  last = insn;
	  insn = next;
	}
      break;

#ifdef ENABLE_RTL_CHECKING
    case SEQUENCE:
      gcc_unreachable ();
      break;
#endif

    default:
      last = (*make_raw) (x);
      add_insn_before (last, before, bb);
      break;
    }

  return last;
}

/* Make X be output before the instruction BEFORE.  */

rtx_insn *
emit_insn_before_noloc (rtx x, rtx_insn *before, basic_block bb)
{
  return emit_pattern_before_noloc (x, before, before, bb, make_insn_raw);
}

/* Make an instruction with body X and code JUMP_INSN
   and output it before the instruction BEFORE.  */

rtx_jump_insn *
emit_jump_insn_before_noloc (rtx x, rtx_insn *before)
{
  return as_a <rtx_jump_insn *> (
		emit_pattern_before_noloc (x, before, NULL, NULL,
					   make_jump_insn_raw));
}

/* Make an instruction with body X and code CALL_INSN
   and output it before the instruction BEFORE.  */

rtx_insn *
emit_call_insn_before_noloc (rtx x, rtx_insn *before)
{
  return emit_pattern_before_noloc (x, before, NULL, NULL,
				    make_call_insn_raw);
}

/* Make an instruction with body X and code DEBUG_INSN
   and output it before the instruction BEFORE.  */

rtx_insn *
emit_debug_insn_before_noloc (rtx x, rtx_insn *before)
{
  return emit_pattern_before_noloc (x, before, NULL, NULL,
				    make_debug_insn_raw);
}

/* Make an insn of code BARRIER
   and output it before the insn BEFORE.  */

rtx_barrier *
emit_barrier_before (rtx_insn *before)
{
  rtx_barrier *insn = as_a <rtx_barrier *> (rtx_alloc (BARRIER));

  INSN_UID (insn) = cur_insn_uid++;

  add_insn_before (insn, before, NULL);
  return insn;
}

/* Emit the label LABEL before the insn BEFORE.  */

rtx_code_label *
emit_label_before (rtx_code_label *label, rtx_insn *before)
{
  gcc_checking_assert (INSN_UID (label) == 0);
  INSN_UID (label) = cur_insn_uid++;
  add_insn_before (label, before, NULL);
  return label;
}

/* Helper for emit_insn_after, handles lists of instructions
   efficiently.  */

static rtx_insn *
emit_insn_after_1 (rtx_insn *first, rtx_insn *after, basic_block bb)
{
  rtx_insn *last;
  rtx_insn *after_after;
  if (!bb && !BARRIER_P (after))
    bb = BLOCK_FOR_INSN (after);

  if (bb)
    {
      df_set_bb_dirty (bb);
      for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
	if (!BARRIER_P (last))
	  {
	    set_block_for_insn (last, bb);
	    df_insn_rescan (last);
	  }
      if (!BARRIER_P (last))
	{
	  set_block_for_insn (last, bb);
	  df_insn_rescan (last);
	}
      if (BB_END (bb) == after)
	BB_END (bb) = last;
    }
  else
    for (last = first; NEXT_INSN (last); last = NEXT_INSN (last))
      continue;

  after_after = NEXT_INSN (after);

  SET_NEXT_INSN (after) = first;
  SET_PREV_INSN (first) = after;
  SET_NEXT_INSN (last) = after_after;
  if (after_after)
    SET_PREV_INSN (after_after) = last;

  if (after == get_last_insn ())
    set_last_insn (last);

  return last;
}

static rtx_insn *
emit_pattern_after_noloc (rtx x, rtx_insn *after, basic_block bb,
			  rtx_insn *(*make_raw)(rtx))
{
  rtx_insn *last = after;

  gcc_assert (after);

  if (x == NULL_RTX)
    return last;

  switch (GET_CODE (x))
    {
    case DEBUG_INSN:
    case INSN:
    case JUMP_INSN:
    case CALL_INSN:
    case CODE_LABEL:
    case BARRIER:
    case NOTE:
      last = emit_insn_after_1 (as_a <rtx_insn *> (x), after, bb);
      break;

#ifdef ENABLE_RTL_CHECKING
    case SEQUENCE:
      gcc_unreachable ();
      break;
#endif

    default:
      last = (*make_raw) (x);
      add_insn_after (last, after, bb);
      break;
    }

  return last;
}

/* Make X be output after the insn AFTER and set the BB of insn.  If
   BB is NULL, an attempt is made to infer the BB from AFTER.  */

rtx_insn *
emit_insn_after_noloc (rtx x, rtx_insn *after, basic_block bb)
{
  return emit_pattern_after_noloc (x, after, bb, make_insn_raw);
}


/* Make an insn of code JUMP_INSN with body X
   and output it after the insn AFTER.  */

rtx_jump_insn *
emit_jump_insn_after_noloc (rtx x, rtx_insn *after)
{
  return as_a <rtx_jump_insn *> (
		emit_pattern_after_noloc (x, after, NULL, make_jump_insn_raw));
}

/* Make an instruction with body X and code CALL_INSN
   and output it after the instruction AFTER.  */

rtx_insn *
emit_call_insn_after_noloc (rtx x, rtx_insn *after)
{
  return emit_pattern_after_noloc (x, after, NULL, make_call_insn_raw);
}

/* Make an instruction with body X and code CALL_INSN
   and output it after the instruction AFTER.  */

rtx_insn *
emit_debug_insn_after_noloc (rtx x, rtx_insn *after)
{
  return emit_pattern_after_noloc (x, after, NULL, make_debug_insn_raw);
}

/* Make an insn of code BARRIER
   and output it after the insn AFTER.  */

rtx_barrier *
emit_barrier_after (rtx_insn *after)
{
  rtx_barrier *insn = as_a <rtx_barrier *> (rtx_alloc (BARRIER));

  INSN_UID (insn) = cur_insn_uid++;

  add_insn_after (insn, after, NULL);
  return insn;
}

/* Emit the label LABEL after the insn AFTER.  */

rtx_insn *
emit_label_after (rtx_insn *label, rtx_insn *after)
{
  gcc_checking_assert (INSN_UID (label) == 0);
  INSN_UID (label) = cur_insn_uid++;
  add_insn_after (label, after, NULL);
  return label;
}

/* Notes require a bit of special handling: Some notes need to have their
   BLOCK_FOR_INSN set, others should never have it set, and some should
   have it set or clear depending on the context.   */

/* Return true iff a note of kind SUBTYPE should be emitted with routines
   that never set BLOCK_FOR_INSN on NOTE.  BB_BOUNDARY is true if the
   caller is asked to emit a note before BB_HEAD, or after BB_END.  */

static bool
note_outside_basic_block_p (enum insn_note subtype, bool on_bb_boundary_p)
{
  switch (subtype)
    {
      /* NOTE_INSN_SWITCH_TEXT_SECTIONS only appears between basic blocks.  */
      case NOTE_INSN_SWITCH_TEXT_SECTIONS:
	return true;

      /* Notes for var tracking and EH region markers can appear between or
	 inside basic blocks.  If the caller is emitting on the basic block
	 boundary, do not set BLOCK_FOR_INSN on the new note.  */
      case NOTE_INSN_VAR_LOCATION:
      case NOTE_INSN_EH_REGION_BEG:
      case NOTE_INSN_EH_REGION_END:
	return on_bb_boundary_p;

      /* Otherwise, BLOCK_FOR_INSN must be set.  */
      default:
	return false;
    }
}

/* Emit a note of subtype SUBTYPE after the insn AFTER.  */

rtx_note *
emit_note_after (enum insn_note subtype, rtx_insn *after)
{
  rtx_note *note = make_note_raw (subtype);
  basic_block bb = BARRIER_P (after) ? NULL : BLOCK_FOR_INSN (after);
  bool on_bb_boundary_p = (bb != NULL && BB_END (bb) == after);

  if (note_outside_basic_block_p (subtype, on_bb_boundary_p))
    add_insn_after_nobb (note, after);
  else
    add_insn_after (note, after, bb);
  return note;
}

/* Emit a note of subtype SUBTYPE before the insn BEFORE.  */

rtx_note *
emit_note_before (enum insn_note subtype, rtx_insn *before)
{
  rtx_note *note = make_note_raw (subtype);
  basic_block bb = BARRIER_P (before) ? NULL : BLOCK_FOR_INSN (before);
  bool on_bb_boundary_p = (bb != NULL && BB_HEAD (bb) == before);

  if (note_outside_basic_block_p (subtype, on_bb_boundary_p))
    add_insn_before_nobb (note, before);
  else
    add_insn_before (note, before, bb);
  return note;
}

/* Insert PATTERN after AFTER, setting its INSN_LOCATION to LOC.
   MAKE_RAW indicates how to turn PATTERN into a real insn.  */

static rtx_insn *
emit_pattern_after_setloc (rtx pattern, rtx_insn *after, location_t loc,
			   rtx_insn *(*make_raw) (rtx))
{
  rtx_insn *last = emit_pattern_after_noloc (pattern, after, NULL, make_raw);

  if (pattern == NULL_RTX || !loc)
    return last;

  after = NEXT_INSN (after);
  while (1)
    {
      if (active_insn_p (after)
	  && !JUMP_TABLE_DATA_P (after) /* FIXME */
	  && !INSN_LOCATION (after))
	INSN_LOCATION (after) = loc;
      if (after == last)
	break;
      after = NEXT_INSN (after);
    }
  return last;
}

/* Insert PATTERN after AFTER.  MAKE_RAW indicates how to turn PATTERN
   into a real insn.  SKIP_DEBUG_INSNS indicates whether to insert after
   any DEBUG_INSNs.  */

static rtx_insn *
emit_pattern_after (rtx pattern, rtx_insn *after, bool skip_debug_insns,
		    rtx_insn *(*make_raw) (rtx))
{
  rtx_insn *prev = after;

  if (skip_debug_insns)
    while (DEBUG_INSN_P (prev))
      prev = PREV_INSN (prev);

  if (INSN_P (prev))
    return emit_pattern_after_setloc (pattern, after, INSN_LOCATION (prev),
				      make_raw);
  else
    return emit_pattern_after_noloc (pattern, after, NULL, make_raw);
}

/* Like emit_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
rtx_insn *
emit_insn_after_setloc (rtx pattern, rtx_insn *after, location_t loc)
{
  return emit_pattern_after_setloc (pattern, after, loc, make_insn_raw);
}

/* Like emit_insn_after_noloc, but set INSN_LOCATION according to AFTER.  */
rtx_insn *
emit_insn_after (rtx pattern, rtx_insn *after)
{
  return emit_pattern_after (pattern, after, true, make_insn_raw);
}

/* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
rtx_jump_insn *
emit_jump_insn_after_setloc (rtx pattern, rtx_insn *after, location_t loc)
{
  return as_a <rtx_jump_insn *> (
	emit_pattern_after_setloc (pattern, after, loc, make_jump_insn_raw));
}

/* Like emit_jump_insn_after_noloc, but set INSN_LOCATION according to AFTER.  */
rtx_jump_insn *
emit_jump_insn_after (rtx pattern, rtx_insn *after)
{
  return as_a <rtx_jump_insn *> (
	emit_pattern_after (pattern, after, true, make_jump_insn_raw));
}

/* Like emit_call_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
rtx_insn *
emit_call_insn_after_setloc (rtx pattern, rtx_insn *after, location_t loc)
{
  return emit_pattern_after_setloc (pattern, after, loc, make_call_insn_raw);
}

/* Like emit_call_insn_after_noloc, but set INSN_LOCATION according to AFTER.  */
rtx_insn *
emit_call_insn_after (rtx pattern, rtx_insn *after)
{
  return emit_pattern_after (pattern, after, true, make_call_insn_raw);
}

/* Like emit_debug_insn_after_noloc, but set INSN_LOCATION according to LOC.  */
rtx_insn *
emit_debug_insn_after_setloc (rtx pattern, rtx_insn *after, location_t loc)
{
  return emit_pattern_after_setloc (pattern, after, loc, make_debug_insn_raw);
}

/* Like emit_debug_insn_after_noloc, but set INSN_LOCATION according to AFTER.  */
rtx_insn *
emit_debug_insn_after (rtx pattern, rtx_insn *after)
{
  return emit_pattern_after (pattern, after, false, make_debug_insn_raw);
}

/* Insert PATTERN before BEFORE, setting its INSN_LOCATION to LOC.
   MAKE_RAW indicates how to turn PATTERN into a real insn.  INSNP
   indicates if PATTERN is meant for an INSN as opposed to a JUMP_INSN,
   CALL_INSN, etc.  */

static rtx_insn *
emit_pattern_before_setloc (rtx pattern, rtx_insn *before, location_t loc,
			    bool insnp, rtx_insn *(*make_raw) (rtx))
{
  rtx_insn *first = PREV_INSN (before);
  rtx_insn *last = emit_pattern_before_noloc (pattern, before,
					      insnp ? before : NULL,
					      NULL, make_raw);

  if (pattern == NULL_RTX || !loc)
    return last;

  if (!first)
    first = get_insns ();
  else
    first = NEXT_INSN (first);
  while (1)
    {
      if (active_insn_p (first)
	  && !JUMP_TABLE_DATA_P (first) /* FIXME */
	  && !INSN_LOCATION (first))
	INSN_LOCATION (first) = loc;
      if (first == last)
	break;
      first = NEXT_INSN (first);
    }
  return last;
}

/* Insert PATTERN before BEFORE.  MAKE_RAW indicates how to turn PATTERN
   into a real insn.  SKIP_DEBUG_INSNS indicates whether to insert
   before any DEBUG_INSNs.  INSNP indicates if PATTERN is meant for an
   INSN as opposed to a JUMP_INSN, CALL_INSN, etc.  */

static rtx_insn *
emit_pattern_before (rtx pattern, rtx_insn *before, bool skip_debug_insns,
		     bool insnp, rtx_insn *(*make_raw) (rtx))
{
  rtx_insn *next = before;

  if (skip_debug_insns)
    while (DEBUG_INSN_P (next))
      next = PREV_INSN (next);

  if (INSN_P (next))
    return emit_pattern_before_setloc (pattern, before, INSN_LOCATION (next),
				       insnp, make_raw);
  else
    return emit_pattern_before_noloc (pattern, before,
				      insnp ? before : NULL,
                                      NULL, make_raw);
}

/* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
rtx_insn *
emit_insn_before_setloc (rtx pattern, rtx_insn *before, location_t loc)
{
  return emit_pattern_before_setloc (pattern, before, loc, true,
				     make_insn_raw);
}

/* Like emit_insn_before_noloc, but set INSN_LOCATION according to BEFORE.  */
rtx_insn *
emit_insn_before (rtx pattern, rtx_insn *before)
{
  return emit_pattern_before (pattern, before, true, true, make_insn_raw);
}

/* like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
rtx_jump_insn *
emit_jump_insn_before_setloc (rtx pattern, rtx_insn *before, location_t loc)
{
  return as_a <rtx_jump_insn *> (
	emit_pattern_before_setloc (pattern, before, loc, false,
				    make_jump_insn_raw));
}

/* Like emit_jump_insn_before_noloc, but set INSN_LOCATION according to BEFORE.  */
rtx_jump_insn *
emit_jump_insn_before (rtx pattern, rtx_insn *before)
{
  return as_a <rtx_jump_insn *> (
	emit_pattern_before (pattern, before, true, false,
			     make_jump_insn_raw));
}

/* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
rtx_insn *
emit_call_insn_before_setloc (rtx pattern, rtx_insn *before, location_t loc)
{
  return emit_pattern_before_setloc (pattern, before, loc, false,
				     make_call_insn_raw);
}

/* Like emit_call_insn_before_noloc,
   but set insn_location according to BEFORE.  */
rtx_insn *
emit_call_insn_before (rtx pattern, rtx_insn *before)
{
  return emit_pattern_before (pattern, before, true, false,
			      make_call_insn_raw);
}

/* Like emit_insn_before_noloc, but set INSN_LOCATION according to LOC.  */
rtx_insn *
emit_debug_insn_before_setloc (rtx pattern, rtx_insn *before, location_t loc)
{
  return emit_pattern_before_setloc (pattern, before, loc, false,
				     make_debug_insn_raw);
}

/* Like emit_debug_insn_before_noloc,
   but set insn_location according to BEFORE.  */
rtx_insn *
emit_debug_insn_before (rtx pattern, rtx_insn *before)
{
  return emit_pattern_before (pattern, before, false, false,
			      make_debug_insn_raw);
}

/* Take X and emit it at the end of the doubly-linked
   INSN list.

   Returns the last insn emitted.  */

rtx_insn *
emit_insn (rtx x)
{
  rtx_insn *last = get_last_insn ();
  rtx_insn *insn;

  if (x == NULL_RTX)
    return last;

  switch (GET_CODE (x))
    {
    case DEBUG_INSN:
    case INSN:
    case JUMP_INSN:
    case CALL_INSN:
    case CODE_LABEL:
    case BARRIER:
    case NOTE:
      insn = as_a <rtx_insn *> (x);
      while (insn)
	{
	  rtx_insn *next = NEXT_INSN (insn);
	  add_insn (insn);
	  last = insn;
	  insn = next;
	}
      break;

#ifdef ENABLE_RTL_CHECKING
    case JUMP_TABLE_DATA:
    case SEQUENCE:
      gcc_unreachable ();
      break;
#endif

    default:
      last = make_insn_raw (x);
      add_insn (last);
      break;
    }

  return last;
}

/* Make an insn of code DEBUG_INSN with pattern X
   and add it to the end of the doubly-linked list.  */

rtx_insn *
emit_debug_insn (rtx x)
{
  rtx_insn *last = get_last_insn ();
  rtx_insn *insn;

  if (x == NULL_RTX)
    return last;

  switch (GET_CODE (x))
    {
    case DEBUG_INSN:
    case INSN:
    case JUMP_INSN:
    case CALL_INSN:
    case CODE_LABEL:
    case BARRIER:
    case NOTE:
      insn = as_a <rtx_insn *> (x);
      while (insn)
	{
	  rtx_insn *next = NEXT_INSN (insn);
	  add_insn (insn);
	  last = insn;
	  insn = next;
	}
      break;

#ifdef ENABLE_RTL_CHECKING
    case JUMP_TABLE_DATA:
    case SEQUENCE:
      gcc_unreachable ();
      break;
#endif

    default:
      last = make_debug_insn_raw (x);
      add_insn (last);
      break;
    }

  return last;
}

/* Make an insn of code JUMP_INSN with pattern X
   and add it to the end of the doubly-linked list.  */

rtx_insn *
emit_jump_insn (rtx x)
{
  rtx_insn *last = NULL;
  rtx_insn *insn;

  switch (GET_CODE (x))
    {
    case DEBUG_INSN:
    case INSN:
    case JUMP_INSN:
    case CALL_INSN:
    case CODE_LABEL:
    case BARRIER:
    case NOTE:
      insn = as_a <rtx_insn *> (x);
      while (insn)
	{
	  rtx_insn *next = NEXT_INSN (insn);
	  add_insn (insn);
	  last = insn;
	  insn = next;
	}
      break;

#ifdef ENABLE_RTL_CHECKING
    case JUMP_TABLE_DATA:
    case SEQUENCE:
      gcc_unreachable ();
      break;
#endif

    default:
      last = make_jump_insn_raw (x);
      add_insn (last);
      break;
    }

  return last;
}

/* Make an insn of code JUMP_INSN with pattern X,
   add a REG_BR_PROB note that indicates very likely probability,
   and add it to the end of the doubly-linked list.  */

rtx_insn *
emit_likely_jump_insn (rtx x)
{
  rtx_insn *jump = emit_jump_insn (x);
  add_reg_br_prob_note (jump, profile_probability::very_likely ());
  return jump;
}

/* Make an insn of code JUMP_INSN with pattern X,
   add a REG_BR_PROB note that indicates very unlikely probability,
   and add it to the end of the doubly-linked list.  */

rtx_insn *
emit_unlikely_jump_insn (rtx x)
{
  rtx_insn *jump = emit_jump_insn (x);
  add_reg_br_prob_note (jump, profile_probability::very_unlikely ());
  return jump;
}

/* Make an insn of code CALL_INSN with pattern X
   and add it to the end of the doubly-linked list.  */

rtx_insn *
emit_call_insn (rtx x)
{
  rtx_insn *insn;

  switch (GET_CODE (x))
    {
    case DEBUG_INSN:
    case INSN:
    case JUMP_INSN:
    case CALL_INSN:
    case CODE_LABEL:
    case BARRIER:
    case NOTE:
      insn = emit_insn (x);
      break;

#ifdef ENABLE_RTL_CHECKING
    case SEQUENCE:
    case JUMP_TABLE_DATA:
      gcc_unreachable ();
      break;
#endif

    default:
      insn = make_call_insn_raw (x);
      add_insn (insn);
      break;
    }

  return insn;
}

/* Add the label LABEL to the end of the doubly-linked list.  */

rtx_code_label *
emit_label (rtx uncast_label)
{
  rtx_code_label *label = as_a <rtx_code_label *> (uncast_label);

  gcc_checking_assert (INSN_UID (label) == 0);
  INSN_UID (label) = cur_insn_uid++;
  add_insn (label);
  return label;
}

/* Make an insn of code JUMP_TABLE_DATA
   and add it to the end of the doubly-linked list.  */

rtx_jump_table_data *
emit_jump_table_data (rtx table)
{
  rtx_jump_table_data *jump_table_data =
    as_a <rtx_jump_table_data *> (rtx_alloc (JUMP_TABLE_DATA));
  INSN_UID (jump_table_data) = cur_insn_uid++;
  PATTERN (jump_table_data) = table;
  BLOCK_FOR_INSN (jump_table_data) = NULL;
  add_insn (jump_table_data);
  return jump_table_data;
}

/* Make an insn of code BARRIER
   and add it to the end of the doubly-linked list.  */

rtx_barrier *
emit_barrier (void)
{
  rtx_barrier *barrier = as_a <rtx_barrier *> (rtx_alloc (BARRIER));
  INSN_UID (barrier) = cur_insn_uid++;
  add_insn (barrier);
  return barrier;
}

/* Emit a copy of note ORIG.  */

rtx_note *
emit_note_copy (rtx_note *orig)
{
  enum insn_note kind = (enum insn_note) NOTE_KIND (orig);
  rtx_note *note = make_note_raw (kind);
  NOTE_DATA (note) = NOTE_DATA (orig);
  add_insn (note);
  return note;
}

/* Make an insn of code NOTE or type NOTE_NO
   and add it to the end of the doubly-linked list.  */

rtx_note *
emit_note (enum insn_note kind)
{
  rtx_note *note = make_note_raw (kind);
  add_insn (note);
  return note;
}

/* Emit a clobber of lvalue X.  */

rtx_insn *
emit_clobber (rtx x)
{
  /* CONCATs should not appear in the insn stream.  */
  if (GET_CODE (x) == CONCAT)
    {
      emit_clobber (XEXP (x, 0));
      return emit_clobber (XEXP (x, 1));
    }
  return emit_insn (gen_rtx_CLOBBER (VOIDmode, x));
}

/* Return a sequence of insns to clobber lvalue X.  */

rtx_insn *
gen_clobber (rtx x)
{
  rtx_insn *seq;

  start_sequence ();
  emit_clobber (x);
  seq = get_insns ();
  end_sequence ();
  return seq;
}

/* Emit a use of rvalue X.  */

rtx_insn *
emit_use (rtx x)
{
  /* CONCATs should not appear in the insn stream.  */
  if (GET_CODE (x) == CONCAT)
    {
      emit_use (XEXP (x, 0));
      return emit_use (XEXP (x, 1));
    }
  return emit_insn (gen_rtx_USE (VOIDmode, x));
}

/* Return a sequence of insns to use rvalue X.  */

rtx_insn *
gen_use (rtx x)
{
  rtx_insn *seq;

  start_sequence ();
  emit_use (x);
  seq = get_insns ();
  end_sequence ();
  return seq;
}

/* Notes like REG_EQUAL and REG_EQUIV refer to a set in an instruction.
   Return the set in INSN that such notes describe, or NULL if the notes
   have no meaning for INSN.  */

rtx
set_for_reg_notes (rtx insn)
{
  rtx pat, reg;

  if (!INSN_P (insn))
    return NULL_RTX;

  pat = PATTERN (insn);
  if (GET_CODE (pat) == PARALLEL)
    {
      /* We do not use single_set because that ignores SETs of unused
	 registers.  REG_EQUAL and REG_EQUIV notes really do require the
	 PARALLEL to have a single SET.  */
      if (multiple_sets (insn))
	return NULL_RTX;
      pat = XVECEXP (pat, 0, 0);
    }

  if (GET_CODE (pat) != SET)
    return NULL_RTX;

  reg = SET_DEST (pat);

  /* Notes apply to the contents of a STRICT_LOW_PART.  */
  if (GET_CODE (reg) == STRICT_LOW_PART
      || GET_CODE (reg) == ZERO_EXTRACT)
    reg = XEXP (reg, 0);

  /* Check that we have a register.  */
  if (!(REG_P (reg) || GET_CODE (reg) == SUBREG))
    return NULL_RTX;

  return pat;
}

/* Place a note of KIND on insn INSN with DATUM as the datum. If a
   note of this type already exists, remove it first.  */

rtx
set_unique_reg_note (rtx insn, enum reg_note kind, rtx datum)
{
  rtx note = find_reg_note (insn, kind, NULL_RTX);

  switch (kind)
    {
    case REG_EQUAL:
    case REG_EQUIV:
      /* We need to support the REG_EQUAL on USE trick of find_reloads.  */
      if (!set_for_reg_notes (insn) && GET_CODE (PATTERN (insn)) != USE)
	return NULL_RTX;

      /* Don't add ASM_OPERAND REG_EQUAL/REG_EQUIV notes.
	 It serves no useful purpose and breaks eliminate_regs.  */
      if (GET_CODE (datum) == ASM_OPERANDS)
	return NULL_RTX;

      /* Notes with side effects are dangerous.  Even if the side-effect
	 initially mirrors one in PATTERN (INSN), later optimizations
	 might alter the way that the final register value is calculated
	 and so move or alter the side-effect in some way.  The note would
	 then no longer be a valid substitution for SET_SRC.  */
      if (side_effects_p (datum))
	return NULL_RTX;
      break;

    default:
      break;
    }

  if (note)
    XEXP (note, 0) = datum;
  else
    {
      add_reg_note (insn, kind, datum);
      note = REG_NOTES (insn);
    }

  switch (kind)
    {
    case REG_EQUAL:
    case REG_EQUIV:
      df_notes_rescan (as_a <rtx_insn *> (insn));
      break;
    default:
      break;
    }

  return note;
}

/* Like set_unique_reg_note, but don't do anything unless INSN sets DST.  */
rtx
set_dst_reg_note (rtx insn, enum reg_note kind, rtx datum, rtx dst)
{
  rtx set = set_for_reg_notes (insn);

  if (set && SET_DEST (set) == dst)
    return set_unique_reg_note (insn, kind, datum);
  return NULL_RTX;
}

/* Emit the rtl pattern X as an appropriate kind of insn.  Also emit a
   following barrier if the instruction needs one and if ALLOW_BARRIER_P
   is true.

   If X is a label, it is simply added into the insn chain.  */

rtx_insn *
emit (rtx x, bool allow_barrier_p)
{
  enum rtx_code code = classify_insn (x);

  switch (code)
    {
    case CODE_LABEL:
      return emit_label (x);
    case INSN:
      return emit_insn (x);
    case  JUMP_INSN:
      {
	rtx_insn *insn = emit_jump_insn (x);
	if (allow_barrier_p
	    && (any_uncondjump_p (insn) || GET_CODE (x) == RETURN))
	  return emit_barrier ();
	return insn;
      }
    case CALL_INSN:
      return emit_call_insn (x);
    case DEBUG_INSN:
      return emit_debug_insn (x);
    default:
      gcc_unreachable ();
    }
}

/* Space for free sequence stack entries.  */
static GTY ((deletable)) struct sequence_stack *free_sequence_stack;

/* Begin emitting insns to a sequence.  If this sequence will contain
   something that might cause the compiler to pop arguments to function
   calls (because those pops have previously been deferred; see
   INHIBIT_DEFER_POP for more details), use do_pending_stack_adjust
   before calling this function.  That will ensure that the deferred
   pops are not accidentally emitted in the middle of this sequence.  */

void
start_sequence (void)
{
  struct sequence_stack *tem;

  if (free_sequence_stack != NULL)
    {
      tem = free_sequence_stack;
      free_sequence_stack = tem->next;
    }
  else
    tem = ggc_alloc<sequence_stack> ();

  tem->next = get_current_sequence ()->next;
  tem->first = get_insns ();
  tem->last = get_last_insn ();
  get_current_sequence ()->next = tem;

  set_first_insn (0);
  set_last_insn (0);
}

/* Set up the insn chain starting with FIRST as the current sequence,
   saving the previously current one.  See the documentation for
   start_sequence for more information about how to use this function.  */

void
push_to_sequence (rtx_insn *first)
{
  rtx_insn *last;

  start_sequence ();

  for (last = first; last && NEXT_INSN (last); last = NEXT_INSN (last))
    ;

  set_first_insn (first);
  set_last_insn (last);
}

/* Like push_to_sequence, but take the last insn as an argument to avoid
   looping through the list.  */

void
push_to_sequence2 (rtx_insn *first, rtx_insn *last)
{
  start_sequence ();

  set_first_insn (first);
  set_last_insn (last);
}

/* Set up the outer-level insn chain
   as the current sequence, saving the previously current one.  */

void
push_topmost_sequence (void)
{
  struct sequence_stack *top;

  start_sequence ();

  top = get_topmost_sequence ();
  set_first_insn (top->first);
  set_last_insn (top->last);
}

/* After emitting to the outer-level insn chain, update the outer-level
   insn chain, and restore the previous saved state.  */

void
pop_topmost_sequence (void)
{
  struct sequence_stack *top;

  top = get_topmost_sequence ();
  top->first = get_insns ();
  top->last = get_last_insn ();

  end_sequence ();
}

/* After emitting to a sequence, restore previous saved state.

   To get the contents of the sequence just made, you must call
   `get_insns' *before* calling here.

   If the compiler might have deferred popping arguments while
   generating this sequence, and this sequence will not be immediately
   inserted into the instruction stream, use do_pending_stack_adjust
   before calling get_insns.  That will ensure that the deferred
   pops are inserted into this sequence, and not into some random
   location in the instruction stream.  See INHIBIT_DEFER_POP for more
   information about deferred popping of arguments.  */

void
end_sequence (void)
{
  struct sequence_stack *tem = get_current_sequence ()->next;

  set_first_insn (tem->first);
  set_last_insn (tem->last);
  get_current_sequence ()->next = tem->next;

  memset (tem, 0, sizeof (*tem));
  tem->next = free_sequence_stack;
  free_sequence_stack = tem;
}

/* Return true if currently emitting into a sequence.  */

bool
in_sequence_p (void)
{
  return get_current_sequence ()->next != 0;
}

/* Put the various virtual registers into REGNO_REG_RTX.  */

static void
init_virtual_regs (void)
{
  regno_reg_rtx[VIRTUAL_INCOMING_ARGS_REGNUM] = virtual_incoming_args_rtx;
  regno_reg_rtx[VIRTUAL_STACK_VARS_REGNUM] = virtual_stack_vars_rtx;
  regno_reg_rtx[VIRTUAL_STACK_DYNAMIC_REGNUM] = virtual_stack_dynamic_rtx;
  regno_reg_rtx[VIRTUAL_OUTGOING_ARGS_REGNUM] = virtual_outgoing_args_rtx;
  regno_reg_rtx[VIRTUAL_CFA_REGNUM] = virtual_cfa_rtx;
  regno_reg_rtx[VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM]
    = virtual_preferred_stack_boundary_rtx;
}


/* Used by copy_insn_1 to avoid copying SCRATCHes more than once.  */
static rtx copy_insn_scratch_in[MAX_RECOG_OPERANDS];
static rtx copy_insn_scratch_out[MAX_RECOG_OPERANDS];
static int copy_insn_n_scratches;

/* When an insn is being copied by copy_insn_1, this is nonzero if we have
   copied an ASM_OPERANDS.
   In that case, it is the original input-operand vector.  */
static rtvec orig_asm_operands_vector;

/* When an insn is being copied by copy_insn_1, this is nonzero if we have
   copied an ASM_OPERANDS.
   In that case, it is the copied input-operand vector.  */
static rtvec copy_asm_operands_vector;

/* Likewise for the constraints vector.  */
static rtvec orig_asm_constraints_vector;
static rtvec copy_asm_constraints_vector;

/* Recursively create a new copy of an rtx for copy_insn.
   This function differs from copy_rtx in that it handles SCRATCHes and
   ASM_OPERANDs properly.
   Normally, this function is not used directly; use copy_insn as front end.
   However, you could first copy an insn pattern with copy_insn and then use
   this function afterwards to properly copy any REG_NOTEs containing
   SCRATCHes.  */

rtx
copy_insn_1 (rtx orig)
{
  rtx copy;
  int i, j;
  RTX_CODE code;
  const char *format_ptr;

  if (orig == NULL)
    return NULL;

  code = GET_CODE (orig);

  switch (code)
    {
    case REG:
    case DEBUG_EXPR:
    CASE_CONST_ANY:
    case SYMBOL_REF:
    case CODE_LABEL:
    case PC:
    case RETURN:
    case SIMPLE_RETURN:
      return orig;
    case CLOBBER:
      /* Share clobbers of hard registers, but do not share pseudo reg
         clobbers or clobbers of hard registers that originated as pseudos.
         This is needed to allow safe register renaming.  */
      if (REG_P (XEXP (orig, 0))
	  && HARD_REGISTER_NUM_P (REGNO (XEXP (orig, 0)))
	  && HARD_REGISTER_NUM_P (ORIGINAL_REGNO (XEXP (orig, 0))))
	return orig;
      break;

    case SCRATCH:
      for (i = 0; i < copy_insn_n_scratches; i++)
	if (copy_insn_scratch_in[i] == orig)
	  return copy_insn_scratch_out[i];
      break;

    case CONST:
      if (shared_const_p (orig))
	return orig;
      break;

      /* A MEM with a constant address is not sharable.  The problem is that
	 the constant address may need to be reloaded.  If the mem is shared,
	 then reloading one copy of this mem will cause all copies to appear
	 to have been reloaded.  */

    default:
      break;
    }

  /* Copy the various flags, fields, and other information.  We assume
     that all fields need copying, and then clear the fields that should
     not be copied.  That is the sensible default behavior, and forces
     us to explicitly document why we are *not* copying a flag.  */
  copy = shallow_copy_rtx (orig);

  /* We do not copy JUMP, CALL, or FRAME_RELATED for INSNs.  */
  if (INSN_P (orig))
    {
      RTX_FLAG (copy, jump) = 0;
      RTX_FLAG (copy, call) = 0;
      RTX_FLAG (copy, frame_related) = 0;
    }

  format_ptr = GET_RTX_FORMAT (GET_CODE (copy));

  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (copy)); i++)
    switch (*format_ptr++)
      {
      case 'e':
	if (XEXP (orig, i) != NULL)
	  XEXP (copy, i) = copy_insn_1 (XEXP (orig, i));
	break;

      case 'E':
      case 'V':
	if (XVEC (orig, i) == orig_asm_constraints_vector)
	  XVEC (copy, i) = copy_asm_constraints_vector;
	else if (XVEC (orig, i) == orig_asm_operands_vector)
	  XVEC (copy, i) = copy_asm_operands_vector;
	else if (XVEC (orig, i) != NULL)
	  {
	    XVEC (copy, i) = rtvec_alloc (XVECLEN (orig, i));
	    for (j = 0; j < XVECLEN (copy, i); j++)
	      XVECEXP (copy, i, j) = copy_insn_1 (XVECEXP (orig, i, j));
	  }
	break;

      case 't':
      case 'w':
      case 'i':
      case 'p':
      case 's':
      case 'S':
      case 'u':
      case '0':
	/* These are left unchanged.  */
	break;

      default:
	gcc_unreachable ();
      }

  if (code == SCRATCH)
    {
      i = copy_insn_n_scratches++;
      gcc_assert (i < MAX_RECOG_OPERANDS);
      copy_insn_scratch_in[i] = orig;
      copy_insn_scratch_out[i] = copy;
    }
  else if (code == ASM_OPERANDS)
    {
      orig_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (orig);
      copy_asm_operands_vector = ASM_OPERANDS_INPUT_VEC (copy);
      orig_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (orig);
      copy_asm_constraints_vector = ASM_OPERANDS_INPUT_CONSTRAINT_VEC (copy);
    }

  return copy;
}

/* Create a new copy of an rtx.
   This function differs from copy_rtx in that it handles SCRATCHes and
   ASM_OPERANDs properly.
   INSN doesn't really have to be a full INSN; it could be just the
   pattern.  */
rtx
copy_insn (rtx insn)
{
  copy_insn_n_scratches = 0;
  orig_asm_operands_vector = 0;
  orig_asm_constraints_vector = 0;
  copy_asm_operands_vector = 0;
  copy_asm_constraints_vector = 0;
  return copy_insn_1 (insn);
}

/* Return a copy of INSN that can be used in a SEQUENCE delay slot,
   on that assumption that INSN itself remains in its original place.  */

rtx_insn *
copy_delay_slot_insn (rtx_insn *insn)
{
  /* Copy INSN with its rtx_code, all its notes, location etc.  */
  insn = as_a <rtx_insn *> (copy_rtx (insn));
  INSN_UID (insn) = cur_insn_uid++;
  return insn;
}

/* Initialize data structures and variables in this file
   before generating rtl for each function.  */

void
init_emit (void)
{
  set_first_insn (NULL);
  set_last_insn (NULL);
  if (param_min_nondebug_insn_uid)
    cur_insn_uid = param_min_nondebug_insn_uid;
  else
    cur_insn_uid = 1;
  cur_debug_insn_uid = 1;
  reg_rtx_no = LAST_VIRTUAL_REGISTER + 1;
  first_label_num = label_num;
  get_current_sequence ()->next = NULL;

  /* Init the tables that describe all the pseudo regs.  */

  crtl->emit.regno_pointer_align_length = LAST_VIRTUAL_REGISTER + 101;

  crtl->emit.regno_pointer_align
    = XCNEWVEC (unsigned char, crtl->emit.regno_pointer_align_length);

  regno_reg_rtx
    = ggc_cleared_vec_alloc<rtx> (crtl->emit.regno_pointer_align_length);

  /* Put copies of all the hard registers into regno_reg_rtx.  */
  memcpy (regno_reg_rtx,
	  initial_regno_reg_rtx,
	  FIRST_PSEUDO_REGISTER * sizeof (rtx));

  /* Put copies of all the virtual register rtx into regno_reg_rtx.  */
  init_virtual_regs ();

  /* Indicate that the virtual registers and stack locations are
     all pointers.  */
  REG_POINTER (stack_pointer_rtx) = 1;
  REG_POINTER (frame_pointer_rtx) = 1;
  REG_POINTER (hard_frame_pointer_rtx) = 1;
  REG_POINTER (arg_pointer_rtx) = 1;

  REG_POINTER (virtual_incoming_args_rtx) = 1;
  REG_POINTER (virtual_stack_vars_rtx) = 1;
  REG_POINTER (virtual_stack_dynamic_rtx) = 1;
  REG_POINTER (virtual_outgoing_args_rtx) = 1;
  REG_POINTER (virtual_cfa_rtx) = 1;

#ifdef STACK_BOUNDARY
  REGNO_POINTER_ALIGN (STACK_POINTER_REGNUM) = STACK_BOUNDARY;
  REGNO_POINTER_ALIGN (FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
  REGNO_POINTER_ALIGN (HARD_FRAME_POINTER_REGNUM) = STACK_BOUNDARY;
  REGNO_POINTER_ALIGN (ARG_POINTER_REGNUM) = STACK_BOUNDARY;

  REGNO_POINTER_ALIGN (VIRTUAL_INCOMING_ARGS_REGNUM) = STACK_BOUNDARY;
  REGNO_POINTER_ALIGN (VIRTUAL_STACK_VARS_REGNUM) = STACK_BOUNDARY;
  REGNO_POINTER_ALIGN (VIRTUAL_STACK_DYNAMIC_REGNUM) = STACK_BOUNDARY;
  REGNO_POINTER_ALIGN (VIRTUAL_OUTGOING_ARGS_REGNUM) = STACK_BOUNDARY;

  REGNO_POINTER_ALIGN (VIRTUAL_CFA_REGNUM) = BITS_PER_WORD;
#endif

#ifdef INIT_EXPANDERS
  INIT_EXPANDERS;
#endif
}

/* Return the value of element I of CONST_VECTOR X as a wide_int.  */

wide_int
const_vector_int_elt (const_rtx x, unsigned int i)
{
  /* First handle elements that are directly encoded.  */
  machine_mode elt_mode = GET_MODE_INNER (GET_MODE (x));
  if (i < (unsigned int) XVECLEN (x, 0))
    return rtx_mode_t (CONST_VECTOR_ENCODED_ELT (x, i), elt_mode);

  /* Identify the pattern that contains element I and work out the index of
     the last encoded element for that pattern.  */
  unsigned int encoded_nelts = const_vector_encoded_nelts (x);
  unsigned int npatterns = CONST_VECTOR_NPATTERNS (x);
  unsigned int count = i / npatterns;
  unsigned int pattern = i % npatterns;
  unsigned int final_i = encoded_nelts - npatterns + pattern;

  /* If there are no steps, the final encoded value is the right one.  */
  if (!CONST_VECTOR_STEPPED_P (x))
    return rtx_mode_t (CONST_VECTOR_ENCODED_ELT (x, final_i), elt_mode);

  /* Otherwise work out the value from the last two encoded elements.  */
  rtx v1 = CONST_VECTOR_ENCODED_ELT (x, final_i - npatterns);
  rtx v2 = CONST_VECTOR_ENCODED_ELT (x, final_i);
  wide_int diff = wi::sub (rtx_mode_t (v2, elt_mode),
			   rtx_mode_t (v1, elt_mode));
  return wi::add (rtx_mode_t (v2, elt_mode), (count - 2) * diff);
}

/* Return the value of element I of CONST_VECTOR X.  */

rtx
const_vector_elt (const_rtx x, unsigned int i)
{
  /* First handle elements that are directly encoded.  */
  if (i < (unsigned int) XVECLEN (x, 0))
    return CONST_VECTOR_ENCODED_ELT (x, i);

  /* If there are no steps, the final encoded value is the right one.  */
  if (!CONST_VECTOR_STEPPED_P (x))
    {
      /* Identify the pattern that contains element I and work out the index of
	 the last encoded element for that pattern.  */
      unsigned int encoded_nelts = const_vector_encoded_nelts (x);
      unsigned int npatterns = CONST_VECTOR_NPATTERNS (x);
      unsigned int pattern = i % npatterns;
      unsigned int final_i = encoded_nelts - npatterns + pattern;
      return CONST_VECTOR_ENCODED_ELT (x, final_i);
    }

  /* Otherwise work out the value from the last two encoded elements.  */
  return immed_wide_int_const (const_vector_int_elt (x, i),
			       GET_MODE_INNER (GET_MODE (x)));
}

/* Return true if X is a valid element for a CONST_VECTOR of the given
  mode.  */

bool
valid_for_const_vector_p (machine_mode, rtx x)
{
  return (CONST_SCALAR_INT_P (x)
	  || CONST_POLY_INT_P (x)
	  || CONST_DOUBLE_AS_FLOAT_P (x)
	  || CONST_FIXED_P (x));
}

/* Generate a vector constant of mode MODE in which every element has
   value ELT.  */

rtx
gen_const_vec_duplicate (machine_mode mode, rtx elt)
{
  rtx_vector_builder builder (mode, 1, 1);
  builder.quick_push (elt);
  return builder.build ();
}

/* Return a vector rtx of mode MODE in which every element has value X.
   The result will be a constant if X is constant.  */

rtx
gen_vec_duplicate (machine_mode mode, rtx x)
{
  if (valid_for_const_vector_p (mode, x))
    return gen_const_vec_duplicate (mode, x);
  return gen_rtx_VEC_DUPLICATE (mode, x);
}

/* A subroutine of const_vec_series_p that handles the case in which:

     (GET_CODE (X) == CONST_VECTOR
      && CONST_VECTOR_NPATTERNS (X) == 1
      && !CONST_VECTOR_DUPLICATE_P (X))

   is known to hold.  */

bool
const_vec_series_p_1 (const_rtx x, rtx *base_out, rtx *step_out)
{
  /* Stepped sequences are only defined for integers, to avoid specifying
     rounding behavior.  */
  if (GET_MODE_CLASS (GET_MODE (x)) != MODE_VECTOR_INT)
    return false;

  /* A non-duplicated vector with two elements can always be seen as a
     series with a nonzero step.  Longer vectors must have a stepped
     encoding.  */
  if (maybe_ne (CONST_VECTOR_NUNITS (x), 2)
      && !CONST_VECTOR_STEPPED_P (x))
    return false;

  /* Calculate the step between the first and second elements.  */
  scalar_mode inner = GET_MODE_INNER (GET_MODE (x));
  rtx base = CONST_VECTOR_ELT (x, 0);
  rtx step = simplify_binary_operation (MINUS, inner,
					CONST_VECTOR_ENCODED_ELT (x, 1), base);
  if (rtx_equal_p (step, CONST0_RTX (inner)))
    return false;

  /* If we have a stepped encoding, check that the step between the
     second and third elements is the same as STEP.  */
  if (CONST_VECTOR_STEPPED_P (x))
    {
      rtx diff = simplify_binary_operation (MINUS, inner,
					    CONST_VECTOR_ENCODED_ELT (x, 2),
					    CONST_VECTOR_ENCODED_ELT (x, 1));
      if (!rtx_equal_p (step, diff))
	return false;
    }

  *base_out = base;
  *step_out = step;
  return true;
}

/* Generate a vector constant of mode MODE in which element I has
   the value BASE + I * STEP.  */

rtx
gen_const_vec_series (machine_mode mode, rtx base, rtx step)
{
  gcc_assert (valid_for_const_vector_p (mode, base)
	      && valid_for_const_vector_p (mode, step));

  rtx_vector_builder builder (mode, 1, 3);
  builder.quick_push (base);
  for (int i = 1; i < 3; ++i)
    builder.quick_push (simplify_gen_binary (PLUS, GET_MODE_INNER (mode),
					     builder[i - 1], step));
  return builder.build ();
}

/* Generate a vector of mode MODE in which element I has the value
   BASE + I * STEP.  The result will be a constant if BASE and STEP
   are both constants.  */

rtx
gen_vec_series (machine_mode mode, rtx base, rtx step)
{
  if (step == const0_rtx)
    return gen_vec_duplicate (mode, base);
  if (valid_for_const_vector_p (mode, base)
      && valid_for_const_vector_p (mode, step))
    return gen_const_vec_series (mode, base, step);
  return gen_rtx_VEC_SERIES (mode, base, step);
}

/* Generate a new vector constant for mode MODE and constant value
   CONSTANT.  */

static rtx
gen_const_vector (machine_mode mode, int constant)
{
  machine_mode inner = GET_MODE_INNER (mode);

  gcc_assert (!DECIMAL_FLOAT_MODE_P (inner));

  rtx el = const_tiny_rtx[constant][(int) inner];
  gcc_assert (el);

  return gen_const_vec_duplicate (mode, el);
}

/* Generate a vector like gen_rtx_raw_CONST_VEC, but use the zero vector when
   all elements are zero, and the one vector when all elements are one.  */
rtx
gen_rtx_CONST_VECTOR (machine_mode mode, rtvec v)
{
  gcc_assert (known_eq (GET_MODE_NUNITS (mode), GET_NUM_ELEM (v)));

  /* If the values are all the same, check to see if we can use one of the
     standard constant vectors.  */
  if (rtvec_all_equal_p (v))
    return gen_const_vec_duplicate (mode, RTVEC_ELT (v, 0));

  unsigned int nunits = GET_NUM_ELEM (v);
  rtx_vector_builder builder (mode, nunits, 1);
  for (unsigned int i = 0; i < nunits; ++i)
    builder.quick_push (RTVEC_ELT (v, i));
  return builder.build (v);
}

/* Initialise global register information required by all functions.  */

void
init_emit_regs (void)
{
  int i;
  machine_mode mode;
  mem_attrs *attrs;

  /* Reset register attributes */
  reg_attrs_htab->empty ();

  /* We need reg_raw_mode, so initialize the modes now.  */
  init_reg_modes_target ();

  /* Assign register numbers to the globally defined register rtx.  */
  stack_pointer_rtx = gen_raw_REG (Pmode, STACK_POINTER_REGNUM);
  frame_pointer_rtx = gen_raw_REG (Pmode, FRAME_POINTER_REGNUM);
  hard_frame_pointer_rtx = gen_raw_REG (Pmode, HARD_FRAME_POINTER_REGNUM);
  arg_pointer_rtx = gen_raw_REG (Pmode, ARG_POINTER_REGNUM);
  virtual_incoming_args_rtx =
    gen_raw_REG (Pmode, VIRTUAL_INCOMING_ARGS_REGNUM);
  virtual_stack_vars_rtx =
    gen_raw_REG (Pmode, VIRTUAL_STACK_VARS_REGNUM);
  virtual_stack_dynamic_rtx =
    gen_raw_REG (Pmode, VIRTUAL_STACK_DYNAMIC_REGNUM);
  virtual_outgoing_args_rtx =
    gen_raw_REG (Pmode, VIRTUAL_OUTGOING_ARGS_REGNUM);
  virtual_cfa_rtx = gen_raw_REG (Pmode, VIRTUAL_CFA_REGNUM);
  virtual_preferred_stack_boundary_rtx =
    gen_raw_REG (Pmode, VIRTUAL_PREFERRED_STACK_BOUNDARY_REGNUM);

  /* Initialize RTL for commonly used hard registers.  These are
     copied into regno_reg_rtx as we begin to compile each function.  */
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    initial_regno_reg_rtx[i] = gen_raw_REG (reg_raw_mode[i], i);

#ifdef RETURN_ADDRESS_POINTER_REGNUM
  return_address_pointer_rtx
    = gen_raw_REG (Pmode, RETURN_ADDRESS_POINTER_REGNUM);
#endif

  pic_offset_table_rtx = NULL_RTX;
  if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM)
    pic_offset_table_rtx = gen_raw_REG (Pmode, PIC_OFFSET_TABLE_REGNUM);

  /* Process stack-limiting command-line options.  */
  if (opt_fstack_limit_symbol_arg != NULL)
    stack_limit_rtx
      = gen_rtx_SYMBOL_REF (Pmode, ggc_strdup (opt_fstack_limit_symbol_arg));
  if (opt_fstack_limit_register_no >= 0)
    stack_limit_rtx = gen_rtx_REG (Pmode, opt_fstack_limit_register_no);

  for (i = 0; i < (int) MAX_MACHINE_MODE; i++)
    {
      mode = (machine_mode) i;
      attrs = ggc_cleared_alloc<mem_attrs> ();
      attrs->align = BITS_PER_UNIT;
      attrs->addrspace = ADDR_SPACE_GENERIC;
      if (mode != BLKmode && mode != VOIDmode)
	{
	  attrs->size_known_p = true;
	  attrs->size = GET_MODE_SIZE (mode);
	  if (STRICT_ALIGNMENT)
	    attrs->align = GET_MODE_ALIGNMENT (mode);
	}
      mode_mem_attrs[i] = attrs;
    }

  split_branch_probability = profile_probability::uninitialized ();
}

/* Initialize global machine_mode variables.  */

void
init_derived_machine_modes (void)
{
  opt_scalar_int_mode mode_iter, opt_byte_mode, opt_word_mode;
  FOR_EACH_MODE_IN_CLASS (mode_iter, MODE_INT)
    {
      scalar_int_mode mode = mode_iter.require ();

      if (GET_MODE_BITSIZE (mode) == BITS_PER_UNIT
	  && !opt_byte_mode.exists ())
	opt_byte_mode = mode;

      if (GET_MODE_BITSIZE (mode) == BITS_PER_WORD
	  && !opt_word_mode.exists ())
	opt_word_mode = mode;
    }

  byte_mode = opt_byte_mode.require ();
  word_mode = opt_word_mode.require ();
  ptr_mode = as_a <scalar_int_mode>
    (mode_for_size (POINTER_SIZE, GET_MODE_CLASS (Pmode), 0).require ());
}

/* Create some permanent unique rtl objects shared between all functions.  */

void
init_emit_once (void)
{
  int i;
  machine_mode mode;
  scalar_float_mode double_mode;
  opt_scalar_mode smode_iter;

  /* Initialize the CONST_INT, CONST_WIDE_INT, CONST_DOUBLE,
     CONST_FIXED, and memory attribute hash tables.  */
  const_int_htab = hash_table<const_int_hasher>::create_ggc (37);

#if TARGET_SUPPORTS_WIDE_INT
  const_wide_int_htab = hash_table<const_wide_int_hasher>::create_ggc (37);
#endif
  const_double_htab = hash_table<const_double_hasher>::create_ggc (37);

  if (NUM_POLY_INT_COEFFS > 1)
    const_poly_int_htab = hash_table<const_poly_int_hasher>::create_ggc (37);

  const_fixed_htab = hash_table<const_fixed_hasher>::create_ggc (37);

  reg_attrs_htab = hash_table<reg_attr_hasher>::create_ggc (37);

#ifdef INIT_EXPANDERS
  /* This is to initialize {init|mark|free}_machine_status before the first
     call to push_function_context_to.  This is needed by the Chill front
     end which calls push_function_context_to before the first call to
     init_function_start.  */
  INIT_EXPANDERS;
#endif

  /* Create the unique rtx's for certain rtx codes and operand values.  */

  /* Don't use gen_rtx_CONST_INT here since gen_rtx_CONST_INT in this case
     tries to use these variables.  */
  for (i = - MAX_SAVED_CONST_INT; i <= MAX_SAVED_CONST_INT; i++)
    const_int_rtx[i + MAX_SAVED_CONST_INT] =
      gen_rtx_raw_CONST_INT (VOIDmode, (HOST_WIDE_INT) i);

  if (STORE_FLAG_VALUE >= - MAX_SAVED_CONST_INT
      && STORE_FLAG_VALUE <= MAX_SAVED_CONST_INT)
    const_true_rtx = const_int_rtx[STORE_FLAG_VALUE + MAX_SAVED_CONST_INT];
  else
    const_true_rtx = gen_rtx_CONST_INT (VOIDmode, STORE_FLAG_VALUE);

  double_mode = float_mode_for_size (DOUBLE_TYPE_SIZE).require ();

  real_from_integer (&dconst0, double_mode, 0, SIGNED);
  real_from_integer (&dconst1, double_mode, 1, SIGNED);
  real_from_integer (&dconst2, double_mode, 2, SIGNED);

  dconstm0 = dconst0;
  dconstm0.sign = 1;

  dconstm1 = dconst1;
  dconstm1.sign = 1;

  dconsthalf = dconst1;
  SET_REAL_EXP (&dconsthalf, REAL_EXP (&dconsthalf) - 1);

  real_inf (&dconstinf);
  real_inf (&dconstninf, true);

  for (i = 0; i < 3; i++)
    {
      const REAL_VALUE_TYPE *const r =
	(i == 0 ? &dconst0 : i == 1 ? &dconst1 : &dconst2);

      FOR_EACH_MODE_IN_CLASS (mode, MODE_FLOAT)
	const_tiny_rtx[i][(int) mode] =
	  const_double_from_real_value (*r, mode);

      FOR_EACH_MODE_IN_CLASS (mode, MODE_DECIMAL_FLOAT)
	const_tiny_rtx[i][(int) mode] =
	  const_double_from_real_value (*r, mode);

      const_tiny_rtx[i][(int) VOIDmode] = GEN_INT (i);

      FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
	const_tiny_rtx[i][(int) mode] = GEN_INT (i);

      for (mode = MIN_MODE_PARTIAL_INT;
	   mode <= MAX_MODE_PARTIAL_INT;
	   mode = (machine_mode)((int)(mode) + 1))
	const_tiny_rtx[i][(int) mode] = GEN_INT (i);
    }

  const_tiny_rtx[3][(int) VOIDmode] = constm1_rtx;

  FOR_EACH_MODE_IN_CLASS (mode, MODE_INT)
    const_tiny_rtx[3][(int) mode] = constm1_rtx;

  /* For BImode, 1 and -1 are unsigned and signed interpretations
     of the same value.  */
  for (mode = MIN_MODE_BOOL;
       mode <= MAX_MODE_BOOL;
       mode = (machine_mode)((int)(mode) + 1))
    {
      const_tiny_rtx[0][(int) mode] = const0_rtx;
      if (mode == BImode)
	{
	  const_tiny_rtx[1][(int) mode] = const_true_rtx;
	  const_tiny_rtx[3][(int) mode] = const_true_rtx;
	}
      else
	{
	  const_tiny_rtx[1][(int) mode] = const1_rtx;
	  const_tiny_rtx[3][(int) mode] = constm1_rtx;
	}
    }

  for (mode = MIN_MODE_PARTIAL_INT;
       mode <= MAX_MODE_PARTIAL_INT;
       mode = (machine_mode)((int)(mode) + 1))
    const_tiny_rtx[3][(int) mode] = constm1_rtx;

  FOR_EACH_MODE_IN_CLASS (mode, MODE_COMPLEX_INT)
    {
      rtx inner = const_tiny_rtx[0][(int)GET_MODE_INNER (mode)];
      const_tiny_rtx[0][(int) mode] = gen_rtx_CONCAT (mode, inner, inner);
    }

  FOR_EACH_MODE_IN_CLASS (mode, MODE_COMPLEX_FLOAT)
    {
      rtx inner = const_tiny_rtx[0][(int)GET_MODE_INNER (mode)];
      const_tiny_rtx[0][(int) mode] = gen_rtx_CONCAT (mode, inner, inner);
    }

  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_BOOL)
    {
      const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
      const_tiny_rtx[3][(int) mode] = gen_const_vector (mode, 3);
      if (GET_MODE_INNER (mode) == BImode)
	/* As for BImode, "all 1" and "all -1" are unsigned and signed
	   interpretations of the same value.  */
	const_tiny_rtx[1][(int) mode] = const_tiny_rtx[3][(int) mode];
      else
	const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
    }

  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_INT)
    {
      const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
      const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
      const_tiny_rtx[3][(int) mode] = gen_const_vector (mode, 3);
    }

  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FLOAT)
    {
      const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
      const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
    }

  FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_FRACT)
    {
      scalar_mode smode = smode_iter.require ();
      FCONST0 (smode).data.high = 0;
      FCONST0 (smode).data.low = 0;
      FCONST0 (smode).mode = smode;
      const_tiny_rtx[0][(int) smode]
	= CONST_FIXED_FROM_FIXED_VALUE (FCONST0 (smode), smode);
    }

  FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_UFRACT)
    {
      scalar_mode smode = smode_iter.require ();
      FCONST0 (smode).data.high = 0;
      FCONST0 (smode).data.low = 0;
      FCONST0 (smode).mode = smode;
      const_tiny_rtx[0][(int) smode]
	= CONST_FIXED_FROM_FIXED_VALUE (FCONST0 (smode), smode);
    }

  FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_ACCUM)
    {
      scalar_mode smode = smode_iter.require ();
      FCONST0 (smode).data.high = 0;
      FCONST0 (smode).data.low = 0;
      FCONST0 (smode).mode = smode;
      const_tiny_rtx[0][(int) smode]
	= CONST_FIXED_FROM_FIXED_VALUE (FCONST0 (smode), smode);

      /* We store the value 1.  */
      FCONST1 (smode).data.high = 0;
      FCONST1 (smode).data.low = 0;
      FCONST1 (smode).mode = smode;
      FCONST1 (smode).data
	= double_int_one.lshift (GET_MODE_FBIT (smode),
				 HOST_BITS_PER_DOUBLE_INT,
				 SIGNED_FIXED_POINT_MODE_P (smode));
      const_tiny_rtx[1][(int) smode]
	= CONST_FIXED_FROM_FIXED_VALUE (FCONST1 (smode), smode);
    }

  FOR_EACH_MODE_IN_CLASS (smode_iter, MODE_UACCUM)
    {
      scalar_mode smode = smode_iter.require ();
      FCONST0 (smode).data.high = 0;
      FCONST0 (smode).data.low = 0;
      FCONST0 (smode).mode = smode;
      const_tiny_rtx[0][(int) smode]
	= CONST_FIXED_FROM_FIXED_VALUE (FCONST0 (smode), smode);

      /* We store the value 1.  */
      FCONST1 (smode).data.high = 0;
      FCONST1 (smode).data.low = 0;
      FCONST1 (smode).mode = smode;
      FCONST1 (smode).data
	= double_int_one.lshift (GET_MODE_FBIT (smode),
				 HOST_BITS_PER_DOUBLE_INT,
				 SIGNED_FIXED_POINT_MODE_P (smode));
      const_tiny_rtx[1][(int) smode]
	= CONST_FIXED_FROM_FIXED_VALUE (FCONST1 (smode), smode);
    }

  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_FRACT)
    {
      const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
    }

  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_UFRACT)
    {
      const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
    }

  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_ACCUM)
    {
      const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
      const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
    }

  FOR_EACH_MODE_IN_CLASS (mode, MODE_VECTOR_UACCUM)
    {
      const_tiny_rtx[0][(int) mode] = gen_const_vector (mode, 0);
      const_tiny_rtx[1][(int) mode] = gen_const_vector (mode, 1);
    }

  for (i = (int) CCmode; i < (int) MAX_MACHINE_MODE; ++i)
    if (GET_MODE_CLASS ((machine_mode) i) == MODE_CC)
      const_tiny_rtx[0][i] = const0_rtx;

  pc_rtx = gen_rtx_fmt_ (PC, VOIDmode);
  ret_rtx = gen_rtx_fmt_ (RETURN, VOIDmode);
  simple_return_rtx = gen_rtx_fmt_ (SIMPLE_RETURN, VOIDmode);
  invalid_insn_rtx = gen_rtx_INSN (VOIDmode,
				   /*prev_insn=*/NULL,
				   /*next_insn=*/NULL,
				   /*bb=*/NULL,
				   /*pattern=*/NULL_RTX,
				   /*location=*/-1,
				   CODE_FOR_nothing,
				   /*reg_notes=*/NULL_RTX);
}

/* Produce exact duplicate of insn INSN after AFTER.
   Care updating of libcall regions if present.  */

rtx_insn *
emit_copy_of_insn_after (rtx_insn *insn, rtx_insn *after)
{
  rtx_insn *new_rtx;
  rtx link;

  switch (GET_CODE (insn))
    {
    case INSN:
      new_rtx = emit_insn_after (copy_insn (PATTERN (insn)), after);
      break;

    case JUMP_INSN:
      new_rtx = emit_jump_insn_after (copy_insn (PATTERN (insn)), after);
      CROSSING_JUMP_P (new_rtx) = CROSSING_JUMP_P (insn);
      break;

    case DEBUG_INSN:
      new_rtx = emit_debug_insn_after (copy_insn (PATTERN (insn)), after);
      break;

    case CALL_INSN:
      new_rtx = emit_call_insn_after (copy_insn (PATTERN (insn)), after);
      if (CALL_INSN_FUNCTION_USAGE (insn))
	CALL_INSN_FUNCTION_USAGE (new_rtx)
	  = copy_insn (CALL_INSN_FUNCTION_USAGE (insn));
      SIBLING_CALL_P (new_rtx) = SIBLING_CALL_P (insn);
      RTL_CONST_CALL_P (new_rtx) = RTL_CONST_CALL_P (insn);
      RTL_PURE_CALL_P (new_rtx) = RTL_PURE_CALL_P (insn);
      RTL_LOOPING_CONST_OR_PURE_CALL_P (new_rtx)
	= RTL_LOOPING_CONST_OR_PURE_CALL_P (insn);
      break;

    default:
      gcc_unreachable ();
    }

  /* Update LABEL_NUSES.  */
  if (NONDEBUG_INSN_P (insn))
    mark_jump_label (PATTERN (new_rtx), new_rtx, 0);

  INSN_LOCATION (new_rtx) = INSN_LOCATION (insn);

  /* If the old insn is frame related, then so is the new one.  This is
     primarily needed for IA-64 unwind info which marks epilogue insns,
     which may be duplicated by the basic block reordering code.  */
  RTX_FRAME_RELATED_P (new_rtx) = RTX_FRAME_RELATED_P (insn);

  /* Locate the end of existing REG_NOTES in NEW_RTX.  */
  rtx *ptail = &REG_NOTES (new_rtx);
  while (*ptail != NULL_RTX)
    ptail = &XEXP (*ptail, 1);

  /* Copy all REG_NOTES except REG_LABEL_OPERAND since mark_jump_label
     will make them.  REG_LABEL_TARGETs are created there too, but are
     supposed to be sticky, so we copy them.  */
  for (link = REG_NOTES (insn); link; link = XEXP (link, 1))
    if (REG_NOTE_KIND (link) != REG_LABEL_OPERAND)
      {
	*ptail = duplicate_reg_note (link);
	ptail = &XEXP (*ptail, 1);
      }

  INSN_CODE (new_rtx) = INSN_CODE (insn);
  return new_rtx;
}

static GTY((deletable)) rtx hard_reg_clobbers [NUM_MACHINE_MODES][FIRST_PSEUDO_REGISTER];
rtx
gen_hard_reg_clobber (machine_mode mode, unsigned int regno)
{
  if (hard_reg_clobbers[mode][regno])
    return hard_reg_clobbers[mode][regno];
  else
    return (hard_reg_clobbers[mode][regno] =
	    gen_rtx_CLOBBER (VOIDmode, gen_rtx_REG (mode, regno)));
}

location_t prologue_location;
location_t epilogue_location;

/* Hold current location information and last location information, so the
   datastructures are built lazily only when some instructions in given
   place are needed.  */
static location_t curr_location;

/* Allocate insn location datastructure.  */
void
insn_locations_init (void)
{
  prologue_location = epilogue_location = 0;
  curr_location = UNKNOWN_LOCATION;
}

/* At the end of emit stage, clear current location.  */
void
insn_locations_finalize (void)
{
  epilogue_location = curr_location;
  curr_location = UNKNOWN_LOCATION;
}

/* Set current location.  */
void
set_curr_insn_location (location_t location)
{
  curr_location = location;
}

/* Get current location.  */
location_t
curr_insn_location (void)
{
  return curr_location;
}

/* Set the location of the insn chain starting at INSN to LOC.  */
void
set_insn_locations (rtx_insn *insn, location_t loc)
{
  while (insn)
    {
      if (INSN_P (insn))
	INSN_LOCATION (insn) = loc;
      insn = NEXT_INSN (insn);
    }
}

/* Return lexical scope block insn belongs to.  */
tree
insn_scope (const rtx_insn *insn)
{
  return LOCATION_BLOCK (INSN_LOCATION (insn));
}

/* Return line number of the statement that produced this insn.  */
int
insn_line (const rtx_insn *insn)
{
  return LOCATION_LINE (INSN_LOCATION (insn));
}

/* Return source file of the statement that produced this insn.  */
const char *
insn_file (const rtx_insn *insn)
{
  return LOCATION_FILE (INSN_LOCATION (insn));
}

/* Return expanded location of the statement that produced this insn.  */
expanded_location
insn_location (const rtx_insn *insn)
{
  return expand_location (INSN_LOCATION (insn));
}

/* Return true if memory model MODEL requires a pre-operation (release-style)
   barrier or a post-operation (acquire-style) barrier.  While not universal,
   this function matches behavior of several targets.  */

bool
need_atomic_barrier_p (enum memmodel model, bool pre)
{
  switch (model & MEMMODEL_BASE_MASK)
    {
    case MEMMODEL_RELAXED:
    case MEMMODEL_CONSUME:
      return false;
    case MEMMODEL_RELEASE:
      return pre;
    case MEMMODEL_ACQUIRE:
      return !pre;
    case MEMMODEL_ACQ_REL:
    case MEMMODEL_SEQ_CST:
      return true;
    default:
      gcc_unreachable ();
    }
}

/* Return a constant shift amount for shifting a value of mode MODE
   by VALUE bits.  */

rtx
gen_int_shift_amount (machine_mode, poly_int64 value)
{
  /* Use a 64-bit mode, to avoid any truncation.

     ??? Perhaps this should be automatically derived from the .md files
     instead, or perhaps have a target hook.  */
  scalar_int_mode shift_mode = (BITS_PER_UNIT == 8
				? DImode
				: int_mode_for_size (64, 0).require ());
  return gen_int_mode (value, shift_mode);
}

/* Initialize fields of rtl_data related to stack alignment.  */

void
rtl_data::init_stack_alignment ()
{
  stack_alignment_needed = STACK_BOUNDARY;
  max_used_stack_slot_alignment = STACK_BOUNDARY;
  stack_alignment_estimated = 0;
  preferred_stack_boundary = STACK_BOUNDARY;
}


#include "gt-emit-rtl.h"
