/* Dwarf2 Call Frame Information helper routines.
   Copyright (C) 1992-2021 Free Software Foundation, Inc.

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "target.h"
#include "function.h"
#include "rtl.h"
#include "tree.h"
#include "tree-pass.h"
#include "memmodel.h"
#include "tm_p.h"
#include "emit-rtl.h"
#include "stor-layout.h"
#include "cfgbuild.h"
#include "dwarf2out.h"
#include "dwarf2asm.h"
#include "common/common-target.h"

#include "except.h"		/* expand_builtin_dwarf_sp_column */
#include "profile-count.h"	/* For expr.h */
#include "expr.h"		/* init_return_column_size */
#include "output.h"		/* asm_out_file */
#include "debug.h"		/* dwarf2out_do_frame, dwarf2out_do_cfi_asm */
#include "flags.h"		/* dwarf_debuginfo_p */

/* ??? Poison these here until it can be done generically.  They've been
   totally replaced in this file; make sure it stays that way.  */
#undef DWARF2_UNWIND_INFO
#undef DWARF2_FRAME_INFO
#if (GCC_VERSION >= 3000)
 #pragma GCC poison DWARF2_UNWIND_INFO DWARF2_FRAME_INFO
#endif

#ifndef INCOMING_RETURN_ADDR_RTX
#define INCOMING_RETURN_ADDR_RTX  (gcc_unreachable (), NULL_RTX)
#endif

#ifndef DEFAULT_INCOMING_FRAME_SP_OFFSET
#define DEFAULT_INCOMING_FRAME_SP_OFFSET INCOMING_FRAME_SP_OFFSET
#endif

/* A collected description of an entire row of the abstract CFI table.  */
struct GTY(()) dw_cfi_row
{
  /* The expression that computes the CFA, expressed in two different ways.
     The CFA member for the simple cases, and the full CFI expression for
     the complex cases.  The later will be a DW_CFA_cfa_expression.  */
  dw_cfa_location cfa;
  dw_cfi_ref cfa_cfi;

  /* The expressions for any register column that is saved.  */
  cfi_vec reg_save;

  /* True if the register window is saved.  */
  bool window_save;

  /* True if the return address is in a mangled state.  */
  bool ra_mangled;
};

/* The caller's ORIG_REG is saved in SAVED_IN_REG.  */
struct GTY(()) reg_saved_in_data {
  rtx orig_reg;
  rtx saved_in_reg;
};


/* Since we no longer have a proper CFG, we're going to create a facsimile
   of one on the fly while processing the frame-related insns.

   We create dw_trace_info structures for each extended basic block beginning
   and ending at a "save point".  Save points are labels, barriers, certain
   notes, and of course the beginning and end of the function.

   As we encounter control transfer insns, we propagate the "current"
   row state across the edges to the starts of traces.  When checking is
   enabled, we validate that we propagate the same data from all sources.

   All traces are members of the TRACE_INFO array, in the order in which
   they appear in the instruction stream.

   All save points are present in the TRACE_INDEX hash, mapping the insn
   starting a trace to the dw_trace_info describing the trace.  */

struct dw_trace_info
{
  /* The insn that begins the trace.  */
  rtx_insn *head;

  /* The row state at the beginning and end of the trace.  */
  dw_cfi_row *beg_row, *end_row;

  /* Tracking for DW_CFA_GNU_args_size.  The "true" sizes are those we find
     while scanning insns.  However, the args_size value is irrelevant at
     any point except can_throw_internal_p insns.  Therefore the "delay"
     sizes the values that must actually be emitted for this trace.  */
  poly_int64_pod beg_true_args_size, end_true_args_size;
  poly_int64_pod beg_delay_args_size, end_delay_args_size;

  /* The first EH insn in the trace, where beg_delay_args_size must be set.  */
  rtx_insn *eh_head;

  /* The following variables contain data used in interpreting frame related
     expressions.  These are not part of the "real" row state as defined by
     Dwarf, but it seems like they need to be propagated into a trace in case
     frame related expressions have been sunk.  */
  /* ??? This seems fragile.  These variables are fragments of a larger
     expression.  If we do not keep the entire expression together, we risk
     not being able to put it together properly.  Consider forcing targets
     to generate self-contained expressions and dropping all of the magic
     interpretation code in this file.  Or at least refusing to shrink wrap
     any frame related insn that doesn't contain a complete expression.  */

  /* The register used for saving registers to the stack, and its offset
     from the CFA.  */
  dw_cfa_location cfa_store;

  /* A temporary register holding an integral value used in adjusting SP
     or setting up the store_reg.  The "offset" field holds the integer
     value, not an offset.  */
  dw_cfa_location cfa_temp;

  /* A set of registers saved in other registers.  This is the inverse of
     the row->reg_save info, if the entry is a DW_CFA_register.  This is
     implemented as a flat array because it normally contains zero or 1
     entry, depending on the target.  IA-64 is the big spender here, using
     a maximum of 5 entries.  */
  vec<reg_saved_in_data> regs_saved_in_regs;

  /* An identifier for this trace.  Used only for debugging dumps.  */
  unsigned id;

  /* True if this trace immediately follows NOTE_INSN_SWITCH_TEXT_SECTIONS.  */
  bool switch_sections;

  /* True if we've seen different values incoming to beg_true_args_size.  */
  bool args_size_undefined;

  /* True if we've seen an insn with a REG_ARGS_SIZE note before EH_HEAD.  */
  bool args_size_defined_for_eh;
};


/* Hashtable helpers.  */

struct trace_info_hasher : nofree_ptr_hash <dw_trace_info>
{
  static inline hashval_t hash (const dw_trace_info *);
  static inline bool equal (const dw_trace_info *, const dw_trace_info *);
};

inline hashval_t
trace_info_hasher::hash (const dw_trace_info *ti)
{
  return INSN_UID (ti->head);
}

inline bool
trace_info_hasher::equal (const dw_trace_info *a, const dw_trace_info *b)
{
  return a->head == b->head;
}


/* The variables making up the pseudo-cfg, as described above.  */
static vec<dw_trace_info> trace_info;
static vec<dw_trace_info *> trace_work_list;
static hash_table<trace_info_hasher> *trace_index;

/* A vector of call frame insns for the CIE.  */
cfi_vec cie_cfi_vec;

/* The state of the first row of the FDE table, which includes the
   state provided by the CIE.  */
static GTY(()) dw_cfi_row *cie_cfi_row;

static GTY(()) reg_saved_in_data *cie_return_save;

static GTY(()) unsigned long dwarf2out_cfi_label_num;

/* The insn after which a new CFI note should be emitted.  */
static rtx_insn *add_cfi_insn;

/* When non-null, add_cfi will add the CFI to this vector.  */
static cfi_vec *add_cfi_vec;

/* The current instruction trace.  */
static dw_trace_info *cur_trace;

/* The current, i.e. most recently generated, row of the CFI table.  */
static dw_cfi_row *cur_row;

/* A copy of the current CFA, for use during the processing of a
   single insn.  */
static dw_cfa_location *cur_cfa;

/* We delay emitting a register save until either (a) we reach the end
   of the prologue or (b) the register is clobbered.  This clusters
   register saves so that there are fewer pc advances.  */

struct queued_reg_save {
  rtx reg;
  rtx saved_reg;
  poly_int64_pod cfa_offset;
};


static vec<queued_reg_save> queued_reg_saves;

/* True if any CFI directives were emitted at the current insn.  */
static bool any_cfis_emitted;

/* Short-hand for commonly used register numbers.  */
static unsigned dw_stack_pointer_regnum;
static unsigned dw_frame_pointer_regnum;

/* Hook used by __throw.  */

rtx
expand_builtin_dwarf_sp_column (void)
{
  unsigned int dwarf_regnum = DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM);
  return GEN_INT (DWARF2_FRAME_REG_OUT (dwarf_regnum, 1));
}

/* MEM is a memory reference for the register size table, each element of
   which has mode MODE.  Initialize column C as a return address column.  */

static void
init_return_column_size (scalar_int_mode mode, rtx mem, unsigned int c)
{
  HOST_WIDE_INT offset = c * GET_MODE_SIZE (mode);
  HOST_WIDE_INT size = GET_MODE_SIZE (Pmode);
  emit_move_insn (adjust_address (mem, mode, offset),
		  gen_int_mode (size, mode));
}

/* Datastructure used by expand_builtin_init_dwarf_reg_sizes and
   init_one_dwarf_reg_size to communicate on what has been done by the
   latter.  */

struct init_one_dwarf_reg_state
{
  /* Whether the dwarf return column was initialized.  */
  bool wrote_return_column;

  /* For each hard register REGNO, whether init_one_dwarf_reg_size
     was given REGNO to process already.  */
  bool processed_regno [FIRST_PSEUDO_REGISTER];

};

/* Helper for expand_builtin_init_dwarf_reg_sizes.  Generate code to
   initialize the dwarf register size table entry corresponding to register
   REGNO in REGMODE.  TABLE is the table base address, SLOTMODE is the mode to
   use for the size entry to initialize, and INIT_STATE is the communication
   datastructure conveying what we're doing to our caller.  */

static
void init_one_dwarf_reg_size (int regno, machine_mode regmode,
			      rtx table, machine_mode slotmode,
			      init_one_dwarf_reg_state *init_state)
{
  const unsigned int dnum = DWARF_FRAME_REGNUM (regno);
  const unsigned int rnum = DWARF2_FRAME_REG_OUT (dnum, 1);
  const unsigned int dcol = DWARF_REG_TO_UNWIND_COLUMN (rnum);
  
  poly_int64 slotoffset = dcol * GET_MODE_SIZE (slotmode);
  poly_int64 regsize = GET_MODE_SIZE (regmode);

  init_state->processed_regno[regno] = true;

  if (rnum >= DWARF_FRAME_REGISTERS)
    return;

  if (dnum == DWARF_FRAME_RETURN_COLUMN)
    {
      if (regmode == VOIDmode)
	return;
      init_state->wrote_return_column = true;
    }

  /* ??? When is this true?  Should it be a test based on DCOL instead?  */
  if (maybe_lt (slotoffset, 0))
    return;

  emit_move_insn (adjust_address (table, slotmode, slotoffset),
		  gen_int_mode (regsize, slotmode));
}

/* Generate code to initialize the dwarf register size table located
   at the provided ADDRESS.  */

void
expand_builtin_init_dwarf_reg_sizes (tree address)
{
  unsigned int i;
  scalar_int_mode mode = SCALAR_INT_TYPE_MODE (char_type_node);
  rtx addr = expand_normal (address);
  rtx mem = gen_rtx_MEM (BLKmode, addr);

  init_one_dwarf_reg_state init_state;

  memset ((char *)&init_state, 0, sizeof (init_state));

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      machine_mode save_mode;
      rtx span;

      /* No point in processing a register multiple times.  This could happen
	 with register spans, e.g. when a reg is first processed as a piece of
	 a span, then as a register on its own later on.  */

      if (init_state.processed_regno[i])
	continue;

      save_mode = targetm.dwarf_frame_reg_mode (i);
      span = targetm.dwarf_register_span (gen_rtx_REG (save_mode, i));

      if (!span)
	init_one_dwarf_reg_size (i, save_mode, mem, mode, &init_state);
      else
	{
	  for (int si = 0; si < XVECLEN (span, 0); si++)
	    {
	      rtx reg = XVECEXP (span, 0, si);

	      init_one_dwarf_reg_size
		(REGNO (reg), GET_MODE (reg), mem, mode, &init_state);
	    }
	}
    }

  if (!init_state.wrote_return_column)
    init_return_column_size (mode, mem, DWARF_FRAME_RETURN_COLUMN);

#ifdef DWARF_ALT_FRAME_RETURN_COLUMN
  init_return_column_size (mode, mem, DWARF_ALT_FRAME_RETURN_COLUMN);
#endif

  targetm.init_dwarf_reg_sizes_extra (address);
}


static dw_trace_info *
get_trace_info (rtx_insn *insn)
{
  dw_trace_info dummy;
  dummy.head = insn;
  return trace_index->find_with_hash (&dummy, INSN_UID (insn));
}

static bool
save_point_p (rtx_insn *insn)
{
  /* Labels, except those that are really jump tables.  */
  if (LABEL_P (insn))
    return inside_basic_block_p (insn);

  /* We split traces at the prologue/epilogue notes because those
     are points at which the unwind info is usually stable.  This
     makes it easier to find spots with identical unwind info so
     that we can use remember/restore_state opcodes.  */
  if (NOTE_P (insn))
    switch (NOTE_KIND (insn))
      {
      case NOTE_INSN_PROLOGUE_END:
      case NOTE_INSN_EPILOGUE_BEG:
	return true;
      }

  return false;
}

/* Divide OFF by DWARF_CIE_DATA_ALIGNMENT, asserting no remainder.  */

static inline HOST_WIDE_INT
div_data_align (HOST_WIDE_INT off)
{
  HOST_WIDE_INT r = off / DWARF_CIE_DATA_ALIGNMENT;
  gcc_assert (r * DWARF_CIE_DATA_ALIGNMENT == off);
  return r;
}

/* Return true if we need a signed version of a given opcode
   (e.g. DW_CFA_offset_extended_sf vs DW_CFA_offset_extended).  */

static inline bool
need_data_align_sf_opcode (HOST_WIDE_INT off)
{
  return DWARF_CIE_DATA_ALIGNMENT < 0 ? off > 0 : off < 0;
}

/* Return a pointer to a newly allocated Call Frame Instruction.  */

static inline dw_cfi_ref
new_cfi (void)
{
  dw_cfi_ref cfi = ggc_alloc<dw_cfi_node> ();

  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = 0;
  cfi->dw_cfi_oprnd2.dw_cfi_reg_num = 0;

  return cfi;
}

/* Return a newly allocated CFI row, with no defined data.  */

static dw_cfi_row *
new_cfi_row (void)
{
  dw_cfi_row *row = ggc_cleared_alloc<dw_cfi_row> ();

  row->cfa.reg = INVALID_REGNUM;

  return row;
}

/* Return a copy of an existing CFI row.  */

static dw_cfi_row *
copy_cfi_row (dw_cfi_row *src)
{
  dw_cfi_row *dst = ggc_alloc<dw_cfi_row> ();

  *dst = *src;
  dst->reg_save = vec_safe_copy (src->reg_save);

  return dst;
}

/* Return a copy of an existing CFA location.  */

static dw_cfa_location *
copy_cfa (dw_cfa_location *src)
{
  dw_cfa_location *dst = ggc_alloc<dw_cfa_location> ();
  *dst = *src;
  return dst;
}

/* Generate a new label for the CFI info to refer to.  */

static char *
dwarf2out_cfi_label (void)
{
  int num = dwarf2out_cfi_label_num++;
  char label[20];

  ASM_GENERATE_INTERNAL_LABEL (label, "LCFI", num);

  return xstrdup (label);
}

/* Add CFI either to the current insn stream or to a vector, or both.  */

static void
add_cfi (dw_cfi_ref cfi)
{
  any_cfis_emitted = true;

  if (add_cfi_insn != NULL)
    {
      add_cfi_insn = emit_note_after (NOTE_INSN_CFI, add_cfi_insn);
      NOTE_CFI (add_cfi_insn) = cfi;
    }

  if (add_cfi_vec != NULL)
    vec_safe_push (*add_cfi_vec, cfi);
}

static void
add_cfi_args_size (poly_int64 size)
{
  /* We don't yet have a representation for polynomial sizes.  */
  HOST_WIDE_INT const_size = size.to_constant ();

  dw_cfi_ref cfi = new_cfi ();

  /* While we can occasionally have args_size < 0 internally, this state
     should not persist at a point we actually need an opcode.  */
  gcc_assert (const_size >= 0);

  cfi->dw_cfi_opc = DW_CFA_GNU_args_size;
  cfi->dw_cfi_oprnd1.dw_cfi_offset = const_size;

  add_cfi (cfi);
}

static void
add_cfi_restore (unsigned reg)
{
  dw_cfi_ref cfi = new_cfi ();

  cfi->dw_cfi_opc = (reg & ~0x3f ? DW_CFA_restore_extended : DW_CFA_restore);
  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = reg;

  add_cfi (cfi);
}

/* Perform ROW->REG_SAVE[COLUMN] = CFI.  CFI may be null, indicating
   that the register column is no longer saved.  */

static void
update_row_reg_save (dw_cfi_row *row, unsigned column, dw_cfi_ref cfi)
{
  if (vec_safe_length (row->reg_save) <= column)
    vec_safe_grow_cleared (row->reg_save, column + 1, true);
  (*row->reg_save)[column] = cfi;
}

/* This function fills in aa dw_cfa_location structure from a dwarf location
   descriptor sequence.  */

static void
get_cfa_from_loc_descr (dw_cfa_location *cfa, struct dw_loc_descr_node *loc)
{
  struct dw_loc_descr_node *ptr;
  cfa->offset = 0;
  cfa->base_offset = 0;
  cfa->indirect = 0;
  cfa->reg = -1;

  for (ptr = loc; ptr != NULL; ptr = ptr->dw_loc_next)
    {
      enum dwarf_location_atom op = ptr->dw_loc_opc;

      switch (op)
	{
	case DW_OP_reg0:
	case DW_OP_reg1:
	case DW_OP_reg2:
	case DW_OP_reg3:
	case DW_OP_reg4:
	case DW_OP_reg5:
	case DW_OP_reg6:
	case DW_OP_reg7:
	case DW_OP_reg8:
	case DW_OP_reg9:
	case DW_OP_reg10:
	case DW_OP_reg11:
	case DW_OP_reg12:
	case DW_OP_reg13:
	case DW_OP_reg14:
	case DW_OP_reg15:
	case DW_OP_reg16:
	case DW_OP_reg17:
	case DW_OP_reg18:
	case DW_OP_reg19:
	case DW_OP_reg20:
	case DW_OP_reg21:
	case DW_OP_reg22:
	case DW_OP_reg23:
	case DW_OP_reg24:
	case DW_OP_reg25:
	case DW_OP_reg26:
	case DW_OP_reg27:
	case DW_OP_reg28:
	case DW_OP_reg29:
	case DW_OP_reg30:
	case DW_OP_reg31:
	  cfa->reg = op - DW_OP_reg0;
	  break;
	case DW_OP_regx:
	  cfa->reg = ptr->dw_loc_oprnd1.v.val_int;
	  break;
	case DW_OP_breg0:
	case DW_OP_breg1:
	case DW_OP_breg2:
	case DW_OP_breg3:
	case DW_OP_breg4:
	case DW_OP_breg5:
	case DW_OP_breg6:
	case DW_OP_breg7:
	case DW_OP_breg8:
	case DW_OP_breg9:
	case DW_OP_breg10:
	case DW_OP_breg11:
	case DW_OP_breg12:
	case DW_OP_breg13:
	case DW_OP_breg14:
	case DW_OP_breg15:
	case DW_OP_breg16:
	case DW_OP_breg17:
	case DW_OP_breg18:
	case DW_OP_breg19:
	case DW_OP_breg20:
	case DW_OP_breg21:
	case DW_OP_breg22:
	case DW_OP_breg23:
	case DW_OP_breg24:
	case DW_OP_breg25:
	case DW_OP_breg26:
	case DW_OP_breg27:
	case DW_OP_breg28:
	case DW_OP_breg29:
	case DW_OP_breg30:
	case DW_OP_breg31:
	  cfa->reg = op - DW_OP_breg0;
	  cfa->base_offset = ptr->dw_loc_oprnd1.v.val_int;
	  break;
	case DW_OP_bregx:
	  cfa->reg = ptr->dw_loc_oprnd1.v.val_int;
	  cfa->base_offset = ptr->dw_loc_oprnd2.v.val_int;
	  break;
	case DW_OP_deref:
	  cfa->indirect = 1;
	  break;
	case DW_OP_plus_uconst:
	  cfa->offset = ptr->dw_loc_oprnd1.v.val_unsigned;
	  break;
	default:
	  gcc_unreachable ();
	}
    }
}

/* Find the previous value for the CFA, iteratively.  CFI is the opcode
   to interpret, *LOC will be updated as necessary, *REMEMBER is used for
   one level of remember/restore state processing.  */

void
lookup_cfa_1 (dw_cfi_ref cfi, dw_cfa_location *loc, dw_cfa_location *remember)
{
  switch (cfi->dw_cfi_opc)
    {
    case DW_CFA_def_cfa_offset:
    case DW_CFA_def_cfa_offset_sf:
      loc->offset = cfi->dw_cfi_oprnd1.dw_cfi_offset;
      break;
    case DW_CFA_def_cfa_register:
      loc->reg = cfi->dw_cfi_oprnd1.dw_cfi_reg_num;
      break;
    case DW_CFA_def_cfa:
    case DW_CFA_def_cfa_sf:
      loc->reg = cfi->dw_cfi_oprnd1.dw_cfi_reg_num;
      loc->offset = cfi->dw_cfi_oprnd2.dw_cfi_offset;
      break;
    case DW_CFA_def_cfa_expression:
      if (cfi->dw_cfi_oprnd2.dw_cfi_cfa_loc)
	*loc = *cfi->dw_cfi_oprnd2.dw_cfi_cfa_loc;
      else
	get_cfa_from_loc_descr (loc, cfi->dw_cfi_oprnd1.dw_cfi_loc);
      break;

    case DW_CFA_remember_state:
      gcc_assert (!remember->in_use);
      *remember = *loc;
      remember->in_use = 1;
      break;
    case DW_CFA_restore_state:
      gcc_assert (remember->in_use);
      *loc = *remember;
      remember->in_use = 0;
      break;

    default:
      break;
    }
}

/* Determine if two dw_cfa_location structures define the same data.  */

bool
cfa_equal_p (const dw_cfa_location *loc1, const dw_cfa_location *loc2)
{
  return (loc1->reg == loc2->reg
	  && known_eq (loc1->offset, loc2->offset)
	  && loc1->indirect == loc2->indirect
	  && (loc1->indirect == 0
	      || known_eq (loc1->base_offset, loc2->base_offset)));
}

/* Determine if two CFI operands are identical.  */

static bool
cfi_oprnd_equal_p (enum dw_cfi_oprnd_type t, dw_cfi_oprnd *a, dw_cfi_oprnd *b)
{
  switch (t)
    {
    case dw_cfi_oprnd_unused:
      return true;
    case dw_cfi_oprnd_reg_num:
      return a->dw_cfi_reg_num == b->dw_cfi_reg_num;
    case dw_cfi_oprnd_offset:
      return a->dw_cfi_offset == b->dw_cfi_offset;
    case dw_cfi_oprnd_addr:
      return (a->dw_cfi_addr == b->dw_cfi_addr
	      || strcmp (a->dw_cfi_addr, b->dw_cfi_addr) == 0);
    case dw_cfi_oprnd_loc:
      return loc_descr_equal_p (a->dw_cfi_loc, b->dw_cfi_loc);
    case dw_cfi_oprnd_cfa_loc:
      return cfa_equal_p (a->dw_cfi_cfa_loc, b->dw_cfi_cfa_loc);
    }
  gcc_unreachable ();
}

/* Determine if two CFI entries are identical.  */

static bool
cfi_equal_p (dw_cfi_ref a, dw_cfi_ref b)
{
  enum dwarf_call_frame_info opc;

  /* Make things easier for our callers, including missing operands.  */
  if (a == b)
    return true;
  if (a == NULL || b == NULL)
    return false;

  /* Obviously, the opcodes must match.  */
  opc = a->dw_cfi_opc;
  if (opc != b->dw_cfi_opc)
    return false;

  /* Compare the two operands, re-using the type of the operands as
     already exposed elsewhere.  */
  return (cfi_oprnd_equal_p (dw_cfi_oprnd1_desc (opc),
			     &a->dw_cfi_oprnd1, &b->dw_cfi_oprnd1)
	  && cfi_oprnd_equal_p (dw_cfi_oprnd2_desc (opc),
				&a->dw_cfi_oprnd2, &b->dw_cfi_oprnd2));
}

/* Determine if two CFI_ROW structures are identical.  */

static bool
cfi_row_equal_p (dw_cfi_row *a, dw_cfi_row *b)
{
  size_t i, n_a, n_b, n_max;

  if (a->cfa_cfi)
    {
      if (!cfi_equal_p (a->cfa_cfi, b->cfa_cfi))
	return false;
    }
  else if (!cfa_equal_p (&a->cfa, &b->cfa))
    return false;

  n_a = vec_safe_length (a->reg_save);
  n_b = vec_safe_length (b->reg_save);
  n_max = MAX (n_a, n_b);

  for (i = 0; i < n_max; ++i)
    {
      dw_cfi_ref r_a = NULL, r_b = NULL;

      if (i < n_a)
	r_a = (*a->reg_save)[i];
      if (i < n_b)
	r_b = (*b->reg_save)[i];

      if (!cfi_equal_p (r_a, r_b))
        return false;
    }

  if (a->window_save != b->window_save)
    return false;

  if (a->ra_mangled != b->ra_mangled)
    return false;

  return true;
}

/* The CFA is now calculated from NEW_CFA.  Consider OLD_CFA in determining
   what opcode to emit.  Returns the CFI opcode to effect the change, or
   NULL if NEW_CFA == OLD_CFA.  */

static dw_cfi_ref
def_cfa_0 (dw_cfa_location *old_cfa, dw_cfa_location *new_cfa)
{
  dw_cfi_ref cfi;

  /* If nothing changed, no need to issue any call frame instructions.  */
  if (cfa_equal_p (old_cfa, new_cfa))
    return NULL;

  cfi = new_cfi ();

  HOST_WIDE_INT const_offset;
  if (new_cfa->reg == old_cfa->reg
      && !new_cfa->indirect
      && !old_cfa->indirect
      && new_cfa->offset.is_constant (&const_offset))
    {
      /* Construct a "DW_CFA_def_cfa_offset <offset>" instruction, indicating
	 the CFA register did not change but the offset did.  The data
	 factoring for DW_CFA_def_cfa_offset_sf happens in output_cfi, or
	 in the assembler via the .cfi_def_cfa_offset directive.  */
      if (const_offset < 0)
	cfi->dw_cfi_opc = DW_CFA_def_cfa_offset_sf;
      else
	cfi->dw_cfi_opc = DW_CFA_def_cfa_offset;
      cfi->dw_cfi_oprnd1.dw_cfi_offset = const_offset;
    }
  else if (new_cfa->offset.is_constant ()
	   && known_eq (new_cfa->offset, old_cfa->offset)
	   && old_cfa->reg != INVALID_REGNUM
	   && !new_cfa->indirect
	   && !old_cfa->indirect)
    {
      /* Construct a "DW_CFA_def_cfa_register <register>" instruction,
	 indicating the CFA register has changed to <register> but the
	 offset has not changed.  This requires the old CFA to have
	 been set as a register plus offset rather than a general
	 DW_CFA_def_cfa_expression.  */
      cfi->dw_cfi_opc = DW_CFA_def_cfa_register;
      cfi->dw_cfi_oprnd1.dw_cfi_reg_num = new_cfa->reg;
    }
  else if (new_cfa->indirect == 0
	   && new_cfa->offset.is_constant (&const_offset))
    {
      /* Construct a "DW_CFA_def_cfa <register> <offset>" instruction,
	 indicating the CFA register has changed to <register> with
	 the specified offset.  The data factoring for DW_CFA_def_cfa_sf
	 happens in output_cfi, or in the assembler via the .cfi_def_cfa
	 directive.  */
      if (const_offset < 0)
	cfi->dw_cfi_opc = DW_CFA_def_cfa_sf;
      else
	cfi->dw_cfi_opc = DW_CFA_def_cfa;
      cfi->dw_cfi_oprnd1.dw_cfi_reg_num = new_cfa->reg;
      cfi->dw_cfi_oprnd2.dw_cfi_offset = const_offset;
    }
  else
    {
      /* Construct a DW_CFA_def_cfa_expression instruction to
	 calculate the CFA using a full location expression since no
	 register-offset pair is available.  */
      struct dw_loc_descr_node *loc_list;

      cfi->dw_cfi_opc = DW_CFA_def_cfa_expression;
      loc_list = build_cfa_loc (new_cfa, 0);
      cfi->dw_cfi_oprnd1.dw_cfi_loc = loc_list;
      if (!new_cfa->offset.is_constant ()
	  || !new_cfa->base_offset.is_constant ())
	/* It's hard to reconstruct the CFA location for a polynomial
	   expression, so just cache it instead.  */
	cfi->dw_cfi_oprnd2.dw_cfi_cfa_loc = copy_cfa (new_cfa);
      else
	cfi->dw_cfi_oprnd2.dw_cfi_cfa_loc = NULL;
    }

  return cfi;
}

/* Similarly, but take OLD_CFA from CUR_ROW, and update it after the fact.  */

static void
def_cfa_1 (dw_cfa_location *new_cfa)
{
  dw_cfi_ref cfi;

  if (cur_trace->cfa_store.reg == new_cfa->reg && new_cfa->indirect == 0)
    cur_trace->cfa_store.offset = new_cfa->offset;

  cfi = def_cfa_0 (&cur_row->cfa, new_cfa);
  if (cfi)
    {
      cur_row->cfa = *new_cfa;
      cur_row->cfa_cfi = (cfi->dw_cfi_opc == DW_CFA_def_cfa_expression
			  ? cfi : NULL);

      add_cfi (cfi);
    }
}

/* Add the CFI for saving a register.  REG is the CFA column number.
   If SREG is -1, the register is saved at OFFSET from the CFA;
   otherwise it is saved in SREG.  */

static void
reg_save (unsigned int reg, unsigned int sreg, poly_int64 offset)
{
  dw_fde_ref fde = cfun ? cfun->fde : NULL;
  dw_cfi_ref cfi = new_cfi ();

  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = reg;

  if (sreg == INVALID_REGNUM)
    {
      HOST_WIDE_INT const_offset;
      /* When stack is aligned, store REG using DW_CFA_expression with FP.  */
      if (fde && fde->stack_realign)
	{
	  cfi->dw_cfi_opc = DW_CFA_expression;
	  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = reg;
	  cfi->dw_cfi_oprnd2.dw_cfi_loc
	    = build_cfa_aligned_loc (&cur_row->cfa, offset,
				     fde->stack_realignment);
	}
      else if (offset.is_constant (&const_offset))
	{
	  if (need_data_align_sf_opcode (const_offset))
	    cfi->dw_cfi_opc = DW_CFA_offset_extended_sf;
	  else if (reg & ~0x3f)
	    cfi->dw_cfi_opc = DW_CFA_offset_extended;
	  else
	    cfi->dw_cfi_opc = DW_CFA_offset;
	  cfi->dw_cfi_oprnd2.dw_cfi_offset = const_offset;
	}
      else
	{
	  cfi->dw_cfi_opc = DW_CFA_expression;
	  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = reg;
	  cfi->dw_cfi_oprnd2.dw_cfi_loc
	    = build_cfa_loc (&cur_row->cfa, offset);
	}
    }
  else if (sreg == reg)
    {
      /* While we could emit something like DW_CFA_same_value or
	 DW_CFA_restore, we never expect to see something like that
	 in a prologue.  This is more likely to be a bug.  A backend
	 can always bypass this by using REG_CFA_RESTORE directly.  */
      gcc_unreachable ();
    }
  else
    {
      cfi->dw_cfi_opc = DW_CFA_register;
      cfi->dw_cfi_oprnd2.dw_cfi_reg_num = sreg;
    }

  add_cfi (cfi);
  update_row_reg_save (cur_row, reg, cfi);
}

/* A subroutine of scan_trace.  Check INSN for a REG_ARGS_SIZE note
   and adjust data structures to match.  */

static void
notice_args_size (rtx_insn *insn)
{
  poly_int64 args_size, delta;
  rtx note;

  note = find_reg_note (insn, REG_ARGS_SIZE, NULL);
  if (note == NULL)
    return;

  if (!cur_trace->eh_head)
    cur_trace->args_size_defined_for_eh = true;

  args_size = get_args_size (note);
  delta = args_size - cur_trace->end_true_args_size;
  if (known_eq (delta, 0))
    return;

  cur_trace->end_true_args_size = args_size;

  /* If the CFA is computed off the stack pointer, then we must adjust
     the computation of the CFA as well.  */
  if (cur_cfa->reg == dw_stack_pointer_regnum)
    {
      gcc_assert (!cur_cfa->indirect);

      /* Convert a change in args_size (always a positive in the
	 direction of stack growth) to a change in stack pointer.  */
      if (!STACK_GROWS_DOWNWARD)
	delta = -delta;

      cur_cfa->offset += delta;
    }
}

/* A subroutine of scan_trace.  INSN is can_throw_internal.  Update the
   data within the trace related to EH insns and args_size.  */

static void
notice_eh_throw (rtx_insn *insn)
{
  poly_int64 args_size = cur_trace->end_true_args_size;
  if (cur_trace->eh_head == NULL)
    {
      cur_trace->eh_head = insn;
      cur_trace->beg_delay_args_size = args_size;
      cur_trace->end_delay_args_size = args_size;
    }
  else if (maybe_ne (cur_trace->end_delay_args_size, args_size))
    {
      cur_trace->end_delay_args_size = args_size;

      /* ??? If the CFA is the stack pointer, search backward for the last
	 CFI note and insert there.  Given that the stack changed for the
	 args_size change, there *must* be such a note in between here and
	 the last eh insn.  */
      add_cfi_args_size (args_size);
    }
}

/* Short-hand inline for the very common D_F_R (REGNO (x)) operation.  */
/* ??? This ought to go into dwarf2out.h, except that dwarf2out.h is
   used in places where rtl is prohibited.  */

static inline unsigned
dwf_regno (const_rtx reg)
{
  gcc_assert (REGNO (reg) < FIRST_PSEUDO_REGISTER);
  return DWARF_FRAME_REGNUM (REGNO (reg));
}

/* Compare X and Y for equivalence.  The inputs may be REGs or PC_RTX.  */

static bool
compare_reg_or_pc (rtx x, rtx y)
{
  if (REG_P (x) && REG_P (y))
    return REGNO (x) == REGNO (y);
  return x == y;
}

/* Record SRC as being saved in DEST.  DEST may be null to delete an
   existing entry.  SRC may be a register or PC_RTX.  */

static void
record_reg_saved_in_reg (rtx dest, rtx src)
{
  reg_saved_in_data *elt;
  size_t i;

  FOR_EACH_VEC_ELT (cur_trace->regs_saved_in_regs, i, elt)
    if (compare_reg_or_pc (elt->orig_reg, src))
      {
	if (dest == NULL)
	  cur_trace->regs_saved_in_regs.unordered_remove (i);
	else
	  elt->saved_in_reg = dest;
	return;
      }

  if (dest == NULL)
    return;

  reg_saved_in_data e = {src, dest};
  cur_trace->regs_saved_in_regs.safe_push (e);
}

/* Add an entry to QUEUED_REG_SAVES saying that REG is now saved at
   SREG, or if SREG is NULL then it is saved at OFFSET to the CFA.  */

static void
queue_reg_save (rtx reg, rtx sreg, poly_int64 offset)
{
  queued_reg_save *q;
  queued_reg_save e = {reg, sreg, offset};
  size_t i;

  /* Duplicates waste space, but it's also necessary to remove them
     for correctness, since the queue gets output in reverse order.  */
  FOR_EACH_VEC_ELT (queued_reg_saves, i, q)
    if (compare_reg_or_pc (q->reg, reg))
      {
	*q = e;
	return;
      }

  queued_reg_saves.safe_push (e);
}

/* Output all the entries in QUEUED_REG_SAVES.  */

static void
dwarf2out_flush_queued_reg_saves (void)
{
  queued_reg_save *q;
  size_t i;

  FOR_EACH_VEC_ELT (queued_reg_saves, i, q)
    {
      unsigned int reg, sreg;

      record_reg_saved_in_reg (q->saved_reg, q->reg);

      if (q->reg == pc_rtx)
	reg = DWARF_FRAME_RETURN_COLUMN;
      else
        reg = dwf_regno (q->reg);
      if (q->saved_reg)
	sreg = dwf_regno (q->saved_reg);
      else
	sreg = INVALID_REGNUM;
      reg_save (reg, sreg, q->cfa_offset);
    }

  queued_reg_saves.truncate (0);
}

/* Does INSN clobber any register which QUEUED_REG_SAVES lists a saved
   location for?  Or, does it clobber a register which we've previously
   said that some other register is saved in, and for which we now
   have a new location for?  */

static bool
clobbers_queued_reg_save (const_rtx insn)
{
  queued_reg_save *q;
  size_t iq;

  FOR_EACH_VEC_ELT (queued_reg_saves, iq, q)
    {
      size_t ir;
      reg_saved_in_data *rir;

      if (modified_in_p (q->reg, insn))
	return true;

      FOR_EACH_VEC_ELT (cur_trace->regs_saved_in_regs, ir, rir)
	if (compare_reg_or_pc (q->reg, rir->orig_reg)
	    && modified_in_p (rir->saved_in_reg, insn))
	  return true;
    }

  return false;
}

/* What register, if any, is currently saved in REG?  */

static rtx
reg_saved_in (rtx reg)
{
  unsigned int regn = REGNO (reg);
  queued_reg_save *q;
  reg_saved_in_data *rir;
  size_t i;

  FOR_EACH_VEC_ELT (queued_reg_saves, i, q)
    if (q->saved_reg && regn == REGNO (q->saved_reg))
      return q->reg;

  FOR_EACH_VEC_ELT (cur_trace->regs_saved_in_regs, i, rir)
    if (regn == REGNO (rir->saved_in_reg))
      return rir->orig_reg;

  return NULL_RTX;
}

/* A subroutine of dwarf2out_frame_debug, process a REG_DEF_CFA note.  */

static void
dwarf2out_frame_debug_def_cfa (rtx pat)
{
  memset (cur_cfa, 0, sizeof (*cur_cfa));

  pat = strip_offset (pat, &cur_cfa->offset);
  if (MEM_P (pat))
    {
      cur_cfa->indirect = 1;
      pat = strip_offset (XEXP (pat, 0), &cur_cfa->base_offset);
    }
  /* ??? If this fails, we could be calling into the _loc functions to
     define a full expression.  So far no port does that.  */
  gcc_assert (REG_P (pat));
  cur_cfa->reg = dwf_regno (pat);
}

/* A subroutine of dwarf2out_frame_debug, process a REG_ADJUST_CFA note.  */

static void
dwarf2out_frame_debug_adjust_cfa (rtx pat)
{
  rtx src, dest;

  gcc_assert (GET_CODE (pat) == SET);
  dest = XEXP (pat, 0);
  src = XEXP (pat, 1);

  switch (GET_CODE (src))
    {
    case PLUS:
      gcc_assert (dwf_regno (XEXP (src, 0)) == cur_cfa->reg);
      cur_cfa->offset -= rtx_to_poly_int64 (XEXP (src, 1));
      break;

    case REG:
      break;

    default:
      gcc_unreachable ();
    }

  cur_cfa->reg = dwf_regno (dest);
  gcc_assert (cur_cfa->indirect == 0);
}

/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_OFFSET note.  */

static void
dwarf2out_frame_debug_cfa_offset (rtx set)
{
  poly_int64 offset;
  rtx src, addr, span;
  unsigned int sregno;

  src = XEXP (set, 1);
  addr = XEXP (set, 0);
  gcc_assert (MEM_P (addr));
  addr = XEXP (addr, 0);

  /* As documented, only consider extremely simple addresses.  */
  switch (GET_CODE (addr))
    {
    case REG:
      gcc_assert (dwf_regno (addr) == cur_cfa->reg);
      offset = -cur_cfa->offset;
      break;
    case PLUS:
      gcc_assert (dwf_regno (XEXP (addr, 0)) == cur_cfa->reg);
      offset = rtx_to_poly_int64 (XEXP (addr, 1)) - cur_cfa->offset;
      break;
    default:
      gcc_unreachable ();
    }

  if (src == pc_rtx)
    {
      span = NULL;
      sregno = DWARF_FRAME_RETURN_COLUMN;
    }
  else
    {
      span = targetm.dwarf_register_span (src);
      sregno = dwf_regno (src);
    }

  /* ??? We'd like to use queue_reg_save, but we need to come up with
     a different flushing heuristic for epilogues.  */
  if (!span)
    reg_save (sregno, INVALID_REGNUM, offset);
  else
    {
      /* We have a PARALLEL describing where the contents of SRC live.
   	 Adjust the offset for each piece of the PARALLEL.  */
      poly_int64 span_offset = offset;

      gcc_assert (GET_CODE (span) == PARALLEL);

      const int par_len = XVECLEN (span, 0);
      for (int par_index = 0; par_index < par_len; par_index++)
	{
	  rtx elem = XVECEXP (span, 0, par_index);
	  sregno = dwf_regno (src);
	  reg_save (sregno, INVALID_REGNUM, span_offset);
	  span_offset += GET_MODE_SIZE (GET_MODE (elem));
	}
    }
}

/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_REGISTER note.  */

static void
dwarf2out_frame_debug_cfa_register (rtx set)
{
  rtx src, dest;
  unsigned sregno, dregno;

  src = XEXP (set, 1);
  dest = XEXP (set, 0);

  record_reg_saved_in_reg (dest, src);
  if (src == pc_rtx)
    sregno = DWARF_FRAME_RETURN_COLUMN;
  else
    sregno = dwf_regno (src);

  dregno = dwf_regno (dest);

  /* ??? We'd like to use queue_reg_save, but we need to come up with
     a different flushing heuristic for epilogues.  */
  reg_save (sregno, dregno, 0);
}

/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_EXPRESSION note.  */

static void
dwarf2out_frame_debug_cfa_expression (rtx set)
{
  rtx src, dest, span;
  dw_cfi_ref cfi = new_cfi ();
  unsigned regno;

  dest = SET_DEST (set);
  src = SET_SRC (set);

  gcc_assert (REG_P (src));
  gcc_assert (MEM_P (dest));

  span = targetm.dwarf_register_span (src);
  gcc_assert (!span);

  regno = dwf_regno (src);

  cfi->dw_cfi_opc = DW_CFA_expression;
  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = regno;
  cfi->dw_cfi_oprnd2.dw_cfi_loc
    = mem_loc_descriptor (XEXP (dest, 0), get_address_mode (dest),
			  GET_MODE (dest), VAR_INIT_STATUS_INITIALIZED);

  /* ??? We'd like to use queue_reg_save, were the interface different,
     and, as above, we could manage flushing for epilogues.  */
  add_cfi (cfi);
  update_row_reg_save (cur_row, regno, cfi);
}

/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_VAL_EXPRESSION
   note.  */

static void
dwarf2out_frame_debug_cfa_val_expression (rtx set)
{
  rtx dest = SET_DEST (set);
  gcc_assert (REG_P (dest));

  rtx span = targetm.dwarf_register_span (dest);
  gcc_assert (!span);

  rtx src = SET_SRC (set);
  dw_cfi_ref cfi = new_cfi ();
  cfi->dw_cfi_opc = DW_CFA_val_expression;
  cfi->dw_cfi_oprnd1.dw_cfi_reg_num = dwf_regno (dest);
  cfi->dw_cfi_oprnd2.dw_cfi_loc
    = mem_loc_descriptor (src, GET_MODE (src),
			  GET_MODE (dest), VAR_INIT_STATUS_INITIALIZED);
  add_cfi (cfi);
  update_row_reg_save (cur_row, dwf_regno (dest), cfi);
}

/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_RESTORE note.  */

static void
dwarf2out_frame_debug_cfa_restore (rtx reg)
{
  gcc_assert (REG_P (reg));

  rtx span = targetm.dwarf_register_span (reg);
  if (!span)
    {
      unsigned int regno = dwf_regno (reg);
      add_cfi_restore (regno);
      update_row_reg_save (cur_row, regno, NULL);
    }
  else
    {
      /* We have a PARALLEL describing where the contents of REG live.
	 Restore the register for each piece of the PARALLEL.  */
      gcc_assert (GET_CODE (span) == PARALLEL);

      const int par_len = XVECLEN (span, 0);
      for (int par_index = 0; par_index < par_len; par_index++)
	{
	  reg = XVECEXP (span, 0, par_index);
	  gcc_assert (REG_P (reg));
	  unsigned int regno = dwf_regno (reg);
	  add_cfi_restore (regno);
	  update_row_reg_save (cur_row, regno, NULL);
	}
    }
}

/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_WINDOW_SAVE.

   ??? Perhaps we should note in the CIE where windows are saved (instead
   of assuming 0(cfa)) and what registers are in the window.  */

static void
dwarf2out_frame_debug_cfa_window_save (void)
{
  dw_cfi_ref cfi = new_cfi ();

  cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
  add_cfi (cfi);
  cur_row->window_save = true;
}

/* A subroutine of dwarf2out_frame_debug, process a REG_CFA_TOGGLE_RA_MANGLE.
   Note: DW_CFA_GNU_window_save dwarf opcode is reused for toggling RA mangle
   state, this is a target specific operation on AArch64 and can only be used
   on other targets if they don't use the window save operation otherwise.  */

static void
dwarf2out_frame_debug_cfa_toggle_ra_mangle (void)
{
  dw_cfi_ref cfi = new_cfi ();

  cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
  add_cfi (cfi);
  cur_row->ra_mangled = !cur_row->ra_mangled;
}

/* Record call frame debugging information for an expression EXPR,
   which either sets SP or FP (adjusting how we calculate the frame
   address) or saves a register to the stack or another register.
   LABEL indicates the address of EXPR.

   This function encodes a state machine mapping rtxes to actions on
   cfa, cfa_store, and cfa_temp.reg.  We describe these rules so
   users need not read the source code.

  The High-Level Picture

  Changes in the register we use to calculate the CFA: Currently we
  assume that if you copy the CFA register into another register, we
  should take the other one as the new CFA register; this seems to
  work pretty well.  If it's wrong for some target, it's simple
  enough not to set RTX_FRAME_RELATED_P on the insn in question.

  Changes in the register we use for saving registers to the stack:
  This is usually SP, but not always.  Again, we deduce that if you
  copy SP into another register (and SP is not the CFA register),
  then the new register is the one we will be using for register
  saves.  This also seems to work.

  Register saves: There's not much guesswork about this one; if
  RTX_FRAME_RELATED_P is set on an insn which modifies memory, it's a
  register save, and the register used to calculate the destination
  had better be the one we think we're using for this purpose.
  It's also assumed that a copy from a call-saved register to another
  register is saving that register if RTX_FRAME_RELATED_P is set on
  that instruction.  If the copy is from a call-saved register to
  the *same* register, that means that the register is now the same
  value as in the caller.

  Except: If the register being saved is the CFA register, and the
  offset is nonzero, we are saving the CFA, so we assume we have to
  use DW_CFA_def_cfa_expression.  If the offset is 0, we assume that
  the intent is to save the value of SP from the previous frame.

  In addition, if a register has previously been saved to a different
  register,

  Invariants / Summaries of Rules

  cfa	       current rule for calculating the CFA.  It usually
	       consists of a register and an offset.  This is
	       actually stored in *cur_cfa, but abbreviated
	       for the purposes of this documentation.
  cfa_store    register used by prologue code to save things to the stack
	       cfa_store.offset is the offset from the value of
	       cfa_store.reg to the actual CFA
  cfa_temp     register holding an integral value.  cfa_temp.offset
	       stores the value, which will be used to adjust the
	       stack pointer.  cfa_temp is also used like cfa_store,
	       to track stores to the stack via fp or a temp reg.

  Rules  1- 4: Setting a register's value to cfa.reg or an expression
	       with cfa.reg as the first operand changes the cfa.reg and its
	       cfa.offset.  Rule 1 and 4 also set cfa_temp.reg and
	       cfa_temp.offset.

  Rules  6- 9: Set a non-cfa.reg register value to a constant or an
	       expression yielding a constant.  This sets cfa_temp.reg
	       and cfa_temp.offset.

  Rule 5:      Create a new register cfa_store used to save items to the
	       stack.

  Rules 10-14: Save a register to the stack.  Define offset as the
	       difference of the original location and cfa_store's
	       location (or cfa_temp's location if cfa_temp is used).

  Rules 16-20: If AND operation happens on sp in prologue, we assume
	       stack is realigned.  We will use a group of DW_OP_XXX
	       expressions to represent the location of the stored
	       register instead of CFA+offset.

  The Rules

  "{a,b}" indicates a choice of a xor b.
  "<reg>:cfa.reg" indicates that <reg> must equal cfa.reg.

  Rule 1:
  (set <reg1> <reg2>:cfa.reg)
  effects: cfa.reg = <reg1>
	   cfa.offset unchanged
	   cfa_temp.reg = <reg1>
	   cfa_temp.offset = cfa.offset

  Rule 2:
  (set sp ({minus,plus,losum} {sp,fp}:cfa.reg
			      {<const_int>,<reg>:cfa_temp.reg}))
  effects: cfa.reg = sp if fp used
	   cfa.offset += {+/- <const_int>, cfa_temp.offset} if cfa.reg==sp
	   cfa_store.offset += {+/- <const_int>, cfa_temp.offset}
	     if cfa_store.reg==sp

  Rule 3:
  (set fp ({minus,plus,losum} <reg>:cfa.reg <const_int>))
  effects: cfa.reg = fp
	   cfa_offset += +/- <const_int>

  Rule 4:
  (set <reg1> ({plus,losum} <reg2>:cfa.reg <const_int>))
  constraints: <reg1> != fp
	       <reg1> != sp
  effects: cfa.reg = <reg1>
	   cfa_temp.reg = <reg1>
	   cfa_temp.offset = cfa.offset

  Rule 5:
  (set <reg1> (plus <reg2>:cfa_temp.reg sp:cfa.reg))
  constraints: <reg1> != fp
	       <reg1> != sp
  effects: cfa_store.reg = <reg1>
	   cfa_store.offset = cfa.offset - cfa_temp.offset

  Rule 6:
  (set <reg> <const_int>)
  effects: cfa_temp.reg = <reg>
	   cfa_temp.offset = <const_int>

  Rule 7:
  (set <reg1>:cfa_temp.reg (ior <reg2>:cfa_temp.reg <const_int>))
  effects: cfa_temp.reg = <reg1>
	   cfa_temp.offset |= <const_int>

  Rule 8:
  (set <reg> (high <exp>))
  effects: none

  Rule 9:
  (set <reg> (lo_sum <exp> <const_int>))
  effects: cfa_temp.reg = <reg>
	   cfa_temp.offset = <const_int>

  Rule 10:
  (set (mem ({pre,post}_modify sp:cfa_store (???? <reg1> <const_int>))) <reg2>)
  effects: cfa_store.offset -= <const_int>
	   cfa.offset = cfa_store.offset if cfa.reg == sp
	   cfa.reg = sp
	   cfa.base_offset = -cfa_store.offset

  Rule 11:
  (set (mem ({pre_inc,pre_dec,post_dec} sp:cfa_store.reg)) <reg>)
  effects: cfa_store.offset += -/+ mode_size(mem)
	   cfa.offset = cfa_store.offset if cfa.reg == sp
	   cfa.reg = sp
	   cfa.base_offset = -cfa_store.offset

  Rule 12:
  (set (mem ({minus,plus,losum} <reg1>:{cfa_store,cfa_temp} <const_int>))

       <reg2>)
  effects: cfa.reg = <reg1>
	   cfa.base_offset = -/+ <const_int> - {cfa_store,cfa_temp}.offset

  Rule 13:
  (set (mem <reg1>:{cfa_store,cfa_temp}) <reg2>)
  effects: cfa.reg = <reg1>
	   cfa.base_offset = -{cfa_store,cfa_temp}.offset

  Rule 14:
  (set (mem (post_inc <reg1>:cfa_temp <const_int>)) <reg2>)
  effects: cfa.reg = <reg1>
	   cfa.base_offset = -cfa_temp.offset
	   cfa_temp.offset -= mode_size(mem)

  Rule 15:
  (set <reg> {unspec, unspec_volatile})
  effects: target-dependent

  Rule 16:
  (set sp (and: sp <const_int>))
  constraints: cfa_store.reg == sp
  effects: cfun->fde.stack_realign = 1
           cfa_store.offset = 0
	   fde->drap_reg = cfa.reg if cfa.reg != sp and cfa.reg != fp

  Rule 17:
  (set (mem ({pre_inc, pre_dec} sp)) (mem (plus (cfa.reg) (const_int))))
  effects: cfa_store.offset += -/+ mode_size(mem)

  Rule 18:
  (set (mem ({pre_inc, pre_dec} sp)) fp)
  constraints: fde->stack_realign == 1
  effects: cfa_store.offset = 0
	   cfa.reg != HARD_FRAME_POINTER_REGNUM

  Rule 19:
  (set (mem ({pre_inc, pre_dec} sp)) cfa.reg)
  constraints: fde->stack_realign == 1
               && cfa.offset == 0
               && cfa.indirect == 0
               && cfa.reg != HARD_FRAME_POINTER_REGNUM
  effects: Use DW_CFA_def_cfa_expression to define cfa
  	   cfa.reg == fde->drap_reg  */

static void
dwarf2out_frame_debug_expr (rtx expr)
{
  rtx src, dest, span;
  poly_int64 offset;
  dw_fde_ref fde;

  /* If RTX_FRAME_RELATED_P is set on a PARALLEL, process each member of
     the PARALLEL independently. The first element is always processed if
     it is a SET. This is for backward compatibility.   Other elements
     are processed only if they are SETs and the RTX_FRAME_RELATED_P
     flag is set in them.  */
  if (GET_CODE (expr) == PARALLEL || GET_CODE (expr) == SEQUENCE)
    {
      int par_index;
      int limit = XVECLEN (expr, 0);
      rtx elem;

      /* PARALLELs have strict read-modify-write semantics, so we
	 ought to evaluate every rvalue before changing any lvalue.
	 It's cumbersome to do that in general, but there's an
	 easy approximation that is enough for all current users:
	 handle register saves before register assignments.  */
      if (GET_CODE (expr) == PARALLEL)
	for (par_index = 0; par_index < limit; par_index++)
	  {
	    elem = XVECEXP (expr, 0, par_index);
	    if (GET_CODE (elem) == SET
		&& MEM_P (SET_DEST (elem))
		&& (RTX_FRAME_RELATED_P (elem) || par_index == 0))
	      dwarf2out_frame_debug_expr (elem);
	  }

      for (par_index = 0; par_index < limit; par_index++)
	{
	  elem = XVECEXP (expr, 0, par_index);
	  if (GET_CODE (elem) == SET
	      && (!MEM_P (SET_DEST (elem)) || GET_CODE (expr) == SEQUENCE)
	      && (RTX_FRAME_RELATED_P (elem) || par_index == 0))
	    dwarf2out_frame_debug_expr (elem);
	}
      return;
    }

  gcc_assert (GET_CODE (expr) == SET);

  src = SET_SRC (expr);
  dest = SET_DEST (expr);

  if (REG_P (src))
    {
      rtx rsi = reg_saved_in (src);
      if (rsi)
	src = rsi;
    }

  fde = cfun->fde;

  switch (GET_CODE (dest))
    {
    case REG:
      switch (GET_CODE (src))
	{
	  /* Setting FP from SP.  */
	case REG:
	  if (cur_cfa->reg == dwf_regno (src))
	    {
	      /* Rule 1 */
	      /* Update the CFA rule wrt SP or FP.  Make sure src is
		 relative to the current CFA register.

		 We used to require that dest be either SP or FP, but the
		 ARM copies SP to a temporary register, and from there to
		 FP.  So we just rely on the backends to only set
		 RTX_FRAME_RELATED_P on appropriate insns.  */
	      cur_cfa->reg = dwf_regno (dest);
	      cur_trace->cfa_temp.reg = cur_cfa->reg;
	      cur_trace->cfa_temp.offset = cur_cfa->offset;
	    }
	  else
	    {
	      /* Saving a register in a register.  */
	      gcc_assert (!fixed_regs [REGNO (dest)]
			  /* For the SPARC and its register window.  */
			  || (dwf_regno (src) == DWARF_FRAME_RETURN_COLUMN));

              /* After stack is aligned, we can only save SP in FP
		 if drap register is used.  In this case, we have
		 to restore stack pointer with the CFA value and we
		 don't generate this DWARF information.  */
	      if (fde
		  && fde->stack_realign
		  && REGNO (src) == STACK_POINTER_REGNUM)
		{
		  gcc_assert (REGNO (dest) == HARD_FRAME_POINTER_REGNUM
			      && fde->drap_reg != INVALID_REGNUM
			      && cur_cfa->reg != dwf_regno (src)
			      && fde->rule18);
		  fde->rule18 = 0;
		  /* The save of hard frame pointer has been deferred
		     until this point when Rule 18 applied.  Emit it now.  */
		  queue_reg_save (dest, NULL_RTX, 0);
		  /* And as the instruction modifies the hard frame pointer,
		     flush the queue as well.  */
		  dwarf2out_flush_queued_reg_saves ();
		}
	      else
		queue_reg_save (src, dest, 0);
	    }
	  break;

	case PLUS:
	case MINUS:
	case LO_SUM:
	  if (dest == stack_pointer_rtx)
	    {
	      /* Rule 2 */
	      /* Adjusting SP.  */
	      if (REG_P (XEXP (src, 1)))
		{
		  gcc_assert (dwf_regno (XEXP (src, 1))
			      == cur_trace->cfa_temp.reg);
		  offset = cur_trace->cfa_temp.offset;
		}
	      else if (!poly_int_rtx_p (XEXP (src, 1), &offset))
		gcc_unreachable ();

	      if (XEXP (src, 0) == hard_frame_pointer_rtx)
		{
		  /* Restoring SP from FP in the epilogue.  */
		  gcc_assert (cur_cfa->reg == dw_frame_pointer_regnum);
		  cur_cfa->reg = dw_stack_pointer_regnum;
		}
	      else if (GET_CODE (src) == LO_SUM)
		/* Assume we've set the source reg of the LO_SUM from sp.  */
		;
	      else
		gcc_assert (XEXP (src, 0) == stack_pointer_rtx);

	      if (GET_CODE (src) != MINUS)
		offset = -offset;
	      if (cur_cfa->reg == dw_stack_pointer_regnum)
		cur_cfa->offset += offset;
	      if (cur_trace->cfa_store.reg == dw_stack_pointer_regnum)
		cur_trace->cfa_store.offset += offset;
	    }
	  else if (dest == hard_frame_pointer_rtx)
	    {
	      /* Rule 3 */
	      /* Either setting the FP from an offset of the SP,
		 or adjusting the FP */
	      gcc_assert (frame_pointer_needed);

	      gcc_assert (REG_P (XEXP (src, 0))
			  && dwf_regno (XEXP (src, 0)) == cur_cfa->reg);
	      offset = rtx_to_poly_int64 (XEXP (src, 1));
	      if (GET_CODE (src) != MINUS)
		offset = -offset;
	      cur_cfa->offset += offset;
	      cur_cfa->reg = dw_frame_pointer_regnum;
	    }
	  else
	    {
	      gcc_assert (GET_CODE (src) != MINUS);

	      /* Rule 4 */
	      if (REG_P (XEXP (src, 0))
		  && dwf_regno (XEXP (src, 0)) == cur_cfa->reg
		  && poly_int_rtx_p (XEXP (src, 1), &offset))
		{
		  /* Setting a temporary CFA register that will be copied
		     into the FP later on.  */
		  offset = -offset;
		  cur_cfa->offset += offset;
		  cur_cfa->reg = dwf_regno (dest);
		  /* Or used to save regs to the stack.  */
		  cur_trace->cfa_temp.reg = cur_cfa->reg;
		  cur_trace->cfa_temp.offset = cur_cfa->offset;
		}

	      /* Rule 5 */
	      else if (REG_P (XEXP (src, 0))
		       && dwf_regno (XEXP (src, 0)) == cur_trace->cfa_temp.reg
		       && XEXP (src, 1) == stack_pointer_rtx)
		{
		  /* Setting a scratch register that we will use instead
		     of SP for saving registers to the stack.  */
		  gcc_assert (cur_cfa->reg == dw_stack_pointer_regnum);
		  cur_trace->cfa_store.reg = dwf_regno (dest);
		  cur_trace->cfa_store.offset
		    = cur_cfa->offset - cur_trace->cfa_temp.offset;
		}

	      /* Rule 9 */
	      else if (GET_CODE (src) == LO_SUM
		       && poly_int_rtx_p (XEXP (src, 1),
					  &cur_trace->cfa_temp.offset))
		cur_trace->cfa_temp.reg = dwf_regno (dest);
	      else
		gcc_unreachable ();
	    }
	  break;

	  /* Rule 6 */
	case CONST_INT:
	case CONST_POLY_INT:
	  cur_trace->cfa_temp.reg = dwf_regno (dest);
	  cur_trace->cfa_temp.offset = rtx_to_poly_int64 (src);
	  break;

	  /* Rule 7 */
	case IOR:
	  gcc_assert (REG_P (XEXP (src, 0))
		      && dwf_regno (XEXP (src, 0)) == cur_trace->cfa_temp.reg
		      && CONST_INT_P (XEXP (src, 1)));

	  cur_trace->cfa_temp.reg = dwf_regno (dest);
	  if (!can_ior_p (cur_trace->cfa_temp.offset, INTVAL (XEXP (src, 1)),
			  &cur_trace->cfa_temp.offset))
	    /* The target shouldn't generate this kind of CFI note if we
	       can't represent it.  */
	    gcc_unreachable ();
	  break;

	  /* Skip over HIGH, assuming it will be followed by a LO_SUM,
	     which will fill in all of the bits.  */
	  /* Rule 8 */
	case HIGH:
	  break;

	  /* Rule 15 */
	case UNSPEC:
	case UNSPEC_VOLATILE:
	  /* All unspecs should be represented by REG_CFA_* notes.  */
	  gcc_unreachable ();
	  return;

	  /* Rule 16 */
	case AND:
          /* If this AND operation happens on stack pointer in prologue,
	     we assume the stack is realigned and we extract the
	     alignment.  */
          if (fde && XEXP (src, 0) == stack_pointer_rtx)
            {
	      /* We interpret reg_save differently with stack_realign set.
		 Thus we must flush whatever we have queued first.  */
	      dwarf2out_flush_queued_reg_saves ();

              gcc_assert (cur_trace->cfa_store.reg
			  == dwf_regno (XEXP (src, 0)));
              fde->stack_realign = 1;
              fde->stack_realignment = INTVAL (XEXP (src, 1));
              cur_trace->cfa_store.offset = 0;

	      if (cur_cfa->reg != dw_stack_pointer_regnum
		  && cur_cfa->reg != dw_frame_pointer_regnum)
		fde->drap_reg = cur_cfa->reg;
            }
          return;

	default:
	  gcc_unreachable ();
	}
      break;

    case MEM:

      /* Saving a register to the stack.  Make sure dest is relative to the
	 CFA register.  */
      switch (GET_CODE (XEXP (dest, 0)))
	{
	  /* Rule 10 */
	  /* With a push.  */
	case PRE_MODIFY:
	case POST_MODIFY:
	  /* We can't handle variable size modifications.  */
	  offset = -rtx_to_poly_int64 (XEXP (XEXP (XEXP (dest, 0), 1), 1));

	  gcc_assert (REGNO (XEXP (XEXP (dest, 0), 0)) == STACK_POINTER_REGNUM
		      && cur_trace->cfa_store.reg == dw_stack_pointer_regnum);

	  cur_trace->cfa_store.offset += offset;
	  if (cur_cfa->reg == dw_stack_pointer_regnum)
	    cur_cfa->offset = cur_trace->cfa_store.offset;

	  if (GET_CODE (XEXP (dest, 0)) == POST_MODIFY)
	    offset -= cur_trace->cfa_store.offset;
	  else
	    offset = -cur_trace->cfa_store.offset;
	  break;

	  /* Rule 11 */
	case PRE_INC:
	case PRE_DEC:
	case POST_DEC:
	  offset = GET_MODE_SIZE (GET_MODE (dest));
	  if (GET_CODE (XEXP (dest, 0)) == PRE_INC)
	    offset = -offset;

	  gcc_assert ((REGNO (XEXP (XEXP (dest, 0), 0))
		       == STACK_POINTER_REGNUM)
		      && cur_trace->cfa_store.reg == dw_stack_pointer_regnum);

	  cur_trace->cfa_store.offset += offset;

          /* Rule 18: If stack is aligned, we will use FP as a
	     reference to represent the address of the stored
	     regiser.  */
          if (fde
              && fde->stack_realign
	      && REG_P (src)
	      && REGNO (src) == HARD_FRAME_POINTER_REGNUM)
	    {
	      gcc_assert (cur_cfa->reg != dw_frame_pointer_regnum);
	      cur_trace->cfa_store.offset = 0;
	      fde->rule18 = 1;
	    }

	  if (cur_cfa->reg == dw_stack_pointer_regnum)
	    cur_cfa->offset = cur_trace->cfa_store.offset;

	  if (GET_CODE (XEXP (dest, 0)) == POST_DEC)
	    offset += -cur_trace->cfa_store.offset;
	  else
	    offset = -cur_trace->cfa_store.offset;
	  break;

	  /* Rule 12 */
	  /* With an offset.  */
	case PLUS:
	case MINUS:
	case LO_SUM:
	  {
	    unsigned int regno;

	    gcc_assert (REG_P (XEXP (XEXP (dest, 0), 0)));
	    offset = rtx_to_poly_int64 (XEXP (XEXP (dest, 0), 1));
	    if (GET_CODE (XEXP (dest, 0)) == MINUS)
	      offset = -offset;

	    regno = dwf_regno (XEXP (XEXP (dest, 0), 0));

	    if (cur_cfa->reg == regno)
	      offset -= cur_cfa->offset;
	    else if (cur_trace->cfa_store.reg == regno)
	      offset -= cur_trace->cfa_store.offset;
	    else
	      {
		gcc_assert (cur_trace->cfa_temp.reg == regno);
		offset -= cur_trace->cfa_temp.offset;
	      }
	  }
	  break;

	  /* Rule 13 */
	  /* Without an offset.  */
	case REG:
	  {
	    unsigned int regno = dwf_regno (XEXP (dest, 0));

	    if (cur_cfa->reg == regno)
	      offset = -cur_cfa->offset;
	    else if (cur_trace->cfa_store.reg == regno)
	      offset = -cur_trace->cfa_store.offset;
	    else
	      {
		gcc_assert (cur_trace->cfa_temp.reg == regno);
		offset = -cur_trace->cfa_temp.offset;
	      }
	  }
	  break;

	  /* Rule 14 */
	case POST_INC:
	  gcc_assert (cur_trace->cfa_temp.reg
		      == dwf_regno (XEXP (XEXP (dest, 0), 0)));
	  offset = -cur_trace->cfa_temp.offset;
	  cur_trace->cfa_temp.offset -= GET_MODE_SIZE (GET_MODE (dest));
	  break;

	default:
	  gcc_unreachable ();
	}

      /* Rule 17 */
      /* If the source operand of this MEM operation is a memory,
	 we only care how much stack grew.  */
      if (MEM_P (src))
        break;

      if (REG_P (src)
	  && REGNO (src) != STACK_POINTER_REGNUM
	  && REGNO (src) != HARD_FRAME_POINTER_REGNUM
	  && dwf_regno (src) == cur_cfa->reg)
	{
	  /* We're storing the current CFA reg into the stack.  */

	  if (known_eq (cur_cfa->offset, 0))
	    {
              /* Rule 19 */
              /* If stack is aligned, putting CFA reg into stack means
		 we can no longer use reg + offset to represent CFA.
		 Here we use DW_CFA_def_cfa_expression instead.  The
		 result of this expression equals to the original CFA
		 value.  */
              if (fde
                  && fde->stack_realign
                  && cur_cfa->indirect == 0
                  && cur_cfa->reg != dw_frame_pointer_regnum)
                {
		  gcc_assert (fde->drap_reg == cur_cfa->reg);

		  cur_cfa->indirect = 1;
		  cur_cfa->reg = dw_frame_pointer_regnum;
		  cur_cfa->base_offset = offset;
		  cur_cfa->offset = 0;

		  fde->drap_reg_saved = 1;
		  break;
                }

	      /* If the source register is exactly the CFA, assume
		 we're saving SP like any other register; this happens
		 on the ARM.  */
	      queue_reg_save (stack_pointer_rtx, NULL_RTX, offset);
	      break;
	    }
	  else
	    {
	      /* Otherwise, we'll need to look in the stack to
		 calculate the CFA.  */
	      rtx x = XEXP (dest, 0);

	      if (!REG_P (x))
		x = XEXP (x, 0);
	      gcc_assert (REG_P (x));

	      cur_cfa->reg = dwf_regno (x);
	      cur_cfa->base_offset = offset;
	      cur_cfa->indirect = 1;
	      break;
	    }
	}

      if (REG_P (src))
	span = targetm.dwarf_register_span (src);
      else
	span = NULL;

      if (!span)
	{
	  if (fde->rule18)
	    /* Just verify the hard frame pointer save when doing dynamic
	       realignment uses expected offset.  The actual queue_reg_save
	       needs to be deferred until the instruction that sets
	       hard frame pointer to stack pointer, see PR99334 for
	       details.  */
	    gcc_assert (known_eq (offset, 0));
	  else
	    queue_reg_save (src, NULL_RTX, offset);
	}
      else
	{
	  /* We have a PARALLEL describing where the contents of SRC live.
	     Queue register saves for each piece of the PARALLEL.  */
	  poly_int64 span_offset = offset;

	  gcc_assert (GET_CODE (span) == PARALLEL);

	  const int par_len = XVECLEN (span, 0);
	  for (int par_index = 0; par_index < par_len; par_index++)
	    {
	      rtx elem = XVECEXP (span, 0, par_index);
	      queue_reg_save (elem, NULL_RTX, span_offset);
	      span_offset += GET_MODE_SIZE (GET_MODE (elem));
	    }
	}
      break;

    default:
      gcc_unreachable ();
    }
}

/* Record call frame debugging information for INSN, which either sets
   SP or FP (adjusting how we calculate the frame address) or saves a
   register to the stack.  */

static void
dwarf2out_frame_debug (rtx_insn *insn)
{
  rtx note, n, pat;
  bool handled_one = false;

  for (note = REG_NOTES (insn); note; note = XEXP (note, 1))
    switch (REG_NOTE_KIND (note))
      {
      case REG_FRAME_RELATED_EXPR:
	pat = XEXP (note, 0);
	goto do_frame_expr;

      case REG_CFA_DEF_CFA:
	dwarf2out_frame_debug_def_cfa (XEXP (note, 0));
	handled_one = true;
	break;

      case REG_CFA_ADJUST_CFA:
	n = XEXP (note, 0);
	if (n == NULL)
	  {
	    n = PATTERN (insn);
	    if (GET_CODE (n) == PARALLEL)
	      n = XVECEXP (n, 0, 0);
	  }
	dwarf2out_frame_debug_adjust_cfa (n);
	handled_one = true;
	break;

      case REG_CFA_OFFSET:
	n = XEXP (note, 0);
	if (n == NULL)
	  n = single_set (insn);
	dwarf2out_frame_debug_cfa_offset (n);
	handled_one = true;
	break;

      case REG_CFA_REGISTER:
	n = XEXP (note, 0);
	if (n == NULL)
	  {
	    n = PATTERN (insn);
	    if (GET_CODE (n) == PARALLEL)
	      n = XVECEXP (n, 0, 0);
	  }
	dwarf2out_frame_debug_cfa_register (n);
	handled_one = true;
	break;

      case REG_CFA_EXPRESSION:
      case REG_CFA_VAL_EXPRESSION:
	n = XEXP (note, 0);
	if (n == NULL)
	  n = single_set (insn);

	if (REG_NOTE_KIND (note) == REG_CFA_EXPRESSION)
	  dwarf2out_frame_debug_cfa_expression (n);
	else
	  dwarf2out_frame_debug_cfa_val_expression (n);

	handled_one = true;
	break;

      case REG_CFA_RESTORE:
	n = XEXP (note, 0);
	if (n == NULL)
	  {
	    n = PATTERN (insn);
	    if (GET_CODE (n) == PARALLEL)
	      n = XVECEXP (n, 0, 0);
	    n = XEXP (n, 0);
	  }
	dwarf2out_frame_debug_cfa_restore (n);
	handled_one = true;
	break;

      case REG_CFA_SET_VDRAP:
	n = XEXP (note, 0);
	if (REG_P (n))
	  {
	    dw_fde_ref fde = cfun->fde;
	    if (fde)
	      {
		gcc_assert (fde->vdrap_reg == INVALID_REGNUM);
		if (REG_P (n))
		  fde->vdrap_reg = dwf_regno (n);
	      }
	  }
	handled_one = true;
	break;

      case REG_CFA_TOGGLE_RA_MANGLE:
	dwarf2out_frame_debug_cfa_toggle_ra_mangle ();
	handled_one = true;
	break;

      case REG_CFA_WINDOW_SAVE:
	dwarf2out_frame_debug_cfa_window_save ();
	handled_one = true;
	break;

      case REG_CFA_FLUSH_QUEUE:
	/* The actual flush happens elsewhere.  */
	handled_one = true;
	break;

      default:
	break;
      }

  if (!handled_one)
    {
      pat = PATTERN (insn);
    do_frame_expr:
      dwarf2out_frame_debug_expr (pat);

      /* Check again.  A parallel can save and update the same register.
         We could probably check just once, here, but this is safer than
         removing the check at the start of the function.  */
      if (clobbers_queued_reg_save (pat))
	dwarf2out_flush_queued_reg_saves ();
    }
}

/* Emit CFI info to change the state from OLD_ROW to NEW_ROW.  */

static void
change_cfi_row (dw_cfi_row *old_row, dw_cfi_row *new_row)
{
  size_t i, n_old, n_new, n_max;
  dw_cfi_ref cfi;

  if (new_row->cfa_cfi && !cfi_equal_p (old_row->cfa_cfi, new_row->cfa_cfi))
    add_cfi (new_row->cfa_cfi);
  else
    {
      cfi = def_cfa_0 (&old_row->cfa, &new_row->cfa);
      if (cfi)
	add_cfi (cfi);
    }

  n_old = vec_safe_length (old_row->reg_save);
  n_new = vec_safe_length (new_row->reg_save);
  n_max = MAX (n_old, n_new);

  for (i = 0; i < n_max; ++i)
    {
      dw_cfi_ref r_old = NULL, r_new = NULL;

      if (i < n_old)
	r_old = (*old_row->reg_save)[i];
      if (i < n_new)
	r_new = (*new_row->reg_save)[i];

      if (r_old == r_new)
	;
      else if (r_new == NULL)
	add_cfi_restore (i);
      else if (!cfi_equal_p (r_old, r_new))
        add_cfi (r_new);
    }

  if (!old_row->window_save && new_row->window_save)
    {
      dw_cfi_ref cfi = new_cfi ();

      gcc_assert (!old_row->ra_mangled && !new_row->ra_mangled);
      cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
      add_cfi (cfi);
    }

  if (old_row->ra_mangled != new_row->ra_mangled)
    {
      dw_cfi_ref cfi = new_cfi ();

      gcc_assert (!old_row->window_save && !new_row->window_save);
      /* DW_CFA_GNU_window_save is reused for toggling RA mangle state.  */
      cfi->dw_cfi_opc = DW_CFA_GNU_window_save;
      add_cfi (cfi);
    }
}

/* Examine CFI and return true if a cfi label and set_loc is needed
   beforehand.  Even when generating CFI assembler instructions, we
   still have to add the cfi to the list so that lookup_cfa_1 works
   later on.  When -g2 and above we even need to force emitting of
   CFI labels and add to list a DW_CFA_set_loc for convert_cfa_to_fb_loc_list
   purposes.  If we're generating DWARF3 output we use DW_OP_call_frame_cfa
   and so don't use convert_cfa_to_fb_loc_list.  */

static bool
cfi_label_required_p (dw_cfi_ref cfi)
{
  if (!dwarf2out_do_cfi_asm ())
    return true;

  if (dwarf_version == 2
      && debug_info_level > DINFO_LEVEL_TERSE
      && dwarf_debuginfo_p ())
    {
      switch (cfi->dw_cfi_opc)
	{
	case DW_CFA_def_cfa_offset:
	case DW_CFA_def_cfa_offset_sf:
	case DW_CFA_def_cfa_register:
	case DW_CFA_def_cfa:
	case DW_CFA_def_cfa_sf:
	case DW_CFA_def_cfa_expression:
	case DW_CFA_restore_state:
	  return true;
	default:
	  return false;
	}
    }
  return false;
}

/* Walk the function, looking for NOTE_INSN_CFI notes.  Add the CFIs to the
   function's FDE, adding CFI labels and set_loc/advance_loc opcodes as
   necessary.  */
static void
add_cfis_to_fde (void)
{
  dw_fde_ref fde = cfun->fde;
  rtx_insn *insn, *next;

  for (insn = get_insns (); insn; insn = next)
    {
      next = NEXT_INSN (insn);

      if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
	fde->dw_fde_switch_cfi_index = vec_safe_length (fde->dw_fde_cfi);

      if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_CFI)
	{
	  bool required = cfi_label_required_p (NOTE_CFI (insn));
	  while (next)
	    if (NOTE_P (next) && NOTE_KIND (next) == NOTE_INSN_CFI)
	      {
		required |= cfi_label_required_p (NOTE_CFI (next));
		next = NEXT_INSN (next);
	      }
	    else if (active_insn_p (next)
		     || (NOTE_P (next) && (NOTE_KIND (next)
					   == NOTE_INSN_SWITCH_TEXT_SECTIONS)))
	      break;
	    else
	      next = NEXT_INSN (next);
	  if (required)
	    {
	      int num = dwarf2out_cfi_label_num;
	      const char *label = dwarf2out_cfi_label ();
	      dw_cfi_ref xcfi;

	      /* Set the location counter to the new label.  */
	      xcfi = new_cfi ();
	      xcfi->dw_cfi_opc = DW_CFA_advance_loc4;
	      xcfi->dw_cfi_oprnd1.dw_cfi_addr = label;
	      vec_safe_push (fde->dw_fde_cfi, xcfi);

	      rtx_note *tmp = emit_note_before (NOTE_INSN_CFI_LABEL, insn);
	      NOTE_LABEL_NUMBER (tmp) = num;
	    }

	  do
	    {
	      if (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_CFI)
		vec_safe_push (fde->dw_fde_cfi, NOTE_CFI (insn));
	      insn = NEXT_INSN (insn);
	    }
	  while (insn != next);
	}
    }
}

static void dump_cfi_row (FILE *f, dw_cfi_row *row);

/* If LABEL is the start of a trace, then initialize the state of that
   trace from CUR_TRACE and CUR_ROW.  */

static void
maybe_record_trace_start (rtx_insn *start, rtx_insn *origin)
{
  dw_trace_info *ti;

  ti = get_trace_info (start);
  gcc_assert (ti != NULL);

  if (dump_file)
    {
      fprintf (dump_file, "   saw edge from trace %u to %u (via %s %d)\n",
	       cur_trace->id, ti->id,
	       (origin ? rtx_name[(int) GET_CODE (origin)] : "fallthru"),
	       (origin ? INSN_UID (origin) : 0));
    }

  poly_int64 args_size = cur_trace->end_true_args_size;
  if (ti->beg_row == NULL)
    {
      /* This is the first time we've encountered this trace.  Propagate
	 state across the edge and push the trace onto the work list.  */
      ti->beg_row = copy_cfi_row (cur_row);
      ti->beg_true_args_size = args_size;

      ti->cfa_store = cur_trace->cfa_store;
      ti->cfa_temp = cur_trace->cfa_temp;
      ti->regs_saved_in_regs = cur_trace->regs_saved_in_regs.copy ();

      trace_work_list.safe_push (ti);

      if (dump_file)
	fprintf (dump_file, "\tpush trace %u to worklist\n", ti->id);
    }
  else
    {

      /* We ought to have the same state incoming to a given trace no
	 matter how we arrive at the trace.  Anything else means we've
	 got some kind of optimization error.  */
#if CHECKING_P
      if (!cfi_row_equal_p (cur_row, ti->beg_row))
	{
	  if (dump_file)
	    {
	      fprintf (dump_file, "Inconsistent CFI state!\n");
	      fprintf (dump_file, "SHOULD have:\n");
	      dump_cfi_row (dump_file, ti->beg_row);
	      fprintf (dump_file, "DO have:\n");
	      dump_cfi_row (dump_file, cur_row);
	    }

	  gcc_unreachable ();
	}
#endif

      /* The args_size is allowed to conflict if it isn't actually used.  */
      if (maybe_ne (ti->beg_true_args_size, args_size))
	ti->args_size_undefined = true;
    }
}

/* Similarly, but handle the args_size and CFA reset across EH
   and non-local goto edges.  */

static void
maybe_record_trace_start_abnormal (rtx_insn *start, rtx_insn *origin)
{
  poly_int64 save_args_size, delta;
  dw_cfa_location save_cfa;

  save_args_size = cur_trace->end_true_args_size;
  if (known_eq (save_args_size, 0))
    {
      maybe_record_trace_start (start, origin);
      return;
    }

  delta = -save_args_size;
  cur_trace->end_true_args_size = 0;

  save_cfa = cur_row->cfa;
  if (cur_row->cfa.reg == dw_stack_pointer_regnum)
    {
      /* Convert a change in args_size (always a positive in the
	 direction of stack growth) to a change in stack pointer.  */
      if (!STACK_GROWS_DOWNWARD)
	delta = -delta;

      cur_row->cfa.offset += delta;
    }
  
  maybe_record_trace_start (start, origin);

  cur_trace->end_true_args_size = save_args_size;
  cur_row->cfa = save_cfa;
}

/* Propagate CUR_TRACE state to the destinations implied by INSN.  */
/* ??? Sadly, this is in large part a duplicate of make_edges.  */

static void
create_trace_edges (rtx_insn *insn)
{
  rtx tmp;
  int i, n;

  if (JUMP_P (insn))
    {
      rtx_jump_table_data *table;

      if (find_reg_note (insn, REG_NON_LOCAL_GOTO, NULL_RTX))
	return;

      if (tablejump_p (insn, NULL, &table))
	{
	  rtvec vec = table->get_labels ();

	  n = GET_NUM_ELEM (vec);
	  for (i = 0; i < n; ++i)
	    {
	      rtx_insn *lab = as_a <rtx_insn *> (XEXP (RTVEC_ELT (vec, i), 0));
	      maybe_record_trace_start (lab, insn);
	    }

	  /* Handle casesi dispatch insns.  */
	  if ((tmp = tablejump_casesi_pattern (insn)) != NULL_RTX)
	    {
	      rtx_insn * lab = label_ref_label (XEXP (SET_SRC (tmp), 2));
	      maybe_record_trace_start (lab, insn);
	    }
	}
      else if (computed_jump_p (insn))
	{
	  rtx_insn *temp;
	  unsigned int i;
	  FOR_EACH_VEC_SAFE_ELT (forced_labels, i, temp)
	    maybe_record_trace_start (temp, insn);
	}
      else if (returnjump_p (insn))
	;
      else if ((tmp = extract_asm_operands (PATTERN (insn))) != NULL)
	{
	  n = ASM_OPERANDS_LABEL_LENGTH (tmp);
	  for (i = 0; i < n; ++i)
	    {
	      rtx_insn *lab =
		as_a <rtx_insn *> (XEXP (ASM_OPERANDS_LABEL (tmp, i), 0));
	      maybe_record_trace_start (lab, insn);
	    }
	}
      else
	{
	  rtx_insn *lab = JUMP_LABEL_AS_INSN (insn);
	  gcc_assert (lab != NULL);
	  maybe_record_trace_start (lab, insn);
	}
    }
  else if (CALL_P (insn))
    {
      /* Sibling calls don't have edges inside this function.  */
      if (SIBLING_CALL_P (insn))
	return;

      /* Process non-local goto edges.  */
      if (can_nonlocal_goto (insn))
	for (rtx_insn_list *lab = nonlocal_goto_handler_labels;
	     lab;
	     lab = lab->next ())
	  maybe_record_trace_start_abnormal (lab->insn (), insn);
    }
  else if (rtx_sequence *seq = dyn_cast <rtx_sequence *> (PATTERN (insn)))
    {
      int i, n = seq->len ();
      for (i = 0; i < n; ++i)
	create_trace_edges (seq->insn (i));
      return;
    }

  /* Process EH edges.  */
  if (CALL_P (insn) || cfun->can_throw_non_call_exceptions)
    {
      eh_landing_pad lp = get_eh_landing_pad_from_rtx (insn);
      if (lp)
	maybe_record_trace_start_abnormal (lp->landing_pad, insn);
    }
}

/* A subroutine of scan_trace.  Do what needs to be done "after" INSN.  */

static void
scan_insn_after (rtx_insn *insn)
{
  if (RTX_FRAME_RELATED_P (insn))
    dwarf2out_frame_debug (insn);
  notice_args_size (insn);
}

/* Scan the trace beginning at INSN and create the CFI notes for the
   instructions therein.  */

static void
scan_trace (dw_trace_info *trace, bool entry)
{
  rtx_insn *prev, *insn = trace->head;
  dw_cfa_location this_cfa;

  if (dump_file)
    fprintf (dump_file, "Processing trace %u : start at %s %d\n",
	     trace->id, rtx_name[(int) GET_CODE (insn)],
	     INSN_UID (insn));

  trace->end_row = copy_cfi_row (trace->beg_row);
  trace->end_true_args_size = trace->beg_true_args_size;

  cur_trace = trace;
  cur_row = trace->end_row;

  this_cfa = cur_row->cfa;
  cur_cfa = &this_cfa;

  /* If the current function starts with a non-standard incoming frame
     sp offset, emit a note before the first instruction.  */
  if (entry
      && DEFAULT_INCOMING_FRAME_SP_OFFSET != INCOMING_FRAME_SP_OFFSET)
    {
      add_cfi_insn = insn;
      gcc_assert (NOTE_P (insn) && NOTE_KIND (insn) == NOTE_INSN_DELETED);
      this_cfa.offset = INCOMING_FRAME_SP_OFFSET;
      def_cfa_1 (&this_cfa);
    }

  for (prev = insn, insn = NEXT_INSN (insn);
       insn;
       prev = insn, insn = NEXT_INSN (insn))
    {
      rtx_insn *control;

      /* Do everything that happens "before" the insn.  */
      add_cfi_insn = prev;

      /* Notice the end of a trace.  */
      if (BARRIER_P (insn))
	{
	  /* Don't bother saving the unneeded queued registers at all.  */
	  queued_reg_saves.truncate (0);
	  break;
	}
      if (save_point_p (insn))
	{
	  /* Propagate across fallthru edges.  */
	  dwarf2out_flush_queued_reg_saves ();
	  maybe_record_trace_start (insn, NULL);
	  break;
	}

      if (DEBUG_INSN_P (insn) || !inside_basic_block_p (insn))
	continue;

      /* Handle all changes to the row state.  Sequences require special
	 handling for the positioning of the notes.  */
      if (rtx_sequence *pat = dyn_cast <rtx_sequence *> (PATTERN (insn)))
	{
	  rtx_insn *elt;
	  int i, n = pat->len ();

	  control = pat->insn (0);
	  if (can_throw_internal (control))
	    notice_eh_throw (control);
	  dwarf2out_flush_queued_reg_saves ();

	  if (JUMP_P (control) && INSN_ANNULLED_BRANCH_P (control))
	    {
	      /* ??? Hopefully multiple delay slots are not annulled.  */
	      gcc_assert (n == 2);
	      gcc_assert (!RTX_FRAME_RELATED_P (control));
	      gcc_assert (!find_reg_note (control, REG_ARGS_SIZE, NULL));

	      elt = pat->insn (1);

	      if (INSN_FROM_TARGET_P (elt))
		{
		  cfi_vec save_row_reg_save;

		  /* If ELT is an instruction from target of an annulled
		     branch, the effects are for the target only and so
		     the args_size and CFA along the current path
		     shouldn't change.  */
		  add_cfi_insn = NULL;
		  poly_int64 restore_args_size = cur_trace->end_true_args_size;
		  cur_cfa = &cur_row->cfa;
		  save_row_reg_save = vec_safe_copy (cur_row->reg_save);

		  scan_insn_after (elt);

		  /* ??? Should we instead save the entire row state?  */
		  gcc_assert (!queued_reg_saves.length ());

		  create_trace_edges (control);

		  cur_trace->end_true_args_size = restore_args_size;
		  cur_row->cfa = this_cfa;
		  cur_row->reg_save = save_row_reg_save;
		  cur_cfa = &this_cfa;
		}
	      else
		{
		  /* If ELT is a annulled branch-taken instruction (i.e.
		     executed only when branch is not taken), the args_size
		     and CFA should not change through the jump.  */
		  create_trace_edges (control);

		  /* Update and continue with the trace.  */
		  add_cfi_insn = insn;
		  scan_insn_after (elt);
		  def_cfa_1 (&this_cfa);
		}
	      continue;
	    }

	  /* The insns in the delay slot should all be considered to happen
	     "before" a call insn.  Consider a call with a stack pointer
	     adjustment in the delay slot.  The backtrace from the callee
	     should include the sp adjustment.  Unfortunately, that leaves
	     us with an unavoidable unwinding error exactly at the call insn
	     itself.  For jump insns we'd prefer to avoid this error by
	     placing the notes after the sequence.  */
	  if (JUMP_P (control))
	    add_cfi_insn = insn;

	  for (i = 1; i < n; ++i)
	    {
	      elt = pat->insn (i);
	      scan_insn_after (elt);
	    }

	  /* Make sure any register saves are visible at the jump target.  */
	  dwarf2out_flush_queued_reg_saves ();
	  any_cfis_emitted = false;

          /* However, if there is some adjustment on the call itself, e.g.
	     a call_pop, that action should be considered to happen after
	     the call returns.  */
	  add_cfi_insn = insn;
	  scan_insn_after (control);
	}
      else
	{
	  /* Flush data before calls and jumps, and of course if necessary.  */
	  if (can_throw_internal (insn))
	    {
	      notice_eh_throw (insn);
	      dwarf2out_flush_queued_reg_saves ();
	    }
	  else if (!NONJUMP_INSN_P (insn)
		   || clobbers_queued_reg_save (insn)
		   || find_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL))
	    dwarf2out_flush_queued_reg_saves ();
	  any_cfis_emitted = false;

	  add_cfi_insn = insn;
	  scan_insn_after (insn);
	  control = insn;
	}

      /* Between frame-related-p and args_size we might have otherwise
	 emitted two cfa adjustments.  Do it now.  */
      def_cfa_1 (&this_cfa);

      /* Minimize the number of advances by emitting the entire queue
	 once anything is emitted.  */
      if (any_cfis_emitted
	  || find_reg_note (insn, REG_CFA_FLUSH_QUEUE, NULL))
	dwarf2out_flush_queued_reg_saves ();

      /* Note that a test for control_flow_insn_p does exactly the
	 same tests as are done to actually create the edges.  So
	 always call the routine and let it not create edges for
	 non-control-flow insns.  */
      create_trace_edges (control);
    }

  gcc_assert (!cfun->fde || !cfun->fde->rule18);
  add_cfi_insn = NULL;
  cur_row = NULL;
  cur_trace = NULL;
  cur_cfa = NULL;
}

/* Scan the function and create the initial set of CFI notes.  */

static void
create_cfi_notes (void)
{
  dw_trace_info *ti;

  gcc_checking_assert (!queued_reg_saves.exists ());
  gcc_checking_assert (!trace_work_list.exists ());

  /* Always begin at the entry trace.  */
  ti = &trace_info[0];
  scan_trace (ti, true);

  while (!trace_work_list.is_empty ())
    {
      ti = trace_work_list.pop ();
      scan_trace (ti, false);
    }

  queued_reg_saves.release ();
  trace_work_list.release ();
}

/* Return the insn before the first NOTE_INSN_CFI after START.  */

static rtx_insn *
before_next_cfi_note (rtx_insn *start)
{
  rtx_insn *prev = start;
  while (start)
    {
      if (NOTE_P (start) && NOTE_KIND (start) == NOTE_INSN_CFI)
	return prev;
      prev = start;
      start = NEXT_INSN (start);
    }
  gcc_unreachable ();
}

/* Insert CFI notes between traces to properly change state between them.  */

static void
connect_traces (void)
{
  unsigned i, n;
  dw_trace_info *prev_ti, *ti;

  /* ??? Ideally, we should have both queued and processed every trace.
     However the current representation of constant pools on various targets
     is indistinguishable from unreachable code.  Assume for the moment that
     we can simply skip over such traces.  */
  /* ??? Consider creating a DATA_INSN rtx code to indicate that
     these are not "real" instructions, and should not be considered.
     This could be generically useful for tablejump data as well.  */
  /* Remove all unprocessed traces from the list.  */
  unsigned ix, ix2;
  VEC_ORDERED_REMOVE_IF_FROM_TO (trace_info, ix, ix2, ti, 1,
				 trace_info.length (), ti->beg_row == NULL);
  FOR_EACH_VEC_ELT (trace_info, ix, ti)
    gcc_assert (ti->end_row != NULL);

  /* Work from the end back to the beginning.  This lets us easily insert
     remember/restore_state notes in the correct order wrt other notes.  */
  n = trace_info.length ();
  prev_ti = &trace_info[n - 1];
  for (i = n - 1; i > 0; --i)
    {
      dw_cfi_row *old_row;

      ti = prev_ti;
      prev_ti = &trace_info[i - 1];

      add_cfi_insn = ti->head;

      /* In dwarf2out_switch_text_section, we'll begin a new FDE
	 for the portion of the function in the alternate text
	 section.  The row state at the very beginning of that
	 new FDE will be exactly the row state from the CIE.  */
      if (ti->switch_sections)
	old_row = cie_cfi_row;
      else
	{
	  old_row = prev_ti->end_row;
	  /* If there's no change from the previous end state, fine.  */
	  if (cfi_row_equal_p (old_row, ti->beg_row))
	    ;
	  /* Otherwise check for the common case of sharing state with
	     the beginning of an epilogue, but not the end.  Insert
	     remember/restore opcodes in that case.  */
	  else if (cfi_row_equal_p (prev_ti->beg_row, ti->beg_row))
	    {
	      dw_cfi_ref cfi;

	      /* Note that if we blindly insert the remember at the
		 start of the trace, we can wind up increasing the
		 size of the unwind info due to extra advance opcodes.
		 Instead, put the remember immediately before the next
		 state change.  We know there must be one, because the 
		 state at the beginning and head of the trace differ.  */
	      add_cfi_insn = before_next_cfi_note (prev_ti->head);
	      cfi = new_cfi ();
	      cfi->dw_cfi_opc = DW_CFA_remember_state;
	      add_cfi (cfi);

	      add_cfi_insn = ti->head;
	      cfi = new_cfi ();
	      cfi->dw_cfi_opc = DW_CFA_restore_state;
	      add_cfi (cfi);

	      /* If the target unwinder does not save the CFA as part of the
		 register state, we need to restore it separately.  */
	      if (targetm.asm_out.should_restore_cfa_state ()
		  && (cfi = def_cfa_0 (&old_row->cfa, &ti->beg_row->cfa)))
		add_cfi (cfi);

	      old_row = prev_ti->beg_row;
	    }
	  /* Otherwise, we'll simply change state from the previous end.  */
	}

      change_cfi_row (old_row, ti->beg_row);

      if (dump_file && add_cfi_insn != ti->head)
	{
	  rtx_insn *note;

	  fprintf (dump_file, "Fixup between trace %u and %u:\n",
		   prev_ti->id, ti->id);

	  note = ti->head;
	  do
	    {
	      note = NEXT_INSN (note);
	      gcc_assert (NOTE_P (note) && NOTE_KIND (note) == NOTE_INSN_CFI);
	      output_cfi_directive (dump_file, NOTE_CFI (note));
	    }
	  while (note != add_cfi_insn);
	}
    }

  /* Connect args_size between traces that have can_throw_internal insns.  */
  if (cfun->eh->lp_array)
    {
      poly_int64 prev_args_size = 0;

      for (i = 0; i < n; ++i)
	{
	  ti = &trace_info[i];

	  if (ti->switch_sections)
	    prev_args_size = 0;

	  if (ti->eh_head == NULL)
	    continue;

	  /* We require either the incoming args_size values to match or the
	     presence of an insn setting it before the first EH insn.  */
	  gcc_assert (!ti->args_size_undefined || ti->args_size_defined_for_eh);

	  /* In the latter case, we force the creation of a CFI note.  */
	  if (ti->args_size_undefined
	      || maybe_ne (ti->beg_delay_args_size, prev_args_size))
	    {
	      /* ??? Search back to previous CFI note.  */
	      add_cfi_insn = PREV_INSN (ti->eh_head);
	      add_cfi_args_size (ti->beg_delay_args_size);
	    }

	  prev_args_size = ti->end_delay_args_size;
	}
    }
}

/* Set up the pseudo-cfg of instruction traces, as described at the
   block comment at the top of the file.  */

static void
create_pseudo_cfg (void)
{
  bool saw_barrier, switch_sections;
  dw_trace_info ti;
  rtx_insn *insn;
  unsigned i;

  /* The first trace begins at the start of the function,
     and begins with the CIE row state.  */
  trace_info.create (16);
  memset (&ti, 0, sizeof (ti));
  ti.head = get_insns ();
  ti.beg_row = cie_cfi_row;
  ti.cfa_store = cie_cfi_row->cfa;
  ti.cfa_temp.reg = INVALID_REGNUM;
  trace_info.quick_push (ti);

  if (cie_return_save)
    ti.regs_saved_in_regs.safe_push (*cie_return_save);

  /* Walk all the insns, collecting start of trace locations.  */
  saw_barrier = false;
  switch_sections = false;
  for (insn = get_insns (); insn; insn = NEXT_INSN (insn))
    {
      if (BARRIER_P (insn))
	saw_barrier = true;
      else if (NOTE_P (insn)
	       && NOTE_KIND (insn) == NOTE_INSN_SWITCH_TEXT_SECTIONS)
	{
	  /* We should have just seen a barrier.  */
	  gcc_assert (saw_barrier);
	  switch_sections = true;
	}
      /* Watch out for save_point notes between basic blocks.
	 In particular, a note after a barrier.  Do not record these,
	 delaying trace creation until the label.  */
      else if (save_point_p (insn)
	       && (LABEL_P (insn) || !saw_barrier))
	{
	  memset (&ti, 0, sizeof (ti));
	  ti.head = insn;
	  ti.switch_sections = switch_sections;
	  ti.id = trace_info.length ();
	  trace_info.safe_push (ti);

	  saw_barrier = false;
	  switch_sections = false;
	}
    }

  /* Create the trace index after we've finished building trace_info,
     avoiding stale pointer problems due to reallocation.  */
  trace_index
    = new hash_table<trace_info_hasher> (trace_info.length ());
  dw_trace_info *tp;
  FOR_EACH_VEC_ELT (trace_info, i, tp)
    {
      dw_trace_info **slot;

      if (dump_file)
	fprintf (dump_file, "Creating trace %u : start at %s %d%s\n", tp->id,
		 rtx_name[(int) GET_CODE (tp->head)], INSN_UID (tp->head),
		 tp->switch_sections ? " (section switch)" : "");

      slot = trace_index->find_slot_with_hash (tp, INSN_UID (tp->head), INSERT);
      gcc_assert (*slot == NULL);
      *slot = tp;
    }
}

/* Record the initial position of the return address.  RTL is
   INCOMING_RETURN_ADDR_RTX.  */

static void
initial_return_save (rtx rtl)
{
  unsigned int reg = INVALID_REGNUM;
  poly_int64 offset = 0;

  switch (GET_CODE (rtl))
    {
    case REG:
      /* RA is in a register.  */
      reg = dwf_regno (rtl);
      break;

    case MEM:
      /* RA is on the stack.  */
      rtl = XEXP (rtl, 0);
      switch (GET_CODE (rtl))
	{
	case REG:
	  gcc_assert (REGNO (rtl) == STACK_POINTER_REGNUM);
	  offset = 0;
	  break;

	case PLUS:
	  gcc_assert (REGNO (XEXP (rtl, 0)) == STACK_POINTER_REGNUM);
	  offset = rtx_to_poly_int64 (XEXP (rtl, 1));
	  break;

	case MINUS:
	  gcc_assert (REGNO (XEXP (rtl, 0)) == STACK_POINTER_REGNUM);
	  offset = -rtx_to_poly_int64 (XEXP (rtl, 1));
	  break;

	default:
	  gcc_unreachable ();
	}

      break;

    case PLUS:
      /* The return address is at some offset from any value we can
	 actually load.  For instance, on the SPARC it is in %i7+8. Just
	 ignore the offset for now; it doesn't matter for unwinding frames.  */
      gcc_assert (CONST_INT_P (XEXP (rtl, 1)));
      initial_return_save (XEXP (rtl, 0));
      return;

    default:
      gcc_unreachable ();
    }

  if (reg != DWARF_FRAME_RETURN_COLUMN)
    {
      if (reg != INVALID_REGNUM)
        record_reg_saved_in_reg (rtl, pc_rtx);
      reg_save (DWARF_FRAME_RETURN_COLUMN, reg, offset - cur_row->cfa.offset);
    }
}

static void
create_cie_data (void)
{
  dw_cfa_location loc;
  dw_trace_info cie_trace;

  dw_stack_pointer_regnum = DWARF_FRAME_REGNUM (STACK_POINTER_REGNUM);

  memset (&cie_trace, 0, sizeof (cie_trace));
  cur_trace = &cie_trace;

  add_cfi_vec = &cie_cfi_vec;
  cie_cfi_row = cur_row = new_cfi_row ();

  /* On entry, the Canonical Frame Address is at SP.  */
  memset (&loc, 0, sizeof (loc));
  loc.reg = dw_stack_pointer_regnum;
  /* create_cie_data is called just once per TU, and when using .cfi_startproc
     is even done by the assembler rather than the compiler.  If the target
     has different incoming frame sp offsets depending on what kind of
     function it is, use a single constant offset for the target and
     if needed, adjust before the first instruction in insn stream.  */
  loc.offset = DEFAULT_INCOMING_FRAME_SP_OFFSET;
  def_cfa_1 (&loc);

  if (targetm.debug_unwind_info () == UI_DWARF2
      || targetm_common.except_unwind_info (&global_options) == UI_DWARF2)
    {
      initial_return_save (INCOMING_RETURN_ADDR_RTX);

      /* For a few targets, we have the return address incoming into a
	 register, but choose a different return column.  This will result
	 in a DW_CFA_register for the return, and an entry in
	 regs_saved_in_regs to match.  If the target later stores that
	 return address register to the stack, we want to be able to emit
	 the DW_CFA_offset against the return column, not the intermediate
	 save register.  Save the contents of regs_saved_in_regs so that
	 we can re-initialize it at the start of each function.  */
      switch (cie_trace.regs_saved_in_regs.length ())
	{
	case 0:
	  break;
	case 1:
	  cie_return_save = ggc_alloc<reg_saved_in_data> ();
	  *cie_return_save = cie_trace.regs_saved_in_regs[0];
	  cie_trace.regs_saved_in_regs.release ();
	  break;
	default:
	  gcc_unreachable ();
	}
    }

  add_cfi_vec = NULL;
  cur_row = NULL;
  cur_trace = NULL;
}

/* Annotate the function with NOTE_INSN_CFI notes to record the CFI
   state at each location within the function.  These notes will be
   emitted during pass_final.  */

static unsigned int
execute_dwarf2_frame (void)
{
  /* Different HARD_FRAME_POINTER_REGNUM might coexist in the same file.  */
  dw_frame_pointer_regnum = DWARF_FRAME_REGNUM (HARD_FRAME_POINTER_REGNUM);

  /* The first time we're called, compute the incoming frame state.  */
  if (cie_cfi_vec == NULL)
    create_cie_data ();

  dwarf2out_alloc_current_fde ();

  create_pseudo_cfg ();

  /* Do the work.  */
  create_cfi_notes ();
  connect_traces ();
  add_cfis_to_fde ();

  /* Free all the data we allocated.  */
  {
    size_t i;
    dw_trace_info *ti;

    FOR_EACH_VEC_ELT (trace_info, i, ti)
      ti->regs_saved_in_regs.release ();
  }
  trace_info.release ();

  delete trace_index;
  trace_index = NULL;

  return 0;
}

/* Convert a DWARF call frame info. operation to its string name */

static const char *
dwarf_cfi_name (unsigned int cfi_opc)
{
  const char *name = get_DW_CFA_name (cfi_opc);

  if (name != NULL)
    return name;

  return "DW_CFA_<unknown>";
}

/* This routine will generate the correct assembly data for a location
   description based on a cfi entry with a complex address.  */

static void
output_cfa_loc (dw_cfi_ref cfi, int for_eh)
{
  dw_loc_descr_ref loc;
  unsigned long size;

  if (cfi->dw_cfi_opc == DW_CFA_expression
      || cfi->dw_cfi_opc == DW_CFA_val_expression)
    {
      unsigned r =
	DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
      dw2_asm_output_data (1, r, NULL);
      loc = cfi->dw_cfi_oprnd2.dw_cfi_loc;
    }
  else
    loc = cfi->dw_cfi_oprnd1.dw_cfi_loc;

  /* Output the size of the block.  */
  size = size_of_locs (loc);
  dw2_asm_output_data_uleb128 (size, NULL);

  /* Now output the operations themselves.  */
  output_loc_sequence (loc, for_eh);
}

/* Similar, but used for .cfi_escape.  */

static void
output_cfa_loc_raw (dw_cfi_ref cfi)
{
  dw_loc_descr_ref loc;
  unsigned long size;

  if (cfi->dw_cfi_opc == DW_CFA_expression
      || cfi->dw_cfi_opc == DW_CFA_val_expression)
    {
      unsigned r =
	DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
      fprintf (asm_out_file, "%#x,", r);
      loc = cfi->dw_cfi_oprnd2.dw_cfi_loc;
    }
  else
    loc = cfi->dw_cfi_oprnd1.dw_cfi_loc;

  /* Output the size of the block.  */
  size = size_of_locs (loc);
  dw2_asm_output_data_uleb128_raw (size);
  fputc (',', asm_out_file);

  /* Now output the operations themselves.  */
  output_loc_sequence_raw (loc);
}

/* Output a Call Frame Information opcode and its operand(s).  */

void
output_cfi (dw_cfi_ref cfi, dw_fde_ref fde, int for_eh)
{
  unsigned long r;
  HOST_WIDE_INT off;

  if (cfi->dw_cfi_opc == DW_CFA_advance_loc)
    dw2_asm_output_data (1, (cfi->dw_cfi_opc
			     | (cfi->dw_cfi_oprnd1.dw_cfi_offset & 0x3f)),
			 "DW_CFA_advance_loc " HOST_WIDE_INT_PRINT_HEX,
			 ((unsigned HOST_WIDE_INT)
			  cfi->dw_cfi_oprnd1.dw_cfi_offset));
  else if (cfi->dw_cfi_opc == DW_CFA_offset)
    {
      r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
      dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)),
			   "DW_CFA_offset, column %#lx", r);
      off = div_data_align (cfi->dw_cfi_oprnd2.dw_cfi_offset);
      dw2_asm_output_data_uleb128 (off, NULL);
    }
  else if (cfi->dw_cfi_opc == DW_CFA_restore)
    {
      r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
      dw2_asm_output_data (1, (cfi->dw_cfi_opc | (r & 0x3f)),
			   "DW_CFA_restore, column %#lx", r);
    }
  else
    {
      dw2_asm_output_data (1, cfi->dw_cfi_opc,
			   "%s", dwarf_cfi_name (cfi->dw_cfi_opc));

      switch (cfi->dw_cfi_opc)
	{
	case DW_CFA_set_loc:
	  if (for_eh)
	    dw2_asm_output_encoded_addr_rtx (
		ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/1, /*global=*/0),
		gen_rtx_SYMBOL_REF (Pmode, cfi->dw_cfi_oprnd1.dw_cfi_addr),
		false, NULL);
	  else
	    dw2_asm_output_addr (DWARF2_ADDR_SIZE,
				 cfi->dw_cfi_oprnd1.dw_cfi_addr, NULL);
	  fde->dw_fde_current_label = cfi->dw_cfi_oprnd1.dw_cfi_addr;
	  break;

	case DW_CFA_advance_loc1:
	  dw2_asm_output_delta (1, cfi->dw_cfi_oprnd1.dw_cfi_addr,
				fde->dw_fde_current_label, NULL);
	  fde->dw_fde_current_label = cfi->dw_cfi_oprnd1.dw_cfi_addr;
	  break;

	case DW_CFA_advance_loc2:
	  dw2_asm_output_delta (2, cfi->dw_cfi_oprnd1.dw_cfi_addr,
				fde->dw_fde_current_label, NULL);
	  fde->dw_fde_current_label = cfi->dw_cfi_oprnd1.dw_cfi_addr;
	  break;

	case DW_CFA_advance_loc4:
	  dw2_asm_output_delta (4, cfi->dw_cfi_oprnd1.dw_cfi_addr,
				fde->dw_fde_current_label, NULL);
	  fde->dw_fde_current_label = cfi->dw_cfi_oprnd1.dw_cfi_addr;
	  break;

	case DW_CFA_MIPS_advance_loc8:
	  dw2_asm_output_delta (8, cfi->dw_cfi_oprnd1.dw_cfi_addr,
				fde->dw_fde_current_label, NULL);
	  fde->dw_fde_current_label = cfi->dw_cfi_oprnd1.dw_cfi_addr;
	  break;

	case DW_CFA_offset_extended:
	  r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
	  dw2_asm_output_data_uleb128 (r, NULL);
	  off = div_data_align (cfi->dw_cfi_oprnd2.dw_cfi_offset);
	  dw2_asm_output_data_uleb128 (off, NULL);
	  break;

	case DW_CFA_def_cfa:
	  r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
	  dw2_asm_output_data_uleb128 (r, NULL);
	  dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd2.dw_cfi_offset, NULL);
	  break;

	case DW_CFA_offset_extended_sf:
	  r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
	  dw2_asm_output_data_uleb128 (r, NULL);
	  off = div_data_align (cfi->dw_cfi_oprnd2.dw_cfi_offset);
	  dw2_asm_output_data_sleb128 (off, NULL);
	  break;

	case DW_CFA_def_cfa_sf:
	  r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
	  dw2_asm_output_data_uleb128 (r, NULL);
	  off = div_data_align (cfi->dw_cfi_oprnd2.dw_cfi_offset);
	  dw2_asm_output_data_sleb128 (off, NULL);
	  break;

	case DW_CFA_restore_extended:
	case DW_CFA_undefined:
	case DW_CFA_same_value:
	case DW_CFA_def_cfa_register:
	  r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
	  dw2_asm_output_data_uleb128 (r, NULL);
	  break;

	case DW_CFA_register:
	  r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, for_eh);
	  dw2_asm_output_data_uleb128 (r, NULL);
	  r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd2.dw_cfi_reg_num, for_eh);
	  dw2_asm_output_data_uleb128 (r, NULL);
	  break;

	case DW_CFA_def_cfa_offset:
	case DW_CFA_GNU_args_size:
	  dw2_asm_output_data_uleb128 (cfi->dw_cfi_oprnd1.dw_cfi_offset, NULL);
	  break;

	case DW_CFA_def_cfa_offset_sf:
	  off = div_data_align (cfi->dw_cfi_oprnd1.dw_cfi_offset);
	  dw2_asm_output_data_sleb128 (off, NULL);
	  break;

	case DW_CFA_GNU_window_save:
	  break;

	case DW_CFA_def_cfa_expression:
	case DW_CFA_expression:
	case DW_CFA_val_expression:
	  output_cfa_loc (cfi, for_eh);
	  break;

	case DW_CFA_GNU_negative_offset_extended:
	  /* Obsoleted by DW_CFA_offset_extended_sf.  */
	  gcc_unreachable ();

	default:
	  break;
	}
    }
}

/* Similar, but do it via assembler directives instead.  */

void
output_cfi_directive (FILE *f, dw_cfi_ref cfi)
{
  unsigned long r, r2;

  switch (cfi->dw_cfi_opc)
    {
    case DW_CFA_advance_loc:
    case DW_CFA_advance_loc1:
    case DW_CFA_advance_loc2:
    case DW_CFA_advance_loc4:
    case DW_CFA_MIPS_advance_loc8:
    case DW_CFA_set_loc:
      /* Should only be created in a code path not followed when emitting
	 via directives.  The assembler is going to take care of this for
	 us.  But this routines is also used for debugging dumps, so
	 print something.  */
      gcc_assert (f != asm_out_file);
      fprintf (f, "\t.cfi_advance_loc\n");
      break;

    case DW_CFA_offset:
    case DW_CFA_offset_extended:
    case DW_CFA_offset_extended_sf:
      r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
      fprintf (f, "\t.cfi_offset %lu, " HOST_WIDE_INT_PRINT_DEC"\n",
	       r, cfi->dw_cfi_oprnd2.dw_cfi_offset);
      break;

    case DW_CFA_restore:
    case DW_CFA_restore_extended:
      r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
      fprintf (f, "\t.cfi_restore %lu\n", r);
      break;

    case DW_CFA_undefined:
      r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
      fprintf (f, "\t.cfi_undefined %lu\n", r);
      break;

    case DW_CFA_same_value:
      r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
      fprintf (f, "\t.cfi_same_value %lu\n", r);
      break;

    case DW_CFA_def_cfa:
    case DW_CFA_def_cfa_sf:
      r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
      fprintf (f, "\t.cfi_def_cfa %lu, " HOST_WIDE_INT_PRINT_DEC"\n",
	       r, cfi->dw_cfi_oprnd2.dw_cfi_offset);
      break;

    case DW_CFA_def_cfa_register:
      r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
      fprintf (f, "\t.cfi_def_cfa_register %lu\n", r);
      break;

    case DW_CFA_register:
      r = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd1.dw_cfi_reg_num, 1);
      r2 = DWARF2_FRAME_REG_OUT (cfi->dw_cfi_oprnd2.dw_cfi_reg_num, 1);
      fprintf (f, "\t.cfi_register %lu, %lu\n", r, r2);
      break;

    case DW_CFA_def_cfa_offset:
    case DW_CFA_def_cfa_offset_sf:
      fprintf (f, "\t.cfi_def_cfa_offset "
	       HOST_WIDE_INT_PRINT_DEC"\n",
	       cfi->dw_cfi_oprnd1.dw_cfi_offset);
      break;

    case DW_CFA_remember_state:
      fprintf (f, "\t.cfi_remember_state\n");
      break;
    case DW_CFA_restore_state:
      fprintf (f, "\t.cfi_restore_state\n");
      break;

    case DW_CFA_GNU_args_size:
      if (f == asm_out_file)
	{
	  fprintf (f, "\t.cfi_escape %#x,", DW_CFA_GNU_args_size);
	  dw2_asm_output_data_uleb128_raw (cfi->dw_cfi_oprnd1.dw_cfi_offset);
	  if (flag_debug_asm)
	    fprintf (f, "\t%s args_size " HOST_WIDE_INT_PRINT_DEC,
		     ASM_COMMENT_START, cfi->dw_cfi_oprnd1.dw_cfi_offset);
	  fputc ('\n', f);
	}
      else
	{
	  fprintf (f, "\t.cfi_GNU_args_size " HOST_WIDE_INT_PRINT_DEC "\n",
		   cfi->dw_cfi_oprnd1.dw_cfi_offset);
	}
      break;

    case DW_CFA_GNU_window_save:
      fprintf (f, "\t.cfi_window_save\n");
      break;

    case DW_CFA_def_cfa_expression:
    case DW_CFA_expression:
    case DW_CFA_val_expression:
      if (f != asm_out_file)
	{
	  fprintf (f, "\t.cfi_%scfa_%sexpression ...\n",
		   cfi->dw_cfi_opc == DW_CFA_def_cfa_expression ? "def_" : "",
		   cfi->dw_cfi_opc == DW_CFA_val_expression ? "val_" : "");
	  break;
	}
      fprintf (f, "\t.cfi_escape %#x,", cfi->dw_cfi_opc);
      output_cfa_loc_raw (cfi);
      fputc ('\n', f);
      break;

    default:
      gcc_unreachable ();
    }
}

void
dwarf2out_emit_cfi (dw_cfi_ref cfi)
{
  if (dwarf2out_do_cfi_asm ())
    output_cfi_directive (asm_out_file, cfi);
}

static void
dump_cfi_row (FILE *f, dw_cfi_row *row)
{
  dw_cfi_ref cfi;
  unsigned i;

  cfi = row->cfa_cfi;
  if (!cfi)
    {
      dw_cfa_location dummy;
      memset (&dummy, 0, sizeof (dummy));
      dummy.reg = INVALID_REGNUM;
      cfi = def_cfa_0 (&dummy, &row->cfa);
    }
  output_cfi_directive (f, cfi);

  FOR_EACH_VEC_SAFE_ELT (row->reg_save, i, cfi)
    if (cfi)
      output_cfi_directive (f, cfi);
}

void debug_cfi_row (dw_cfi_row *row);

void
debug_cfi_row (dw_cfi_row *row)
{
  dump_cfi_row (stderr, row);
}


/* Save the result of dwarf2out_do_frame across PCH.
   This variable is tri-state, with 0 unset, >0 true, <0 false.  */
static GTY(()) signed char saved_do_cfi_asm = 0;

/* Decide whether to emit EH frame unwind information for the current
   translation unit.  */

bool
dwarf2out_do_eh_frame (void)
{
  return
    (flag_unwind_tables || flag_exceptions)
    && targetm_common.except_unwind_info (&global_options) == UI_DWARF2;
}

/* Decide whether we want to emit frame unwind information for the current
   translation unit.  */

bool
dwarf2out_do_frame (void)
{
  /* We want to emit correct CFA location expressions or lists, so we
     have to return true if we're going to generate debug info, even if
     we're not going to output frame or unwind info.  */
  if (dwarf_debuginfo_p () || dwarf_based_debuginfo_p ())
    return true;

  if (saved_do_cfi_asm > 0)
    return true;

  if (targetm.debug_unwind_info () == UI_DWARF2)
    return true;

  if (dwarf2out_do_eh_frame ())
    return true;

  return false;
}

/* Decide whether to emit frame unwind via assembler directives.  */

bool
dwarf2out_do_cfi_asm (void)
{
  int enc;

  if (saved_do_cfi_asm != 0)
    return saved_do_cfi_asm > 0;

  /* Assume failure for a moment.  */
  saved_do_cfi_asm = -1;

  if (!flag_dwarf2_cfi_asm || !dwarf2out_do_frame ())
    return false;
  if (!HAVE_GAS_CFI_PERSONALITY_DIRECTIVE)
    return false;

  /* Make sure the personality encoding is one the assembler can support.
     In particular, aligned addresses can't be handled.  */
  enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/2,/*global=*/1);
  if ((enc & 0x70) != 0 && (enc & 0x70) != DW_EH_PE_pcrel)
    return false;
  enc = ASM_PREFERRED_EH_DATA_FORMAT (/*code=*/0,/*global=*/0);
  if ((enc & 0x70) != 0 && (enc & 0x70) != DW_EH_PE_pcrel)
    return false;

  /* If we can't get the assembler to emit only .debug_frame, and we don't need
     dwarf2 unwind info for exceptions, then emit .debug_frame by hand.  */
  if (!HAVE_GAS_CFI_SECTIONS_DIRECTIVE && !dwarf2out_do_eh_frame ())
    return false;

  /* Success!  */
  saved_do_cfi_asm = 1;
  return true;
}

namespace {

const pass_data pass_data_dwarf2_frame =
{
  RTL_PASS, /* type */
  "dwarf2", /* 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_dwarf2_frame : public rtl_opt_pass
{
public:
  pass_dwarf2_frame (gcc::context *ctxt)
    : rtl_opt_pass (pass_data_dwarf2_frame, ctxt)
  {}

  /* opt_pass methods: */
  virtual bool gate (function *);
  virtual unsigned int execute (function *) { return execute_dwarf2_frame (); }

}; // class pass_dwarf2_frame

bool
pass_dwarf2_frame::gate (function *)
{
  /* Targets which still implement the prologue in assembler text
     cannot use the generic dwarf2 unwinding.  */
  if (!targetm.have_prologue ())
    return false;

  /* ??? What to do for UI_TARGET unwinding?  They might be able to benefit
     from the optimized shrink-wrapping annotations that we will compute.
     For now, only produce the CFI notes for dwarf2.  */
  return dwarf2out_do_frame ();
}

} // anon namespace

rtl_opt_pass *
make_pass_dwarf2_frame (gcc::context *ctxt)
{
  return new pass_dwarf2_frame (ctxt);
}

#include "gt-dwarf2cfi.h"
