/* Emit RTL for the GCC expander.
   Copyright (C) 1987-2022 Free Software Foundation, Inc.

This file is part of GCC.

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

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

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


/* 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 "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 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 nonzero 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 nonzero 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 nonzero 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 nonzero 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 0;
  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 nonzero 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 0;
  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 nonzero 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_INNER (omode) == GET_MODE_INNER (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);
    }

  /* 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 1 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 1 (it is its own low part!).  */

int
subreg_lowpart_p (const_rtx x)
{
  if (GET_CODE (x) != SUBREG)
    return 1;
  else if (GET_MODE (SUBREG_REG (x)) == VOIDmode)
    return 0;

  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 1 if both MEM_EXPR can be considered equal
   and 0 otherwise.  */

int
mem_expr_equal_p (const_tree expr1, const_tree expr2)
{
  if (expr1 == expr2)
    return 1;

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

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

  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);
	      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);
}

/* 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);
}

unsigned int
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));
    }

  return 0;
}


/* 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;
	}
    }
  return;
}

/* 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;
    }
  return;
}

/* 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);
}

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

int
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))));
}

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 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 1 if currently emitting into a sequence.  */

int
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);

  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"
