/* Convert RTL to assembler code and output it, for GNU compiler.
   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/>.  */

/* This is the final pass of the compiler.
   It looks at the rtl code for a function and outputs assembler code.

   Call `final_start_function' to output the assembler code for function entry,
   `final' to output assembler code for some RTL code,
   `final_end_function' to output assembler code for function exit.
   If a function is compiled in several pieces, each piece is
   output separately with `final'.

   Some optimizations are also done at this level.
   Move instructions that were made unnecessary by good register allocation
   are detected and omitted from the output.  (Though most of these
   are removed by the last jump pass.)

   Instructions to set the condition codes are omitted when it can be
   seen that the condition codes already had the desired values.

   In some cases it is sufficient if the inherited condition codes
   have related values, but this may require the following insn
   (the one that tests the condition codes) to be modified.

   The code for the function prologue and epilogue are generated
   directly in assembler by the target functions function_prologue and
   function_epilogue.  Those instructions never exist as rtl.  */

#include "config.h"
#define INCLUDE_ALGORITHM /* reverse */
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "cfghooks.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "insn-config.h"
#include "regs.h"
#include "emit-rtl.h"
#include "recog.h"
#include "cgraph.h"
#include "tree-pretty-print.h" /* for dump_function_header */
#include "varasm.h"
#include "insn-attr.h"
#include "conditions.h"
#include "flags.h"
#include "output.h"
#include "except.h"
#include "rtl-error.h"
#include "toplev.h" /* exact_log2, floor_log2 */
#include "reload.h"
#include "intl.h"
#include "cfgrtl.h"
#include "debug.h"
#include "tree-pass.h"
#include "tree-ssa.h"
#include "cfgloop.h"
#include "stringpool.h"
#include "attribs.h"
#include "asan.h"
#include "rtl-iter.h"
#include "print-rtl.h"
#include "function-abi.h"
#include "common/common-target.h"

#include "dwarf2out.h"

/* Most ports don't need to define CC_STATUS_INIT.
   So define a null default for it to save conditionalization later.  */
#ifndef CC_STATUS_INIT
#define CC_STATUS_INIT
#endif

/* Is the given character a logical line separator for the assembler?  */
#ifndef IS_ASM_LOGICAL_LINE_SEPARATOR
#define IS_ASM_LOGICAL_LINE_SEPARATOR(C, STR) ((C) == ';')
#endif

#ifndef JUMP_TABLES_IN_TEXT_SECTION
#define JUMP_TABLES_IN_TEXT_SECTION 0
#endif

/* Bitflags used by final_scan_insn.  */
#define SEEN_NOTE	1
#define SEEN_EMITTED	2
#define SEEN_NEXT_VIEW	4

/* Last insn processed by final_scan_insn.  */
static rtx_insn *debug_insn;
rtx_insn *current_output_insn;

/* Line number of last NOTE.  */
static int last_linenum;

/* Column number of last NOTE.  */
static int last_columnnum;

/* Discriminator written to assembly.  */
static int last_discriminator;

/* Compute discriminator to be written to assembly for current instruction.
   Note: actual usage depends on loc_discriminator_kind setting.  */
static inline int compute_discriminator (location_t loc);

/* Highest line number in current block.  */
static int high_block_linenum;

/* Likewise for function.  */
static int high_function_linenum;

/* Filename of last NOTE.  */
static const char *last_filename;

/* Override filename, line and column number.  */
static const char *override_filename;
static int override_linenum;
static int override_columnnum;
static int override_discriminator;

/* Whether to force emission of a line note before the next insn.  */
static bool force_source_line = false;

extern const int length_unit_log; /* This is defined in insn-attrtab.cc.  */

/* Nonzero while outputting an `asm' with operands.
   This means that inconsistencies are the user's fault, so don't die.
   The precise value is the insn being output, to pass to error_for_asm.  */
const rtx_insn *this_is_asm_operands;

/* Number of operands of this insn, for an `asm' with operands.  */
static unsigned int insn_noperands;

/* Compare optimization flag.  */

static rtx last_ignored_compare = 0;

/* Assign a unique number to each insn that is output.
   This can be used to generate unique local labels.  */

static int insn_counter = 0;

/* Number of unmatched NOTE_INSN_BLOCK_BEG notes we have seen.  */

static int block_depth;

/* Nonzero if have enabled APP processing of our assembler output.  */

static int app_on;

/* If we are outputting an insn sequence, this contains the sequence rtx.
   Zero otherwise.  */

rtx_sequence *final_sequence;

#ifdef ASSEMBLER_DIALECT

/* Number of the assembler dialect to use, starting at 0.  */
static int dialect_number;
#endif

/* Nonnull if the insn currently being emitted was a COND_EXEC pattern.  */
rtx current_insn_predicate;

/* True if printing into -fdump-final-insns= dump.  */
bool final_insns_dump_p;

/* True if profile_function should be called, but hasn't been called yet.  */
static bool need_profile_function;

static int asm_insn_count (rtx);
static void profile_function (FILE *);
static void profile_after_prologue (FILE *);
static bool notice_source_line (rtx_insn *, bool *);
static rtx walk_alter_subreg (rtx *, bool *);
static void output_asm_name (void);
static void output_alternate_entry_point (FILE *, rtx_insn *);
static tree get_mem_expr_from_op (rtx, int *);
static void output_asm_operand_names (rtx *, int *, int);
#ifdef LEAF_REGISTERS
static void leaf_renumber_regs (rtx_insn *);
#endif
static int align_fuzz (rtx, rtx, int, unsigned);
static void collect_fn_hard_reg_usage (void);

/* Initialize data in final at the beginning of a compilation.  */

void
init_final (const char *filename ATTRIBUTE_UNUSED)
{
  app_on = 0;
  final_sequence = 0;

#ifdef ASSEMBLER_DIALECT
  dialect_number = ASSEMBLER_DIALECT;
#endif
}

/* Default target function prologue and epilogue assembler output.

   If not overridden for epilogue code, then the function body itself
   contains return instructions wherever needed.  */
void
default_function_pro_epilogue (FILE *)
{
}

void
default_function_switched_text_sections (FILE *file ATTRIBUTE_UNUSED,
					 tree decl ATTRIBUTE_UNUSED,
					 bool new_is_cold ATTRIBUTE_UNUSED)
{
}

/* Default target hook that outputs nothing to a stream.  */
void
no_asm_to_stream (FILE *file ATTRIBUTE_UNUSED)
{
}

/* Enable APP processing of subsequent output.
   Used before the output from an `asm' statement.  */

void
app_enable (void)
{
  if (! app_on)
    {
      fputs (ASM_APP_ON, asm_out_file);
      app_on = 1;
    }
}

/* Disable APP processing of subsequent output.
   Called from varasm.cc before most kinds of output.  */

void
app_disable (void)
{
  if (app_on)
    {
      fputs (ASM_APP_OFF, asm_out_file);
      app_on = 0;
    }
}

/* Return the number of slots filled in the current
   delayed branch sequence (we don't count the insn needing the
   delay slot).   Zero if not in a delayed branch sequence.  */

int
dbr_sequence_length (void)
{
  if (final_sequence != 0)
    return XVECLEN (final_sequence, 0) - 1;
  else
    return 0;
}

/* The next two pages contain routines used to compute the length of an insn
   and to shorten branches.  */

/* Arrays for insn lengths, and addresses.  The latter is referenced by
   `insn_current_length'.  */

static int *insn_lengths;

vec<int> insn_addresses_;

/* Max uid for which the above arrays are valid.  */
static int insn_lengths_max_uid;

/* Address of insn being processed.  Used by `insn_current_length'.  */
int insn_current_address;

/* Address of insn being processed in previous iteration.  */
int insn_last_address;

/* known invariant alignment of insn being processed.  */
int insn_current_align;

/* After shorten_branches, for any insn, uid_align[INSN_UID (insn)]
   gives the next following alignment insn that increases the known
   alignment, or NULL_RTX if there is no such insn.
   For any alignment obtained this way, we can again index uid_align with
   its uid to obtain the next following align that in turn increases the
   alignment, till we reach NULL_RTX; the sequence obtained this way
   for each insn we'll call the alignment chain of this insn in the following
   comments.  */

static rtx *uid_align;
static int *uid_shuid;
static vec<align_flags> label_align;

/* Indicate that branch shortening hasn't yet been done.  */

void
init_insn_lengths (void)
{
  if (uid_shuid)
    {
      free (uid_shuid);
      uid_shuid = 0;
    }
  if (insn_lengths)
    {
      free (insn_lengths);
      insn_lengths = 0;
      insn_lengths_max_uid = 0;
    }
  if (HAVE_ATTR_length)
    INSN_ADDRESSES_FREE ();
  if (uid_align)
    {
      free (uid_align);
      uid_align = 0;
    }
}

/* Obtain the current length of an insn.  If branch shortening has been done,
   get its actual length.  Otherwise, use FALLBACK_FN to calculate the
   length.  */
static int
get_attr_length_1 (rtx_insn *insn, int (*fallback_fn) (rtx_insn *))
{
  rtx body;
  int i;
  int length = 0;

  if (!HAVE_ATTR_length)
    return 0;

  if (insn_lengths_max_uid > INSN_UID (insn))
    return insn_lengths[INSN_UID (insn)];
  else
    switch (GET_CODE (insn))
      {
      case NOTE:
      case BARRIER:
      case CODE_LABEL:
      case DEBUG_INSN:
	return 0;

      case CALL_INSN:
      case JUMP_INSN:
	length = fallback_fn (insn);
	break;

      case INSN:
	body = PATTERN (insn);
	if (GET_CODE (body) == USE || GET_CODE (body) == CLOBBER)
	  return 0;

	else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
	  length = asm_insn_count (body) * fallback_fn (insn);
	else if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (body))
	  for (i = 0; i < seq->len (); i++)
	    length += get_attr_length_1 (seq->insn (i), fallback_fn);
	else
	  length = fallback_fn (insn);
	break;

      default:
	break;
      }

#ifdef ADJUST_INSN_LENGTH
  ADJUST_INSN_LENGTH (insn, length);
#endif
  return length;
}

/* Obtain the current length of an insn.  If branch shortening has been done,
   get its actual length.  Otherwise, get its maximum length.  */
int
get_attr_length (rtx_insn *insn)
{
  return get_attr_length_1 (insn, insn_default_length);
}

/* Obtain the current length of an insn.  If branch shortening has been done,
   get its actual length.  Otherwise, get its minimum length.  */
int
get_attr_min_length (rtx_insn *insn)
{
  return get_attr_length_1 (insn, insn_min_length);
}

/* Code to handle alignment inside shorten_branches.  */

/* Here is an explanation how the algorithm in align_fuzz can give
   proper results:

   Call a sequence of instructions beginning with alignment point X
   and continuing until the next alignment point `block X'.  When `X'
   is used in an expression, it means the alignment value of the
   alignment point.

   Call the distance between the start of the first insn of block X, and
   the end of the last insn of block X `IX', for the `inner size of X'.
   This is clearly the sum of the instruction lengths.

   Likewise with the next alignment-delimited block following X, which we
   shall call block Y.

   Call the distance between the start of the first insn of block X, and
   the start of the first insn of block Y `OX', for the `outer size of X'.

   The estimated padding is then OX - IX.

   OX can be safely estimated as

           if (X >= Y)
                   OX = round_up(IX, Y)
           else
                   OX = round_up(IX, X) + Y - X

   Clearly est(IX) >= real(IX), because that only depends on the
   instruction lengths, and those being overestimated is a given.

   Clearly round_up(foo, Z) >= round_up(bar, Z) if foo >= bar, so
   we needn't worry about that when thinking about OX.

   When X >= Y, the alignment provided by Y adds no uncertainty factor
   for branch ranges starting before X, so we can just round what we have.
   But when X < Y, we don't know anything about the, so to speak,
   `middle bits', so we have to assume the worst when aligning up from an
   address mod X to one mod Y, which is Y - X.  */

#ifndef LABEL_ALIGN
#define LABEL_ALIGN(LABEL) align_labels
#endif

#ifndef LOOP_ALIGN
#define LOOP_ALIGN(LABEL) align_loops
#endif

#ifndef LABEL_ALIGN_AFTER_BARRIER
#define LABEL_ALIGN_AFTER_BARRIER(LABEL) 0
#endif

#ifndef JUMP_ALIGN
#define JUMP_ALIGN(LABEL) align_jumps
#endif

#ifndef ADDR_VEC_ALIGN
static int
final_addr_vec_align (rtx_jump_table_data *addr_vec)
{
  int align = GET_MODE_SIZE (addr_vec->get_data_mode ());

  if (align > BIGGEST_ALIGNMENT / BITS_PER_UNIT)
    align = BIGGEST_ALIGNMENT / BITS_PER_UNIT;
  return exact_log2 (align);

}

#define ADDR_VEC_ALIGN(ADDR_VEC) final_addr_vec_align (ADDR_VEC)
#endif

#ifndef INSN_LENGTH_ALIGNMENT
#define INSN_LENGTH_ALIGNMENT(INSN) length_unit_log
#endif

#define INSN_SHUID(INSN) (uid_shuid[INSN_UID (INSN)])

static int min_labelno, max_labelno;

#define LABEL_TO_ALIGNMENT(LABEL) \
  (label_align[CODE_LABEL_NUMBER (LABEL) - min_labelno])

/* For the benefit of port specific code do this also as a function.  */

align_flags
label_to_alignment (rtx label)
{
  if (CODE_LABEL_NUMBER (label) <= max_labelno)
    return LABEL_TO_ALIGNMENT (label);
  return align_flags ();
}

/* The differences in addresses
   between a branch and its target might grow or shrink depending on
   the alignment the start insn of the range (the branch for a forward
   branch or the label for a backward branch) starts out on; if these
   differences are used naively, they can even oscillate infinitely.
   We therefore want to compute a 'worst case' address difference that
   is independent of the alignment the start insn of the range end
   up on, and that is at least as large as the actual difference.
   The function align_fuzz calculates the amount we have to add to the
   naively computed difference, by traversing the part of the alignment
   chain of the start insn of the range that is in front of the end insn
   of the range, and considering for each alignment the maximum amount
   that it might contribute to a size increase.

   For casesi tables, we also want to know worst case minimum amounts of
   address difference, in case a machine description wants to introduce
   some common offset that is added to all offsets in a table.
   For this purpose, align_fuzz with a growth argument of 0 computes the
   appropriate adjustment.  */

/* Compute the maximum delta by which the difference of the addresses of
   START and END might grow / shrink due to a different address for start
   which changes the size of alignment insns between START and END.
   KNOWN_ALIGN_LOG is the alignment known for START.
   GROWTH should be ~0 if the objective is to compute potential code size
   increase, and 0 if the objective is to compute potential shrink.
   The return value is undefined for any other value of GROWTH.  */

static int
align_fuzz (rtx start, rtx end, int known_align_log, unsigned int growth)
{
  int uid = INSN_UID (start);
  rtx align_label;
  int known_align = 1 << known_align_log;
  int end_shuid = INSN_SHUID (end);
  int fuzz = 0;

  for (align_label = uid_align[uid]; align_label; align_label = uid_align[uid])
    {
      int align_addr, new_align;

      uid = INSN_UID (align_label);
      align_addr = INSN_ADDRESSES (uid) - insn_lengths[uid];
      if (uid_shuid[uid] > end_shuid)
	break;
      align_flags alignment = LABEL_TO_ALIGNMENT (align_label);
      new_align = 1 << alignment.levels[0].log;
      if (new_align < known_align)
	continue;
      fuzz += (-align_addr ^ growth) & (new_align - known_align);
      known_align = new_align;
    }
  return fuzz;
}

/* Compute a worst-case reference address of a branch so that it
   can be safely used in the presence of aligned labels.  Since the
   size of the branch itself is unknown, the size of the branch is
   not included in the range.  I.e. for a forward branch, the reference
   address is the end address of the branch as known from the previous
   branch shortening pass, minus a value to account for possible size
   increase due to alignment.  For a backward branch, it is the start
   address of the branch as known from the current pass, plus a value
   to account for possible size increase due to alignment.
   NB.: Therefore, the maximum offset allowed for backward branches needs
   to exclude the branch size.  */

int
insn_current_reference_address (rtx_insn *branch)
{
  rtx dest;
  int seq_uid;

  if (! INSN_ADDRESSES_SET_P ())
    return 0;

  rtx_insn *seq = NEXT_INSN (PREV_INSN (branch));
  seq_uid = INSN_UID (seq);
  if (!jump_to_label_p (branch))
    /* This can happen for example on the PA; the objective is to know the
       offset to address something in front of the start of the function.
       Thus, we can treat it like a backward branch.
       We assume here that FUNCTION_BOUNDARY / BITS_PER_UNIT is larger than
       any alignment we'd encounter, so we skip the call to align_fuzz.  */
    return insn_current_address;
  dest = JUMP_LABEL (branch);

  /* BRANCH has no proper alignment chain set, so use SEQ.
     BRANCH also has no INSN_SHUID.  */
  if (INSN_SHUID (seq) < INSN_SHUID (dest))
    {
      /* Forward branch.  */
      return (insn_last_address + insn_lengths[seq_uid]
	      - align_fuzz (seq, dest, length_unit_log, ~0));
    }
  else
    {
      /* Backward branch.  */
      return (insn_current_address
	      + align_fuzz (dest, seq, length_unit_log, ~0));
    }
}

/* Compute branch alignments based on CFG profile.  */

unsigned int
compute_alignments (void)
{
  basic_block bb;
  align_flags max_alignment;

  label_align.truncate (0);

  max_labelno = max_label_num ();
  min_labelno = get_first_label_num ();
  label_align.safe_grow_cleared (max_labelno - min_labelno + 1, true);

  /* If not optimizing or optimizing for size, don't assign any alignments.  */
  if (! optimize || optimize_function_for_size_p (cfun))
    return 0;

  if (dump_file)
    {
      dump_reg_info (dump_file);
      dump_flow_info (dump_file, TDF_DETAILS);
      flow_loops_dump (dump_file, NULL, 1);
    }
  loop_optimizer_init (AVOID_CFG_MODIFICATIONS);
  profile_count count_threshold = cfun->cfg->count_max / param_align_threshold;

  if (dump_file)
    {
      fprintf (dump_file, "count_max: ");
      cfun->cfg->count_max.dump (dump_file);
      fprintf (dump_file, "\n");
    }
  FOR_EACH_BB_FN (bb, cfun)
    {
      rtx_insn *label = BB_HEAD (bb);
      bool has_fallthru = 0;
      edge e;
      edge_iterator ei;

      if (!LABEL_P (label)
	  || optimize_bb_for_size_p (bb))
	{
	  if (dump_file)
	    fprintf (dump_file,
		     "BB %4i loop %2i loop_depth %2i skipped.\n",
		     bb->index,
		     bb->loop_father->num,
		     bb_loop_depth (bb));
	  continue;
	}
      max_alignment = LABEL_ALIGN (label);
      profile_count fallthru_count = profile_count::zero ();
      profile_count branch_count = profile_count::zero ();

      FOR_EACH_EDGE (e, ei, bb->preds)
	{
	  if (e->flags & EDGE_FALLTHRU)
	    has_fallthru = 1, fallthru_count += e->count ();
	  else
	    branch_count += e->count ();
	}
      if (dump_file)
	{
	  fprintf (dump_file, "BB %4i loop %2i loop_depth"
		   " %2i fall ",
		   bb->index, bb->loop_father->num,
		   bb_loop_depth (bb));
	  fallthru_count.dump (dump_file);
	  fprintf (dump_file, " branch ");
	  branch_count.dump (dump_file);
	  if (!bb->loop_father->inner && bb->loop_father->num)
	    fprintf (dump_file, " inner_loop");
	  if (bb->loop_father->header == bb)
	    fprintf (dump_file, " loop_header");
	  fprintf (dump_file, "\n");
	}
      if (!fallthru_count.initialized_p () || !branch_count.initialized_p ())
	continue;

      /* There are two purposes to align block with no fallthru incoming edge:
	 1) to avoid fetch stalls when branch destination is near cache boundary
	 2) to improve cache efficiency in case the previous block is not executed
	    (so it does not need to be in the cache).

	 We to catch first case, we align frequently executed blocks.
	 To catch the second, we align blocks that are executed more frequently
	 than the predecessor and the predecessor is likely to not be executed
	 when function is called.  */

      if (!has_fallthru
	  && (branch_count > count_threshold
	      || (bb->count > bb->prev_bb->count * 10
		  && (bb->prev_bb->count
		      <= ENTRY_BLOCK_PTR_FOR_FN (cfun)->count / 2))))
	{
	  align_flags alignment = JUMP_ALIGN (label);
	  if (dump_file)
	    fprintf (dump_file, "  jump alignment added.\n");
	  max_alignment = align_flags::max (max_alignment, alignment);
	}
      /* In case block is frequent and reached mostly by non-fallthru edge,
	 align it.  It is most likely a first block of loop.  */
      if (has_fallthru
	  && !(single_succ_p (bb)
	       && single_succ (bb) == EXIT_BLOCK_PTR_FOR_FN (cfun))
	  && optimize_bb_for_speed_p (bb)
	  && branch_count + fallthru_count > count_threshold
	  && (branch_count > fallthru_count * param_align_loop_iterations))
	{
	  align_flags alignment = LOOP_ALIGN (label);
	  if (dump_file)
	    fprintf (dump_file, "  internal loop alignment added.\n");
	  max_alignment = align_flags::max (max_alignment, alignment);
	}
      LABEL_TO_ALIGNMENT (label) = max_alignment;
    }

  loop_optimizer_finalize ();
  free_dominance_info (CDI_DOMINATORS);
  return 0;
}

/* Grow the LABEL_ALIGN array after new labels are created.  */

static void
grow_label_align (void)
{
  int old = max_labelno;
  int n_labels;
  int n_old_labels;

  max_labelno = max_label_num ();

  n_labels = max_labelno - min_labelno + 1;
  n_old_labels = old - min_labelno + 1;

  label_align.safe_grow_cleared (n_labels, true);

  /* Range of labels grows monotonically in the function.  Failing here
     means that the initialization of array got lost.  */
  gcc_assert (n_old_labels <= n_labels);
}

/* Update the already computed alignment information.  LABEL_PAIRS is a vector
   made up of pairs of labels for which the alignment information of the first
   element will be copied from that of the second element.  */

void
update_alignments (vec<rtx> &label_pairs)
{
  unsigned int i = 0;
  rtx iter, label = NULL_RTX;

  if (max_labelno != max_label_num ())
    grow_label_align ();

  FOR_EACH_VEC_ELT (label_pairs, i, iter)
    if (i & 1)
      LABEL_TO_ALIGNMENT (label) = LABEL_TO_ALIGNMENT (iter);
    else
      label = iter;
}

namespace {

const pass_data pass_data_compute_alignments =
{
  RTL_PASS, /* type */
  "alignments", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_NONE, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_compute_alignments : public rtl_opt_pass
{
public:
  pass_compute_alignments (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_compute_alignments, ctxt)
  {}

  /* opt_pass methods: */
  unsigned int execute (function *) final override
  {
    return compute_alignments ();
  }

}; // class pass_compute_alignments

} // anon namespace

rtl_opt_pass *
make_pass_compute_alignments (gcc::context *ctxt)
{
  return new pass_compute_alignments (ctxt);
}


/* Make a pass over all insns and compute their actual lengths by shortening
   any branches of variable length if possible.  */

/* shorten_branches might be called multiple times:  for example, the SH
   port splits out-of-range conditional branches in MACHINE_DEPENDENT_REORG.
   In order to do this, it needs proper length information, which it obtains
   by calling shorten_branches.  This cannot be collapsed with
   shorten_branches itself into a single pass unless we also want to integrate
   reorg.cc, since the branch splitting exposes new instructions with delay
   slots.  */

void
shorten_branches (rtx_insn *first)
{
  rtx_insn *insn;
  int max_uid;
  int i;
  rtx_insn *seq;
  int something_changed = 1;
  char *varying_length;
  rtx body;
  int uid;
  rtx align_tab[MAX_CODE_ALIGN + 1];

  /* Compute maximum UID and allocate label_align / uid_shuid.  */
  max_uid = get_max_uid ();

  /* Free uid_shuid before reallocating it.  */
  free (uid_shuid);

  uid_shuid = XNEWVEC (int, max_uid);

  if (max_labelno != max_label_num ())
    grow_label_align ();

  /* Initialize label_align and set up uid_shuid to be strictly
     monotonically rising with insn order.  */
  /* We use alignment here to keep track of the maximum alignment we want to
     impose on the next CODE_LABEL (or the current one if we are processing
     the CODE_LABEL itself).  */

  align_flags max_alignment;

  for (insn = get_insns (), i = 1; insn; insn = NEXT_INSN (insn))
    {
      INSN_SHUID (insn) = i++;
      if (INSN_P (insn))
	continue;

      if (rtx_code_label *label = dyn_cast <rtx_code_label *> (insn))
	{
	  /* Merge in alignments computed by compute_alignments.  */
	  align_flags alignment = LABEL_TO_ALIGNMENT (label);
	  max_alignment = align_flags::max (max_alignment, alignment);

	  rtx_jump_table_data *table = jump_table_for_label (label);
	  if (!table)
	    {
	      align_flags alignment = LABEL_ALIGN (label);
	      max_alignment = align_flags::max (max_alignment, alignment);
	    }
	  /* ADDR_VECs only take room if read-only data goes into the text
	     section.  */
	  if ((JUMP_TABLES_IN_TEXT_SECTION
	       || readonly_data_section == text_section)
	      && table)
	    {
	      align_flags alignment = align_flags (ADDR_VEC_ALIGN (table));
	      max_alignment = align_flags::max (max_alignment, alignment);
	    }
	  LABEL_TO_ALIGNMENT (label) = max_alignment;
	  max_alignment = align_flags ();
	}
      else if (BARRIER_P (insn))
	{
	  rtx_insn *label;

	  for (label = insn; label && ! INSN_P (label);
	       label = NEXT_INSN (label))
	    if (LABEL_P (label))
	      {
		align_flags alignment
		  = align_flags (LABEL_ALIGN_AFTER_BARRIER (insn));
		max_alignment = align_flags::max (max_alignment, alignment);
		break;
	      }
	}
    }
  if (!HAVE_ATTR_length)
    return;

  /* Allocate the rest of the arrays.  */
  insn_lengths = XNEWVEC (int, max_uid);
  insn_lengths_max_uid = max_uid;
  /* Syntax errors can lead to labels being outside of the main insn stream.
     Initialize insn_addresses, so that we get reproducible results.  */
  INSN_ADDRESSES_ALLOC (max_uid);

  varying_length = XCNEWVEC (char, max_uid);

  /* Initialize uid_align.  We scan instructions
     from end to start, and keep in align_tab[n] the last seen insn
     that does an alignment of at least n+1, i.e. the successor
     in the alignment chain for an insn that does / has a known
     alignment of n.  */
  uid_align = XCNEWVEC (rtx, max_uid);

  for (i = MAX_CODE_ALIGN + 1; --i >= 0;)
    align_tab[i] = NULL_RTX;
  seq = get_last_insn ();
  for (; seq; seq = PREV_INSN (seq))
    {
      int uid = INSN_UID (seq);
      int log;
      log = (LABEL_P (seq) ? LABEL_TO_ALIGNMENT (seq).levels[0].log : 0);
      uid_align[uid] = align_tab[0];
      if (log)
	{
	  /* Found an alignment label.  */
	  gcc_checking_assert (log < MAX_CODE_ALIGN + 1);
	  uid_align[uid] = align_tab[log];
	  for (i = log - 1; i >= 0; i--)
	    align_tab[i] = seq;
	}
    }

  /* When optimizing, we start assuming minimum length, and keep increasing
     lengths as we find the need for this, till nothing changes.
     When not optimizing, we start assuming maximum lengths, and
     do a single pass to update the lengths.  */
  bool increasing = optimize != 0;

#ifdef CASE_VECTOR_SHORTEN_MODE
  if (optimize)
    {
      /* Look for ADDR_DIFF_VECs, and initialize their minimum and maximum
         label fields.  */

      int min_shuid = INSN_SHUID (get_insns ()) - 1;
      int max_shuid = INSN_SHUID (get_last_insn ()) + 1;
      int rel;

      for (insn = first; insn != 0; insn = NEXT_INSN (insn))
	{
	  rtx min_lab = NULL_RTX, max_lab = NULL_RTX, pat;
	  int len, i, min, max, insn_shuid;
	  int min_align;
	  addr_diff_vec_flags flags;

	  if (! JUMP_TABLE_DATA_P (insn)
	      || GET_CODE (PATTERN (insn)) != ADDR_DIFF_VEC)
	    continue;
	  pat = PATTERN (insn);
	  len = XVECLEN (pat, 1);
	  gcc_assert (len > 0);
	  min_align = MAX_CODE_ALIGN;
	  for (min = max_shuid, max = min_shuid, i = len - 1; i >= 0; i--)
	    {
	      rtx lab = XEXP (XVECEXP (pat, 1, i), 0);
	      int shuid = INSN_SHUID (lab);
	      if (shuid < min)
		{
		  min = shuid;
		  min_lab = lab;
		}
	      if (shuid > max)
		{
		  max = shuid;
		  max_lab = lab;
		}

	      int label_alignment = LABEL_TO_ALIGNMENT (lab).levels[0].log;
	      if (min_align > label_alignment)
		min_align = label_alignment;
	    }
	  XEXP (pat, 2) = gen_rtx_LABEL_REF (Pmode, min_lab);
	  XEXP (pat, 3) = gen_rtx_LABEL_REF (Pmode, max_lab);
	  insn_shuid = INSN_SHUID (insn);
	  rel = INSN_SHUID (XEXP (XEXP (pat, 0), 0));
	  memset (&flags, 0, sizeof (flags));
	  flags.min_align = min_align;
	  flags.base_after_vec = rel > insn_shuid;
	  flags.min_after_vec  = min > insn_shuid;
	  flags.max_after_vec  = max > insn_shuid;
	  flags.min_after_base = min > rel;
	  flags.max_after_base = max > rel;
	  ADDR_DIFF_VEC_FLAGS (pat) = flags;

	  if (increasing)
	    PUT_MODE (pat, CASE_VECTOR_SHORTEN_MODE (0, 0, pat));
	}
    }
#endif /* CASE_VECTOR_SHORTEN_MODE */

  /* Compute initial lengths, addresses, and varying flags for each insn.  */
  int (*length_fun) (rtx_insn *) = increasing ? insn_min_length : insn_default_length;

  for (insn_current_address = 0, insn = first;
       insn != 0;
       insn_current_address += insn_lengths[uid], insn = NEXT_INSN (insn))
    {
      uid = INSN_UID (insn);

      insn_lengths[uid] = 0;

      if (LABEL_P (insn))
	{
	  int log = LABEL_TO_ALIGNMENT (insn).levels[0].log;
	  if (log)
	    {
	      int align = 1 << log;
	      int new_address = (insn_current_address + align - 1) & -align;
	      insn_lengths[uid] = new_address - insn_current_address;
	    }
	}

      INSN_ADDRESSES (uid) = insn_current_address + insn_lengths[uid];

      if (NOTE_P (insn) || BARRIER_P (insn)
	  || LABEL_P (insn) || DEBUG_INSN_P (insn))
	continue;
      if (insn->deleted ())
	continue;

      body = PATTERN (insn);
      if (rtx_jump_table_data *table = dyn_cast <rtx_jump_table_data *> (insn))
	{
	  /* This only takes room if read-only data goes into the text
	     section.  */
	  if (JUMP_TABLES_IN_TEXT_SECTION
	      || readonly_data_section == text_section)
	    insn_lengths[uid] = (XVECLEN (body,
					  GET_CODE (body) == ADDR_DIFF_VEC)
				 * GET_MODE_SIZE (table->get_data_mode ()));
	  /* Alignment is handled by ADDR_VEC_ALIGN.  */
	}
      else if (GET_CODE (body) == ASM_INPUT || asm_noperands (body) >= 0)
	insn_lengths[uid] = asm_insn_count (body) * insn_default_length (insn);
      else if (rtx_sequence *body_seq = dyn_cast <rtx_sequence *> (body))
	{
	  int i;
	  int const_delay_slots;
	  if (DELAY_SLOTS)
	    const_delay_slots = const_num_delay_slots (body_seq->insn (0));
	  else
	    const_delay_slots = 0;

	  int (*inner_length_fun) (rtx_insn *)
	    = const_delay_slots ? length_fun : insn_default_length;
	  /* Inside a delay slot sequence, we do not do any branch shortening
	     if the shortening could change the number of delay slots
	     of the branch.  */
	  for (i = 0; i < body_seq->len (); i++)
	    {
	      rtx_insn *inner_insn = body_seq->insn (i);
	      int inner_uid = INSN_UID (inner_insn);
	      int inner_length;

	      if (GET_CODE (PATTERN (inner_insn)) == ASM_INPUT
		  || asm_noperands (PATTERN (inner_insn)) >= 0)
		inner_length = (asm_insn_count (PATTERN (inner_insn))
				* insn_default_length (inner_insn));
	      else
		inner_length = inner_length_fun (inner_insn);

	      insn_lengths[inner_uid] = inner_length;
	      if (const_delay_slots)
		{
		  if ((varying_length[inner_uid]
		       = insn_variable_length_p (inner_insn)) != 0)
		    varying_length[uid] = 1;
		  INSN_ADDRESSES (inner_uid) = (insn_current_address
						+ insn_lengths[uid]);
		}
	      else
		varying_length[inner_uid] = 0;
	      insn_lengths[uid] += inner_length;
	    }
	}
      else if (GET_CODE (body) != USE && GET_CODE (body) != CLOBBER)
	{
	  insn_lengths[uid] = length_fun (insn);
	  varying_length[uid] = insn_variable_length_p (insn);
	}

      /* If needed, do any adjustment.  */
#ifdef ADJUST_INSN_LENGTH
      ADJUST_INSN_LENGTH (insn, insn_lengths[uid]);
      if (insn_lengths[uid] < 0)
	fatal_insn ("negative insn length", insn);
#endif
    }

  /* Now loop over all the insns finding varying length insns.  For each,
     get the current insn length.  If it has changed, reflect the change.
     When nothing changes for a full pass, we are done.  */

  while (something_changed)
    {
      something_changed = 0;
      insn_current_align = MAX_CODE_ALIGN - 1;
      for (insn_current_address = 0, insn = first;
	   insn != 0;
	   insn = NEXT_INSN (insn))
	{
	  int new_length;
#ifdef ADJUST_INSN_LENGTH
	  int tmp_length;
#endif
	  int length_align;

	  uid = INSN_UID (insn);

	  if (rtx_code_label *label = dyn_cast <rtx_code_label *> (insn))
	    {
	      int log = LABEL_TO_ALIGNMENT (label).levels[0].log;

#ifdef CASE_VECTOR_SHORTEN_MODE
	      /* If the mode of a following jump table was changed, we
		 may need to update the alignment of this label.  */

	      if (JUMP_TABLES_IN_TEXT_SECTION
		  || readonly_data_section == text_section)
		{
		  rtx_jump_table_data *table = jump_table_for_label (label);
		  if (table)
		    {
		      int newlog = ADDR_VEC_ALIGN (table);
		      if (newlog != log)
			{
			  log = newlog;
			  LABEL_TO_ALIGNMENT (insn) = log;
			  something_changed = 1;
			}
		    }
		}
#endif

	      if (log > insn_current_align)
		{
		  int align = 1 << log;
		  int new_address= (insn_current_address + align - 1) & -align;
		  insn_lengths[uid] = new_address - insn_current_address;
		  insn_current_align = log;
		  insn_current_address = new_address;
		}
	      else
		insn_lengths[uid] = 0;
	      INSN_ADDRESSES (uid) = insn_current_address;
	      continue;
	    }

	  length_align = INSN_LENGTH_ALIGNMENT (insn);
	  if (length_align < insn_current_align)
	    insn_current_align = length_align;

	  insn_last_address = INSN_ADDRESSES (uid);
	  INSN_ADDRESSES (uid) = insn_current_address;

#ifdef CASE_VECTOR_SHORTEN_MODE
	  if (optimize
	      && JUMP_TABLE_DATA_P (insn)
	      && GET_CODE (PATTERN (insn)) == ADDR_DIFF_VEC)
	    {
	      rtx_jump_table_data *table = as_a <rtx_jump_table_data *> (insn);
	      rtx body = PATTERN (insn);
	      int old_length = insn_lengths[uid];
	      rtx_insn *rel_lab =
		safe_as_a <rtx_insn *> (XEXP (XEXP (body, 0), 0));
	      rtx min_lab = XEXP (XEXP (body, 2), 0);
	      rtx max_lab = XEXP (XEXP (body, 3), 0);
	      int rel_addr = INSN_ADDRESSES (INSN_UID (rel_lab));
	      int min_addr = INSN_ADDRESSES (INSN_UID (min_lab));
	      int max_addr = INSN_ADDRESSES (INSN_UID (max_lab));
	      rtx_insn *prev;
	      int rel_align = 0;
	      addr_diff_vec_flags flags;
	      scalar_int_mode vec_mode;

	      /* Avoid automatic aggregate initialization.  */
	      flags = ADDR_DIFF_VEC_FLAGS (body);

	      /* Try to find a known alignment for rel_lab.  */
	      for (prev = rel_lab;
		   prev
		   && ! insn_lengths[INSN_UID (prev)]
		   && ! (varying_length[INSN_UID (prev)] & 1);
		   prev = PREV_INSN (prev))
		if (varying_length[INSN_UID (prev)] & 2)
		  {
		    rel_align = LABEL_TO_ALIGNMENT (prev).levels[0].log;
		    break;
		  }

	      /* See the comment on addr_diff_vec_flags in rtl.h for the
		 meaning of the flags values.  base: REL_LAB   vec: INSN  */
	      /* Anything after INSN has still addresses from the last
		 pass; adjust these so that they reflect our current
		 estimate for this pass.  */
	      if (flags.base_after_vec)
		rel_addr += insn_current_address - insn_last_address;
	      if (flags.min_after_vec)
		min_addr += insn_current_address - insn_last_address;
	      if (flags.max_after_vec)
		max_addr += insn_current_address - insn_last_address;
	      /* We want to know the worst case, i.e. lowest possible value
		 for the offset of MIN_LAB.  If MIN_LAB is after REL_LAB,
		 its offset is positive, and we have to be wary of code shrink;
		 otherwise, it is negative, and we have to be vary of code
		 size increase.  */
	      if (flags.min_after_base)
		{
		  /* If INSN is between REL_LAB and MIN_LAB, the size
		     changes we are about to make can change the alignment
		     within the observed offset, therefore we have to break
		     it up into two parts that are independent.  */
		  if (! flags.base_after_vec && flags.min_after_vec)
		    {
		      min_addr -= align_fuzz (rel_lab, insn, rel_align, 0);
		      min_addr -= align_fuzz (insn, min_lab, 0, 0);
		    }
		  else
		    min_addr -= align_fuzz (rel_lab, min_lab, rel_align, 0);
		}
	      else
		{
		  if (flags.base_after_vec && ! flags.min_after_vec)
		    {
		      min_addr -= align_fuzz (min_lab, insn, 0, ~0);
		      min_addr -= align_fuzz (insn, rel_lab, 0, ~0);
		    }
		  else
		    min_addr -= align_fuzz (min_lab, rel_lab, 0, ~0);
		}
	      /* Likewise, determine the highest lowest possible value
		 for the offset of MAX_LAB.  */
	      if (flags.max_after_base)
		{
		  if (! flags.base_after_vec && flags.max_after_vec)
		    {
		      max_addr += align_fuzz (rel_lab, insn, rel_align, ~0);
		      max_addr += align_fuzz (insn, max_lab, 0, ~0);
		    }
		  else
		    max_addr += align_fuzz (rel_lab, max_lab, rel_align, ~0);
		}
	      else
		{
		  if (flags.base_after_vec && ! flags.max_after_vec)
		    {
		      max_addr += align_fuzz (max_lab, insn, 0, 0);
		      max_addr += align_fuzz (insn, rel_lab, 0, 0);
		    }
		  else
		    max_addr += align_fuzz (max_lab, rel_lab, 0, 0);
		}
	      vec_mode = CASE_VECTOR_SHORTEN_MODE (min_addr - rel_addr,
						   max_addr - rel_addr, body);
	      if (!increasing
		  || (GET_MODE_SIZE (vec_mode)
		      >= GET_MODE_SIZE (table->get_data_mode ())))
		PUT_MODE (body, vec_mode);
	      if (JUMP_TABLES_IN_TEXT_SECTION
		  || readonly_data_section == text_section)
		{
		  insn_lengths[uid]
		    = (XVECLEN (body, 1)
		       * GET_MODE_SIZE (table->get_data_mode ()));
		  insn_current_address += insn_lengths[uid];
		  if (insn_lengths[uid] != old_length)
		    something_changed = 1;
		}

	      continue;
	    }
#endif /* CASE_VECTOR_SHORTEN_MODE */

	  if (! (varying_length[uid]))
	    {
	      if (NONJUMP_INSN_P (insn)
		  && GET_CODE (PATTERN (insn)) == SEQUENCE)
		{
		  int i;

		  body = PATTERN (insn);
		  for (i = 0; i < XVECLEN (body, 0); i++)
		    {
		      rtx inner_insn = XVECEXP (body, 0, i);
		      int inner_uid = INSN_UID (inner_insn);

		      INSN_ADDRESSES (inner_uid) = insn_current_address;

		      insn_current_address += insn_lengths[inner_uid];
		    }
		}
	      else
		insn_current_address += insn_lengths[uid];

	      continue;
	    }

	  if (NONJUMP_INSN_P (insn) && GET_CODE (PATTERN (insn)) == SEQUENCE)
	    {
	      rtx_sequence *seqn = as_a <rtx_sequence *> (PATTERN (insn));
	      int i;

	      body = PATTERN (insn);
	      new_length = 0;
	      for (i = 0; i < seqn->len (); i++)
		{
		  rtx_insn *inner_insn = seqn->insn (i);
		  int inner_uid = INSN_UID (inner_insn);
		  int inner_length;

		  INSN_ADDRESSES (inner_uid) = insn_current_address;

		  /* insn_current_length returns 0 for insns with a
		     non-varying length.  */
		  if (! varying_length[inner_uid])
		    inner_length = insn_lengths[inner_uid];
		  else
		    inner_length = insn_current_length (inner_insn);

		  if (inner_length != insn_lengths[inner_uid])
		    {
		      if (!increasing || inner_length > insn_lengths[inner_uid])
			{
			  insn_lengths[inner_uid] = inner_length;
			  something_changed = 1;
			}
		      else
			inner_length = insn_lengths[inner_uid];
		    }
		  insn_current_address += inner_length;
		  new_length += inner_length;
		}
	    }
	  else
	    {
	      new_length = insn_current_length (insn);
	      insn_current_address += new_length;
	    }

#ifdef ADJUST_INSN_LENGTH
	  /* If needed, do any adjustment.  */
	  tmp_length = new_length;
	  ADJUST_INSN_LENGTH (insn, new_length);
	  insn_current_address += (new_length - tmp_length);
#endif

	  if (new_length != insn_lengths[uid]
	      && (!increasing || new_length > insn_lengths[uid]))
	    {
	      insn_lengths[uid] = new_length;
	      something_changed = 1;
	    }
	  else
	    insn_current_address += insn_lengths[uid] - new_length;
	}
      /* For a non-optimizing compile, do only a single pass.  */
      if (!increasing)
	break;
    }
  crtl->max_insn_address = insn_current_address;
  free (varying_length);
}

/* Given the body of an INSN known to be generated by an ASM statement, return
   the number of machine instructions likely to be generated for this insn.
   This is used to compute its length.  */

static int
asm_insn_count (rtx body)
{
  const char *templ;

  if (GET_CODE (body) == ASM_INPUT)
    templ = XSTR (body, 0);
  else
    templ = decode_asm_operands (body, NULL, NULL, NULL, NULL, NULL);

  return asm_str_count (templ);
}

/* Return the number of machine instructions likely to be generated for the
   inline-asm template. */
int
asm_str_count (const char *templ)
{
  int count = 1;

  if (!*templ)
    return 0;

  for (; *templ; templ++)
    if (IS_ASM_LOGICAL_LINE_SEPARATOR (*templ, templ)
	|| *templ == '\n')
      count++;

  return count;
}

/* Return true if DWARF2 debug info can be emitted for DECL.  */

static bool
dwarf2_debug_info_emitted_p (tree decl)
{
  /* When DWARF2 debug info is not generated internally.  */
  if (!dwarf_debuginfo_p () && !dwarf_based_debuginfo_p ())
    return false;

  if (DECL_IGNORED_P (decl))
    return false;

  return true;
}

/* Return scope resulting from combination of S1 and S2.  */
static tree
choose_inner_scope (tree s1, tree s2)
{
   if (!s1)
     return s2;
   if (!s2)
     return s1;
   if (BLOCK_NUMBER (s1) > BLOCK_NUMBER (s2))
     return s1;
   return s2;
}

/* Emit lexical block notes needed to change scope from S1 to S2.  */

static void
change_scope (rtx_insn *orig_insn, tree s1, tree s2)
{
  rtx_insn *insn = orig_insn;
  tree com = NULL_TREE;
  tree ts1 = s1, ts2 = s2;
  tree s;

  while (ts1 != ts2)
    {
      gcc_assert (ts1 && ts2);
      if (BLOCK_NUMBER (ts1) > BLOCK_NUMBER (ts2))
	ts1 = BLOCK_SUPERCONTEXT (ts1);
      else if (BLOCK_NUMBER (ts1) < BLOCK_NUMBER (ts2))
	ts2 = BLOCK_SUPERCONTEXT (ts2);
      else
	{
	  ts1 = BLOCK_SUPERCONTEXT (ts1);
	  ts2 = BLOCK_SUPERCONTEXT (ts2);
	}
    }
  com = ts1;

  /* Close scopes.  */
  s = s1;
  while (s != com)
    {
      rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, insn);
      NOTE_BLOCK (note) = s;
      s = BLOCK_SUPERCONTEXT (s);
    }

  /* Open scopes.  */
  s = s2;
  while (s != com)
    {
      insn = emit_note_before (NOTE_INSN_BLOCK_BEG, insn);
      NOTE_BLOCK (insn) = s;
      s = BLOCK_SUPERCONTEXT (s);
    }
}

/* Rebuild all the NOTE_INSN_BLOCK_BEG and NOTE_INSN_BLOCK_END notes based
   on the scope tree and the newly reordered instructions.  */

static void
reemit_insn_block_notes (void)
{
  tree cur_block = DECL_INITIAL (cfun->decl);
  rtx_insn *insn;

  insn = get_insns ();
  for (; insn; insn = NEXT_INSN (insn))
    {
      tree this_block;

      /* Prevent lexical blocks from straddling section boundaries.  */
      if (NOTE_P (insn))
	switch (NOTE_KIND (insn))
	  {
	  case NOTE_INSN_SWITCH_TEXT_SECTIONS:
	    {
	      for (tree s = cur_block; s != DECL_INITIAL (cfun->decl);
		   s = BLOCK_SUPERCONTEXT (s))
		{
		  rtx_note *note = emit_note_before (NOTE_INSN_BLOCK_END, insn);
		  NOTE_BLOCK (note) = s;
		  note = emit_note_after (NOTE_INSN_BLOCK_BEG, insn);
		  NOTE_BLOCK (note) = s;
		}
	    }
	    break;

	  case NOTE_INSN_BEGIN_STMT:
	  case NOTE_INSN_INLINE_ENTRY:
	    this_block = LOCATION_BLOCK (NOTE_MARKER_LOCATION (insn));
	    goto set_cur_block_to_this_block;

	  default:
	    continue;
	}

      if (!active_insn_p (insn))
        continue;

      /* Avoid putting scope notes between jump table and its label.  */
      if (JUMP_TABLE_DATA_P (insn))
	continue;

      this_block = insn_scope (insn);
      /* For sequences compute scope resulting from merging all scopes
	 of instructions nested inside.  */
      if (rtx_sequence *body = dyn_cast <rtx_sequence *> (PATTERN (insn)))
	{
	  int i;

	  this_block = NULL;
	  for (i = 0; i < body->len (); i++)
	    this_block = choose_inner_scope (this_block,
					     insn_scope (body->insn (i)));
	}
    set_cur_block_to_this_block:
      if (! this_block)
	{
	  if (INSN_LOCATION (insn) == UNKNOWN_LOCATION)
	    continue;
	  else
	    this_block = DECL_INITIAL (cfun->decl);
	}

      if (this_block != cur_block)
	{
	  change_scope (insn, cur_block, this_block);
	  cur_block = this_block;
	}
    }

  /* change_scope emits before the insn, not after.  */
  rtx_note *note = emit_note (NOTE_INSN_DELETED);
  change_scope (note, cur_block, DECL_INITIAL (cfun->decl));
  delete_insn (note);

  reorder_blocks ();
}

static const char *some_local_dynamic_name;

/* Locate some local-dynamic symbol still in use by this function
   so that we can print its name in local-dynamic base patterns.
   Return null if there are no local-dynamic references.  */

const char *
get_some_local_dynamic_name ()
{
  subrtx_iterator::array_type array;
  rtx_insn *insn;

  if (some_local_dynamic_name)
    return some_local_dynamic_name;

  for (insn = get_insns (); insn ; insn = NEXT_INSN (insn))
    if (NONDEBUG_INSN_P (insn))
      FOR_EACH_SUBRTX (iter, array, PATTERN (insn), ALL)
	{
	  const_rtx x = *iter;
	  if (GET_CODE (x) == SYMBOL_REF)
	    {
	      if (SYMBOL_REF_TLS_MODEL (x) == TLS_MODEL_LOCAL_DYNAMIC)
		return some_local_dynamic_name = XSTR (x, 0);
	      if (CONSTANT_POOL_ADDRESS_P (x))
		iter.substitute (get_pool_constant (x));
	    }
	}

  return 0;
}

/* Arrange for us to emit a source location note before any further
   real insns or section changes, by setting the SEEN_NEXT_VIEW bit in
   *SEEN, as long as we are keeping track of location views.  The bit
   indicates we have referenced the next view at the current PC, so we
   have to emit it.  This should be called next to the var_location
   debug hook.  */

static inline void
set_next_view_needed (int *seen)
{
  if (debug_variable_location_views)
    *seen |= SEEN_NEXT_VIEW;
}

/* Clear the flag in *SEEN indicating we need to emit the next view.
   This should be called next to the source_line debug hook.  */

static inline void
clear_next_view_needed (int *seen)
{
  *seen &= ~SEEN_NEXT_VIEW;
}

/* Test whether we have a pending request to emit the next view in
   *SEEN, and emit it if needed, clearing the request bit.  */

static inline void
maybe_output_next_view (int *seen)
{
  if ((*seen & SEEN_NEXT_VIEW) != 0)
    {
      clear_next_view_needed (seen);
      (*debug_hooks->source_line) (last_linenum, last_columnnum,
				   last_filename, last_discriminator,
				   false);
    }
}

/* We want to emit param bindings (before the first begin_stmt) in the
   initial view, if we are emitting views.  To that end, we may
   consume initial notes in the function, processing them in
   final_start_function, before signaling the beginning of the
   prologue, rather than in final.

   We don't test whether the DECLs are PARM_DECLs: the assumption is
   that there will be a NOTE_INSN_BEGIN_STMT marker before any
   non-parameter NOTE_INSN_VAR_LOCATION.  It's ok if the marker is not
   there, we'll just have more variable locations bound in the initial
   view, which is consistent with their being bound without any code
   that would give them a value.  */

static inline bool
in_initial_view_p (rtx_insn *insn)
{
  return (!DECL_IGNORED_P (current_function_decl)
	  && debug_variable_location_views
	  && insn && GET_CODE (insn) == NOTE
	  && (NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION
	      || NOTE_KIND (insn) == NOTE_INSN_DELETED));
}

/* Output assembler code for the start of a function,
   and initialize some of the variables in this file
   for the new function.  The label for the function and associated
   assembler pseudo-ops have already been output in `assemble_start_function'.

   FIRST is the first insn of the rtl for the function being compiled.
   FILE is the file to write assembler code to.
   SEEN should be initially set to zero, and it may be updated to
   indicate we have references to the next location view, that would
   require us to emit it at the current PC.
   OPTIMIZE_P is nonzero if we should eliminate redundant
     test and compare insns.  */

static void
final_start_function_1 (rtx_insn **firstp, FILE *file, int *seen,
			int optimize_p ATTRIBUTE_UNUSED)
{
  block_depth = 0;

  this_is_asm_operands = 0;

  need_profile_function = false;

  last_filename = LOCATION_FILE (prologue_location);
  last_linenum = LOCATION_LINE (prologue_location);
  last_columnnum = LOCATION_COLUMN (prologue_location);
  last_discriminator = 0;
  force_source_line = false;

  high_block_linenum = high_function_linenum = last_linenum;

  if (flag_sanitize & SANITIZE_ADDRESS)
    asan_function_start ();

  rtx_insn *first = *firstp;
  if (in_initial_view_p (first))
    {
      do
	{
	  final_scan_insn (first, file, 0, 0, seen);
	  first = NEXT_INSN (first);
	}
      while (in_initial_view_p (first));
      *firstp = first;
    }

  if (!DECL_IGNORED_P (current_function_decl))
    debug_hooks->begin_prologue (last_linenum, last_columnnum,
				 last_filename);

  if (!dwarf2_debug_info_emitted_p (current_function_decl))
    dwarf2out_begin_prologue (0, 0, NULL);

  if (DECL_IGNORED_P (current_function_decl) && last_linenum && last_filename)
    debug_hooks->set_ignored_loc (last_linenum, last_columnnum, last_filename);

#ifdef LEAF_REG_REMAP
  if (crtl->uses_only_leaf_regs)
    leaf_renumber_regs (first);
#endif

  /* The Sun386i and perhaps other machines don't work right
     if the profiling code comes after the prologue.  */
  if (targetm.profile_before_prologue () && crtl->profile)
    {
      if (targetm.asm_out.function_prologue == default_function_pro_epilogue
	  && targetm.have_prologue ())
	{
	  rtx_insn *insn;
	  for (insn = first; insn; insn = NEXT_INSN (insn))
	    if (!NOTE_P (insn))
	      {
		insn = NULL;
		break;
	      }
	    else if (NOTE_KIND (insn) == NOTE_INSN_BASIC_BLOCK
		     || NOTE_KIND (insn) == NOTE_INSN_FUNCTION_BEG)
	      break;
	    else if (NOTE_KIND (insn) == NOTE_INSN_DELETED
		     || NOTE_KIND (insn) == NOTE_INSN_VAR_LOCATION)
	      continue;
	    else
	      {
		insn = NULL;
		break;
	      }

	  if (insn)
	    need_profile_function = true;
	  else
	    profile_function (file);
	}
      else
	profile_function (file);
    }

  /* If debugging, assign block numbers to all of the blocks in this
     function.  */
  if (write_symbols)
    {
      reemit_insn_block_notes ();
      number_blocks (current_function_decl);
      /* We never actually put out begin/end notes for the top-level
	 block in the function.  But, conceptually, that block is
	 always needed.  */
      TREE_ASM_WRITTEN (DECL_INITIAL (current_function_decl)) = 1;
    }

  unsigned HOST_WIDE_INT min_frame_size
    = constant_lower_bound (get_frame_size ());
  if (min_frame_size > (unsigned HOST_WIDE_INT) warn_frame_larger_than_size)
    {
      /* Issue a warning */
      warning (OPT_Wframe_larger_than_,
	       "the frame size of %wu bytes is larger than %wu bytes",
	       min_frame_size, warn_frame_larger_than_size);
    }

  /* First output the function prologue: code to set up the stack frame.  */
  targetm.asm_out.function_prologue (file);

  /* If the machine represents the prologue as RTL, the profiling code must
     be emitted when NOTE_INSN_PROLOGUE_END is scanned.  */
  if (! targetm.have_prologue ())
    profile_after_prologue (file);
}

/* This is an exported final_start_function_1, callable without SEEN.  */

void
final_start_function (rtx_insn *first, FILE *file,
		      int optimize_p ATTRIBUTE_UNUSED)
{
  int seen = 0;
  final_start_function_1 (&first, file, &seen, optimize_p);
  gcc_assert (seen == 0);
}

static void
profile_after_prologue (FILE *file ATTRIBUTE_UNUSED)
{
  if (!targetm.profile_before_prologue () && crtl->profile)
    profile_function (file);
}

static void
profile_function (FILE *file ATTRIBUTE_UNUSED)
{
#ifndef NO_PROFILE_COUNTERS
# define NO_PROFILE_COUNTERS	0
#endif
#ifdef ASM_OUTPUT_REG_PUSH
  rtx sval = NULL, chain = NULL;

  if (cfun->returns_struct)
    sval = targetm.calls.struct_value_rtx (TREE_TYPE (current_function_decl),
					   true);
  if (cfun->static_chain_decl)
    chain = targetm.calls.static_chain (current_function_decl, true);
#endif /* ASM_OUTPUT_REG_PUSH */

  if (! NO_PROFILE_COUNTERS)
    {
      int align = MIN (BIGGEST_ALIGNMENT, LONG_TYPE_SIZE);
      switch_to_section (data_section);
      ASM_OUTPUT_ALIGN (file, floor_log2 (align / BITS_PER_UNIT));
      targetm.asm_out.internal_label (file, "LP", current_function_funcdef_no);
      assemble_integer (const0_rtx, LONG_TYPE_SIZE / BITS_PER_UNIT, align, 1);
    }

  switch_to_section (current_function_section ());

#ifdef ASM_OUTPUT_REG_PUSH
  if (sval && REG_P (sval))
    ASM_OUTPUT_REG_PUSH (file, REGNO (sval));
  if (chain && REG_P (chain))
    ASM_OUTPUT_REG_PUSH (file, REGNO (chain));
#endif

  FUNCTION_PROFILER (file, current_function_funcdef_no);

#ifdef ASM_OUTPUT_REG_PUSH
  if (chain && REG_P (chain))
    ASM_OUTPUT_REG_POP (file, REGNO (chain));
  if (sval && REG_P (sval))
    ASM_OUTPUT_REG_POP (file, REGNO (sval));
#endif
}

/* Output assembler code for the end of a function.
   For clarity, args are same as those of `final_start_function'
   even though not all of them are needed.  */

void
final_end_function (void)
{
  app_disable ();

  if (!DECL_IGNORED_P (current_function_decl))
    debug_hooks->end_function (high_function_linenum);

  /* Finally, output the function epilogue:
     code to restore the stack frame and return to the caller.  */
  targetm.asm_out.function_epilogue (asm_out_file);

  /* And debug output.  */
  if (!DECL_IGNORED_P (current_function_decl))
    debug_hooks->end_epilogue (last_linenum, last_filename);

  if (!dwarf2_debug_info_emitted_p (current_function_decl)
      && dwarf2out_do_frame ())
    dwarf2out_end_epilogue (last_linenum, last_filename);

  some_local_dynamic_name = 0;
}


/* Dumper helper for basic block information. FILE is the assembly
   output file, and INSN is the instruction being emitted.  */

static void
dump_basic_block_info (FILE *file, rtx_insn *insn, basic_block *start_to_bb,
                       basic_block *end_to_bb, int bb_map_size, int *bb_seqn)
{
  basic_block bb;

  if (!flag_debug_asm)
    return;

  if (INSN_UID (insn) < bb_map_size
      && (bb = start_to_bb[INSN_UID (insn)]) != NULL)
    {
      edge e;
      edge_iterator ei;

      fprintf (file, "%s BLOCK %d", ASM_COMMENT_START, bb->index);
      if (bb->count.initialized_p ())
	{
          fprintf (file, ", count:");
	  bb->count.dump (file);
	}
      fprintf (file, " seq:%d", (*bb_seqn)++);
      fprintf (file, "\n%s PRED:", ASM_COMMENT_START);
      FOR_EACH_EDGE (e, ei, bb->preds)
        {
          dump_edge_info (file, e, TDF_DETAILS, 0);
        }
      fprintf (file, "\n");
    }
  if (INSN_UID (insn) < bb_map_size
      && (bb = end_to_bb[INSN_UID (insn)]) != NULL)
    {
      edge e;
      edge_iterator ei;

      fprintf (asm_out_file, "%s SUCC:", ASM_COMMENT_START);
      FOR_EACH_EDGE (e, ei, bb->succs)
       {
         dump_edge_info (asm_out_file, e, TDF_DETAILS, 1);
       }
      fprintf (file, "\n");
    }
}

/* Output assembler code for some insns: all or part of a function.
   For description of args, see `final_start_function', above.  */

static void
final_1 (rtx_insn *first, FILE *file, int seen, int optimize_p)
{
  rtx_insn *insn, *next;

  /* Used for -dA dump.  */
  basic_block *start_to_bb = NULL;
  basic_block *end_to_bb = NULL;
  int bb_map_size = 0;
  int bb_seqn = 0;

  last_ignored_compare = 0;

  init_recog ();

  CC_STATUS_INIT;

  if (flag_debug_asm)
    {
      basic_block bb;

      bb_map_size = get_max_uid () + 1;
      start_to_bb = XCNEWVEC (basic_block, bb_map_size);
      end_to_bb = XCNEWVEC (basic_block, bb_map_size);

      /* There is no cfg for a thunk.  */
      if (!cfun->is_thunk)
	FOR_EACH_BB_REVERSE_FN (bb, cfun)
	  {
	    start_to_bb[INSN_UID (BB_HEAD (bb))] = bb;
	    end_to_bb[INSN_UID (BB_END (bb))] = bb;
	  }
    }

  /* Output the insns.  */
  for (insn = first; insn;)
    {
      if (HAVE_ATTR_length)
	{
	  if ((unsigned) INSN_UID (insn) >= INSN_ADDRESSES_SIZE ())
	    {
	      /* This can be triggered by bugs elsewhere in the compiler if
		 new insns are created after init_insn_lengths is called.  */
	      gcc_assert (NOTE_P (insn));
	      insn_current_address = -1;
	    }
	  else
	    insn_current_address = INSN_ADDRESSES (INSN_UID (insn));
	  /* final can be seen as an iteration of shorten_branches that
	     does nothing (since a fixed point has already been reached).  */
	  insn_last_address = insn_current_address;
	}

      dump_basic_block_info (file, insn, start_to_bb, end_to_bb,
                             bb_map_size, &bb_seqn);
      insn = final_scan_insn (insn, file, optimize_p, 0, &seen);
    }

  maybe_output_next_view (&seen);

  if (flag_debug_asm)
    {
      free (start_to_bb);
      free (end_to_bb);
    }

  /* Remove CFI notes, to avoid compare-debug failures.  */
  for (insn = first; insn; insn = next)
    {
      next = NEXT_INSN (insn);
      if (NOTE_P (insn)
	  && (NOTE_KIND (insn) == NOTE_INSN_CFI
	      || NOTE_KIND (insn) == NOTE_INSN_CFI_LABEL))
	delete_insn (insn);
    }
}

/* This is an exported final_1, callable without SEEN.  */

void
final (rtx_insn *first, FILE *file, int optimize_p)
{
  /* Those that use the internal final_start_function_1/final_1 API
     skip initial debug bind notes in final_start_function_1, and pass
     the modified FIRST to final_1.  But those that use the public
     final_start_function/final APIs, final_start_function can't move
     FIRST because it's not passed by reference, so if they were
     skipped there, skip them again here.  */
  while (in_initial_view_p (first))
    first = NEXT_INSN (first);

  final_1 (first, file, 0, optimize_p);
}

const char *
get_insn_template (int code, rtx_insn *insn)
{
  switch (insn_data[code].output_format)
    {
    case INSN_OUTPUT_FORMAT_SINGLE:
      return insn_data[code].output.single;
    case INSN_OUTPUT_FORMAT_MULTI:
      return insn_data[code].output.multi[which_alternative];
    case INSN_OUTPUT_FORMAT_FUNCTION:
      gcc_assert (insn);
      return (*insn_data[code].output.function) (recog_data.operand, insn);

    default:
      gcc_unreachable ();
    }
}

/* Emit the appropriate declaration for an alternate-entry-point
   symbol represented by INSN, to FILE.  INSN is a CODE_LABEL with
   LABEL_KIND != LABEL_NORMAL.

   The case fall-through in this function is intentional.  */
static void
output_alternate_entry_point (FILE *file, rtx_insn *insn)
{
  const char *name = LABEL_NAME (insn);

  switch (LABEL_KIND (insn))
    {
    case LABEL_WEAK_ENTRY:
#ifdef ASM_WEAKEN_LABEL
      ASM_WEAKEN_LABEL (file, name);
      gcc_fallthrough ();
#endif
    case LABEL_GLOBAL_ENTRY:
      targetm.asm_out.globalize_label (file, name);
      gcc_fallthrough ();
    case LABEL_STATIC_ENTRY:
#ifdef ASM_OUTPUT_TYPE_DIRECTIVE
      ASM_OUTPUT_TYPE_DIRECTIVE (file, name, "function");
#endif
      ASM_OUTPUT_LABEL (file, name);
      break;

    case LABEL_NORMAL:
    default:
      gcc_unreachable ();
    }
}

/* Given a CALL_INSN, find and return the nested CALL. */
static rtx
call_from_call_insn (rtx_call_insn *insn)
{
  rtx x;
  gcc_assert (CALL_P (insn));
  x = PATTERN (insn);

  while (GET_CODE (x) != CALL)
    {
      switch (GET_CODE (x))
	{
	default:
	  gcc_unreachable ();
	case COND_EXEC:
	  x = COND_EXEC_CODE (x);
	  break;
	case PARALLEL:
	  x = XVECEXP (x, 0, 0);
	  break;
	case SET:
	  x = XEXP (x, 1);
	  break;
	}
    }
  return x;
}

/* Print a comment into the asm showing FILENAME, LINENUM, and the
   corresponding source line, if available.  */

static void
asm_show_source (const char *filename, int linenum)
{
  if (!filename)
    return;

  char_span line = location_get_source_line (filename, linenum);
  if (!line)
    return;

  fprintf (asm_out_file, "%s %s:%i: ", ASM_COMMENT_START, filename, linenum);
  /* "line" is not 0-terminated, so we must use its length.  */
  fwrite (line.get_buffer (), 1, line.length (), asm_out_file);
  fputc ('\n', asm_out_file);
}

/* Judge if an absolute jump table is relocatable.  */

bool
jumptable_relocatable (void)
{
  bool relocatable = false;

  if (!CASE_VECTOR_PC_RELATIVE
      && !targetm.asm_out.generate_pic_addr_diff_vec ()
      && targetm_common.have_named_sections)
     relocatable = targetm.asm_out.reloc_rw_mask ();

  return relocatable;
}

/* The final scan for one insn, INSN.
   Args are same as in `final', except that INSN
   is the insn being scanned.
   Value returned is the next insn to be scanned.

   NOPEEPHOLES is the flag to disallow peephole processing (currently
   used for within delayed branch sequence output).

   SEEN is used to track the end of the prologue, for emitting
   debug information.  We force the emission of a line note after
   both NOTE_INSN_PROLOGUE_END and NOTE_INSN_FUNCTION_BEG.  */

static rtx_insn *
final_scan_insn_1 (rtx_insn *insn, FILE *file, int optimize_p ATTRIBUTE_UNUSED,
		   int nopeepholes ATTRIBUTE_UNUSED, int *seen)
{
  rtx_insn *next;
  rtx_jump_table_data *table;

  insn_counter++;

  /* Ignore deleted insns.  These can occur when we split insns (due to a
     template of "#") while not optimizing.  */
  if (insn->deleted ())
    return NEXT_INSN (insn);

  switch (GET_CODE (insn))
    {
    case NOTE:
      switch (NOTE_KIND (insn))
	{
	case NOTE_INSN_DELETED:
	case NOTE_INSN_UPDATE_SJLJ_CONTEXT:
	  break;

	case NOTE_INSN_SWITCH_TEXT_SECTIONS:
	  maybe_output_next_view (seen);

	  output_function_exception_table (0);

	  if (targetm.asm_out.unwind_emit)
	    targetm.asm_out.unwind_emit (asm_out_file, insn);

	  in_cold_section_p = !in_cold_section_p;

	  gcc_checking_assert (in_cold_section_p);
	  if (in_cold_section_p)
	    cold_function_name
	      = clone_function_name (current_function_decl, "cold");

	  if (dwarf2out_do_frame ())
	    {
	      dwarf2out_switch_text_section ();
	      if (!dwarf2_debug_info_emitted_p (current_function_decl)
		  && !DECL_IGNORED_P (current_function_decl))
		debug_hooks->switch_text_section ();
	    }
	  else if (!DECL_IGNORED_P (current_function_decl))
	    debug_hooks->switch_text_section ();
	  if (DECL_IGNORED_P (current_function_decl) && last_linenum
	      && last_filename)
	    debug_hooks->set_ignored_loc (last_linenum, last_columnnum,
					  last_filename);

	  switch_to_section (current_function_section ());
	  targetm.asm_out.function_switched_text_sections (asm_out_file,
							   current_function_decl,
							   in_cold_section_p);
	  /* Emit a label for the split cold section.  Form label name by
	     suffixing "cold" to the original function's name.  */
	  if (in_cold_section_p)
	    {
#ifdef ASM_DECLARE_COLD_FUNCTION_NAME
	      ASM_DECLARE_COLD_FUNCTION_NAME (asm_out_file,
					      IDENTIFIER_POINTER
					          (cold_function_name),
					      current_function_decl);
#else
	      ASM_OUTPUT_LABEL (asm_out_file,
				IDENTIFIER_POINTER (cold_function_name));
#endif
	      if (dwarf2out_do_frame ()
	          && cfun->fde->dw_fde_second_begin != NULL)
		ASM_OUTPUT_LABEL (asm_out_file, cfun->fde->dw_fde_second_begin);
	    }
	  break;

	case NOTE_INSN_BASIC_BLOCK:
	  if (need_profile_function)
	    {
	      profile_function (asm_out_file);
	      need_profile_function = false;
	    }

	  if (targetm.asm_out.unwind_emit)
	    targetm.asm_out.unwind_emit (asm_out_file, insn);

	  break;

	case NOTE_INSN_EH_REGION_BEG:
	  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHB",
				  NOTE_EH_HANDLER (insn));
	  break;

	case NOTE_INSN_EH_REGION_END:
	  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LEHE",
				  NOTE_EH_HANDLER (insn));
	  break;

	case NOTE_INSN_PROLOGUE_END:
	  targetm.asm_out.function_end_prologue (file);
	  profile_after_prologue (file);

	  if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
	    {
	      *seen |= SEEN_EMITTED;
	      force_source_line = true;
	    }
	  else
	    *seen |= SEEN_NOTE;

	  break;

	case NOTE_INSN_EPILOGUE_BEG:
          if (!DECL_IGNORED_P (current_function_decl))
            (*debug_hooks->begin_epilogue) (last_linenum, last_filename);
	  targetm.asm_out.function_begin_epilogue (file);
	  break;

	case NOTE_INSN_CFI:
	  dwarf2out_emit_cfi (NOTE_CFI (insn));
	  break;

	case NOTE_INSN_CFI_LABEL:
	  ASM_OUTPUT_DEBUG_LABEL (asm_out_file, "LCFI",
				  NOTE_LABEL_NUMBER (insn));
	  break;

	case NOTE_INSN_FUNCTION_BEG:
	  if (need_profile_function)
	    {
	      profile_function (asm_out_file);
	      need_profile_function = false;
	    }

	  app_disable ();
	  if (!DECL_IGNORED_P (current_function_decl))
	    debug_hooks->end_prologue (last_linenum, last_filename);

	  if ((*seen & (SEEN_EMITTED | SEEN_NOTE)) == SEEN_NOTE)
	    {
	      *seen |= SEEN_EMITTED;
	      force_source_line = true;
	    }
	  else
	    *seen |= SEEN_NOTE;

	  break;

	case NOTE_INSN_BLOCK_BEG:
	  if (debug_info_level >= DINFO_LEVEL_NORMAL
	      || dwarf_debuginfo_p ()
	      || write_symbols == VMS_DEBUG)
	    {
	      int n = BLOCK_NUMBER (NOTE_BLOCK (insn));

	      app_disable ();
	      ++block_depth;
	      high_block_linenum = last_linenum;

	      /* Output debugging info about the symbol-block beginning.  */
	      if (!DECL_IGNORED_P (current_function_decl))
		debug_hooks->begin_block (last_linenum, n);

	      /* Mark this block as output.  */
	      TREE_ASM_WRITTEN (NOTE_BLOCK (insn)) = 1;
	      BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn)) = in_cold_section_p;
	    }
	  break;

	case NOTE_INSN_BLOCK_END:
	  maybe_output_next_view (seen);

	  if (debug_info_level >= DINFO_LEVEL_NORMAL
	      || dwarf_debuginfo_p ()
	      || write_symbols == VMS_DEBUG)
	    {
	      int n = BLOCK_NUMBER (NOTE_BLOCK (insn));

	      app_disable ();

	      /* End of a symbol-block.  */
	      --block_depth;
	      gcc_assert (block_depth >= 0);

	      if (!DECL_IGNORED_P (current_function_decl))
		debug_hooks->end_block (high_block_linenum, n);
	      gcc_assert (BLOCK_IN_COLD_SECTION_P (NOTE_BLOCK (insn))
			  == in_cold_section_p);
	    }
	  break;

	case NOTE_INSN_DELETED_LABEL:
	  /* Emit the label.  We may have deleted the CODE_LABEL because
	     the label could be proved to be unreachable, though still
	     referenced (in the form of having its address taken.  */
	  ASM_OUTPUT_DEBUG_LABEL (file, "L", CODE_LABEL_NUMBER (insn));
	  break;

	case NOTE_INSN_DELETED_DEBUG_LABEL:
	  /* Similarly, but need to use different namespace for it.  */
	  if (CODE_LABEL_NUMBER (insn) != -1)
	    ASM_OUTPUT_DEBUG_LABEL (file, "LDL", CODE_LABEL_NUMBER (insn));
	  break;

	case NOTE_INSN_VAR_LOCATION:
	  if (!DECL_IGNORED_P (current_function_decl))
	    {
	      debug_hooks->var_location (insn);
	      set_next_view_needed (seen);
	    }
	  break;

	case NOTE_INSN_BEGIN_STMT:
	  gcc_checking_assert (cfun->debug_nonbind_markers);
	  if (!DECL_IGNORED_P (current_function_decl)
	      && notice_source_line (insn, NULL))
	    {
	    output_source_line:
	      (*debug_hooks->source_line) (last_linenum, last_columnnum,
					   last_filename, last_discriminator,
					   true);
	      clear_next_view_needed (seen);
	    }
	  break;

	case NOTE_INSN_INLINE_ENTRY:
	  gcc_checking_assert (cfun->debug_nonbind_markers);
	  if (!DECL_IGNORED_P (current_function_decl)
	      && notice_source_line (insn, NULL))
	    {
	      (*debug_hooks->inline_entry) (LOCATION_BLOCK
					    (NOTE_MARKER_LOCATION (insn)));
	      goto output_source_line;
	    }
	  break;

	default:
	  gcc_unreachable ();
	  break;
	}
      break;

    case BARRIER:
      break;

    case CODE_LABEL:
      /* The target port might emit labels in the output function for
	 some insn, e.g. sh.cc output_branchy_insn.  */
      if (CODE_LABEL_NUMBER (insn) <= max_labelno)
	{
	  align_flags alignment = LABEL_TO_ALIGNMENT (insn);
	  if (alignment.levels[0].log && NEXT_INSN (insn))
	    {
#ifdef ASM_OUTPUT_MAX_SKIP_ALIGN
	      /* Output both primary and secondary alignment.  */
	      ASM_OUTPUT_MAX_SKIP_ALIGN (file, alignment.levels[0].log,
					 alignment.levels[0].maxskip);
	      ASM_OUTPUT_MAX_SKIP_ALIGN (file, alignment.levels[1].log,
					 alignment.levels[1].maxskip);
#else
#ifdef ASM_OUTPUT_ALIGN_WITH_NOP
              ASM_OUTPUT_ALIGN_WITH_NOP (file, alignment.levels[0].log);
#else
	      ASM_OUTPUT_ALIGN (file, alignment.levels[0].log);
#endif
#endif
	    }
	}
      CC_STATUS_INIT;

      if (!DECL_IGNORED_P (current_function_decl) && LABEL_NAME (insn))
	debug_hooks->label (as_a <rtx_code_label *> (insn));

      app_disable ();

      /* If this label is followed by a jump-table, make sure we put
	 the label in the read-only section.  Also possibly write the
	 label and jump table together.  */
      table = jump_table_for_label (as_a <rtx_code_label *> (insn));
      if (table)
	{
#if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
	  /* In this case, the case vector is being moved by the
	     target, so don't output the label at all.  Leave that
	     to the back end macros.  */
#else
	  if (! JUMP_TABLES_IN_TEXT_SECTION)
	    {
	      int log_align;

	      switch_to_section (targetm.asm_out.function_rodata_section
				 (current_function_decl,
				  jumptable_relocatable ()));

#ifdef ADDR_VEC_ALIGN
	      log_align = ADDR_VEC_ALIGN (table);
#else
	      log_align = exact_log2 (BIGGEST_ALIGNMENT / BITS_PER_UNIT);
#endif
	      ASM_OUTPUT_ALIGN (file, log_align);
	    }
	  else
	    switch_to_section (current_function_section ());

#ifdef ASM_OUTPUT_CASE_LABEL
	  ASM_OUTPUT_CASE_LABEL (file, "L", CODE_LABEL_NUMBER (insn), table);
#else
	  targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
#endif
#endif
	  break;
	}
      if (LABEL_ALT_ENTRY_P (insn))
	output_alternate_entry_point (file, insn);
      else
	targetm.asm_out.internal_label (file, "L", CODE_LABEL_NUMBER (insn));
      break;

    default:
      {
	rtx body = PATTERN (insn);
	int insn_code_number;
	const char *templ;
	bool is_stmt, *is_stmt_p;

	if (MAY_HAVE_DEBUG_MARKER_INSNS && cfun->debug_nonbind_markers)
	  {
	    is_stmt = false;
	    is_stmt_p = NULL;
	  }
	else
	  is_stmt_p = &is_stmt;

	/* Reset this early so it is correct for ASM statements.  */
	current_insn_predicate = NULL_RTX;

	/* An INSN, JUMP_INSN or CALL_INSN.
	   First check for special kinds that recog doesn't recognize.  */

	if (GET_CODE (body) == USE /* These are just declarations.  */
	    || GET_CODE (body) == CLOBBER)
	  break;

	/* Detect insns that are really jump-tables
	   and output them as such.  */

        if (JUMP_TABLE_DATA_P (insn))
	  {
#if !(defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC))
	    int vlen, idx;
#endif

	    if (! JUMP_TABLES_IN_TEXT_SECTION)
	      switch_to_section (targetm.asm_out.function_rodata_section
				 (current_function_decl,
				  jumptable_relocatable ()));
	    else
	      switch_to_section (current_function_section ());

	    app_disable ();

#if defined(ASM_OUTPUT_ADDR_VEC) || defined(ASM_OUTPUT_ADDR_DIFF_VEC)
	    if (GET_CODE (body) == ADDR_VEC)
	      {
#ifdef ASM_OUTPUT_ADDR_VEC
		ASM_OUTPUT_ADDR_VEC (PREV_INSN (insn), body);
#else
		gcc_unreachable ();
#endif
	      }
	    else
	      {
#ifdef ASM_OUTPUT_ADDR_DIFF_VEC
		ASM_OUTPUT_ADDR_DIFF_VEC (PREV_INSN (insn), body);
#else
		gcc_unreachable ();
#endif
	      }
#else
	    vlen = XVECLEN (body, GET_CODE (body) == ADDR_DIFF_VEC);
	    for (idx = 0; idx < vlen; idx++)
	      {
		if (GET_CODE (body) == ADDR_VEC)
		  {
#ifdef ASM_OUTPUT_ADDR_VEC_ELT
		    ASM_OUTPUT_ADDR_VEC_ELT
		      (file, CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 0, idx), 0)));
#else
		    gcc_unreachable ();
#endif
		  }
		else
		  {
#ifdef ASM_OUTPUT_ADDR_DIFF_ELT
		    ASM_OUTPUT_ADDR_DIFF_ELT
		      (file,
		       body,
		       CODE_LABEL_NUMBER (XEXP (XVECEXP (body, 1, idx), 0)),
		       CODE_LABEL_NUMBER (XEXP (XEXP (body, 0), 0)));
#else
		    gcc_unreachable ();
#endif
		  }
	      }
#ifdef ASM_OUTPUT_CASE_END
	    ASM_OUTPUT_CASE_END (file,
				 CODE_LABEL_NUMBER (PREV_INSN (insn)),
				 insn);
#endif
#endif

	    switch_to_section (current_function_section ());

	    if (debug_variable_location_views
		&& !DECL_IGNORED_P (current_function_decl))
	      debug_hooks->var_location (insn);

	    break;
	  }
	/* Output this line note if it is the first or the last line
	   note in a row.  */
	if (!DECL_IGNORED_P (current_function_decl)
	    && notice_source_line (insn, is_stmt_p))
	  {
	    if (flag_verbose_asm)
	      asm_show_source (last_filename, last_linenum);
	    (*debug_hooks->source_line) (last_linenum, last_columnnum,
					 last_filename, last_discriminator,
					 is_stmt);
	    clear_next_view_needed (seen);
	  }
	else
	  maybe_output_next_view (seen);

	gcc_checking_assert (!DEBUG_INSN_P (insn));

	if (GET_CODE (body) == PARALLEL
	    && GET_CODE (XVECEXP (body, 0, 0)) == ASM_INPUT)
	  body = XVECEXP (body, 0, 0);

	if (GET_CODE (body) == ASM_INPUT)
	  {
	    const char *string = XSTR (body, 0);

	    /* There's no telling what that did to the condition codes.  */
	    CC_STATUS_INIT;

	    if (string[0])
	      {
		expanded_location loc;

		app_enable ();
		loc = expand_location (ASM_INPUT_SOURCE_LOCATION (body));
		if (*loc.file && loc.line)
		  fprintf (asm_out_file, "%s %i \"%s\" 1\n",
			   ASM_COMMENT_START, loc.line, loc.file);
		fprintf (asm_out_file, "\t%s\n", string);
#if HAVE_AS_LINE_ZERO
		if (*loc.file && loc.line)
		  fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START);
#endif
	      }
	    break;
	  }

	/* Detect `asm' construct with operands.  */
	if (asm_noperands (body) >= 0)
	  {
	    unsigned int noperands = asm_noperands (body);
	    rtx *ops = XALLOCAVEC (rtx, noperands);
	    const char *string;
	    location_t loc;
	    expanded_location expanded;

	    /* There's no telling what that did to the condition codes.  */
	    CC_STATUS_INIT;

	    /* Get out the operand values.  */
	    string = decode_asm_operands (body, ops, NULL, NULL, NULL, &loc);
	    /* Inhibit dying on what would otherwise be compiler bugs.  */
	    insn_noperands = noperands;
	    this_is_asm_operands = insn;
	    expanded = expand_location (loc);

#ifdef FINAL_PRESCAN_INSN
	    FINAL_PRESCAN_INSN (insn, ops, insn_noperands);
#endif

	    /* Output the insn using them.  */
	    if (string[0])
	      {
		app_enable ();
		if (expanded.file && expanded.line)
		  fprintf (asm_out_file, "%s %i \"%s\" 1\n",
			   ASM_COMMENT_START, expanded.line, expanded.file);
	        output_asm_insn (string, ops);
#if HAVE_AS_LINE_ZERO
		if (expanded.file && expanded.line)
		  fprintf (asm_out_file, "%s 0 \"\" 2\n", ASM_COMMENT_START);
#endif
	      }

	    if (targetm.asm_out.final_postscan_insn)
	      targetm.asm_out.final_postscan_insn (file, insn, ops,
						   insn_noperands);

	    this_is_asm_operands = 0;
	    break;
	  }

	app_disable ();

	if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (body))
	  {
	    /* A delayed-branch sequence */
	    int i;

	    final_sequence = seq;

	    /* The first insn in this SEQUENCE might be a JUMP_INSN that will
	       force the restoration of a comparison that was previously
	       thought unnecessary.  If that happens, cancel this sequence
	       and cause that insn to be restored.  */

	    next = final_scan_insn (seq->insn (0), file, 0, 1, seen);
	    if (next != seq->insn (1))
	      {
		final_sequence = 0;
		return next;
	      }

	    for (i = 1; i < seq->len (); i++)
	      {
		rtx_insn *insn = seq->insn (i);
		rtx_insn *next = NEXT_INSN (insn);
		/* We loop in case any instruction in a delay slot gets
		   split.  */
		do
		  insn = final_scan_insn (insn, file, 0, 1, seen);
		while (insn != next);
	      }
#ifdef DBR_OUTPUT_SEQEND
	    DBR_OUTPUT_SEQEND (file);
#endif
	    final_sequence = 0;

	    /* If the insn requiring the delay slot was a CALL_INSN, the
	       insns in the delay slot are actually executed before the
	       called function.  Hence we don't preserve any CC-setting
	       actions in these insns and the CC must be marked as being
	       clobbered by the function.  */
	    if (CALL_P (seq->insn (0)))
	      {
		CC_STATUS_INIT;
	      }
	    break;
	  }

	/* We have a real machine instruction as rtl.  */

	body = PATTERN (insn);

	/* Do machine-specific peephole optimizations if desired.  */

	if (HAVE_peephole && optimize_p && !flag_no_peephole && !nopeepholes)
	  {
	    rtx_insn *next = peephole (insn);
	    /* When peepholing, if there were notes within the peephole,
	       emit them before the peephole.  */
	    if (next != 0 && next != NEXT_INSN (insn))
	      {
		rtx_insn *note, *prev = PREV_INSN (insn);

		for (note = NEXT_INSN (insn); note != next;
		     note = NEXT_INSN (note))
		  final_scan_insn (note, file, optimize_p, nopeepholes, seen);

		/* Put the notes in the proper position for a later
		   rescan.  For example, the SH target can do this
		   when generating a far jump in a delayed branch
		   sequence.  */
		note = NEXT_INSN (insn);
		SET_PREV_INSN (note) = prev;
		SET_NEXT_INSN (prev) = note;
		SET_NEXT_INSN (PREV_INSN (next)) = insn;
		SET_PREV_INSN (insn) = PREV_INSN (next);
		SET_NEXT_INSN (insn) = next;
		SET_PREV_INSN (next) = insn;
	      }

	    /* PEEPHOLE might have changed this.  */
	    body = PATTERN (insn);
	  }

	/* Try to recognize the instruction.
	   If successful, verify that the operands satisfy the
	   constraints for the instruction.  Crash if they don't,
	   since `reload' should have changed them so that they do.  */

	insn_code_number = recog_memoized (insn);
	cleanup_subreg_operands (insn);

	/* Dump the insn in the assembly for debugging (-dAP).
	   If the final dump is requested as slim RTL, dump slim
	   RTL to the assembly file also.  */
	if (flag_dump_rtl_in_asm)
	  {
	    print_rtx_head = ASM_COMMENT_START;
	    if (! (dump_flags & TDF_SLIM))
	      print_rtl_single (asm_out_file, insn);
	    else
	      dump_insn_slim (asm_out_file, insn);
	    print_rtx_head = "";
	  }

	if (! constrain_operands_cached (insn, 1))
	  fatal_insn_not_found (insn);

	/* Some target machines need to prescan each insn before
	   it is output.  */

#ifdef FINAL_PRESCAN_INSN
	FINAL_PRESCAN_INSN (insn, recog_data.operand, recog_data.n_operands);
#endif

	if (targetm.have_conditional_execution ()
	    && GET_CODE (PATTERN (insn)) == COND_EXEC)
	  current_insn_predicate = COND_EXEC_TEST (PATTERN (insn));

	current_output_insn = debug_insn = insn;

	/* Find the proper template for this insn.  */
	templ = get_insn_template (insn_code_number, insn);

	/* If the C code returns 0, it means that it is a jump insn
	   which follows a deleted test insn, and that test insn
	   needs to be reinserted.  */
	if (templ == 0)
	  {
	    rtx_insn *prev;

	    gcc_assert (prev_nonnote_insn (insn) == last_ignored_compare);

	    /* We have already processed the notes between the setter and
	       the user.  Make sure we don't process them again, this is
	       particularly important if one of the notes is a block
	       scope note or an EH note.  */
	    for (prev = insn;
		 prev != last_ignored_compare;
		 prev = PREV_INSN (prev))
	      {
		if (NOTE_P (prev))
		  delete_insn (prev);	/* Use delete_note.  */
	      }

	    return prev;
	  }

	/* If the template is the string "#", it means that this insn must
	   be split.  */
	if (templ[0] == '#' && templ[1] == '\0')
	  {
	    rtx_insn *new_rtx = try_split (body, insn, 0);

	    /* If we didn't split the insn, go away.  */
	    if (new_rtx == insn && PATTERN (new_rtx) == body)
	      fatal_insn ("could not split insn", insn);

	    /* If we have a length attribute, this instruction should have
	       been split in shorten_branches, to ensure that we would have
	       valid length info for the splitees.  */
	    gcc_assert (!HAVE_ATTR_length);

	    return new_rtx;
	  }

	/* ??? This will put the directives in the wrong place if
	   get_insn_template outputs assembly directly.  However calling it
	   before get_insn_template breaks if the insns is split.  */
	if (targetm.asm_out.unwind_emit_before_insn
	    && targetm.asm_out.unwind_emit)
	  targetm.asm_out.unwind_emit (asm_out_file, insn);

	rtx_call_insn *call_insn = dyn_cast <rtx_call_insn *> (insn);
	if (call_insn != NULL)
	  {
	    rtx x = call_from_call_insn (call_insn);
	    x = XEXP (x, 0);
	    if (x && MEM_P (x) && GET_CODE (XEXP (x, 0)) == SYMBOL_REF)
	      {
		tree t;
		x = XEXP (x, 0);
		t = SYMBOL_REF_DECL (x);
		if (t)
		  assemble_external (t);
	      }
	  }

	/* Output assembler code from the template.  */
	output_asm_insn (templ, recog_data.operand);

	/* Some target machines need to postscan each insn after
	   it is output.  */
	if (targetm.asm_out.final_postscan_insn)
	  targetm.asm_out.final_postscan_insn (file, insn, recog_data.operand,
					       recog_data.n_operands);

	if (!targetm.asm_out.unwind_emit_before_insn
	    && targetm.asm_out.unwind_emit)
	  targetm.asm_out.unwind_emit (asm_out_file, insn);

	/* Let the debug info back-end know about this call.  We do this only
	   after the instruction has been emitted because labels that may be
	   created to reference the call instruction must appear after it.  */
	if ((debug_variable_location_views || call_insn != NULL)
	    && !DECL_IGNORED_P (current_function_decl))
	  debug_hooks->var_location (insn);

	current_output_insn = debug_insn = 0;
      }
    }
  return NEXT_INSN (insn);
}

/* This is a wrapper around final_scan_insn_1 that allows ports to
   call it recursively without a known value for SEEN.  The value is
   saved at the outermost call, and recovered for recursive calls.
   Recursive calls MUST pass NULL, or the same pointer if they can
   otherwise get to it.  */

rtx_insn *
final_scan_insn (rtx_insn *insn, FILE *file, int optimize_p,
		 int nopeepholes, int *seen)
{
  static int *enclosing_seen;
  static int recursion_counter;

  gcc_assert (seen || recursion_counter);
  gcc_assert (!recursion_counter || !seen || seen == enclosing_seen);

  if (!recursion_counter++)
    enclosing_seen = seen;
  else if (!seen)
    seen = enclosing_seen;

  rtx_insn *ret = final_scan_insn_1 (insn, file, optimize_p, nopeepholes, seen);

  if (!--recursion_counter)
    enclosing_seen = NULL;

  return ret;
}



/* Map DECLs to instance discriminators.  This is allocated and
   defined in ada/gcc-interfaces/trans.cc, when compiling with -gnateS.
   Mappings from this table are saved and restored for LTO, so
   link-time compilation will have this map set, at least in
   partitions containing at least one DECL with an associated instance
   discriminator.  */

decl_to_instance_map_t *decl_to_instance_map;

/* Return the instance number assigned to DECL.  */

static inline int
map_decl_to_instance (const_tree decl)
{
  int *inst;

  if (!decl_to_instance_map || !decl || !DECL_P (decl))
    return 0;

  inst = decl_to_instance_map->get (decl);

  if (!inst)
    return 0;

  return *inst;
}

/* Set DISCRIMINATOR to the appropriate value, possibly derived from LOC.  */

static inline int
compute_discriminator (location_t loc)
{
  int discriminator;

  if (!decl_to_instance_map)
    discriminator = get_discriminator_from_loc (loc);
  else
    {
      tree block = LOCATION_BLOCK (loc);

      while (block && TREE_CODE (block) == BLOCK
	     && !inlined_function_outer_scope_p (block))
	block = BLOCK_SUPERCONTEXT (block);

      tree decl;

      if (!block)
	decl = current_function_decl;
      else if (DECL_P (block))
	decl = block;
      else
	decl = block_ultimate_origin (block);

      discriminator = map_decl_to_instance (decl);
    }

  return discriminator;
}

/* Return discriminator of the statement that produced this insn.  */
int
insn_discriminator (const rtx_insn *insn)
{
  return compute_discriminator (INSN_LOCATION (insn));
}

/* Return whether a source line note needs to be emitted before INSN.
   Sets IS_STMT to TRUE if the line should be marked as a possible
   breakpoint location.  */

static bool
notice_source_line (rtx_insn *insn, bool *is_stmt)
{
  const char *filename;
  int linenum, columnnum;
  int discriminator;

  if (NOTE_MARKER_P (insn))
    {
      location_t loc = NOTE_MARKER_LOCATION (insn);
      expanded_location xloc = expand_location (loc);
      if (xloc.line == 0
	  && (LOCATION_LOCUS (loc) == UNKNOWN_LOCATION
	      || LOCATION_LOCUS (loc) == BUILTINS_LOCATION))
	return false;

      filename = xloc.file;
      linenum = xloc.line;
      columnnum = xloc.column;
      discriminator = compute_discriminator (loc);
      force_source_line = true;
    }
  else if (override_filename)
    {
      filename = override_filename;
      linenum = override_linenum;
      columnnum = override_columnnum;
      discriminator = override_discriminator;
    }
  else if (INSN_HAS_LOCATION (insn))
    {
      expanded_location xloc = insn_location (insn);
      filename = xloc.file;
      linenum = xloc.line;
      columnnum = xloc.column;
      discriminator = insn_discriminator (insn);
    }
  else
    {
      filename = NULL;
      linenum = 0;
      columnnum = 0;
      discriminator = 0;
    }

  if (filename == NULL)
    return false;

  if (force_source_line
      || filename != last_filename
      || last_linenum != linenum
      || (debug_column_info && last_columnnum != columnnum))
    {
      force_source_line = false;
      last_filename = filename;
      last_linenum = linenum;
      last_columnnum = columnnum;
      last_discriminator = discriminator;
      if (is_stmt)
	*is_stmt = true;
      high_block_linenum = MAX (last_linenum, high_block_linenum);
      high_function_linenum = MAX (last_linenum, high_function_linenum);
      return true;
    }

  if (SUPPORTS_DISCRIMINATOR && last_discriminator != discriminator)
    {
      /* If the discriminator changed, but the line number did not,
         output the line table entry with is_stmt false so the
         debugger does not treat this as a breakpoint location.  */
      last_discriminator = discriminator;
      if (is_stmt)
	*is_stmt = false;
      return true;
    }

  return false;
}

/* For each operand in INSN, simplify (subreg (reg)) so that it refers
   directly to the desired hard register.  */

void
cleanup_subreg_operands (rtx_insn *insn)
{
  int i;
  bool changed = false;
  extract_insn_cached (insn);
  for (i = 0; i < recog_data.n_operands; i++)
    {
      /* The following test cannot use recog_data.operand when testing
	 for a SUBREG: the underlying object might have been changed
	 already if we are inside a match_operator expression that
	 matches the else clause.  Instead we test the underlying
	 expression directly.  */
      if (GET_CODE (*recog_data.operand_loc[i]) == SUBREG)
	{
	  recog_data.operand[i] = alter_subreg (recog_data.operand_loc[i], true);
	  changed = true;
	}
      else if (GET_CODE (recog_data.operand[i]) == PLUS
	       || GET_CODE (recog_data.operand[i]) == MULT
	       || MEM_P (recog_data.operand[i]))
	recog_data.operand[i] = walk_alter_subreg (recog_data.operand_loc[i], &changed);
    }

  for (i = 0; i < recog_data.n_dups; i++)
    {
      if (GET_CODE (*recog_data.dup_loc[i]) == SUBREG)
	{
	  *recog_data.dup_loc[i] = alter_subreg (recog_data.dup_loc[i], true);
	  changed = true;
	}
      else if (GET_CODE (*recog_data.dup_loc[i]) == PLUS
	       || GET_CODE (*recog_data.dup_loc[i]) == MULT
	       || MEM_P (*recog_data.dup_loc[i]))
	*recog_data.dup_loc[i] = walk_alter_subreg (recog_data.dup_loc[i], &changed);
    }
  if (changed)
    df_insn_rescan (insn);
}

/* If X is a SUBREG, try to replace it with a REG or a MEM, based on
   the thing it is a subreg of.  Do it anyway if FINAL_P.  */

rtx
alter_subreg (rtx *xp, bool final_p)
{
  rtx x = *xp;
  rtx y = SUBREG_REG (x);

  /* simplify_subreg does not remove subreg from volatile references.
     We are required to.  */
  if (MEM_P (y))
    {
      poly_int64 offset = SUBREG_BYTE (x);

      /* For paradoxical subregs on big-endian machines, SUBREG_BYTE
	 contains 0 instead of the proper offset.  See simplify_subreg.  */
      if (paradoxical_subreg_p (x))
	offset = byte_lowpart_offset (GET_MODE (x), GET_MODE (y));

      if (final_p)
	*xp = adjust_address (y, GET_MODE (x), offset);
      else
	*xp = adjust_address_nv (y, GET_MODE (x), offset);
    }
  else if (REG_P (y) && HARD_REGISTER_P (y))
    {
      rtx new_rtx = simplify_subreg (GET_MODE (x), y, GET_MODE (y),
				     SUBREG_BYTE (x));

      if (new_rtx != 0)
	*xp = new_rtx;
      else if (final_p && REG_P (y))
	{
	  /* Simplify_subreg can't handle some REG cases, but we have to.  */
	  unsigned int regno;
	  poly_int64 offset;

	  regno = subreg_regno (x);
	  if (subreg_lowpart_p (x))
	    offset = byte_lowpart_offset (GET_MODE (x), GET_MODE (y));
	  else
	    offset = SUBREG_BYTE (x);
	  *xp = gen_rtx_REG_offset (y, GET_MODE (x), regno, offset);
	}
    }

  return *xp;
}

/* Do alter_subreg on all the SUBREGs contained in X.  */

static rtx
walk_alter_subreg (rtx *xp, bool *changed)
{
  rtx x = *xp;
  switch (GET_CODE (x))
    {
    case PLUS:
    case MULT:
    case AND:
      XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0), changed);
      XEXP (x, 1) = walk_alter_subreg (&XEXP (x, 1), changed);
      break;

    case MEM:
    case ZERO_EXTEND:
      XEXP (x, 0) = walk_alter_subreg (&XEXP (x, 0), changed);
      break;

    case SUBREG:
      *changed = true;
      return alter_subreg (xp, true);

    default:
      break;
    }

  return *xp;
}

/* Report inconsistency between the assembler template and the operands.
   In an `asm', it's the user's fault; otherwise, the compiler's fault.  */

void
output_operand_lossage (const char *cmsgid, ...)
{
  char *fmt_string;
  char *new_message;
  const char *pfx_str;
  va_list ap;

  va_start (ap, cmsgid);

  pfx_str = this_is_asm_operands ? _("invalid 'asm': ") : "output_operand: ";
  fmt_string = xasprintf ("%s%s", pfx_str, _(cmsgid));
  new_message = xvasprintf (fmt_string, ap);

  if (this_is_asm_operands)
    error_for_asm (this_is_asm_operands, "%s", new_message);
  else
    internal_error ("%s", new_message);

  free (fmt_string);
  free (new_message);
  va_end (ap);
}

/* Output of assembler code from a template, and its subroutines.  */

/* Annotate the assembly with a comment describing the pattern and
   alternative used.  */

static void
output_asm_name (void)
{
  if (debug_insn)
    {
      fprintf (asm_out_file, "\t%s %d\t",
	       ASM_COMMENT_START, INSN_UID (debug_insn));

      fprintf (asm_out_file, "[c=%d",
	       insn_cost (debug_insn, optimize_insn_for_speed_p ()));
      if (HAVE_ATTR_length)
	fprintf (asm_out_file, " l=%d",
		 get_attr_length (debug_insn));
      fprintf (asm_out_file, "]  ");

      int num = INSN_CODE (debug_insn);
      fprintf (asm_out_file, "%s", insn_data[num].name);
      if (insn_data[num].n_alternatives > 1)
	fprintf (asm_out_file, "/%d", which_alternative);

      /* Clear this so only the first assembler insn
	 of any rtl insn will get the special comment for -dp.  */
      debug_insn = 0;
    }
}

/* If OP is a REG or MEM and we can find a MEM_EXPR corresponding to it
   or its address, return that expr .  Set *PADDRESSP to 1 if the expr
   corresponds to the address of the object and 0 if to the object.  */

static tree
get_mem_expr_from_op (rtx op, int *paddressp)
{
  tree expr;
  int inner_addressp;

  *paddressp = 0;

  if (REG_P (op))
    return REG_EXPR (op);
  else if (!MEM_P (op))
    return 0;

  if (MEM_EXPR (op) != 0)
    return MEM_EXPR (op);

  /* Otherwise we have an address, so indicate it and look at the address.  */
  *paddressp = 1;
  op = XEXP (op, 0);

  /* First check if we have a decl for the address, then look at the right side
     if it is a PLUS.  Otherwise, strip off arithmetic and keep looking.
     But don't allow the address to itself be indirect.  */
  if ((expr = get_mem_expr_from_op (op, &inner_addressp)) && ! inner_addressp)
    return expr;
  else if (GET_CODE (op) == PLUS
	   && (expr = get_mem_expr_from_op (XEXP (op, 1), &inner_addressp)))
    return expr;

  while (UNARY_P (op)
	 || GET_RTX_CLASS (GET_CODE (op)) == RTX_BIN_ARITH)
    op = XEXP (op, 0);

  expr = get_mem_expr_from_op (op, &inner_addressp);
  return inner_addressp ? 0 : expr;
}

/* Output operand names for assembler instructions.  OPERANDS is the
   operand vector, OPORDER is the order to write the operands, and NOPS
   is the number of operands to write.  */

static void
output_asm_operand_names (rtx *operands, int *oporder, int nops)
{
  int wrote = 0;
  int i;

  for (i = 0; i < nops; i++)
    {
      int addressp;
      rtx op = operands[oporder[i]];
      tree expr = get_mem_expr_from_op (op, &addressp);

      fprintf (asm_out_file, "%c%s",
	       wrote ? ',' : '\t', wrote ? "" : ASM_COMMENT_START);
      wrote = 1;
      if (expr)
	{
	  fprintf (asm_out_file, "%s",
		   addressp ? "*" : "");
	  print_mem_expr (asm_out_file, expr);
	  wrote = 1;
	}
      else if (REG_P (op) && ORIGINAL_REGNO (op)
	       && ORIGINAL_REGNO (op) != REGNO (op))
	fprintf (asm_out_file, " tmp%i", ORIGINAL_REGNO (op));
    }
}

#ifdef ASSEMBLER_DIALECT
/* Helper function to parse assembler dialects in the asm string.
   This is called from output_asm_insn and asm_fprintf.  */
static const char *
do_assembler_dialects (const char *p, int *dialect)
{
  char c = *(p - 1);

  switch (c)
    {
    case '{':
      {
        int i;

        if (*dialect)
          output_operand_lossage ("nested assembly dialect alternatives");
        else
          *dialect = 1;

        /* If we want the first dialect, do nothing.  Otherwise, skip
           DIALECT_NUMBER of strings ending with '|'.  */
        for (i = 0; i < dialect_number; i++)
          {
            while (*p && *p != '}')
	      {
		if (*p == '|')
		  {
		    p++;
		    break;
		  }

		/* Skip over any character after a percent sign.  */
		if (*p == '%')
		  p++;
		if (*p)
		  p++;
	      }

            if (*p == '}')
	      break;
          }

        if (*p == '\0')
          output_operand_lossage ("unterminated assembly dialect alternative");
      }
      break;

    case '|':
      if (*dialect)
        {
          /* Skip to close brace.  */
          do
            {
	      if (*p == '\0')
		{
		  output_operand_lossage ("unterminated assembly dialect alternative");
		  break;
		}

	      /* Skip over any character after a percent sign.  */
	      if (*p == '%' && p[1])
		{
		  p += 2;
		  continue;
		}

	      if (*p++ == '}')
		break;
            }
          while (1);

          *dialect = 0;
        }
      else
        putc (c, asm_out_file);
      break;

    case '}':
      if (! *dialect)
        putc (c, asm_out_file);
      *dialect = 0;
      break;
    default:
      gcc_unreachable ();
    }

  return p;
}
#endif

/* Output text from TEMPLATE to the assembler output file,
   obeying %-directions to substitute operands taken from
   the vector OPERANDS.

   %N (for N a digit) means print operand N in usual manner.
   %lN means require operand N to be a CODE_LABEL or LABEL_REF
      and print the label name with no punctuation.
   %cN means require operand N to be a constant
      and print the constant expression with no punctuation.
   %aN means expect operand N to be a memory address
      (not a memory reference!) and print a reference
      to that address.
   %nN means expect operand N to be a constant
      and print a constant expression for minus the value
      of the operand, with no other punctuation.  */

void
output_asm_insn (const char *templ, rtx *operands)
{
  const char *p;
  int c;
#ifdef ASSEMBLER_DIALECT
  int dialect = 0;
#endif
  int oporder[MAX_RECOG_OPERANDS];
  char opoutput[MAX_RECOG_OPERANDS];
  int ops = 0;

  /* An insn may return a null string template
     in a case where no assembler code is needed.  */
  if (*templ == 0)
    return;

  memset (opoutput, 0, sizeof opoutput);
  p = templ;
  putc ('\t', asm_out_file);

#ifdef ASM_OUTPUT_OPCODE
  ASM_OUTPUT_OPCODE (asm_out_file, p);
#endif

  while ((c = *p++))
    switch (c)
      {
      case '\n':
	if (flag_verbose_asm)
	  output_asm_operand_names (operands, oporder, ops);
	if (flag_print_asm_name)
	  output_asm_name ();

	ops = 0;
	memset (opoutput, 0, sizeof opoutput);

	putc (c, asm_out_file);
#ifdef ASM_OUTPUT_OPCODE
	while ((c = *p) == '\t')
	  {
	    putc (c, asm_out_file);
	    p++;
	  }
	ASM_OUTPUT_OPCODE (asm_out_file, p);
#endif
	break;

#ifdef ASSEMBLER_DIALECT
      case '{':
      case '}':
      case '|':
	p = do_assembler_dialects (p, &dialect);
	break;
#endif

      case '%':
	/* %% outputs a single %.  %{, %} and %| print {, } and | respectively
	   if ASSEMBLER_DIALECT defined and these characters have a special
	   meaning as dialect delimiters.*/
	if (*p == '%'
#ifdef ASSEMBLER_DIALECT
	    || *p == '{' || *p == '}' || *p == '|'
#endif
	    )
	  {
	    putc (*p, asm_out_file);
	    p++;
	  }
	/* %= outputs a number which is unique to each insn in the entire
	   compilation.  This is useful for making local labels that are
	   referred to more than once in a given insn.  */
	else if (*p == '=')
	  {
	    p++;
	    fprintf (asm_out_file, "%d", insn_counter);
	  }
	/* % followed by a letter and some digits
	   outputs an operand in a special way depending on the letter.
	   Letters `acln' are implemented directly.
	   Other letters are passed to `output_operand' so that
	   the TARGET_PRINT_OPERAND hook can define them.  */
	else if (ISALPHA (*p))
	  {
	    int letter = *p++;
	    unsigned long opnum;
	    char *endptr;

	    opnum = strtoul (p, &endptr, 10);

	    if (endptr == p)
	      output_operand_lossage ("operand number missing "
				      "after %%-letter");
	    else if (this_is_asm_operands && opnum >= insn_noperands)
	      output_operand_lossage ("operand number out of range");
	    else if (letter == 'l')
	      output_asm_label (operands[opnum]);
	    else if (letter == 'a')
	      output_address (VOIDmode, operands[opnum]);
	    else if (letter == 'c')
	      {
		if (CONSTANT_ADDRESS_P (operands[opnum]))
		  output_addr_const (asm_out_file, operands[opnum]);
		else
		  output_operand (operands[opnum], 'c');
	      }
	    else if (letter == 'n')
	      {
		if (CONST_INT_P (operands[opnum]))
		  fprintf (asm_out_file, HOST_WIDE_INT_PRINT_DEC,
			   - INTVAL (operands[opnum]));
		else
		  {
		    putc ('-', asm_out_file);
		    output_addr_const (asm_out_file, operands[opnum]);
		  }
	      }
	    else
	      output_operand (operands[opnum], letter);

	    if (!opoutput[opnum])
	      oporder[ops++] = opnum;
	    opoutput[opnum] = 1;

	    p = endptr;
	    c = *p;
	  }
	/* % followed by a digit outputs an operand the default way.  */
	else if (ISDIGIT (*p))
	  {
	    unsigned long opnum;
	    char *endptr;

	    opnum = strtoul (p, &endptr, 10);
	    if (this_is_asm_operands && opnum >= insn_noperands)
	      output_operand_lossage ("operand number out of range");
	    else
	      output_operand (operands[opnum], 0);

	    if (!opoutput[opnum])
	      oporder[ops++] = opnum;
	    opoutput[opnum] = 1;

	    p = endptr;
	    c = *p;
	  }
	/* % followed by punctuation: output something for that
	   punctuation character alone, with no operand.  The
	   TARGET_PRINT_OPERAND hook decides what is actually done.  */
	else if (targetm.asm_out.print_operand_punct_valid_p ((unsigned char) *p))
	  output_operand (NULL_RTX, *p++);
	else
	  output_operand_lossage ("invalid %%-code");
	break;

      default:
	putc (c, asm_out_file);
      }

  /* Try to keep the asm a bit more readable.  */
  if ((flag_verbose_asm || flag_print_asm_name) && strlen (templ) < 9)
    putc ('\t', asm_out_file);

  /* Write out the variable names for operands, if we know them.  */
  if (flag_verbose_asm)
    output_asm_operand_names (operands, oporder, ops);
  if (flag_print_asm_name)
    output_asm_name ();

  putc ('\n', asm_out_file);
}

/* Output a LABEL_REF, or a bare CODE_LABEL, as an assembler symbol.  */

void
output_asm_label (rtx x)
{
  char buf[256];

  if (GET_CODE (x) == LABEL_REF)
    x = label_ref_label (x);
  if (LABEL_P (x)
      || (NOTE_P (x)
	  && NOTE_KIND (x) == NOTE_INSN_DELETED_LABEL))
    ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
  else
    output_operand_lossage ("'%%l' operand isn't a label");

  assemble_name (asm_out_file, buf);
}

/* Marks SYMBOL_REFs in x as referenced through use of assemble_external.  */

void
mark_symbol_refs_as_used (rtx x)
{
  subrtx_iterator::array_type array;
  FOR_EACH_SUBRTX (iter, array, x, ALL)
    {
      const_rtx x = *iter;
      if (GET_CODE (x) == SYMBOL_REF)
	if (tree t = SYMBOL_REF_DECL (x))
	  assemble_external (t);
    }
}

/* Print operand X using machine-dependent assembler syntax.
   CODE is a non-digit that preceded the operand-number in the % spec,
   such as 'z' if the spec was `%z3'.  CODE is 0 if there was no char
   between the % and the digits.
   When CODE is a non-letter, X is 0.

   The meanings of the letters are machine-dependent and controlled
   by TARGET_PRINT_OPERAND.  */

void
output_operand (rtx x, int code ATTRIBUTE_UNUSED)
{
  if (x && GET_CODE (x) == SUBREG)
    x = alter_subreg (&x, true);

  /* X must not be a pseudo reg.  */
  if (!targetm.no_register_allocation)
    gcc_assert (!x || !REG_P (x) || REGNO (x) < FIRST_PSEUDO_REGISTER);

  targetm.asm_out.print_operand (asm_out_file, x, code);

  if (x == NULL_RTX)
    return;

  mark_symbol_refs_as_used (x);
}

/* Print a memory reference operand for address X using
   machine-dependent assembler syntax.  */

void
output_address (machine_mode mode, rtx x)
{
  bool changed = false;
  walk_alter_subreg (&x, &changed);
  targetm.asm_out.print_operand_address (asm_out_file, mode, x);
}

/* Print an integer constant expression in assembler syntax.
   Addition and subtraction are the only arithmetic
   that may appear in these expressions.  */

void
output_addr_const (FILE *file, rtx x)
{
  char buf[256];

 restart:
  switch (GET_CODE (x))
    {
    case PC:
      putc ('.', file);
      break;

    case SYMBOL_REF:
      if (SYMBOL_REF_DECL (x))
	assemble_external (SYMBOL_REF_DECL (x));
#ifdef ASM_OUTPUT_SYMBOL_REF
      ASM_OUTPUT_SYMBOL_REF (file, x);
#else
      assemble_name (file, XSTR (x, 0));
#endif
      break;

    case LABEL_REF:
      x = label_ref_label (x);
      /* Fall through.  */
    case CODE_LABEL:
      ASM_GENERATE_INTERNAL_LABEL (buf, "L", CODE_LABEL_NUMBER (x));
#ifdef ASM_OUTPUT_LABEL_REF
      ASM_OUTPUT_LABEL_REF (file, buf);
#else
      assemble_name (file, buf);
#endif
      break;

    case CONST_INT:
      fprintf (file, HOST_WIDE_INT_PRINT_DEC, INTVAL (x));
      break;

    case CONST:
      /* This used to output parentheses around the expression,
	 but that does not work on the 386 (either ATT or BSD assembler).  */
      output_addr_const (file, XEXP (x, 0));
      break;

    case CONST_WIDE_INT:
      /* We do not know the mode here so we have to use a round about
	 way to build a wide-int to get it printed properly.  */
      {
	wide_int w = wide_int::from_array (&CONST_WIDE_INT_ELT (x, 0),
					   CONST_WIDE_INT_NUNITS (x),
					   CONST_WIDE_INT_NUNITS (x)
					   * HOST_BITS_PER_WIDE_INT,
					   false);
	print_decs (w, file);
      }
      break;

    case CONST_DOUBLE:
      if (CONST_DOUBLE_AS_INT_P (x))
	{
	  /* We can use %d if the number is one word and positive.  */
	  if (CONST_DOUBLE_HIGH (x))
	    fprintf (file, HOST_WIDE_INT_PRINT_DOUBLE_HEX,
		     (unsigned HOST_WIDE_INT) CONST_DOUBLE_HIGH (x),
		     (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x));
	  else if (CONST_DOUBLE_LOW (x) < 0)
	    fprintf (file, HOST_WIDE_INT_PRINT_HEX,
		     (unsigned HOST_WIDE_INT) CONST_DOUBLE_LOW (x));
	  else
	    fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_DOUBLE_LOW (x));
	}
      else
	/* We can't handle floating point constants;
	   PRINT_OPERAND must handle them.  */
	output_operand_lossage ("floating constant misused");
      break;

    case CONST_FIXED:
      fprintf (file, HOST_WIDE_INT_PRINT_DEC, CONST_FIXED_VALUE_LOW (x));
      break;

    case PLUS:
      /* Some assemblers need integer constants to appear last (eg masm).  */
      if (CONST_INT_P (XEXP (x, 0)))
	{
	  output_addr_const (file, XEXP (x, 1));
	  if (INTVAL (XEXP (x, 0)) >= 0)
	    fprintf (file, "+");
	  output_addr_const (file, XEXP (x, 0));
	}
      else
	{
	  output_addr_const (file, XEXP (x, 0));
	  if (!CONST_INT_P (XEXP (x, 1))
	      || INTVAL (XEXP (x, 1)) >= 0)
	    fprintf (file, "+");
	  output_addr_const (file, XEXP (x, 1));
	}
      break;

    case MINUS:
      /* Avoid outputting things like x-x or x+5-x,
	 since some assemblers can't handle that.  */
      x = simplify_subtraction (x);
      if (GET_CODE (x) != MINUS)
	goto restart;

      output_addr_const (file, XEXP (x, 0));
      fprintf (file, "-");
      if ((CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) >= 0)
	  || GET_CODE (XEXP (x, 1)) == PC
	  || GET_CODE (XEXP (x, 1)) == SYMBOL_REF)
	output_addr_const (file, XEXP (x, 1));
      else
	{
	  fputs (targetm.asm_out.open_paren, file);
	  output_addr_const (file, XEXP (x, 1));
	  fputs (targetm.asm_out.close_paren, file);
	}
      break;

    case ZERO_EXTEND:
    case SIGN_EXTEND:
    case SUBREG:
    case TRUNCATE:
      output_addr_const (file, XEXP (x, 0));
      break;

    default:
      if (targetm.asm_out.output_addr_const_extra (file, x))
	break;

      output_operand_lossage ("invalid expression as operand");
    }
}

/* Output a quoted string.  */

void
output_quoted_string (FILE *asm_file, const char *string)
{
#ifdef OUTPUT_QUOTED_STRING
  OUTPUT_QUOTED_STRING (asm_file, string);
#else
  char c;

  putc ('\"', asm_file);
  while ((c = *string++) != 0)
    {
      if (ISPRINT (c))
	{
	  if (c == '\"' || c == '\\')
	    putc ('\\', asm_file);
	  putc (c, asm_file);
	}
      else
	fprintf (asm_file, "\\%03o", (unsigned char) c);
    }
  putc ('\"', asm_file);
#endif
}

/* Write a HOST_WIDE_INT number in hex form 0x1234, fast. */

void
fprint_whex (FILE *f, unsigned HOST_WIDE_INT value)
{
  char buf[2 + CHAR_BIT * sizeof (value) / 4];
  if (value == 0)
    putc ('0', f);
  else
    {
      char *p = buf + sizeof (buf);
      do
        *--p = "0123456789abcdef"[value % 16];
      while ((value /= 16) != 0);
      *--p = 'x';
      *--p = '0';
      fwrite (p, 1, buf + sizeof (buf) - p, f);
    }
}

/* Internal function that prints an unsigned long in decimal in reverse.
   The output string IS NOT null-terminated. */

static int
sprint_ul_rev (char *s, unsigned long value)
{
  int i = 0;
  do
    {
      s[i] = "0123456789"[value % 10];
      value /= 10;
      i++;
      /* alternate version, without modulo */
      /* oldval = value; */
      /* value /= 10; */
      /* s[i] = "0123456789" [oldval - 10*value]; */
      /* i++ */
    }
  while (value != 0);
  return i;
}

/* Write an unsigned long as decimal to a file, fast. */

void
fprint_ul (FILE *f, unsigned long value)
{
  /* python says: len(str(2**64)) == 20 */
  char s[20];
  int i;

  i = sprint_ul_rev (s, value);

  /* It's probably too small to bother with string reversal and fputs. */
  do
    {
      i--;
      putc (s[i], f);
    }
  while (i != 0);
}

/* Write an unsigned long as decimal to a string, fast.
   s must be wide enough to not overflow, at least 21 chars.
   Returns the length of the string (without terminating '\0'). */

int
sprint_ul (char *s, unsigned long value)
{
  int len = sprint_ul_rev (s, value);
  s[len] = '\0';

  std::reverse (s, s + len);
  return len;
}

/* A poor man's fprintf, with the added features of %I, %R, %L, and %U.
   %R prints the value of REGISTER_PREFIX.
   %L prints the value of LOCAL_LABEL_PREFIX.
   %U prints the value of USER_LABEL_PREFIX.
   %I prints the value of IMMEDIATE_PREFIX.
   %O runs ASM_OUTPUT_OPCODE to transform what follows in the string.
   Also supported are %d, %i, %u, %x, %X, %o, %c, %s and %%.

   We handle alternate assembler dialects here, just like output_asm_insn.  */

void
asm_fprintf (FILE *file, const char *p, ...)
{
  char buf[10];
  char *q, c;
#ifdef ASSEMBLER_DIALECT
  int dialect = 0;
#endif
  va_list argptr;

  va_start (argptr, p);

  buf[0] = '%';

  while ((c = *p++))
    switch (c)
      {
#ifdef ASSEMBLER_DIALECT
      case '{':
      case '}':
      case '|':
	p = do_assembler_dialects (p, &dialect);
	break;
#endif

      case '%':
	c = *p++;
	q = &buf[1];
	while (strchr ("-+ #0", c))
	  {
	    *q++ = c;
	    c = *p++;
	  }
	while (ISDIGIT (c) || c == '.')
	  {
	    *q++ = c;
	    c = *p++;
	  }
	switch (c)
	  {
	  case '%':
	    putc ('%', file);
	    break;

	  case 'd':  case 'i':  case 'u':
	  case 'x':  case 'X':  case 'o':
	  case 'c':
	    *q++ = c;
	    *q = 0;
	    fprintf (file, buf, va_arg (argptr, int));
	    break;

	  case 'w':
	    /* This is a prefix to the 'd', 'i', 'u', 'x', 'X', and
	       'o' cases, but we do not check for those cases.  It
	       means that the value is a HOST_WIDE_INT, which may be
	       either `long' or `long long'.  */
	    memcpy (q, HOST_WIDE_INT_PRINT, strlen (HOST_WIDE_INT_PRINT));
	    q += strlen (HOST_WIDE_INT_PRINT);
	    *q++ = *p++;
	    *q = 0;
	    fprintf (file, buf, va_arg (argptr, HOST_WIDE_INT));
	    break;

	  case 'l':
	    *q++ = c;
#ifdef HAVE_LONG_LONG
	    if (*p == 'l')
	      {
		*q++ = *p++;
		*q++ = *p++;
		*q = 0;
		fprintf (file, buf, va_arg (argptr, long long));
	      }
	    else
#endif
	      {
		*q++ = *p++;
		*q = 0;
		fprintf (file, buf, va_arg (argptr, long));
	      }

	    break;

	  case 's':
	    *q++ = c;
	    *q = 0;
	    fprintf (file, buf, va_arg (argptr, char *));
	    break;

	  case 'O':
#ifdef ASM_OUTPUT_OPCODE
	    ASM_OUTPUT_OPCODE (asm_out_file, p);
#endif
	    break;

	  case 'R':
#ifdef REGISTER_PREFIX
	    fprintf (file, "%s", REGISTER_PREFIX);
#endif
	    break;

	  case 'I':
#ifdef IMMEDIATE_PREFIX
	    fprintf (file, "%s", IMMEDIATE_PREFIX);
#endif
	    break;

	  case 'L':
#ifdef LOCAL_LABEL_PREFIX
	    fprintf (file, "%s", LOCAL_LABEL_PREFIX);
#endif
	    break;

	  case 'U':
	    fputs (user_label_prefix, file);
	    break;

#ifdef ASM_FPRINTF_EXTENSIONS
	    /* Uppercase letters are reserved for general use by asm_fprintf
	       and so are not available to target specific code.  In order to
	       prevent the ASM_FPRINTF_EXTENSIONS macro from using them then,
	       they are defined here.  As they get turned into real extensions
	       to asm_fprintf they should be removed from this list.  */
	  case 'A': case 'B': case 'C': case 'D': case 'E':
	  case 'F': case 'G': case 'H': case 'J': case 'K':
	  case 'M': case 'N': case 'P': case 'Q': case 'S':
	  case 'T': case 'V': case 'W': case 'Y': case 'Z':
	    break;

	  ASM_FPRINTF_EXTENSIONS (file, argptr, p)
#endif
	  default:
	    gcc_unreachable ();
	  }
	break;

      default:
	putc (c, file);
      }
  va_end (argptr);
}

/* Return nonzero if this function has no function calls.  */

int
leaf_function_p (void)
{
  rtx_insn *insn;

  /* Ensure we walk the entire function body.  */
  gcc_assert (!in_sequence_p ());

  /* Some back-ends (e.g. s390) want leaf functions to stay leaf
     functions even if they call mcount.  */
  if (crtl->profile && !targetm.keep_leaf_when_profiled ())
    return 0;

  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    {
      if (CALL_P (insn)
	  && ! SIBLING_CALL_P (insn)
	  && ! FAKE_CALL_P (insn))
	return 0;
      if (NONJUMP_INSN_P (insn)
	  && GET_CODE (PATTERN (insn)) == SEQUENCE
	  && CALL_P (XVECEXP (PATTERN (insn), 0, 0))
	  && ! SIBLING_CALL_P (XVECEXP (PATTERN (insn), 0, 0)))
	return 0;
    }

  return 1;
}

/* Return 1 if branch is a forward branch.
   Uses insn_shuid array, so it works only in the final pass.  May be used by
   output templates to customary add branch prediction hints.
 */
int
final_forward_branch_p (rtx_insn *insn)
{
  int insn_id, label_id;

  gcc_assert (uid_shuid);
  insn_id = INSN_SHUID (insn);
  label_id = INSN_SHUID (JUMP_LABEL (insn));
  /* We've hit some insns that does not have id information available.  */
  gcc_assert (insn_id && label_id);
  return insn_id < label_id;
}

/* On some machines, a function with no call insns
   can run faster if it doesn't create its own register window.
   When output, the leaf function should use only the "output"
   registers.  Ordinarily, the function would be compiled to use
   the "input" registers to find its arguments; it is a candidate
   for leaf treatment if it uses only the "input" registers.
   Leaf function treatment means renumbering so the function
   uses the "output" registers instead.  */

#ifdef LEAF_REGISTERS

/* Return 1 if this function uses only the registers that can be
   safely renumbered.  */

int
only_leaf_regs_used (void)
{
  int i;
  const char *const permitted_reg_in_leaf_functions = LEAF_REGISTERS;

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if ((df_regs_ever_live_p (i) || global_regs[i])
	&& ! permitted_reg_in_leaf_functions[i])
      return 0;

  if (crtl->uses_pic_offset_table
      && pic_offset_table_rtx != 0
      && REG_P (pic_offset_table_rtx)
      && ! permitted_reg_in_leaf_functions[REGNO (pic_offset_table_rtx)])
    return 0;

  return 1;
}

/* Scan all instructions and renumber all registers into those
   available in leaf functions.  */

static void
leaf_renumber_regs (rtx_insn *first)
{
  rtx_insn *insn;

  /* Renumber only the actual patterns.
     The reg-notes can contain frame pointer refs,
     and renumbering them could crash, and should not be needed.  */
  for (insn = first; insn; insn = NEXT_INSN (insn))
    if (INSN_P (insn))
      leaf_renumber_regs_insn (PATTERN (insn));
}

/* Scan IN_RTX and its subexpressions, and renumber all regs into those
   available in leaf functions.  */

void
leaf_renumber_regs_insn (rtx in_rtx)
{
  int i, j;
  const char *format_ptr;

  if (in_rtx == 0)
    return;

  /* Renumber all input-registers into output-registers.
     renumbered_regs would be 1 for an output-register;
     they  */

  if (REG_P (in_rtx))
    {
      int newreg;

      /* Don't renumber the same reg twice.  */
      if (in_rtx->used)
	return;

      newreg = REGNO (in_rtx);
      /* Don't try to renumber pseudo regs.  It is possible for a pseudo reg
	 to reach here as part of a REG_NOTE.  */
      if (newreg >= FIRST_PSEUDO_REGISTER)
	{
	  in_rtx->used = 1;
	  return;
	}
      newreg = LEAF_REG_REMAP (newreg);
      gcc_assert (newreg >= 0);
      df_set_regs_ever_live (REGNO (in_rtx), false);
      df_set_regs_ever_live (newreg, true);
      SET_REGNO (in_rtx, newreg);
      in_rtx->used = 1;
      return;
    }

  if (INSN_P (in_rtx))
    {
      /* Inside a SEQUENCE, we find insns.
	 Renumber just the patterns of these insns,
	 just as we do for the top-level insns.  */
      leaf_renumber_regs_insn (PATTERN (in_rtx));
      return;
    }

  format_ptr = GET_RTX_FORMAT (GET_CODE (in_rtx));

  for (i = 0; i < GET_RTX_LENGTH (GET_CODE (in_rtx)); i++)
    switch (*format_ptr++)
      {
      case 'e':
	leaf_renumber_regs_insn (XEXP (in_rtx, i));
	break;

      case 'E':
	if (XVEC (in_rtx, i) != NULL)
	  for (j = 0; j < XVECLEN (in_rtx, i); j++)
	    leaf_renumber_regs_insn (XVECEXP (in_rtx, i, j));
	break;

      case 'S':
      case 's':
      case '0':
      case 'i':
      case 'w':
      case 'p':
      case 'n':
      case 'u':
	break;

      default:
	gcc_unreachable ();
      }
}
#endif

/* Turn the RTL into assembly.  */
static unsigned int
rest_of_handle_final (void)
{
  const char *fnname = get_fnname_from_decl (current_function_decl);

  /* Turn debug markers into notes if the var-tracking pass has not
     been invoked.  */
  if (!flag_var_tracking && MAY_HAVE_DEBUG_MARKER_INSNS)
    delete_vta_debug_insns (false);

  assemble_start_function (current_function_decl, fnname);
  rtx_insn *first = get_insns ();
  int seen = 0;
  final_start_function_1 (&first, asm_out_file, &seen, optimize);
  final_1 (first, asm_out_file, seen, optimize);
  if (flag_ipa_ra
      && !lookup_attribute ("noipa", DECL_ATTRIBUTES (current_function_decl))
      /* Functions with naked attributes are supported only with basic asm
	 statements in the body, thus for supported use cases the information
	 on clobbered registers is not available.  */
      && !lookup_attribute ("naked", DECL_ATTRIBUTES (current_function_decl)))
    collect_fn_hard_reg_usage ();
  final_end_function ();

  /* The IA-64 ".handlerdata" directive must be issued before the ".endp"
     directive that closes the procedure descriptor.  Similarly, for x64 SEH.
     Otherwise it's not strictly necessary, but it doesn't hurt either.  */
  output_function_exception_table (crtl->has_bb_partition ? 1 : 0);

  assemble_end_function (current_function_decl, fnname);

  /* Free up reg info memory.  */
  free_reg_info ();

  if (! quiet_flag)
    fflush (asm_out_file);

  /* Note that for those inline functions where we don't initially
     know for certain that we will be generating an out-of-line copy,
     the first invocation of this routine (rest_of_compilation) will
     skip over this code by doing a `goto exit_rest_of_compilation;'.
     Later on, wrapup_global_declarations will (indirectly) call
     rest_of_compilation again for those inline functions that need
     to have out-of-line copies generated.  During that call, we
     *will* be routed past here.  */

  timevar_push (TV_SYMOUT);
  if (!DECL_IGNORED_P (current_function_decl))
    debug_hooks->function_decl (current_function_decl);
  timevar_pop (TV_SYMOUT);

  /* Release the blocks that are linked to DECL_INITIAL() to free the memory.  */
  DECL_INITIAL (current_function_decl) = error_mark_node;

  if (DECL_STATIC_CONSTRUCTOR (current_function_decl)
      && targetm.have_ctors_dtors)
    targetm.asm_out.constructor (XEXP (DECL_RTL (current_function_decl), 0),
				 decl_init_priority_lookup
				   (current_function_decl));
  if (DECL_STATIC_DESTRUCTOR (current_function_decl)
      && targetm.have_ctors_dtors)
    targetm.asm_out.destructor (XEXP (DECL_RTL (current_function_decl), 0),
				decl_fini_priority_lookup
				  (current_function_decl));
  return 0;
}

namespace {

const pass_data pass_data_final =
{
  RTL_PASS, /* type */
  "final", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_FINAL, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_final : public rtl_opt_pass
{
public:
  pass_final (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_final, ctxt)
  {}

  /* opt_pass methods: */
  unsigned int execute (function *) final override
  {
    return rest_of_handle_final ();
  }

}; // class pass_final

} // anon namespace

rtl_opt_pass *
make_pass_final (gcc::context *ctxt)
{
  return new pass_final (ctxt);
}


static unsigned int
rest_of_handle_shorten_branches (void)
{
  /* Shorten branches.  */
  shorten_branches (get_insns ());
  return 0;
}

namespace {

const pass_data pass_data_shorten_branches =
{
  RTL_PASS, /* type */
  "shorten", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_SHORTEN_BRANCH, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  0, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_shorten_branches : public rtl_opt_pass
{
public:
  pass_shorten_branches (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_shorten_branches, ctxt)
  {}

  /* opt_pass methods: */
  unsigned int execute (function *) final override
    {
      return rest_of_handle_shorten_branches ();
    }

}; // class pass_shorten_branches

} // anon namespace

rtl_opt_pass *
make_pass_shorten_branches (gcc::context *ctxt)
{
  return new pass_shorten_branches (ctxt);
}


static unsigned int
rest_of_clean_state (void)
{
  rtx_insn *insn, *next;
  FILE *final_output = NULL;
  int save_unnumbered = flag_dump_unnumbered;
  int save_noaddr = flag_dump_noaddr;

  if (flag_dump_final_insns)
    {
      final_output = fopen (flag_dump_final_insns, "a");
      if (!final_output)
	{
	  error ("could not open final insn dump file %qs: %m",
		 flag_dump_final_insns);
	  flag_dump_final_insns = NULL;
	}
      else
	{
	  flag_dump_noaddr = flag_dump_unnumbered = 1;
	  if (flag_compare_debug_opt || flag_compare_debug)
	    dump_flags |= TDF_NOUID | TDF_COMPARE_DEBUG;
	  dump_function_header (final_output, current_function_decl,
				dump_flags);
	  final_insns_dump_p = true;

	  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
	    if (LABEL_P (insn))
	      INSN_UID (insn) = CODE_LABEL_NUMBER (insn);
	    else
	      {
		if (NOTE_P (insn))
		  set_block_for_insn (insn, NULL);
		INSN_UID (insn) = 0;
	      }
	}
    }

  /* It is very important to decompose the RTL instruction chain here:
     debug information keeps pointing into CODE_LABEL insns inside the function
     body.  If these remain pointing to the other insns, we end up preserving
     whole RTL chain and attached detailed debug info in memory.  */
  for (insn = get_insns (); insn; insn = next)
    {
      next = NEXT_INSN (insn);
      SET_NEXT_INSN (insn) = NULL;
      SET_PREV_INSN (insn) = NULL;

      rtx_insn *call_insn = insn;
      if (NONJUMP_INSN_P (call_insn)
	  && GET_CODE (PATTERN (call_insn)) == SEQUENCE)
	{
	  rtx_sequence *seq = as_a <rtx_sequence *> (PATTERN (call_insn));
	  call_insn = seq->insn (0);
	}
      if (CALL_P (call_insn))
	{
	  rtx note
	    = find_reg_note (call_insn, REG_CALL_ARG_LOCATION, NULL_RTX);
	  if (note)
	    remove_note (call_insn, note);
	}

      if (final_output
	  && (!NOTE_P (insn)
	      || (NOTE_KIND (insn) != NOTE_INSN_VAR_LOCATION
		  && NOTE_KIND (insn) != NOTE_INSN_BEGIN_STMT
		  && NOTE_KIND (insn) != NOTE_INSN_INLINE_ENTRY
		  && NOTE_KIND (insn) != NOTE_INSN_BLOCK_BEG
		  && NOTE_KIND (insn) != NOTE_INSN_BLOCK_END
		  && NOTE_KIND (insn) != NOTE_INSN_DELETED_DEBUG_LABEL)))
	print_rtl_single (final_output, insn);
    }

  if (final_output)
    {
      flag_dump_noaddr = save_noaddr;
      flag_dump_unnumbered = save_unnumbered;
      final_insns_dump_p = false;

      if (fclose (final_output))
	{
	  error ("could not close final insn dump file %qs: %m",
		 flag_dump_final_insns);
	  flag_dump_final_insns = NULL;
	}
    }

  flag_rerun_cse_after_global_opts = 0;
  reload_completed = 0;
  epilogue_completed = 0;
#ifdef STACK_REGS
  regstack_completed = 0;
#endif

  /* Clear out the insn_length contents now that they are no
     longer valid.  */
  init_insn_lengths ();

  /* Show no temporary slots allocated.  */
  init_temp_slots ();

  free_bb_for_insn ();

  if (cfun->gimple_df)
    delete_tree_ssa (cfun);

  /* We can reduce stack alignment on call site only when we are sure that
     the function body just produced will be actually used in the final
     executable.  */
  if (flag_ipa_stack_alignment
      && decl_binds_to_current_def_p (current_function_decl))
    {
      unsigned int pref = crtl->preferred_stack_boundary;
      if (crtl->stack_alignment_needed > crtl->preferred_stack_boundary)
        pref = crtl->stack_alignment_needed;
      cgraph_node::rtl_info (current_function_decl)
	->preferred_incoming_stack_boundary = pref;
    }

  /* Make sure volatile mem refs aren't considered valid operands for
     arithmetic insns.  We must call this here if this is a nested inline
     function, since the above code leaves us in the init_recog state,
     and the function context push/pop code does not save/restore volatile_ok.

     ??? Maybe it isn't necessary for expand_start_function to call this
     anymore if we do it here?  */

  init_recog_no_volatile ();

  /* We're done with this function.  Free up memory if we can.  */
  free_after_parsing (cfun);
  free_after_compilation (cfun);
  return 0;
}

namespace {

const pass_data pass_data_clean_state =
{
  RTL_PASS, /* type */
  "*clean_state", /* name */
  OPTGROUP_NONE, /* optinfo_flags */
  TV_FINAL, /* tv_id */
  0, /* properties_required */
  0, /* properties_provided */
  PROP_rtl, /* properties_destroyed */
  0, /* todo_flags_start */
  0, /* todo_flags_finish */
};

class pass_clean_state : public rtl_opt_pass
{
public:
  pass_clean_state (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_clean_state, ctxt)
  {}

  /* opt_pass methods: */
  unsigned int execute (function *) final override
    {
      return rest_of_clean_state ();
    }

}; // class pass_clean_state

} // anon namespace

rtl_opt_pass *
make_pass_clean_state (gcc::context *ctxt)
{
  return new pass_clean_state (ctxt);
}

/* Return true if INSN is a call to the current function.  */

static bool
self_recursive_call_p (rtx_insn *insn)
{
  tree fndecl = get_call_fndecl (insn);
  return (fndecl == current_function_decl
	  && decl_binds_to_current_def_p (fndecl));
}

/* Collect hard register usage for the current function.  */

static void
collect_fn_hard_reg_usage (void)
{
  rtx_insn *insn;
#ifdef STACK_REGS
  int i;
#endif
  struct cgraph_rtl_info *node;
  HARD_REG_SET function_used_regs;

  /* ??? To be removed when all the ports have been fixed.  */
  if (!targetm.call_fusage_contains_non_callee_clobbers)
    return;

  /* Be conservative - mark fixed and global registers as used.  */
  function_used_regs = fixed_reg_set;

#ifdef STACK_REGS
  /* Handle STACK_REGS conservatively, since the df-framework does not
     provide accurate information for them.  */

  for (i = FIRST_STACK_REG; i <= LAST_STACK_REG; i++)
    SET_HARD_REG_BIT (function_used_regs, i);
#endif

  for (insn = get_insns (); insn != NULL_RTX; insn = next_insn (insn))
    {
      HARD_REG_SET insn_used_regs;

      if (!NONDEBUG_INSN_P (insn))
	continue;

      if (CALL_P (insn)
	  && !self_recursive_call_p (insn))
	function_used_regs
	  |= insn_callee_abi (insn).full_and_partial_reg_clobbers ();

      find_all_hard_reg_sets (insn, &insn_used_regs, false);
      function_used_regs |= insn_used_regs;

      if (hard_reg_set_subset_p (crtl->abi->full_and_partial_reg_clobbers (),
				 function_used_regs))
	return;
    }

  /* Mask out fully-saved registers, so that they don't affect equality
     comparisons between function_abis.  */
  function_used_regs &= crtl->abi->full_and_partial_reg_clobbers ();

  node = cgraph_node::rtl_info (current_function_decl);
  gcc_assert (node != NULL);

  node->function_used_regs = function_used_regs;
}
