/* Scanning of rtl for dataflow analysis.
   Copyright (C) 1999-2021 Free Software Foundation, Inc.
   Originally contributed by Michael P. Hayes
             (m.hayes@elec.canterbury.ac.nz, mhayes@redhat.com)
   Major rewrite contributed by Danny Berlin (dberlin@dberlin.org)
             and Kenneth Zadeck (zadeck@naturalbridge.com).

This file is part of GCC.

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

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

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

#include "config.h"
#include "system.h"
#include "coretypes.h"
#include "backend.h"
#include "target.h"
#include "rtl.h"
#include "tree.h"
#include "df.h"
#include "memmodel.h"
#include "tm_p.h"
#include "regs.h"
#include "emit-rtl.h"  /* FIXME: Can go away once crtl is moved to rtl.h.  */
#include "dumpfile.h"
#include "calls.h"
#include "function-abi.h"

/* The set of hard registers in eliminables[i].from. */

static HARD_REG_SET elim_reg_set;

/* Initialize ur_in and ur_out as if all hard registers were partially
   available.  */

class df_collection_rec
{
public:
  auto_vec<df_ref, 128> def_vec;
  auto_vec<df_ref, 32> use_vec;
  auto_vec<df_ref, 32> eq_use_vec;
  auto_vec<df_mw_hardreg *, 32> mw_vec;
};

static void df_ref_record (enum df_ref_class, class df_collection_rec *,
			   rtx, rtx *,
			   basic_block, struct df_insn_info *,
			   enum df_ref_type, int ref_flags);
static void df_def_record_1 (class df_collection_rec *, rtx *,
			     basic_block, struct df_insn_info *,
			     int ref_flags);
static void df_defs_record (class df_collection_rec *, rtx,
			    basic_block, struct df_insn_info *,
			    int ref_flags);
static void df_uses_record (class df_collection_rec *,
			    rtx *, enum df_ref_type,
			    basic_block, struct df_insn_info *,
			    int ref_flags);

static void df_install_ref_incremental (df_ref);
static void df_insn_refs_collect (class df_collection_rec*,
				  basic_block, struct df_insn_info *);
static void df_canonize_collection_rec (class df_collection_rec *);

static void df_get_regular_block_artificial_uses (bitmap);
static void df_get_eh_block_artificial_uses (bitmap);

static void df_record_entry_block_defs (bitmap);
static void df_record_exit_block_uses (bitmap);
static void df_get_exit_block_use_set (bitmap);
static void df_get_entry_block_def_set (bitmap);
static void df_grow_ref_info (struct df_ref_info *, unsigned int);
static void df_ref_chain_delete_du_chain (df_ref);
static void df_ref_chain_delete (df_ref);

static void df_refs_add_to_chains (class df_collection_rec *,
				   basic_block, rtx_insn *, unsigned int);

static bool df_insn_refs_verify (class df_collection_rec *, basic_block,
				 rtx_insn *, bool);
static void df_entry_block_defs_collect (class df_collection_rec *, bitmap);
static void df_exit_block_uses_collect (class df_collection_rec *, bitmap);
static void df_install_ref (df_ref, struct df_reg_info *,
			    struct df_ref_info *, bool);

static int df_ref_compare (df_ref, df_ref);
static int df_ref_ptr_compare (const void *, const void *);
static int df_mw_compare (const df_mw_hardreg *, const df_mw_hardreg *);
static int df_mw_ptr_compare (const void *, const void *);

static void df_insn_info_delete (unsigned int);

/* Indexed by hardware reg number, is true if that register is ever
   used in the current function.

   In df-scan.c, this is set up to record the hard regs used
   explicitly.  Reload adds in the hard regs used for holding pseudo
   regs.  Final uses it to generate the code in the function prologue
   and epilogue to save and restore registers as needed.  */

static bool regs_ever_live[FIRST_PSEUDO_REGISTER];

/* Flags used to tell df_refs_add_to_chains() which vectors it should copy. */
static const unsigned int copy_defs = 0x1;
static const unsigned int copy_uses = 0x2;
static const unsigned int copy_eq_uses = 0x4;
static const unsigned int copy_mw = 0x8;
static const unsigned int copy_all = copy_defs | copy_uses | copy_eq_uses
| copy_mw;

/*----------------------------------------------------------------------------
   SCANNING DATAFLOW PROBLEM

   There are several ways in which scanning looks just like the other
   dataflow problems.  It shares the all the mechanisms for local info
   as well as basic block info.  Where it differs is when and how often
   it gets run.  It also has no need for the iterative solver.
----------------------------------------------------------------------------*/

/* Problem data for the scanning dataflow function.  */
struct df_scan_problem_data
{
  object_allocator<df_base_ref> *ref_base_pool;
  object_allocator<df_artificial_ref> *ref_artificial_pool;
  object_allocator<df_regular_ref> *ref_regular_pool;
  object_allocator<df_insn_info> *insn_pool;
  object_allocator<df_reg_info> *reg_pool;
  object_allocator<df_mw_hardreg> *mw_reg_pool;

  bitmap_obstack reg_bitmaps;
  bitmap_obstack insn_bitmaps;
};

/* Internal function to shut down the scanning problem.  */
static void
df_scan_free_internal (void)
{
  struct df_scan_problem_data *problem_data
    = (struct df_scan_problem_data *) df_scan->problem_data;

  free (df->def_info.refs);
  free (df->def_info.begin);
  free (df->def_info.count);
  memset (&df->def_info, 0, (sizeof (struct df_ref_info)));

  free (df->use_info.refs);
  free (df->use_info.begin);
  free (df->use_info.count);
  memset (&df->use_info, 0, (sizeof (struct df_ref_info)));

  free (df->def_regs);
  df->def_regs = NULL;
  free (df->use_regs);
  df->use_regs = NULL;
  free (df->eq_use_regs);
  df->eq_use_regs = NULL;
  df->regs_size = 0;
  DF_REG_SIZE (df) = 0;

  free (df->insns);
  df->insns = NULL;
  DF_INSN_SIZE () = 0;

  free (df_scan->block_info);
  df_scan->block_info = NULL;
  df_scan->block_info_size = 0;

  bitmap_clear (&df->hardware_regs_used);
  bitmap_clear (&df->regular_block_artificial_uses);
  bitmap_clear (&df->eh_block_artificial_uses);
  BITMAP_FREE (df->entry_block_defs);
  BITMAP_FREE (df->exit_block_uses);
  bitmap_clear (&df->insns_to_delete);
  bitmap_clear (&df->insns_to_rescan);
  bitmap_clear (&df->insns_to_notes_rescan);

  delete problem_data->ref_base_pool;
  delete problem_data->ref_artificial_pool;
  delete problem_data->ref_regular_pool;
  delete problem_data->insn_pool;
  delete problem_data->reg_pool;
  delete problem_data->mw_reg_pool;
  bitmap_obstack_release (&problem_data->reg_bitmaps);
  bitmap_obstack_release (&problem_data->insn_bitmaps);
  free (df_scan->problem_data);
}


/* Free basic block info.  */

static void
df_scan_free_bb_info (basic_block bb, void *vbb_info)
{
  struct df_scan_bb_info *bb_info = (struct df_scan_bb_info *) vbb_info;
  unsigned int bb_index = bb->index;
  rtx_insn *insn;

  FOR_BB_INSNS (bb, insn)
    if (INSN_P (insn))
      df_insn_info_delete (INSN_UID (insn));

  if (bb_index < df_scan->block_info_size)
    bb_info = df_scan_get_bb_info (bb_index);

  /* Get rid of any artificial uses or defs.  */
  df_ref_chain_delete_du_chain (bb_info->artificial_defs);
  df_ref_chain_delete_du_chain (bb_info->artificial_uses);
  df_ref_chain_delete (bb_info->artificial_defs);
  df_ref_chain_delete (bb_info->artificial_uses);
  bb_info->artificial_defs = NULL;
  bb_info->artificial_uses = NULL;
}


/* Allocate the problem data for the scanning problem.  This should be
   called when the problem is created or when the entire function is to
   be rescanned.  */
void
df_scan_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
{
  struct df_scan_problem_data *problem_data;
  basic_block bb;

  /* Given the number of pools, this is really faster than tearing
     everything apart.  */
  if (df_scan->problem_data)
    df_scan_free_internal ();

  problem_data = XNEW (struct df_scan_problem_data);
  df_scan->problem_data = problem_data;
  df_scan->computed = true;

  problem_data->ref_base_pool = new object_allocator<df_base_ref>
    ("df_scan ref base");
  problem_data->ref_artificial_pool = new object_allocator<df_artificial_ref>
    ("df_scan ref artificial");
  problem_data->ref_regular_pool = new object_allocator<df_regular_ref>
    ("df_scan ref regular");
  problem_data->insn_pool = new object_allocator<df_insn_info>
    ("df_scan insn");
  problem_data->reg_pool = new object_allocator<df_reg_info>
    ("df_scan reg");
  problem_data->mw_reg_pool = new object_allocator<df_mw_hardreg>
    ("df_scan mw_reg");

  bitmap_obstack_initialize (&problem_data->reg_bitmaps);
  bitmap_obstack_initialize (&problem_data->insn_bitmaps);

  df_grow_reg_info ();

  df_grow_insn_info ();
  df_grow_bb_info (df_scan);

  FOR_ALL_BB_FN (bb, cfun)
    {
      unsigned int bb_index = bb->index;
      struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb_index);
      bb_info->artificial_defs = NULL;
      bb_info->artificial_uses = NULL;
    }

  bitmap_initialize (&df->hardware_regs_used, &problem_data->reg_bitmaps);
  bitmap_initialize (&df->regular_block_artificial_uses, &problem_data->reg_bitmaps);
  bitmap_initialize (&df->eh_block_artificial_uses, &problem_data->reg_bitmaps);
  df->entry_block_defs = BITMAP_ALLOC (&problem_data->reg_bitmaps);
  df->exit_block_uses = BITMAP_ALLOC (&problem_data->reg_bitmaps);
  bitmap_initialize (&df->insns_to_delete, &problem_data->insn_bitmaps);
  bitmap_initialize (&df->insns_to_rescan, &problem_data->insn_bitmaps);
  bitmap_initialize (&df->insns_to_notes_rescan, &problem_data->insn_bitmaps);
  df_scan->optional_p = false;
}


/* Free all of the data associated with the scan problem.  */

static void
df_scan_free (void)
{
  if (df_scan->problem_data)
    df_scan_free_internal ();

  if (df->blocks_to_analyze)
    {
      BITMAP_FREE (df->blocks_to_analyze);
      df->blocks_to_analyze = NULL;
    }

  free (df_scan);
}

/* Dump the preamble for DF_SCAN dump. */
static void
df_scan_start_dump (FILE *file ATTRIBUTE_UNUSED)
{
  int i;
  int dcount = 0;
  int ucount = 0;
  int ecount = 0;
  int icount = 0;
  int ccount = 0;
  basic_block bb;
  rtx_insn *insn;

  fprintf (file, ";;  fully invalidated by EH \t");
  df_print_regset
    (file, bitmap_view<HARD_REG_SET> (eh_edge_abi.full_reg_clobbers ()));
  fprintf (file, ";;  hardware regs used \t");
  df_print_regset (file, &df->hardware_regs_used);
  fprintf (file, ";;  regular block artificial uses \t");
  df_print_regset (file, &df->regular_block_artificial_uses);
  fprintf (file, ";;  eh block artificial uses \t");
  df_print_regset (file, &df->eh_block_artificial_uses);
  fprintf (file, ";;  entry block defs \t");
  df_print_regset (file, df->entry_block_defs);
  fprintf (file, ";;  exit block uses \t");
  df_print_regset (file, df->exit_block_uses);
  fprintf (file, ";;  regs ever live \t");
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (df_regs_ever_live_p (i))
      fprintf (file, " %d [%s]", i, reg_names[i]);
  fprintf (file, "\n;;  ref usage \t");

  for (i = 0; i < (int)df->regs_inited; i++)
    if (DF_REG_DEF_COUNT (i) || DF_REG_USE_COUNT (i) || DF_REG_EQ_USE_COUNT (i))
      {
	const char * sep = "";

	fprintf (file, "r%d={", i);
	if (DF_REG_DEF_COUNT (i))
	  {
	    fprintf (file, "%dd", DF_REG_DEF_COUNT (i));
	    sep = ",";
	    dcount += DF_REG_DEF_COUNT (i);
	  }
	if (DF_REG_USE_COUNT (i))
	  {
	    fprintf (file, "%s%du", sep, DF_REG_USE_COUNT (i));
	    sep = ",";
	    ucount += DF_REG_USE_COUNT (i);
	  }
	if (DF_REG_EQ_USE_COUNT (i))
	  {
	    fprintf (file, "%s%de", sep, DF_REG_EQ_USE_COUNT (i));
	    ecount += DF_REG_EQ_USE_COUNT (i);
	  }
	fprintf (file, "} ");
      }

  FOR_EACH_BB_FN (bb, cfun)
    FOR_BB_INSNS (bb, insn)
      if (INSN_P (insn))
	{
	  if (CALL_P (insn))
	    ccount++;
	  else
	    icount++;
	}

  fprintf (file, "\n;;    total ref usage %d{%dd,%du,%de}"
		 " in %d{%d regular + %d call} insns.\n",
		 dcount + ucount + ecount, dcount, ucount, ecount,
		 icount + ccount, icount, ccount);
}

/* Dump the bb_info for a given basic block. */
static void
df_scan_start_block (basic_block bb, FILE *file)
{
  struct df_scan_bb_info *bb_info
    = df_scan_get_bb_info (bb->index);

  if (bb_info)
    {
      fprintf (file, ";; bb %d artificial_defs: ", bb->index);
      df_refs_chain_dump (bb_info->artificial_defs, true, file);
      fprintf (file, "\n;; bb %d artificial_uses: ", bb->index);
      df_refs_chain_dump (bb_info->artificial_uses, true, file);
      fprintf (file, "\n");
    }
#if 0
  {
    rtx_insn *insn;
    FOR_BB_INSNS (bb, insn)
      if (INSN_P (insn))
	df_insn_debug (insn, false, file);
  }
#endif
}

static const struct df_problem problem_SCAN =
{
  DF_SCAN,                    /* Problem id.  */
  DF_NONE,                    /* Direction.  */
  df_scan_alloc,              /* Allocate the problem specific data.  */
  NULL,                       /* Reset global information.  */
  df_scan_free_bb_info,       /* Free basic block info.  */
  NULL,                       /* Local compute function.  */
  NULL,                       /* Init the solution specific data.  */
  NULL,                       /* Iterative solver.  */
  NULL,                       /* Confluence operator 0.  */
  NULL,                       /* Confluence operator n.  */
  NULL,                       /* Transfer function.  */
  NULL,                       /* Finalize function.  */
  df_scan_free,               /* Free all of the problem information.  */
  NULL,                       /* Remove this problem from the stack of dataflow problems.  */
  df_scan_start_dump,         /* Debugging.  */
  df_scan_start_block,        /* Debugging start block.  */
  NULL,                       /* Debugging end block.  */
  NULL,                       /* Debugging start insn.  */
  NULL,                       /* Debugging end insn.  */
  NULL,                       /* Incremental solution verify start.  */
  NULL,                       /* Incremental solution verify end.  */
  NULL,                       /* Dependent problem.  */
  sizeof (struct df_scan_bb_info),/* Size of entry of block_info array.  */
  TV_DF_SCAN,                 /* Timing variable.  */
  false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
};


/* Create a new DATAFLOW instance and add it to an existing instance
   of DF.  The returned structure is what is used to get at the
   solution.  */

void
df_scan_add_problem (void)
{
  df_add_problem (&problem_SCAN);
}


/*----------------------------------------------------------------------------
   Storage Allocation Utilities
----------------------------------------------------------------------------*/


/* First, grow the reg_info information.  If the current size is less than
   the number of pseudos, grow to 25% more than the number of
   pseudos.

   Second, assure that all of the slots up to max_reg_num have been
   filled with reg_info structures.  */

void
df_grow_reg_info (void)
{
  unsigned int max_reg = max_reg_num ();
  unsigned int new_size = max_reg;
  struct df_scan_problem_data *problem_data
    = (struct df_scan_problem_data *) df_scan->problem_data;
  unsigned int i;

  if (df->regs_size < new_size)
    {
      new_size += new_size / 4;
      df->def_regs = XRESIZEVEC (struct df_reg_info *, df->def_regs, new_size);
      df->use_regs = XRESIZEVEC (struct df_reg_info *, df->use_regs, new_size);
      df->eq_use_regs = XRESIZEVEC (struct df_reg_info *, df->eq_use_regs,
				    new_size);
      df->def_info.begin = XRESIZEVEC (unsigned, df->def_info.begin, new_size);
      df->def_info.count = XRESIZEVEC (unsigned, df->def_info.count, new_size);
      df->use_info.begin = XRESIZEVEC (unsigned, df->use_info.begin, new_size);
      df->use_info.count = XRESIZEVEC (unsigned, df->use_info.count, new_size);
      df->regs_size = new_size;
    }

  for (i = df->regs_inited; i < max_reg; i++)
    {
      struct df_reg_info *reg_info;

      // TODO
      reg_info = problem_data->reg_pool->allocate ();
      memset (reg_info, 0, sizeof (struct df_reg_info));
      df->def_regs[i] = reg_info;
      reg_info = problem_data->reg_pool->allocate ();
      memset (reg_info, 0, sizeof (struct df_reg_info));
      df->use_regs[i] = reg_info;
      reg_info = problem_data->reg_pool->allocate ();
      memset (reg_info, 0, sizeof (struct df_reg_info));
      df->eq_use_regs[i] = reg_info;
      df->def_info.begin[i] = 0;
      df->def_info.count[i] = 0;
      df->use_info.begin[i] = 0;
      df->use_info.count[i] = 0;
    }

  df->regs_inited = max_reg;
}


/* Grow the ref information.  */

static void
df_grow_ref_info (struct df_ref_info *ref_info, unsigned int new_size)
{
  if (ref_info->refs_size < new_size)
    {
      ref_info->refs = XRESIZEVEC (df_ref, ref_info->refs, new_size);
      memset (ref_info->refs + ref_info->refs_size, 0,
	      (new_size - ref_info->refs_size) *sizeof (df_ref));
      ref_info->refs_size = new_size;
    }
}


/* Check and grow the ref information if necessary.  This routine
   guarantees total_size + BITMAP_ADDEND amount of entries in refs
   array.  It updates ref_info->refs_size only and does not change
   ref_info->total_size.  */

static void
df_check_and_grow_ref_info (struct df_ref_info *ref_info,
			    unsigned bitmap_addend)
{
  if (ref_info->refs_size < ref_info->total_size + bitmap_addend)
    {
      int new_size = ref_info->total_size + bitmap_addend;
      new_size += ref_info->total_size / 4;
      df_grow_ref_info (ref_info, new_size);
    }
}


/* Grow the ref information.  If the current size is less than the
   number of instructions, grow to 25% more than the number of
   instructions.  */

void
df_grow_insn_info (void)
{
  unsigned int new_size = get_max_uid () + 1;
  if (DF_INSN_SIZE () < new_size)
    {
      new_size += new_size / 4;
      df->insns = XRESIZEVEC (struct df_insn_info *, df->insns, new_size);
      memset (df->insns + df->insns_size, 0,
	      (new_size - DF_INSN_SIZE ()) *sizeof (struct df_insn_info *));
      DF_INSN_SIZE () = new_size;
    }
}




/*----------------------------------------------------------------------------
   PUBLIC INTERFACES FOR SMALL GRAIN CHANGES TO SCANNING.
----------------------------------------------------------------------------*/

/* Rescan all of the block_to_analyze or all of the blocks in the
   function if df_set_blocks if blocks_to_analyze is NULL;  */

void
df_scan_blocks (void)
{
  basic_block bb;

  df->def_info.ref_order = DF_REF_ORDER_NO_TABLE;
  df->use_info.ref_order = DF_REF_ORDER_NO_TABLE;

  df_get_regular_block_artificial_uses (&df->regular_block_artificial_uses);
  df_get_eh_block_artificial_uses (&df->eh_block_artificial_uses);

  bitmap_ior_into (&df->eh_block_artificial_uses,
		   &df->regular_block_artificial_uses);

  /* ENTRY and EXIT blocks have special defs/uses.  */
  df_get_entry_block_def_set (df->entry_block_defs);
  df_record_entry_block_defs (df->entry_block_defs);
  df_get_exit_block_use_set (df->exit_block_uses);
  df_record_exit_block_uses (df->exit_block_uses);
  df_set_bb_dirty (BASIC_BLOCK_FOR_FN (cfun, ENTRY_BLOCK));
  df_set_bb_dirty (BASIC_BLOCK_FOR_FN (cfun, EXIT_BLOCK));

  /* Regular blocks */
  FOR_EACH_BB_FN (bb, cfun)
    {
      unsigned int bb_index = bb->index;
      df_bb_refs_record (bb_index, true);
    }
}

/* Create new refs under address LOC within INSN.  This function is
   only used externally.  REF_FLAGS must be either 0 or DF_REF_IN_NOTE,
   depending on whether LOC is inside PATTERN (INSN) or a note.  */

void
df_uses_create (rtx *loc, rtx_insn *insn, int ref_flags)
{
  gcc_assert (!(ref_flags & ~DF_REF_IN_NOTE));
  df_uses_record (NULL, loc, DF_REF_REG_USE,
                  BLOCK_FOR_INSN (insn),
                  DF_INSN_INFO_GET (insn),
                  ref_flags);
}

static void
df_install_ref_incremental (df_ref ref)
{
  struct df_reg_info **reg_info;
  struct df_ref_info *ref_info;
  df_ref *ref_ptr;
  bool add_to_table;

  rtx_insn *insn = DF_REF_INSN (ref);
  basic_block bb = BLOCK_FOR_INSN (insn);

  if (DF_REF_REG_DEF_P (ref))
    {
      reg_info = df->def_regs;
      ref_info = &df->def_info;
      ref_ptr = &DF_INSN_DEFS (insn);
      add_to_table = ref_info->ref_order != DF_REF_ORDER_NO_TABLE;
    }
  else if (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE)
    {
      reg_info = df->eq_use_regs;
      ref_info = &df->use_info;
      ref_ptr = &DF_INSN_EQ_USES (insn);
      switch (ref_info->ref_order)
	{
	case DF_REF_ORDER_UNORDERED_WITH_NOTES:
	case DF_REF_ORDER_BY_REG_WITH_NOTES:
	case DF_REF_ORDER_BY_INSN_WITH_NOTES:
	  add_to_table = true;
	  break;
	default:
	  add_to_table = false;
	  break;
	}
    }
  else
    {
      reg_info = df->use_regs;
      ref_info = &df->use_info;
      ref_ptr = &DF_INSN_USES (insn);
      add_to_table = ref_info->ref_order != DF_REF_ORDER_NO_TABLE;
    }

  /* Do not add if ref is not in the right blocks.  */
  if (add_to_table && df->analyze_subset)
    add_to_table = bitmap_bit_p (df->blocks_to_analyze, bb->index);

  df_install_ref (ref, reg_info[DF_REF_REGNO (ref)], ref_info, add_to_table);

  if (add_to_table)
    switch (ref_info->ref_order)
      {
      case DF_REF_ORDER_UNORDERED_WITH_NOTES:
      case DF_REF_ORDER_BY_REG_WITH_NOTES:
      case DF_REF_ORDER_BY_INSN_WITH_NOTES:
	ref_info->ref_order = DF_REF_ORDER_UNORDERED_WITH_NOTES;
	break;
      default:
	ref_info->ref_order = DF_REF_ORDER_UNORDERED;
	break;
      }

  while (*ref_ptr && df_ref_compare (*ref_ptr, ref) < 0)
    ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr);

  DF_REF_NEXT_LOC (ref) = *ref_ptr;
  *ref_ptr = ref;

#if 0
  if (dump_file)
    {
      fprintf (dump_file, "adding ref ");
      df_ref_debug (ref, dump_file);
    }
#endif
  /* By adding the ref directly, df_insn_rescan my not find any
     differences even though the block will have changed.  So we need
     to mark the block dirty ourselves.  */
  if (!DEBUG_INSN_P (DF_REF_INSN (ref)))
    df_set_bb_dirty (bb);
}



/*----------------------------------------------------------------------------
   UTILITIES TO CREATE AND DESTROY REFS AND CHAINS.
----------------------------------------------------------------------------*/

static void
df_free_ref (df_ref ref)
{
  struct df_scan_problem_data *problem_data
    = (struct df_scan_problem_data *) df_scan->problem_data;

  switch (DF_REF_CLASS (ref))
    {
    case DF_REF_BASE:
      problem_data->ref_base_pool->remove ((df_base_ref *) (ref));
      break;

    case DF_REF_ARTIFICIAL:
      problem_data->ref_artificial_pool->remove
	((df_artificial_ref *) (ref));
      break;

    case DF_REF_REGULAR:
      problem_data->ref_regular_pool->remove
	((df_regular_ref *) (ref));
      break;
    }
}


/* Unlink and delete REF at the reg_use, reg_eq_use or reg_def chain.
   Also delete the def-use or use-def chain if it exists.  */

static void
df_reg_chain_unlink (df_ref ref)
{
  df_ref next = DF_REF_NEXT_REG (ref);
  df_ref prev = DF_REF_PREV_REG (ref);
  int id = DF_REF_ID (ref);
  struct df_reg_info *reg_info;
  df_ref *refs = NULL;

  if (DF_REF_REG_DEF_P (ref))
    {
      int regno = DF_REF_REGNO (ref);
      reg_info = DF_REG_DEF_GET (regno);
      refs = df->def_info.refs;
    }
  else
    {
      if (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE)
	{
	  reg_info = DF_REG_EQ_USE_GET (DF_REF_REGNO (ref));
	  switch (df->use_info.ref_order)
	    {
	    case DF_REF_ORDER_UNORDERED_WITH_NOTES:
	    case DF_REF_ORDER_BY_REG_WITH_NOTES:
	    case DF_REF_ORDER_BY_INSN_WITH_NOTES:
	      refs = df->use_info.refs;
	      break;
	    default:
	      break;
	    }
	}
      else
	{
	  reg_info = DF_REG_USE_GET (DF_REF_REGNO (ref));
	  refs = df->use_info.refs;
	}
    }

  if (refs)
    {
      if (df->analyze_subset)
	{
	  if (bitmap_bit_p (df->blocks_to_analyze, DF_REF_BBNO (ref)))
	    refs[id] = NULL;
	}
      else
	refs[id] = NULL;
    }

  /* Delete any def-use or use-def chains that start here. It is
     possible that there is trash in this field.  This happens for
     insns that have been deleted when rescanning has been deferred
     and the chain problem has also been deleted.  The chain tear down
     code skips deleted insns.  */
  if (df_chain && DF_REF_CHAIN (ref))
    df_chain_unlink (ref);

  reg_info->n_refs--;
  if (DF_REF_FLAGS_IS_SET (ref, DF_HARD_REG_LIVE))
    {
      gcc_assert (DF_REF_REGNO (ref) < FIRST_PSEUDO_REGISTER);
      df->hard_regs_live_count[DF_REF_REGNO (ref)]--;
    }

  /* Unlink from the reg chain.  If there is no prev, this is the
     first of the list.  If not, just join the next and prev.  */
  if (prev)
    DF_REF_NEXT_REG (prev) = next;
  else
    {
      gcc_assert (reg_info->reg_chain == ref);
      reg_info->reg_chain = next;
    }
  if (next)
    DF_REF_PREV_REG (next) = prev;

  df_free_ref (ref);
}

/* Initialize INSN_INFO to describe INSN.  */

static void
df_insn_info_init_fields (df_insn_info *insn_info, rtx_insn *insn)
{
  memset (insn_info, 0, sizeof (struct df_insn_info));
  insn_info->insn = insn;
}

/* Create the insn record for INSN.  If there was one there, zero it
   out.  */

struct df_insn_info *
df_insn_create_insn_record (rtx_insn *insn)
{
  struct df_scan_problem_data *problem_data
    = (struct df_scan_problem_data *) df_scan->problem_data;
  struct df_insn_info *insn_rec;

  df_grow_insn_info ();
  insn_rec = DF_INSN_INFO_GET (insn);
  if (!insn_rec)
    {
      insn_rec = problem_data->insn_pool->allocate ();
      DF_INSN_INFO_SET (insn, insn_rec);
    }
  df_insn_info_init_fields (insn_rec, insn);
  return insn_rec;
}


/* Delete all du chain (DF_REF_CHAIN()) of all refs in the ref chain.  */

static void
df_ref_chain_delete_du_chain (df_ref ref)
{
  for (; ref; ref = DF_REF_NEXT_LOC (ref))
    /* CHAIN is allocated by DF_CHAIN. So make sure to
       pass df_scan instance for the problem.  */
    if (DF_REF_CHAIN (ref))
      df_chain_unlink (ref);
}


/* Delete all refs in the ref chain.  */

static void
df_ref_chain_delete (df_ref ref)
{
  df_ref next;
  for (; ref; ref = next)
    {
      next = DF_REF_NEXT_LOC (ref);
      df_reg_chain_unlink (ref);
    }
}


/* Delete the hardreg chain.  */

static void
df_mw_hardreg_chain_delete (struct df_mw_hardreg *hardregs)
{
  struct df_scan_problem_data *problem_data
    = (struct df_scan_problem_data *) df_scan->problem_data;
  df_mw_hardreg *next;

  for (; hardregs; hardregs = next)
    {
      next = DF_MWS_NEXT (hardregs);
      problem_data->mw_reg_pool->remove (hardregs);
    }
}

/* Remove the contents of INSN_INFO (but don't free INSN_INFO itself).  */

static void
df_insn_info_free_fields (df_insn_info *insn_info)
{
  /* In general, notes do not have the insn_info fields
     initialized.  However, combine deletes insns by changing them
     to notes.  How clever.  So we cannot just check if it is a
     valid insn before short circuiting this code, we need to see
     if we actually initialized it.  */
  df_mw_hardreg_chain_delete (insn_info->mw_hardregs);

  if (df_chain)
    {
      df_ref_chain_delete_du_chain (insn_info->defs);
      df_ref_chain_delete_du_chain (insn_info->uses);
      df_ref_chain_delete_du_chain (insn_info->eq_uses);
    }

  df_ref_chain_delete (insn_info->defs);
  df_ref_chain_delete (insn_info->uses);
  df_ref_chain_delete (insn_info->eq_uses);
}

/* Delete all of the refs information from the insn with UID.
   Internal helper for df_insn_delete, df_insn_rescan, and other
   df-scan routines that don't have to work in deferred mode
   and do not have to mark basic blocks for re-processing.  */

static void
df_insn_info_delete (unsigned int uid)
{
  struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);

  bitmap_clear_bit (&df->insns_to_delete, uid);
  bitmap_clear_bit (&df->insns_to_rescan, uid);
  bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
  if (insn_info)
    {
      struct df_scan_problem_data *problem_data
	= (struct df_scan_problem_data *) df_scan->problem_data;

      df_insn_info_free_fields (insn_info);
      problem_data->insn_pool->remove (insn_info);
      DF_INSN_UID_SET (uid, NULL);
    }
}

/* Delete all of the refs information from INSN, either right now
   or marked for later in deferred mode.  */

void
df_insn_delete (rtx_insn *insn)
{
  unsigned int uid;
  basic_block bb;

  gcc_checking_assert (INSN_P (insn));

  if (!df)
    return;

  uid = INSN_UID (insn);
  bb = BLOCK_FOR_INSN (insn);

  /* ??? bb can be NULL after pass_free_cfg.  At that point, DF should
     not exist anymore (as mentioned in df-core.c: "The only requirement
     [for DF] is that there be a correct control flow graph."  Clearly
     that isn't the case after pass_free_cfg.  But DF is freed much later
     because some back-ends want to use DF info even though the CFG is
     already gone.  It's not clear to me whether that is safe, actually.
     In any case, we expect BB to be non-NULL at least up to register
     allocation, so disallow a non-NULL BB up to there.  Not perfect
     but better than nothing...  */
  gcc_checking_assert (bb != NULL || reload_completed);

  df_grow_bb_info (df_scan);
  df_grow_reg_info ();

  /* The block must be marked as dirty now, rather than later as in
     df_insn_rescan and df_notes_rescan because it may not be there at
     rescanning time and the mark would blow up.
     DEBUG_INSNs do not make a block's data flow solution dirty (at
     worst the LUIDs are no longer contiguous).  */
  if (bb != NULL && NONDEBUG_INSN_P (insn))
    df_set_bb_dirty (bb);

  /* The client has deferred rescanning.  */
  if (df->changeable_flags & DF_DEFER_INSN_RESCAN)
    {
      struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
      if (insn_info)
	{
	  bitmap_clear_bit (&df->insns_to_rescan, uid);
	  bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
	  bitmap_set_bit (&df->insns_to_delete, uid);
	}
      if (dump_file)
	fprintf (dump_file, "deferring deletion of insn with uid = %d.\n", uid);
      return;
    }

  if (dump_file)
    fprintf (dump_file, "deleting insn with uid = %d.\n", uid);

  df_insn_info_delete (uid);
}


/* Free all of the refs and the mw_hardregs in COLLECTION_REC.  */

static void
df_free_collection_rec (class df_collection_rec *collection_rec)
{
  unsigned int ix;
  struct df_scan_problem_data *problem_data
    = (struct df_scan_problem_data *) df_scan->problem_data;
  df_ref ref;
  struct df_mw_hardreg *mw;

  FOR_EACH_VEC_ELT (collection_rec->def_vec, ix, ref)
    df_free_ref (ref);
  FOR_EACH_VEC_ELT (collection_rec->use_vec, ix, ref)
    df_free_ref (ref);
  FOR_EACH_VEC_ELT (collection_rec->eq_use_vec, ix, ref)
    df_free_ref (ref);
  FOR_EACH_VEC_ELT (collection_rec->mw_vec, ix, mw)
    problem_data->mw_reg_pool->remove (mw);

  collection_rec->def_vec.release ();
  collection_rec->use_vec.release ();
  collection_rec->eq_use_vec.release ();
  collection_rec->mw_vec.release ();
}

/* Rescan INSN.  Return TRUE if the rescanning produced any changes.  */

bool
df_insn_rescan (rtx_insn *insn)
{
  unsigned int uid = INSN_UID (insn);
  struct df_insn_info *insn_info = NULL;
  basic_block bb = BLOCK_FOR_INSN (insn);
  class df_collection_rec collection_rec;

  if ((!df) || (!INSN_P (insn)))
    return false;

  if (!bb)
    {
      if (dump_file)
	fprintf (dump_file, "no bb for insn with uid = %d.\n", uid);
      return false;
    }

  /* The client has disabled rescanning and plans to do it itself.  */
  if (df->changeable_flags & DF_NO_INSN_RESCAN)
    return false;

  df_grow_bb_info (df_scan);
  df_grow_reg_info ();

  insn_info = DF_INSN_UID_SAFE_GET (uid);

  /* The client has deferred rescanning.  */
  if (df->changeable_flags & DF_DEFER_INSN_RESCAN)
    {
      if (!insn_info)
	{
	  insn_info = df_insn_create_insn_record (insn);
	  insn_info->defs = 0;
	  insn_info->uses = 0;
	  insn_info->eq_uses = 0;
	  insn_info->mw_hardregs = 0;
	}
      if (dump_file)
	fprintf (dump_file, "deferring rescan insn with uid = %d.\n", uid);

      bitmap_clear_bit (&df->insns_to_delete, uid);
      bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
      bitmap_set_bit (&df->insns_to_rescan, INSN_UID (insn));
      return false;
    }

  bitmap_clear_bit (&df->insns_to_delete, uid);
  bitmap_clear_bit (&df->insns_to_rescan, uid);
  bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
  if (insn_info)
    {
      int luid;
      bool the_same = df_insn_refs_verify (&collection_rec, bb, insn, false);
      /* If there's no change, return false. */
      if (the_same)
	{
	  df_free_collection_rec (&collection_rec);
	  if (dump_file)
	    fprintf (dump_file, "verify found no changes in insn with uid = %d.\n", uid);
	  return false;
	}
      if (dump_file)
	fprintf (dump_file, "rescanning insn with uid = %d.\n", uid);

      /* There's change - we need to delete the existing info.
	 Since the insn isn't moved, we can salvage its LUID.  */
      luid = DF_INSN_LUID (insn);
      df_insn_info_free_fields (insn_info);
      df_insn_info_init_fields (insn_info, insn);
      DF_INSN_LUID (insn) = luid;
    }
  else
    {
      struct df_insn_info *insn_info = df_insn_create_insn_record (insn);
      df_insn_refs_collect (&collection_rec, bb, insn_info);
      if (dump_file)
	fprintf (dump_file, "scanning new insn with uid = %d.\n", uid);
    }

  df_refs_add_to_chains (&collection_rec, bb, insn, copy_all);
  if (!DEBUG_INSN_P (insn))
    df_set_bb_dirty (bb);

  return true;
}

/* Same as df_insn_rescan, but don't mark the basic block as
   dirty.  */

bool
df_insn_rescan_debug_internal (rtx_insn *insn)
{
  unsigned int uid = INSN_UID (insn);
  struct df_insn_info *insn_info;

  gcc_assert (DEBUG_INSN_P (insn)
	      && VAR_LOC_UNKNOWN_P (INSN_VAR_LOCATION_LOC (insn)));

  if (!df)
    return false;

  insn_info = DF_INSN_UID_SAFE_GET (INSN_UID (insn));
  if (!insn_info)
    return false;

  if (dump_file)
    fprintf (dump_file, "deleting debug_insn with uid = %d.\n", uid);

  bitmap_clear_bit (&df->insns_to_delete, uid);
  bitmap_clear_bit (&df->insns_to_rescan, uid);
  bitmap_clear_bit (&df->insns_to_notes_rescan, uid);

  if (insn_info->defs == 0
      && insn_info->uses == 0
      && insn_info->eq_uses == 0
      && insn_info->mw_hardregs == 0)
    return false;

  df_mw_hardreg_chain_delete (insn_info->mw_hardregs);

  if (df_chain)
    {
      df_ref_chain_delete_du_chain (insn_info->defs);
      df_ref_chain_delete_du_chain (insn_info->uses);
      df_ref_chain_delete_du_chain (insn_info->eq_uses);
    }

  df_ref_chain_delete (insn_info->defs);
  df_ref_chain_delete (insn_info->uses);
  df_ref_chain_delete (insn_info->eq_uses);

  insn_info->defs = 0;
  insn_info->uses = 0;
  insn_info->eq_uses = 0;
  insn_info->mw_hardregs = 0;

  return true;
}


/* Rescan all of the insns in the function.  Note that the artificial
   uses and defs are not touched.  This function will destroy def-use
   or use-def chains.  */

void
df_insn_rescan_all (void)
{
  bool no_insn_rescan = false;
  bool defer_insn_rescan = false;
  basic_block bb;
  bitmap_iterator bi;
  unsigned int uid;

  if (df->changeable_flags & DF_NO_INSN_RESCAN)
    {
      df_clear_flags (DF_NO_INSN_RESCAN);
      no_insn_rescan = true;
    }

  if (df->changeable_flags & DF_DEFER_INSN_RESCAN)
    {
      df_clear_flags (DF_DEFER_INSN_RESCAN);
      defer_insn_rescan = true;
    }

  auto_bitmap tmp (&df_bitmap_obstack);
  bitmap_copy (tmp, &df->insns_to_delete);
  EXECUTE_IF_SET_IN_BITMAP (tmp, 0, uid, bi)
    {
      struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
      if (insn_info)
	df_insn_info_delete (uid);
    }

  bitmap_clear (&df->insns_to_delete);
  bitmap_clear (&df->insns_to_rescan);
  bitmap_clear (&df->insns_to_notes_rescan);

  FOR_EACH_BB_FN (bb, cfun)
    {
      rtx_insn *insn;
      FOR_BB_INSNS (bb, insn)
	{
	  df_insn_rescan (insn);
	}
    }

  if (no_insn_rescan)
    df_set_flags (DF_NO_INSN_RESCAN);
  if (defer_insn_rescan)
    df_set_flags (DF_DEFER_INSN_RESCAN);
}


/* Process all of the deferred rescans or deletions.  */

void
df_process_deferred_rescans (void)
{
  bool no_insn_rescan = false;
  bool defer_insn_rescan = false;
  bitmap_iterator bi;
  unsigned int uid;

  if (df->changeable_flags & DF_NO_INSN_RESCAN)
    {
      df_clear_flags (DF_NO_INSN_RESCAN);
      no_insn_rescan = true;
    }

  if (df->changeable_flags & DF_DEFER_INSN_RESCAN)
    {
      df_clear_flags (DF_DEFER_INSN_RESCAN);
      defer_insn_rescan = true;
    }

  if (dump_file)
    fprintf (dump_file, "starting the processing of deferred insns\n");

  auto_bitmap tmp (&df_bitmap_obstack);
  bitmap_copy (tmp, &df->insns_to_delete);
  EXECUTE_IF_SET_IN_BITMAP (tmp, 0, uid, bi)
    {
      struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
      if (insn_info)
	df_insn_info_delete (uid);
    }

  bitmap_copy (tmp, &df->insns_to_rescan);
  EXECUTE_IF_SET_IN_BITMAP (tmp, 0, uid, bi)
    {
      struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
      if (insn_info)
	df_insn_rescan (insn_info->insn);
    }

  bitmap_copy (tmp, &df->insns_to_notes_rescan);
  EXECUTE_IF_SET_IN_BITMAP (tmp, 0, uid, bi)
    {
      struct df_insn_info *insn_info = DF_INSN_UID_SAFE_GET (uid);
      if (insn_info)
	df_notes_rescan (insn_info->insn);
    }

  if (dump_file)
    fprintf (dump_file, "ending the processing of deferred insns\n");

  bitmap_clear (&df->insns_to_delete);
  bitmap_clear (&df->insns_to_rescan);
  bitmap_clear (&df->insns_to_notes_rescan);

  if (no_insn_rescan)
    df_set_flags (DF_NO_INSN_RESCAN);
  if (defer_insn_rescan)
    df_set_flags (DF_DEFER_INSN_RESCAN);

  /* If someone changed regs_ever_live during this pass, fix up the
     entry and exit blocks.  */
  if (df->redo_entry_and_exit)
    {
      df_update_entry_exit_and_calls ();
      df->redo_entry_and_exit = false;
    }
}


/* Count the number of refs. Include the defs if INCLUDE_DEFS. Include
   the uses if INCLUDE_USES. Include the eq_uses if
   INCLUDE_EQ_USES.  */

static unsigned int
df_count_refs (bool include_defs, bool include_uses,
	       bool include_eq_uses)
{
  unsigned int regno;
  int size = 0;
  unsigned int m = df->regs_inited;

  for (regno = 0; regno < m; regno++)
    {
      if (include_defs)
	size += DF_REG_DEF_COUNT (regno);
      if (include_uses)
	size += DF_REG_USE_COUNT (regno);
      if (include_eq_uses)
	size += DF_REG_EQ_USE_COUNT (regno);
    }
  return size;
}


/* Take build ref table for either the uses or defs from the reg-use
   or reg-def chains.  This version processes the refs in reg order
   which is likely to be best if processing the whole function.  */

static void
df_reorganize_refs_by_reg_by_reg (struct df_ref_info *ref_info,
				  bool include_defs,
				  bool include_uses,
				  bool include_eq_uses)
{
  unsigned int m = df->regs_inited;
  unsigned int regno;
  unsigned int offset = 0;
  unsigned int start;

  if (df->changeable_flags & DF_NO_HARD_REGS)
    {
      start = FIRST_PSEUDO_REGISTER;
      memset (ref_info->begin, 0, sizeof (int) * FIRST_PSEUDO_REGISTER);
      memset (ref_info->count, 0, sizeof (int) * FIRST_PSEUDO_REGISTER);
    }
  else
    start = 0;

  ref_info->total_size
    = df_count_refs (include_defs, include_uses, include_eq_uses);

  df_check_and_grow_ref_info (ref_info, 1);

  for (regno = start; regno < m; regno++)
    {
      int count = 0;
      ref_info->begin[regno] = offset;
      if (include_defs)
	{
	  df_ref ref = DF_REG_DEF_CHAIN (regno);
	  while (ref)
	    {
	      ref_info->refs[offset] = ref;
	      DF_REF_ID (ref) = offset++;
	      count++;
	      ref = DF_REF_NEXT_REG (ref);
	      gcc_checking_assert (offset < ref_info->refs_size);
	    }
	}
      if (include_uses)
	{
	  df_ref ref = DF_REG_USE_CHAIN (regno);
	  while (ref)
	    {
	      ref_info->refs[offset] = ref;
	      DF_REF_ID (ref) = offset++;
	      count++;
	      ref = DF_REF_NEXT_REG (ref);
	      gcc_checking_assert (offset < ref_info->refs_size);
	    }
	}
      if (include_eq_uses)
	{
	  df_ref ref = DF_REG_EQ_USE_CHAIN (regno);
	  while (ref)
	    {
	      ref_info->refs[offset] = ref;
	      DF_REF_ID (ref) = offset++;
	      count++;
	      ref = DF_REF_NEXT_REG (ref);
	      gcc_checking_assert (offset < ref_info->refs_size);
	    }
	}
      ref_info->count[regno] = count;
    }

  /* The bitmap size is not decremented when refs are deleted.  So
     reset it now that we have squished out all of the empty
     slots.  */
  ref_info->table_size = offset;
}


/* Take build ref table for either the uses or defs from the reg-use
   or reg-def chains.  This version processes the refs in insn order
   which is likely to be best if processing some segment of the
   function.  */

static void
df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info,
				   bool include_defs,
				   bool include_uses,
				   bool include_eq_uses)
{
  bitmap_iterator bi;
  unsigned int bb_index;
  unsigned int m = df->regs_inited;
  unsigned int offset = 0;
  unsigned int r;
  unsigned int start
    = (df->changeable_flags & DF_NO_HARD_REGS) ? FIRST_PSEUDO_REGISTER : 0;

  memset (ref_info->begin, 0, sizeof (int) * df->regs_inited);
  memset (ref_info->count, 0, sizeof (int) * df->regs_inited);

  ref_info->total_size = df_count_refs (include_defs, include_uses, include_eq_uses);
  df_check_and_grow_ref_info (ref_info, 1);

  EXECUTE_IF_SET_IN_BITMAP (df->blocks_to_analyze, 0, bb_index, bi)
    {
      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
      rtx_insn *insn;
      df_ref def, use;

      if (include_defs)
	FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
	  {
	    unsigned int regno = DF_REF_REGNO (def);
	    ref_info->count[regno]++;
	  }
      if (include_uses)
	FOR_EACH_ARTIFICIAL_USE (use, bb_index)
	  {
	    unsigned int regno = DF_REF_REGNO (use);
	    ref_info->count[regno]++;
	  }

      FOR_BB_INSNS (bb, insn)
	{
	  if (INSN_P (insn))
	    {
	      struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);

	      if (include_defs)
		FOR_EACH_INSN_INFO_DEF (def, insn_info)
		  {
		    unsigned int regno = DF_REF_REGNO (def);
		    ref_info->count[regno]++;
		  }
	      if (include_uses)
		FOR_EACH_INSN_INFO_USE (use, insn_info)
		  {
		    unsigned int regno = DF_REF_REGNO (use);
		    ref_info->count[regno]++;
		  }
	      if (include_eq_uses)
		FOR_EACH_INSN_INFO_EQ_USE (use, insn_info)
		  {
		    unsigned int regno = DF_REF_REGNO (use);
		    ref_info->count[regno]++;
		  }
	    }
	}
    }

  for (r = start; r < m; r++)
    {
      ref_info->begin[r] = offset;
      offset += ref_info->count[r];
      ref_info->count[r] = 0;
    }

  EXECUTE_IF_SET_IN_BITMAP (df->blocks_to_analyze, 0, bb_index, bi)
    {
      basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
      rtx_insn *insn;
      df_ref def, use;

      if (include_defs)
	FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
	  {
	    unsigned int regno = DF_REF_REGNO (def);
	    if (regno >= start)
	      {
		unsigned int id
		  = ref_info->begin[regno] + ref_info->count[regno]++;
		DF_REF_ID (def) = id;
		ref_info->refs[id] = def;
	      }
	  }
      if (include_uses)
	FOR_EACH_ARTIFICIAL_USE (use, bb_index)
	  {
	    unsigned int regno = DF_REF_REGNO (def);
	    if (regno >= start)
	      {
		unsigned int id
		  = ref_info->begin[regno] + ref_info->count[regno]++;
		DF_REF_ID (use) = id;
		ref_info->refs[id] = use;
	      }
	  }

      FOR_BB_INSNS (bb, insn)
	{
	  if (INSN_P (insn))
	    {
	      struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);

	      if (include_defs)
		FOR_EACH_INSN_INFO_DEF (def, insn_info)
		  {
		    unsigned int regno = DF_REF_REGNO (def);
		    if (regno >= start)
		      {
			unsigned int id
			  = ref_info->begin[regno] + ref_info->count[regno]++;
			DF_REF_ID (def) = id;
			ref_info->refs[id] = def;
		      }
		  }
	      if (include_uses)
		FOR_EACH_INSN_INFO_USE (use, insn_info)
		  {
		    unsigned int regno = DF_REF_REGNO (use);
		    if (regno >= start)
		      {
			unsigned int id
			  = ref_info->begin[regno] + ref_info->count[regno]++;
			DF_REF_ID (use) = id;
			ref_info->refs[id] = use;
		      }
		  }
	      if (include_eq_uses)
		FOR_EACH_INSN_INFO_EQ_USE (use, insn_info)
		  {
		    unsigned int regno = DF_REF_REGNO (use);
		    if (regno >= start)
		      {
			unsigned int id
			  = ref_info->begin[regno] + ref_info->count[regno]++;
			DF_REF_ID (use) = id;
			ref_info->refs[id] = use;
		      }
		  }
	    }
	}
    }

  /* The bitmap size is not decremented when refs are deleted.  So
     reset it now that we have squished out all of the empty
     slots.  */

  ref_info->table_size = offset;
}

/* Take build ref table for either the uses or defs from the reg-use
   or reg-def chains.  */

static void
df_reorganize_refs_by_reg (struct df_ref_info *ref_info,
			   bool include_defs,
			   bool include_uses,
			   bool include_eq_uses)
{
  if (df->analyze_subset)
    df_reorganize_refs_by_reg_by_insn (ref_info, include_defs,
				       include_uses, include_eq_uses);
  else
    df_reorganize_refs_by_reg_by_reg (ref_info, include_defs,
				       include_uses, include_eq_uses);
}


/* Add the refs in REF_VEC to the table in REF_INFO starting at OFFSET.  */
static unsigned int
df_add_refs_to_table (unsigned int offset,
		      struct df_ref_info *ref_info,
		      df_ref ref)
{
  for (; ref; ref = DF_REF_NEXT_LOC (ref))
    if (!(df->changeable_flags & DF_NO_HARD_REGS)
	|| (DF_REF_REGNO (ref) >= FIRST_PSEUDO_REGISTER))
      {
	ref_info->refs[offset] = ref;
	DF_REF_ID (ref) = offset++;
      }
  return offset;
}


/* Count the number of refs in all of the insns of BB. Include the
   defs if INCLUDE_DEFS. Include the uses if INCLUDE_USES. Include the
   eq_uses if INCLUDE_EQ_USES.  */

static unsigned int
df_reorganize_refs_by_insn_bb (basic_block bb, unsigned int offset,
			       struct df_ref_info *ref_info,
			       bool include_defs, bool include_uses,
			       bool include_eq_uses)
{
  rtx_insn *insn;

  if (include_defs)
    offset = df_add_refs_to_table (offset, ref_info,
				   df_get_artificial_defs (bb->index));
  if (include_uses)
    offset = df_add_refs_to_table (offset, ref_info,
				   df_get_artificial_uses (bb->index));

  FOR_BB_INSNS (bb, insn)
    if (INSN_P (insn))
      {
	unsigned int uid = INSN_UID (insn);
	if (include_defs)
	  offset = df_add_refs_to_table (offset, ref_info,
					 DF_INSN_UID_DEFS (uid));
	if (include_uses)
	  offset = df_add_refs_to_table (offset, ref_info,
					 DF_INSN_UID_USES (uid));
	if (include_eq_uses)
	  offset = df_add_refs_to_table (offset, ref_info,
					 DF_INSN_UID_EQ_USES (uid));
      }
  return offset;
}


/* Organize the refs by insn into the table in REF_INFO.  If
   blocks_to_analyze is defined, use that set, otherwise the entire
   program.  Include the defs if INCLUDE_DEFS. Include the uses if
   INCLUDE_USES. Include the eq_uses if INCLUDE_EQ_USES.  */

static void
df_reorganize_refs_by_insn (struct df_ref_info *ref_info,
			    bool include_defs, bool include_uses,
			    bool include_eq_uses)
{
  basic_block bb;
  unsigned int offset = 0;

  ref_info->total_size = df_count_refs (include_defs, include_uses, include_eq_uses);
  df_check_and_grow_ref_info (ref_info, 1);
  if (df->blocks_to_analyze)
    {
      bitmap_iterator bi;
      unsigned int index;

      EXECUTE_IF_SET_IN_BITMAP (df->blocks_to_analyze, 0, index, bi)
	{
	  offset = df_reorganize_refs_by_insn_bb (BASIC_BLOCK_FOR_FN (cfun,
								      index),
						  offset, ref_info,
						  include_defs, include_uses,
						  include_eq_uses);
	}

      ref_info->table_size = offset;
    }
  else
    {
      FOR_ALL_BB_FN (bb, cfun)
	offset = df_reorganize_refs_by_insn_bb (bb, offset, ref_info,
						include_defs, include_uses,
						include_eq_uses);
      ref_info->table_size = offset;
    }
}


/* If the use refs in DF are not organized, reorganize them.  */

void
df_maybe_reorganize_use_refs (enum df_ref_order order)
{
  if (order == df->use_info.ref_order)
    return;

  switch (order)
    {
    case DF_REF_ORDER_BY_REG:
      df_reorganize_refs_by_reg (&df->use_info, false, true, false);
      break;

    case DF_REF_ORDER_BY_REG_WITH_NOTES:
      df_reorganize_refs_by_reg (&df->use_info, false, true, true);
      break;

    case DF_REF_ORDER_BY_INSN:
      df_reorganize_refs_by_insn (&df->use_info, false, true, false);
      break;

    case DF_REF_ORDER_BY_INSN_WITH_NOTES:
      df_reorganize_refs_by_insn (&df->use_info, false, true, true);
      break;

    case DF_REF_ORDER_NO_TABLE:
      free (df->use_info.refs);
      df->use_info.refs = NULL;
      df->use_info.refs_size = 0;
      break;

    case DF_REF_ORDER_UNORDERED:
    case DF_REF_ORDER_UNORDERED_WITH_NOTES:
      gcc_unreachable ();
      break;
    }

  df->use_info.ref_order = order;
}


/* If the def refs in DF are not organized, reorganize them.  */

void
df_maybe_reorganize_def_refs (enum df_ref_order order)
{
  if (order == df->def_info.ref_order)
    return;

  switch (order)
    {
    case DF_REF_ORDER_BY_REG:
      df_reorganize_refs_by_reg (&df->def_info, true, false, false);
      break;

    case DF_REF_ORDER_BY_INSN:
      df_reorganize_refs_by_insn (&df->def_info, true, false, false);
      break;

    case DF_REF_ORDER_NO_TABLE:
      free (df->def_info.refs);
      df->def_info.refs = NULL;
      df->def_info.refs_size = 0;
      break;

    case DF_REF_ORDER_BY_INSN_WITH_NOTES:
    case DF_REF_ORDER_BY_REG_WITH_NOTES:
    case DF_REF_ORDER_UNORDERED:
    case DF_REF_ORDER_UNORDERED_WITH_NOTES:
      gcc_unreachable ();
      break;
    }

  df->def_info.ref_order = order;
}


/* Change all of the basic block references in INSN to use the insn's
   current basic block.  This function is called from routines that move
   instructions from one block to another.  */

void
df_insn_change_bb (rtx_insn *insn, basic_block new_bb)
{
  basic_block old_bb = BLOCK_FOR_INSN (insn);
  struct df_insn_info *insn_info;
  unsigned int uid = INSN_UID (insn);

  if (old_bb == new_bb)
    return;

  set_block_for_insn (insn, new_bb);

  if (!df)
    return;

  if (dump_file)
    fprintf (dump_file, "changing bb of uid %d\n", uid);

  insn_info = DF_INSN_UID_SAFE_GET (uid);
  if (insn_info == NULL)
    {
      if (dump_file)
	fprintf (dump_file, "  unscanned insn\n");
      df_insn_rescan (insn);
      return;
    }

  if (!INSN_P (insn))
    return;

  df_set_bb_dirty (new_bb);
  if (old_bb)
    {
      if (dump_file)
	fprintf (dump_file, "  from %d to %d\n",
		 old_bb->index, new_bb->index);
      df_set_bb_dirty (old_bb);
    }
  else
    if (dump_file)
      fprintf (dump_file, "  to %d\n", new_bb->index);
}


/* Helper function for df_ref_change_reg_with_loc.  */

static void
df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df,
			      struct df_reg_info *new_df,
			      unsigned int new_regno, rtx loc)
{
  df_ref the_ref = old_df->reg_chain;

  while (the_ref)
    {
      if ((!DF_REF_IS_ARTIFICIAL (the_ref))
	  && DF_REF_LOC (the_ref)
	  && (*DF_REF_LOC (the_ref) == loc))
	{
	  df_ref next_ref = DF_REF_NEXT_REG (the_ref);
	  df_ref prev_ref = DF_REF_PREV_REG (the_ref);
	  df_ref *ref_ptr;
	  struct df_insn_info *insn_info = DF_REF_INSN_INFO (the_ref);

	  DF_REF_REGNO (the_ref) = new_regno;
	  DF_REF_REG (the_ref) = regno_reg_rtx[new_regno];

	  /* Pull the_ref out of the old regno chain.  */
	  if (prev_ref)
	    DF_REF_NEXT_REG (prev_ref) = next_ref;
	  else
	    old_df->reg_chain = next_ref;
	  if (next_ref)
	    DF_REF_PREV_REG (next_ref) = prev_ref;
	  old_df->n_refs--;

	  /* Put the ref into the new regno chain.  */
	  DF_REF_PREV_REG (the_ref) = NULL;
	  DF_REF_NEXT_REG (the_ref) = new_df->reg_chain;
	  if (new_df->reg_chain)
	    DF_REF_PREV_REG (new_df->reg_chain) = the_ref;
	  new_df->reg_chain = the_ref;
	  new_df->n_refs++;
	  if (DF_REF_BB (the_ref))
	    df_set_bb_dirty (DF_REF_BB (the_ref));

	  /* Need to sort the record again that the ref was in because
	     the regno is a sorting key.  First, find the right
	     record.  */
	  if (DF_REF_REG_DEF_P (the_ref))
	    ref_ptr = &insn_info->defs;
	  else if (DF_REF_FLAGS (the_ref) & DF_REF_IN_NOTE)
	    ref_ptr = &insn_info->eq_uses;
	  else
	    ref_ptr = &insn_info->uses;
	  if (dump_file)
	    fprintf (dump_file, "changing reg in insn %d\n",
		     DF_REF_INSN_UID (the_ref));

	  /* Stop if we find the current reference or where the reference
	     needs to be.  */
	  while (*ref_ptr != the_ref && df_ref_compare (*ref_ptr, the_ref) < 0)
	    ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr);
	  if (*ref_ptr != the_ref)
	    {
	      /* The reference needs to be promoted up the list.  */
	      df_ref next = DF_REF_NEXT_LOC (the_ref);
	      DF_REF_NEXT_LOC (the_ref) = *ref_ptr;
	      *ref_ptr = the_ref;
	      do
		ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr);
	      while (*ref_ptr != the_ref);
	      *ref_ptr = next;
	    }
	  else if (DF_REF_NEXT_LOC (the_ref)
		   && df_ref_compare (the_ref, DF_REF_NEXT_LOC (the_ref)) > 0)
	    {
	      /* The reference needs to be demoted down the list.  */
	      *ref_ptr = DF_REF_NEXT_LOC (the_ref);
	      do
		ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr);
	      while (*ref_ptr && df_ref_compare (the_ref, *ref_ptr) > 0);
	      DF_REF_NEXT_LOC (the_ref) = *ref_ptr;
	      *ref_ptr = the_ref;
	    }

	  the_ref = next_ref;
	}
      else
	the_ref = DF_REF_NEXT_REG (the_ref);
    }
}


/* Change the regno of register LOC to NEW_REGNO and update the df
   information accordingly.  Refs that do not match LOC are not changed
   which means that artificial refs are not changed since they have no loc.
   This call is to support the SET_REGNO macro. */

void
df_ref_change_reg_with_loc (rtx loc, unsigned int new_regno)
{
  unsigned int old_regno = REGNO (loc);
  if (old_regno == new_regno)
    return;

  if (df)
    {
      df_grow_reg_info ();

      df_ref_change_reg_with_loc_1 (DF_REG_DEF_GET (old_regno),
				    DF_REG_DEF_GET (new_regno),
				    new_regno, loc);
      df_ref_change_reg_with_loc_1 (DF_REG_USE_GET (old_regno),
				    DF_REG_USE_GET (new_regno),
				    new_regno, loc);
      df_ref_change_reg_with_loc_1 (DF_REG_EQ_USE_GET (old_regno),
				    DF_REG_EQ_USE_GET (new_regno),
				    new_regno, loc);
    }
  set_mode_and_regno (loc, GET_MODE (loc), new_regno);
}


/* Delete the mw_hardregs that point into the eq_notes.  */

static void
df_mw_hardreg_chain_delete_eq_uses (struct df_insn_info *insn_info)
{
  struct df_mw_hardreg **mw_ptr = &insn_info->mw_hardregs;
  struct df_scan_problem_data *problem_data
    = (struct df_scan_problem_data *) df_scan->problem_data;

  while (*mw_ptr)
    {
      df_mw_hardreg *mw = *mw_ptr;
      if (mw->flags & DF_REF_IN_NOTE)
	{
	  *mw_ptr = DF_MWS_NEXT (mw);
	  problem_data->mw_reg_pool->remove (mw);
	}
      else
	mw_ptr = &DF_MWS_NEXT (mw);
    }
}


/* Rescan only the REG_EQUIV/REG_EQUAL notes part of INSN.  */

void
df_notes_rescan (rtx_insn *insn)
{
  struct df_insn_info *insn_info;
  unsigned int uid = INSN_UID (insn);

  if (!df)
    return;

  /* The client has disabled rescanning and plans to do it itself.  */
  if (df->changeable_flags & DF_NO_INSN_RESCAN)
    return;

  /* Do nothing if the insn hasn't been emitted yet.  */
  if (!BLOCK_FOR_INSN (insn))
    return;

  df_grow_bb_info (df_scan);
  df_grow_reg_info ();

  insn_info = DF_INSN_UID_SAFE_GET (INSN_UID (insn));

  /* The client has deferred rescanning.  */
  if (df->changeable_flags & DF_DEFER_INSN_RESCAN)
    {
      if (!insn_info)
	{
	  insn_info = df_insn_create_insn_record (insn);
	  insn_info->defs = 0;
	  insn_info->uses = 0;
	  insn_info->eq_uses = 0;
	  insn_info->mw_hardregs = 0;
	}

      bitmap_clear_bit (&df->insns_to_delete, uid);
      /* If the insn is set to be rescanned, it does not need to also
	 be notes rescanned.  */
      if (!bitmap_bit_p (&df->insns_to_rescan, uid))
	bitmap_set_bit (&df->insns_to_notes_rescan, INSN_UID (insn));
      return;
    }

  bitmap_clear_bit (&df->insns_to_delete, uid);
  bitmap_clear_bit (&df->insns_to_notes_rescan, uid);

  if (insn_info)
    {
      basic_block bb = BLOCK_FOR_INSN (insn);
      rtx note;
      class df_collection_rec collection_rec;
      unsigned int i;

      df_mw_hardreg_chain_delete_eq_uses (insn_info);
      df_ref_chain_delete (insn_info->eq_uses);
      insn_info->eq_uses = NULL;

      /* Process REG_EQUIV/REG_EQUAL notes */
      for (note = REG_NOTES (insn); note;
	   note = XEXP (note, 1))
	{
	  switch (REG_NOTE_KIND (note))
	    {
	    case REG_EQUIV:
	    case REG_EQUAL:
	      df_uses_record (&collection_rec,
			      &XEXP (note, 0), DF_REF_REG_USE,
			      bb, insn_info, DF_REF_IN_NOTE);
	    default:
	      break;
	    }
	}

      /* Find some place to put any new mw_hardregs.  */
      df_canonize_collection_rec (&collection_rec);
      struct df_mw_hardreg **mw_ptr = &insn_info->mw_hardregs, *mw;
      FOR_EACH_VEC_ELT (collection_rec.mw_vec, i, mw)
	{
	  while (*mw_ptr && df_mw_compare (*mw_ptr, mw) < 0)
	    mw_ptr = &DF_MWS_NEXT (*mw_ptr);
	  DF_MWS_NEXT (mw) = *mw_ptr;
	  *mw_ptr = mw;
	  mw_ptr = &DF_MWS_NEXT (mw);
	}
      df_refs_add_to_chains (&collection_rec, bb, insn, copy_eq_uses);
    }
  else
    df_insn_rescan (insn);

}


/*----------------------------------------------------------------------------
   Hard core instruction scanning code.  No external interfaces here,
   just a lot of routines that look inside insns.
----------------------------------------------------------------------------*/


/* Return true if the contents of two df_ref's are identical.
   It ignores DF_REF_MARKER.  */

static bool
df_ref_equal_p (df_ref ref1, df_ref ref2)
{
  if (!ref2)
    return false;

  if (ref1 == ref2)
    return true;

  if (DF_REF_CLASS (ref1) != DF_REF_CLASS (ref2)
      || DF_REF_REGNO (ref1) != DF_REF_REGNO (ref2)
      || DF_REF_REG (ref1) != DF_REF_REG (ref2)
      || DF_REF_TYPE (ref1) != DF_REF_TYPE (ref2)
      || ((DF_REF_FLAGS (ref1) & ~(DF_REF_REG_MARKER + DF_REF_MW_HARDREG))
	  != (DF_REF_FLAGS (ref2) & ~(DF_REF_REG_MARKER + DF_REF_MW_HARDREG)))
      || DF_REF_BB (ref1) != DF_REF_BB (ref2)
      || DF_REF_INSN_INFO (ref1) != DF_REF_INSN_INFO (ref2))
    return false;

  switch (DF_REF_CLASS (ref1))
    {
    case DF_REF_ARTIFICIAL:
    case DF_REF_BASE:
      return true;

    case DF_REF_REGULAR:
      return DF_REF_LOC (ref1) == DF_REF_LOC (ref2);

    default:
      gcc_unreachable ();
    }
  return false;
}


/* Compare REF1 and REF2 for sorting.  This is only called from places
   where all of the refs are of the same type, in the same insn, and
   have the same bb.  So these fields are not checked.  */

static int
df_ref_compare (df_ref ref1, df_ref ref2)
{
  if (DF_REF_CLASS (ref1) != DF_REF_CLASS (ref2))
    return (int)DF_REF_CLASS (ref1) - (int)DF_REF_CLASS (ref2);

  if (DF_REF_REGNO (ref1) != DF_REF_REGNO (ref2))
    return (int)DF_REF_REGNO (ref1) - (int)DF_REF_REGNO (ref2);

  if (DF_REF_TYPE (ref1) != DF_REF_TYPE (ref2))
    return (int)DF_REF_TYPE (ref1) - (int)DF_REF_TYPE (ref2);

  if (DF_REF_REG (ref1) != DF_REF_REG (ref2))
    return (int)DF_REF_ORDER (ref1) - (int)DF_REF_ORDER (ref2);

  /* Cannot look at the LOC field on artificial refs.  */
  if (DF_REF_CLASS (ref1) != DF_REF_ARTIFICIAL
      && DF_REF_LOC (ref1) != DF_REF_LOC (ref2))
    return (int)DF_REF_ORDER (ref1) - (int)DF_REF_ORDER (ref2);

  if (DF_REF_FLAGS (ref1) != DF_REF_FLAGS (ref2))
    {
      /* If two refs are identical except that one of them has is from
	 a mw and one is not, we need to have the one with the mw
	 first.  */
      if (DF_REF_FLAGS_IS_SET (ref1, DF_REF_MW_HARDREG) ==
	  DF_REF_FLAGS_IS_SET (ref2, DF_REF_MW_HARDREG))
	return DF_REF_FLAGS (ref1) - DF_REF_FLAGS (ref2);
      else if (DF_REF_FLAGS_IS_SET (ref1, DF_REF_MW_HARDREG))
	return -1;
      else
	return 1;
    }

  return (int)DF_REF_ORDER (ref1) - (int)DF_REF_ORDER (ref2);
}

/* Like df_ref_compare, but compare two df_ref* pointers R1 and R2.  */

static int
df_ref_ptr_compare (const void *r1, const void *r2)
{
  return df_ref_compare (*(const df_ref *) r1, *(const df_ref *) r2);
}

/* Sort and compress a set of refs.  */

static void
df_sort_and_compress_refs (vec<df_ref, va_heap> *ref_vec)
{
  unsigned int count;
  unsigned int i;
  unsigned int dist = 0;

  count = ref_vec->length ();

  /* If there are 1 or 0 elements, there is nothing to do.  */
  if (count < 2)
    return;
  else if (count == 2)
    {
      df_ref r0 = (*ref_vec)[0];
      df_ref r1 = (*ref_vec)[1];
      if (df_ref_compare (r0, r1) > 0)
	std::swap ((*ref_vec)[0], (*ref_vec)[1]);
    }
  else
    {
      for (i = 0; i < count - 1; i++)
	{
	  df_ref r0 = (*ref_vec)[i];
	  df_ref r1 = (*ref_vec)[i + 1];
	  if (df_ref_compare (r0, r1) >= 0)
	    break;
	}
      /* If the array is already strictly ordered,
         which is the most common case for large COUNT case
         (which happens for CALL INSNs),
         no need to sort and filter out duplicate.
         Simply return the count.
         Make sure DF_GET_ADD_REFS adds refs in the increasing order
         of DF_REF_COMPARE.  */
      if (i == count - 1)
        return;
      ref_vec->qsort (df_ref_ptr_compare);
    }

  for (i=0; i<count-dist; i++)
    {
      /* Find the next ref that is not equal to the current ref.  */
      while (i + dist + 1 < count
	     && df_ref_equal_p ((*ref_vec)[i],
				(*ref_vec)[i + dist + 1]))
	{
	  df_free_ref ((*ref_vec)[i + dist + 1]);
	  dist++;
	}
      /* Copy it down to the next position.  */
      if (dist && i + dist + 1 < count)
	(*ref_vec)[i + 1] = (*ref_vec)[i + dist + 1];
    }

  count -= dist;
  ref_vec->truncate (count);
}


/* Return true if the contents of two df_ref's are identical.
   It ignores DF_REF_MARKER.  */

static bool
df_mw_equal_p (struct df_mw_hardreg *mw1, struct df_mw_hardreg *mw2)
{
  if (!mw2)
    return false;
  return (mw1 == mw2) ||
    (mw1->mw_reg == mw2->mw_reg
     && mw1->type == mw2->type
     && mw1->flags == mw2->flags
     && mw1->start_regno == mw2->start_regno
     && mw1->end_regno == mw2->end_regno);
}


/* Compare MW1 and MW2 for sorting.  */

static int
df_mw_compare (const df_mw_hardreg *mw1, const df_mw_hardreg *mw2)
{
  if (mw1->type != mw2->type)
    return mw1->type - mw2->type;

  if (mw1->flags != mw2->flags)
    return mw1->flags - mw2->flags;

  if (mw1->start_regno != mw2->start_regno)
    return mw1->start_regno - mw2->start_regno;

  if (mw1->end_regno != mw2->end_regno)
    return mw1->end_regno - mw2->end_regno;

  return mw1->mw_order - mw2->mw_order;
}

/* Like df_mw_compare, but compare two df_mw_hardreg** pointers R1 and R2.  */

static int
df_mw_ptr_compare (const void *m1, const void *m2)
{
  return df_mw_compare (*(const df_mw_hardreg *const *) m1,
			*(const df_mw_hardreg *const *) m2);
}

/* Sort and compress a set of refs.  */

static void
df_sort_and_compress_mws (vec<df_mw_hardreg *, va_heap> *mw_vec)
{
  unsigned int count;
  struct df_scan_problem_data *problem_data
    = (struct df_scan_problem_data *) df_scan->problem_data;
  unsigned int i;
  unsigned int dist = 0;

  count = mw_vec->length ();
  if (count < 2)
    return;
  else if (count == 2)
    {
      struct df_mw_hardreg *m0 = (*mw_vec)[0];
      struct df_mw_hardreg *m1 = (*mw_vec)[1];
      if (df_mw_compare (m0, m1) > 0)
        {
          struct df_mw_hardreg *tmp = (*mw_vec)[0];
	  (*mw_vec)[0] = (*mw_vec)[1];
	  (*mw_vec)[1] = tmp;
        }
    }
  else
    mw_vec->qsort (df_mw_ptr_compare);

  for (i=0; i<count-dist; i++)
    {
      /* Find the next ref that is not equal to the current ref.  */
      while (i + dist + 1 < count
	     && df_mw_equal_p ((*mw_vec)[i], (*mw_vec)[i + dist + 1]))
	{
	  problem_data->mw_reg_pool->remove ((*mw_vec)[i + dist + 1]);
	  dist++;
	}
      /* Copy it down to the next position.  */
      if (dist && i + dist + 1 < count)
	(*mw_vec)[i + 1] = (*mw_vec)[i + dist + 1];
    }

  count -= dist;
  mw_vec->truncate (count);
}


/* Sort and remove duplicates from the COLLECTION_REC.  */

static void
df_canonize_collection_rec (class df_collection_rec *collection_rec)
{
  df_sort_and_compress_refs (&collection_rec->def_vec);
  df_sort_and_compress_refs (&collection_rec->use_vec);
  df_sort_and_compress_refs (&collection_rec->eq_use_vec);
  df_sort_and_compress_mws (&collection_rec->mw_vec);
}


/* Add the new df_ref to appropriate reg_info/ref_info chains.  */

static void
df_install_ref (df_ref this_ref,
		struct df_reg_info *reg_info,
		struct df_ref_info *ref_info,
		bool add_to_table)
{
  unsigned int regno = DF_REF_REGNO (this_ref);
  /* Add the ref to the reg_{def,use,eq_use} chain.  */
  df_ref head = reg_info->reg_chain;

  reg_info->reg_chain = this_ref;
  reg_info->n_refs++;

  if (DF_REF_FLAGS_IS_SET (this_ref, DF_HARD_REG_LIVE))
    {
      gcc_assert (regno < FIRST_PSEUDO_REGISTER);
      df->hard_regs_live_count[regno]++;
    }

  gcc_checking_assert (DF_REF_NEXT_REG (this_ref) == NULL
		       && DF_REF_PREV_REG (this_ref) == NULL);

  DF_REF_NEXT_REG (this_ref) = head;

  /* We cannot actually link to the head of the chain.  */
  DF_REF_PREV_REG (this_ref) = NULL;

  if (head)
    DF_REF_PREV_REG (head) = this_ref;

  if (add_to_table)
    {
      gcc_assert (ref_info->ref_order != DF_REF_ORDER_NO_TABLE);
      df_check_and_grow_ref_info (ref_info, 1);
      DF_REF_ID (this_ref) = ref_info->table_size;
      /* Add the ref to the big array of defs.  */
      ref_info->refs[ref_info->table_size] = this_ref;
      ref_info->table_size++;
    }
  else
    DF_REF_ID (this_ref) = -1;

  ref_info->total_size++;
}


/* This function takes one of the groups of refs (defs, uses or
   eq_uses) and installs the entire group into the insn.  It also adds
   each of these refs into the appropriate chains.  */

static df_ref
df_install_refs (basic_block bb,
		 const vec<df_ref, va_heap> *old_vec,
		 struct df_reg_info **reg_info,
		 struct df_ref_info *ref_info,
		 bool is_notes)
{
  unsigned int count = old_vec->length ();
  if (count)
    {
      bool add_to_table;
      df_ref this_ref;
      unsigned int ix;

      switch (ref_info->ref_order)
	{
	case DF_REF_ORDER_UNORDERED_WITH_NOTES:
	case DF_REF_ORDER_BY_REG_WITH_NOTES:
	case DF_REF_ORDER_BY_INSN_WITH_NOTES:
	  ref_info->ref_order = DF_REF_ORDER_UNORDERED_WITH_NOTES;
	  add_to_table = true;
	  break;
	case DF_REF_ORDER_UNORDERED:
	case DF_REF_ORDER_BY_REG:
	case DF_REF_ORDER_BY_INSN:
	  ref_info->ref_order = DF_REF_ORDER_UNORDERED;
	  add_to_table = !is_notes;
	  break;
	default:
	  add_to_table = false;
	  break;
	}

      /* Do not add if ref is not in the right blocks.  */
      if (add_to_table && df->analyze_subset)
	add_to_table = bitmap_bit_p (df->blocks_to_analyze, bb->index);

      FOR_EACH_VEC_ELT (*old_vec, ix, this_ref)
	{
	  DF_REF_NEXT_LOC (this_ref) = (ix + 1 < old_vec->length ()
					? (*old_vec)[ix + 1]
					: NULL);
	  df_install_ref (this_ref, reg_info[DF_REF_REGNO (this_ref)],
			  ref_info, add_to_table);
	}
      return (*old_vec)[0];
    }
  else
    return 0;
}


/* This function takes the mws installs the entire group into the
   insn.  */

static struct df_mw_hardreg *
df_install_mws (const vec<df_mw_hardreg *, va_heap> *old_vec)
{
  unsigned int count = old_vec->length ();
  if (count)
    {
      for (unsigned int i = 0; i < count - 1; i++)
	DF_MWS_NEXT ((*old_vec)[i]) = (*old_vec)[i + 1];
      DF_MWS_NEXT ((*old_vec)[count - 1]) = 0;
      return (*old_vec)[0];
    }
  else
    return 0;
}


/* Add a chain of df_refs to appropriate ref chain/reg_info/ref_info
   chains and update other necessary information.  */

static void
df_refs_add_to_chains (class df_collection_rec *collection_rec,
		       basic_block bb, rtx_insn *insn, unsigned int flags)
{
  if (insn)
    {
      struct df_insn_info *insn_rec = DF_INSN_INFO_GET (insn);
      /* If there is a vector in the collection rec, add it to the
	 insn.  A null rec is a signal that the caller will handle the
	 chain specially.  */
      if (flags & copy_defs)
	{
	  gcc_checking_assert (!insn_rec->defs);
	  insn_rec->defs
	    = df_install_refs (bb, &collection_rec->def_vec,
			       df->def_regs,
			       &df->def_info, false);
	}
      if (flags & copy_uses)
	{
	  gcc_checking_assert (!insn_rec->uses);
	  insn_rec->uses
	    = df_install_refs (bb, &collection_rec->use_vec,
			       df->use_regs,
			       &df->use_info, false);
	}
      if (flags & copy_eq_uses)
	{
	  gcc_checking_assert (!insn_rec->eq_uses);
	  insn_rec->eq_uses
	    = df_install_refs (bb, &collection_rec->eq_use_vec,
			       df->eq_use_regs,
			       &df->use_info, true);
	}
      if (flags & copy_mw)
	{
	  gcc_checking_assert (!insn_rec->mw_hardregs);
	  insn_rec->mw_hardregs
	    = df_install_mws (&collection_rec->mw_vec);
	}
    }
  else
    {
      struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index);

      gcc_checking_assert (!bb_info->artificial_defs);
      bb_info->artificial_defs
	= df_install_refs (bb, &collection_rec->def_vec,
			   df->def_regs,
			   &df->def_info, false);
      gcc_checking_assert (!bb_info->artificial_uses);
      bb_info->artificial_uses
	= df_install_refs (bb, &collection_rec->use_vec,
			   df->use_regs,
			   &df->use_info, false);
    }
}


/* Allocate a ref and initialize its fields.  */

static df_ref
df_ref_create_structure (enum df_ref_class cl,
			 class df_collection_rec *collection_rec,
			 rtx reg, rtx *loc,
			 basic_block bb, struct df_insn_info *info,
			 enum df_ref_type ref_type,
			 int ref_flags)
{
  df_ref this_ref = NULL;
  unsigned int regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
  struct df_scan_problem_data *problem_data
    = (struct df_scan_problem_data *) df_scan->problem_data;

  switch (cl)
    {
    case DF_REF_BASE:
      this_ref = (df_ref) (problem_data->ref_base_pool->allocate ());
      gcc_checking_assert (loc == NULL);
      break;

    case DF_REF_ARTIFICIAL:
      this_ref = (df_ref) (problem_data->ref_artificial_pool->allocate ());
      this_ref->artificial_ref.bb = bb;
      gcc_checking_assert (loc == NULL);
      break;

    case DF_REF_REGULAR:
      this_ref = (df_ref) (problem_data->ref_regular_pool->allocate ());
      this_ref->regular_ref.loc = loc;
      gcc_checking_assert (loc);
      break;
    }

  DF_REF_CLASS (this_ref) = cl;
  DF_REF_ID (this_ref) = -1;
  DF_REF_REG (this_ref) = reg;
  DF_REF_REGNO (this_ref) =  regno;
  DF_REF_TYPE (this_ref) = ref_type;
  DF_REF_INSN_INFO (this_ref) = info;
  DF_REF_CHAIN (this_ref) = NULL;
  DF_REF_FLAGS (this_ref) = ref_flags;
  DF_REF_NEXT_REG (this_ref) = NULL;
  DF_REF_PREV_REG (this_ref) = NULL;
  DF_REF_ORDER (this_ref) = df->ref_order++;

  /* We need to clear this bit because fwprop, and in the future
     possibly other optimizations sometimes create new refs using ond
     refs as the model.  */
  DF_REF_FLAGS_CLEAR (this_ref, DF_HARD_REG_LIVE);

  /* See if this ref needs to have DF_HARD_REG_LIVE bit set.  */
  if (regno < FIRST_PSEUDO_REGISTER
      && !DF_REF_IS_ARTIFICIAL (this_ref)
      && !DEBUG_INSN_P (DF_REF_INSN (this_ref)))
    {
      if (DF_REF_REG_DEF_P (this_ref))
	{
	  if (!DF_REF_FLAGS_IS_SET (this_ref, DF_REF_MAY_CLOBBER))
	    DF_REF_FLAGS_SET (this_ref, DF_HARD_REG_LIVE);
	}
      else if (!(TEST_HARD_REG_BIT (elim_reg_set, regno)
		 && (regno == FRAME_POINTER_REGNUM
		     || regno == ARG_POINTER_REGNUM)))
	DF_REF_FLAGS_SET (this_ref, DF_HARD_REG_LIVE);
    }

  if (collection_rec)
    {
      if (DF_REF_REG_DEF_P (this_ref))
	collection_rec->def_vec.safe_push (this_ref);
      else if (DF_REF_FLAGS (this_ref) & DF_REF_IN_NOTE)
	collection_rec->eq_use_vec.safe_push (this_ref);
      else
	collection_rec->use_vec.safe_push (this_ref);
    }
  else
    df_install_ref_incremental (this_ref);

  return this_ref;
}


/* Create new references of type DF_REF_TYPE for each part of register REG
   at address LOC within INSN of BB.  */


static void
df_ref_record (enum df_ref_class cl,
	       class df_collection_rec *collection_rec,
               rtx reg, rtx *loc,
	       basic_block bb, struct df_insn_info *insn_info,
	       enum df_ref_type ref_type,
	       int ref_flags)
{
  unsigned int regno;

  gcc_checking_assert (REG_P (reg) || GET_CODE (reg) == SUBREG);

  regno = REGNO (GET_CODE (reg) == SUBREG ? SUBREG_REG (reg) : reg);
  if (regno < FIRST_PSEUDO_REGISTER)
    {
      struct df_mw_hardreg *hardreg = NULL;
      struct df_scan_problem_data *problem_data
        = (struct df_scan_problem_data *) df_scan->problem_data;
      unsigned int i;
      unsigned int endregno;
      df_ref ref;

      if (GET_CODE (reg) == SUBREG)
	{
	  int off = subreg_regno_offset (regno, GET_MODE (SUBREG_REG (reg)),
					 SUBREG_BYTE (reg), GET_MODE (reg));
	  unsigned int nregno = regno + off;
	  endregno = nregno + subreg_nregs (reg);
	  if (off < 0 && regno < (unsigned) -off)
	    /* Deal with paradoxical SUBREGs on big endian where
	       in debug insns the hard reg number might be smaller
	       than -off, such as (subreg:DI (reg:SI 0 [+4 ]) 0));
	       RA decisions shouldn't be affected by debug insns
	       and so RA can decide to put pseudo into a hard reg
	       with small REGNO, even when it is referenced in
	       a paradoxical SUBREG in a debug insn.  */
	    regno = 0;
	  else
	    regno = nregno;
	}
      else
	endregno = END_REGNO (reg);

      /*  If this is a multiword hardreg, we create some extra
	  datastructures that will enable us to easily build REG_DEAD
	  and REG_UNUSED notes.  */
      if (collection_rec
	  && (endregno != regno + 1) && insn_info)
	{
	  /* Sets to a subreg of a multiword register are partial.
	     Sets to a non-subreg of a multiword register are not.  */
	  if (GET_CODE (reg) == SUBREG)
	    ref_flags |= DF_REF_PARTIAL;
	  ref_flags |= DF_REF_MW_HARDREG;

	  gcc_assert (regno < endregno);

	  hardreg = problem_data->mw_reg_pool->allocate ();
	  hardreg->type = ref_type;
	  hardreg->flags = ref_flags;
	  hardreg->mw_reg = reg;
	  hardreg->start_regno = regno;
	  hardreg->end_regno = endregno - 1;
	  hardreg->mw_order = df->ref_order++;
	  collection_rec->mw_vec.safe_push (hardreg);
	}

      for (i = regno; i < endregno; i++)
	{
	  ref = df_ref_create_structure (cl, collection_rec, regno_reg_rtx[i], loc,
					 bb, insn_info, ref_type, ref_flags);

          gcc_assert (ORIGINAL_REGNO (DF_REF_REG (ref)) == i);
	}
    }
  else
    {
      df_ref_create_structure (cl, collection_rec, reg, loc, bb, insn_info,
			       ref_type, ref_flags);
    }
}


/* Process all the registers defined in the rtx pointed by LOC.
   Autoincrement/decrement definitions will be picked up by df_uses_record.
   Any change here has to be matched in df_find_hard_reg_defs_1.  */

static void
df_def_record_1 (class df_collection_rec *collection_rec,
                 rtx *loc, basic_block bb, struct df_insn_info *insn_info,
		 int flags)
{
  rtx dst = *loc;

  /* It is legal to have a set destination be a parallel. */
  if (GET_CODE (dst) == PARALLEL)
    {
      int i;
      for (i = XVECLEN (dst, 0) - 1; i >= 0; i--)
	{
	  rtx temp = XVECEXP (dst, 0, i);
	  gcc_assert (GET_CODE (temp) == EXPR_LIST);
	  df_def_record_1 (collection_rec, &XEXP (temp, 0),
			   bb, insn_info, flags);
	}
      return;
    }

  if (GET_CODE (dst) == STRICT_LOW_PART)
    {
      flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL | DF_REF_STRICT_LOW_PART;

      loc = &XEXP (dst, 0);
      dst = *loc;
    }

  if (GET_CODE (dst) == ZERO_EXTRACT)
    {
      flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL | DF_REF_ZERO_EXTRACT;

      loc = &XEXP (dst, 0);
      dst = *loc;
    }

  /* At this point if we do not have a reg or a subreg, just return.  */
  if (REG_P (dst))
    {
      df_ref_record (DF_REF_REGULAR, collection_rec,
		     dst, loc, bb, insn_info, DF_REF_REG_DEF, flags);

      /* We want to keep sp alive everywhere - by making all
	 writes to sp also use of sp. */
      if (REGNO (dst) == STACK_POINTER_REGNUM)
	df_ref_record (DF_REF_BASE, collection_rec,
		       dst, NULL, bb, insn_info, DF_REF_REG_USE, flags);
    }
  else if (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst)))
    {
      if (read_modify_subreg_p (dst))
	flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL;

      flags |= DF_REF_SUBREG;

      df_ref_record (DF_REF_REGULAR, collection_rec,
		     dst, loc, bb, insn_info, DF_REF_REG_DEF, flags);
    }
}


/* Process all the registers defined in the pattern rtx, X.  Any change
   here has to be matched in df_find_hard_reg_defs.  */

static void
df_defs_record (class df_collection_rec *collection_rec,
                rtx x, basic_block bb, struct df_insn_info *insn_info,
		int flags)
{
  RTX_CODE code = GET_CODE (x);
  int i;

  switch (code)
    {
    case SET:
      df_def_record_1 (collection_rec, &SET_DEST (x), bb, insn_info, flags);
      break;

    case CLOBBER:
      flags |= DF_REF_MUST_CLOBBER;
      df_def_record_1 (collection_rec, &XEXP (x, 0), bb, insn_info, flags);
      break;

    case COND_EXEC:
      df_defs_record (collection_rec, COND_EXEC_CODE (x),
		      bb, insn_info, DF_REF_CONDITIONAL);
      break;

    case PARALLEL:
      for (i = 0; i < XVECLEN (x, 0); i++)
	df_defs_record (collection_rec, XVECEXP (x, 0, i),
			bb, insn_info, flags);
      break;
    default:
      /* No DEFs to record in other cases */
      break;
    }
}

/* Set bits in *DEFS for hard registers found in the rtx DST, which is the
   destination of a set or clobber.  This has to match the logic in
   df_defs_record_1.  */

static void
df_find_hard_reg_defs_1 (rtx dst, HARD_REG_SET *defs)
{
  /* It is legal to have a set destination be a parallel. */
  if (GET_CODE (dst) == PARALLEL)
    {
      int i;
      for (i = XVECLEN (dst, 0) - 1; i >= 0; i--)
	{
	  rtx temp = XVECEXP (dst, 0, i);
	  gcc_assert (GET_CODE (temp) == EXPR_LIST);
	  df_find_hard_reg_defs_1 (XEXP (temp, 0), defs);
	}
      return;
    }

  if (GET_CODE (dst) == STRICT_LOW_PART)
      dst = XEXP (dst, 0);

  if (GET_CODE (dst) == ZERO_EXTRACT)
      dst = XEXP (dst, 0);

  /* At this point if we do not have a reg or a subreg, just return.  */
  if (REG_P (dst) && HARD_REGISTER_P (dst))
    SET_HARD_REG_BIT (*defs, REGNO (dst));
  else if (GET_CODE (dst) == SUBREG
	   && REG_P (SUBREG_REG (dst)) && HARD_REGISTER_P (dst))
    SET_HARD_REG_BIT (*defs, REGNO (SUBREG_REG (dst)));
}

/* Set bits in *DEFS for hard registers defined in the pattern X.  This
   has to match the logic in df_defs_record.  */

static void
df_find_hard_reg_defs (rtx x, HARD_REG_SET *defs)
{
  RTX_CODE code = GET_CODE (x);
  int i;

  switch (code)
    {
    case SET:
      df_find_hard_reg_defs_1 (SET_DEST (x), defs);
      break;

    case CLOBBER:
      df_find_hard_reg_defs_1 (XEXP (x, 0), defs);
      break;

    case COND_EXEC:
      df_find_hard_reg_defs (COND_EXEC_CODE (x), defs);
      break;

    case PARALLEL:
      for (i = 0; i < XVECLEN (x, 0); i++)
	df_find_hard_reg_defs (XVECEXP (x, 0, i), defs);
      break;
    default:
      /* No DEFs to record in other cases */
      break;
    }
}


/* Process all the registers used in the rtx at address LOC.  */

static void
df_uses_record (class df_collection_rec *collection_rec,
                rtx *loc, enum df_ref_type ref_type,
		basic_block bb, struct df_insn_info *insn_info,
		int flags)
{
  RTX_CODE code;
  rtx x;

 retry:
  x = *loc;
  if (!x)
    return;
  code = GET_CODE (x);
  switch (code)
    {
    case LABEL_REF:
    case SYMBOL_REF:
    case CONST:
    CASE_CONST_ANY:
    case PC:
    case ADDR_VEC:
    case ADDR_DIFF_VEC:
      return;

    case CLOBBER:
      /* If we are clobbering a MEM, mark any registers inside the address
	 as being used.  */
      if (MEM_P (XEXP (x, 0)))
	df_uses_record (collection_rec,
			&XEXP (XEXP (x, 0), 0),
			DF_REF_REG_MEM_STORE,
		        bb, insn_info,
			flags);

      /* If we're clobbering a REG then we have a def so ignore.  */
      return;

    case MEM:
      df_uses_record (collection_rec,
		      &XEXP (x, 0), DF_REF_REG_MEM_LOAD,
		      bb, insn_info, flags & DF_REF_IN_NOTE);
      return;

    case SUBREG:
      /* While we're here, optimize this case.  */
      flags |= DF_REF_PARTIAL;
      /* In case the SUBREG is not of a REG, do not optimize.  */
      if (!REG_P (SUBREG_REG (x)))
	{
	  loc = &SUBREG_REG (x);
	  df_uses_record (collection_rec, loc, ref_type, bb, insn_info, flags);
	  return;
	}
      /* Fall through */

    case REG:
      df_ref_record (DF_REF_REGULAR, collection_rec,
		     x, loc, bb, insn_info,
		     ref_type, flags);
      return;

    case SIGN_EXTRACT:
    case ZERO_EXTRACT:
      {
        df_uses_record (collection_rec,
                        &XEXP (x, 1), ref_type, bb, insn_info, flags);
        df_uses_record (collection_rec,
                        &XEXP (x, 2), ref_type, bb, insn_info, flags);

        /* If the parameters to the zero or sign extract are
           constants, strip them off and recurse, otherwise there is
           no information that we can gain from this operation.  */
        if (code == ZERO_EXTRACT)
          flags |= DF_REF_ZERO_EXTRACT;
        else
          flags |= DF_REF_SIGN_EXTRACT;

        df_uses_record (collection_rec,
                        &XEXP (x, 0), ref_type, bb, insn_info, flags);
        return;
      }
      break;

    case SET:
      {
	rtx dst = SET_DEST (x);
	gcc_assert (!(flags & DF_REF_IN_NOTE));
	df_uses_record (collection_rec,
			&SET_SRC (x), DF_REF_REG_USE, bb, insn_info, flags);

	switch (GET_CODE (dst))
	  {
	    case SUBREG:
	      if (read_modify_subreg_p (dst))
		{
		  df_uses_record (collection_rec, &SUBREG_REG (dst),
				  DF_REF_REG_USE, bb, insn_info,
				  flags | DF_REF_READ_WRITE | DF_REF_SUBREG);
		  break;
		}
	      /* Fall through.  */
	    case REG:
	    case PARALLEL:
	    case SCRATCH:
	    case PC:
		break;
	    case MEM:
	      df_uses_record (collection_rec, &XEXP (dst, 0),
			      DF_REF_REG_MEM_STORE, bb, insn_info, flags);
	      break;
	    case STRICT_LOW_PART:
	      {
		rtx *temp = &XEXP (dst, 0);
		/* A strict_low_part uses the whole REG and not just the
		 SUBREG.  */
		dst = XEXP (dst, 0);
		df_uses_record (collection_rec,
				(GET_CODE (dst) == SUBREG) ? &SUBREG_REG (dst) : temp,
				DF_REF_REG_USE, bb, insn_info,
				DF_REF_READ_WRITE | DF_REF_STRICT_LOW_PART);
	      }
	      break;
	    case ZERO_EXTRACT:
	      {
		df_uses_record (collection_rec, &XEXP (dst, 1),
				DF_REF_REG_USE, bb, insn_info, flags);
		df_uses_record (collection_rec, &XEXP (dst, 2),
				DF_REF_REG_USE, bb, insn_info, flags);
                if (GET_CODE (XEXP (dst,0)) == MEM)
                  df_uses_record (collection_rec, &XEXP (dst, 0),
                                  DF_REF_REG_USE, bb, insn_info,
                                  flags);
                else
                  df_uses_record (collection_rec, &XEXP (dst, 0),
                                  DF_REF_REG_USE, bb, insn_info,
                                  DF_REF_READ_WRITE | DF_REF_ZERO_EXTRACT);
	      }
	      break;

	    default:
	      gcc_unreachable ();
	  }
	return;
      }

    case RETURN:
    case SIMPLE_RETURN:
      break;

    case ASM_OPERANDS:
    case UNSPEC_VOLATILE:
    case TRAP_IF:
    case ASM_INPUT:
      {
	/* Traditional and volatile asm instructions must be
	   considered to use and clobber all hard registers, all
	   pseudo-registers and all of memory.  So must TRAP_IF and
	   UNSPEC_VOLATILE operations.

	   Consider for instance a volatile asm that changes the fpu
	   rounding mode.  An insn should not be moved across this
	   even if it only uses pseudo-regs because it might give an
	   incorrectly rounded result.

	   However, flow.c's liveness computation did *not* do this,
	   giving the reasoning as " ?!? Unfortunately, marking all
	   hard registers as live causes massive problems for the
	   register allocator and marking all pseudos as live creates
	   mountains of uninitialized variable warnings."

	   In order to maintain the status quo with regard to liveness
	   and uses, we do what flow.c did and just mark any regs we
	   can find in ASM_OPERANDS as used.  In global asm insns are
	   scanned and regs_asm_clobbered is filled out.

	   For all ASM_OPERANDS, we must traverse the vector of input
	   operands.  We cannot just fall through here since then we
	   would be confused by the ASM_INPUT rtx inside ASM_OPERANDS,
	   which do not indicate traditional asms unlike their normal
	   usage.  */
	if (code == ASM_OPERANDS)
	  {
	    int j;

	    for (j = 0; j < ASM_OPERANDS_INPUT_LENGTH (x); j++)
	      df_uses_record (collection_rec, &ASM_OPERANDS_INPUT (x, j),
			      DF_REF_REG_USE, bb, insn_info, flags);
	    return;
	  }
	break;
      }

    case VAR_LOCATION:
      df_uses_record (collection_rec,
		      &PAT_VAR_LOCATION_LOC (x),
		      DF_REF_REG_USE, bb, insn_info, flags);
      return;

    case PRE_DEC:
    case POST_DEC:
    case PRE_INC:
    case POST_INC:
    case PRE_MODIFY:
    case POST_MODIFY:
      gcc_assert (!DEBUG_INSN_P (insn_info->insn));
      /* Catch the def of the register being modified.  */
      df_ref_record (DF_REF_REGULAR, collection_rec, XEXP (x, 0), &XEXP (x, 0),
		     bb, insn_info,
		     DF_REF_REG_DEF,
                     flags | DF_REF_READ_WRITE | DF_REF_PRE_POST_MODIFY);

      /* ... Fall through to handle uses ...  */

    default:
      break;
    }

  /* Recursively scan the operands of this expression.  */
  {
    const char *fmt = GET_RTX_FORMAT (code);
    int i;

    for (i = GET_RTX_LENGTH (code) - 1; i >= 0; i--)
      {
	if (fmt[i] == 'e')
	  {
	    /* Tail recursive case: save a function call level.  */
	    if (i == 0)
	      {
		loc = &XEXP (x, 0);
		goto retry;
	      }
	    df_uses_record (collection_rec, &XEXP (x, i), ref_type,
			    bb, insn_info, flags);
	  }
	else if (fmt[i] == 'E')
	  {
	    int j;
	    for (j = 0; j < XVECLEN (x, i); j++)
	      df_uses_record (collection_rec,
			      &XVECEXP (x, i, j), ref_type,
			      bb, insn_info, flags);
	  }
      }
  }

  return;
}


/* For all DF_REF_CONDITIONAL defs, add a corresponding uses.  */

static void
df_get_conditional_uses (class df_collection_rec *collection_rec)
{
  unsigned int ix;
  df_ref ref;

  FOR_EACH_VEC_ELT (collection_rec->def_vec, ix, ref)
    {
      if (DF_REF_FLAGS_IS_SET (ref, DF_REF_CONDITIONAL))
        {
          df_ref use;

          use = df_ref_create_structure (DF_REF_CLASS (ref), collection_rec, DF_REF_REG (ref),
					 DF_REF_LOC (ref), DF_REF_BB (ref),
					 DF_REF_INSN_INFO (ref), DF_REF_REG_USE,
					 DF_REF_FLAGS (ref) & ~DF_REF_CONDITIONAL);
          DF_REF_REGNO (use) = DF_REF_REGNO (ref);
        }
    }
}


/* Get call's extra defs and uses (track caller-saved registers). */

static void
df_get_call_refs (class df_collection_rec *collection_rec,
                  basic_block bb,
                  struct df_insn_info *insn_info,
                  int flags)
{
  rtx note;
  bool is_sibling_call;
  unsigned int i;
  HARD_REG_SET defs_generated;

  CLEAR_HARD_REG_SET (defs_generated);
  df_find_hard_reg_defs (PATTERN (insn_info->insn), &defs_generated);
  is_sibling_call = SIBLING_CALL_P (insn_info->insn);
  function_abi callee_abi = insn_callee_abi (insn_info->insn);

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      if (i == STACK_POINTER_REGNUM
	  && !FAKE_CALL_P (insn_info->insn))
	/* The stack ptr is used (honorarily) by a CALL insn.  */
	df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
		       NULL, bb, insn_info, DF_REF_REG_USE,
		       DF_REF_CALL_STACK_USAGE | flags);
      else if (global_regs[i])
	{
	  /* Calls to const functions cannot access any global registers and
	     calls to pure functions cannot set them.  All other calls may
	     reference any of the global registers, so they are recorded as
	     used. */
	  if (!RTL_CONST_CALL_P (insn_info->insn))
	    {
	      df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
			     NULL, bb, insn_info, DF_REF_REG_USE, flags);
	      if (!RTL_PURE_CALL_P (insn_info->insn))
		df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
			       NULL, bb, insn_info, DF_REF_REG_DEF, flags);
	    }
	}
      else if (callee_abi.clobbers_full_reg_p (i)
	       /* no clobbers for regs that are the result of the call */
	       && !TEST_HARD_REG_BIT (defs_generated, i)
	       && (!is_sibling_call
		   || !bitmap_bit_p (df->exit_block_uses, i)
		   || refers_to_regno_p (i, crtl->return_rtx)))
	  df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
			 NULL, bb, insn_info, DF_REF_REG_DEF,
			 DF_REF_MAY_CLOBBER | flags);
    }

  /* Record the registers used to pass arguments, and explicitly
     noted as clobbered.  */
  for (note = CALL_INSN_FUNCTION_USAGE (insn_info->insn); note;
       note = XEXP (note, 1))
    {
      if (GET_CODE (XEXP (note, 0)) == USE)
        df_uses_record (collection_rec, &XEXP (XEXP (note, 0), 0),
			DF_REF_REG_USE, bb, insn_info, flags);
      else if (GET_CODE (XEXP (note, 0)) == CLOBBER)
	{
	  if (REG_P (XEXP (XEXP (note, 0), 0)))
	    {
	      unsigned int regno = REGNO (XEXP (XEXP (note, 0), 0));
	      if (!TEST_HARD_REG_BIT (defs_generated, regno))
		df_defs_record (collection_rec, XEXP (note, 0), bb,
				insn_info, flags);
	    }
	  else
	    df_uses_record (collection_rec, &XEXP (note, 0),
		            DF_REF_REG_USE, bb, insn_info, flags);
	}
    }

  return;
}

/* Collect all refs in the INSN. This function is free of any
   side-effect - it will create and return a lists of df_ref's in the
   COLLECTION_REC without putting those refs into existing ref chains
   and reg chains. */

static void
df_insn_refs_collect (class df_collection_rec *collection_rec,
		      basic_block bb, struct df_insn_info *insn_info)
{
  rtx note;
  bool is_cond_exec = (GET_CODE (PATTERN (insn_info->insn)) == COND_EXEC);

  /* Clear out the collection record.  */
  collection_rec->def_vec.truncate (0);
  collection_rec->use_vec.truncate (0);
  collection_rec->eq_use_vec.truncate (0);
  collection_rec->mw_vec.truncate (0);

  /* Process REG_EQUIV/REG_EQUAL notes.  */
  for (note = REG_NOTES (insn_info->insn); note;
       note = XEXP (note, 1))
    {
      switch (REG_NOTE_KIND (note))
        {
        case REG_EQUIV:
        case REG_EQUAL:
          df_uses_record (collection_rec,
                          &XEXP (note, 0), DF_REF_REG_USE,
                          bb, insn_info, DF_REF_IN_NOTE);
          break;
        case REG_NON_LOCAL_GOTO:
          /* The frame ptr is used by a non-local goto.  */
          df_ref_record (DF_REF_BASE, collection_rec,
                         regno_reg_rtx[FRAME_POINTER_REGNUM],
                         NULL, bb, insn_info,
                         DF_REF_REG_USE, 0);
	  if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
	    df_ref_record (DF_REF_BASE, collection_rec,
			   regno_reg_rtx[HARD_FRAME_POINTER_REGNUM],
			   NULL, bb, insn_info,
			   DF_REF_REG_USE, 0);
          break;
        default:
          break;
        }
    }

  int flags = (is_cond_exec) ? DF_REF_CONDITIONAL : 0;
  /* For CALL_INSNs, first record DF_REF_BASE register defs, as well as
     uses from CALL_INSN_FUNCTION_USAGE. */
  if (CALL_P (insn_info->insn))
    df_get_call_refs (collection_rec, bb, insn_info, flags);

  /* Record other defs.  These should be mostly for DF_REF_REGULAR, so
     that a qsort on the defs is unnecessary in most cases.  */
  df_defs_record (collection_rec,
		  PATTERN (insn_info->insn), bb, insn_info, 0);

  /* Record the register uses.  */
  df_uses_record (collection_rec,
		  &PATTERN (insn_info->insn), DF_REF_REG_USE, bb, insn_info, 0);

  /* DF_REF_CONDITIONAL needs corresponding USES. */
  if (is_cond_exec)
    df_get_conditional_uses (collection_rec);

  df_canonize_collection_rec (collection_rec);
}

/* Recompute the luids for the insns in BB.  */

void
df_recompute_luids (basic_block bb)
{
  rtx_insn *insn;
  int luid = 0;

  df_grow_insn_info ();

  /* Scan the block an insn at a time from beginning to end.  */
  FOR_BB_INSNS (bb, insn)
    {
      struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
      /* Inserting labels does not always trigger the incremental
	 rescanning.  */
      if (!insn_info)
	{
	  gcc_assert (!INSN_P (insn));
	  insn_info = df_insn_create_insn_record (insn);
	}

      DF_INSN_INFO_LUID (insn_info) = luid;
      if (INSN_P (insn))
	luid++;
    }
}


/* Collect all artificial refs at the block level for BB and add them
   to COLLECTION_REC.  */

static void
df_bb_refs_collect (class df_collection_rec *collection_rec, basic_block bb)
{
  collection_rec->def_vec.truncate (0);
  collection_rec->use_vec.truncate (0);
  collection_rec->eq_use_vec.truncate (0);
  collection_rec->mw_vec.truncate (0);

  if (bb->index == ENTRY_BLOCK)
    {
      df_entry_block_defs_collect (collection_rec, df->entry_block_defs);
      return;
    }
  else if (bb->index == EXIT_BLOCK)
    {
      df_exit_block_uses_collect (collection_rec, df->exit_block_uses);
      return;
    }

  if (bb_has_eh_pred (bb))
    {
      unsigned int i;
      /* Mark the registers that will contain data for the handler.  */
      for (i = 0; ; ++i)
	{
	  unsigned regno = EH_RETURN_DATA_REGNO (i);
	  if (regno == INVALID_REGNUM)
	    break;
	  df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[regno], NULL,
			 bb, NULL, DF_REF_REG_DEF, DF_REF_AT_TOP);
	}
    }

  /* Add the hard_frame_pointer if this block is the target of a
     non-local goto.  */
  if (bb->flags & BB_NON_LOCAL_GOTO_TARGET)
    df_ref_record (DF_REF_ARTIFICIAL, collection_rec, hard_frame_pointer_rtx, NULL,
		   bb, NULL, DF_REF_REG_DEF, DF_REF_AT_TOP);

  /* Add the artificial uses.  */
  if (bb->index >= NUM_FIXED_BLOCKS)
    {
      bitmap_iterator bi;
      unsigned int regno;
      bitmap au = bb_has_eh_pred (bb)
	? &df->eh_block_artificial_uses
	: &df->regular_block_artificial_uses;

      EXECUTE_IF_SET_IN_BITMAP (au, 0, regno, bi)
	{
	  df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[regno], NULL,
			 bb, NULL, DF_REF_REG_USE, 0);
	}
    }

  df_canonize_collection_rec (collection_rec);
}


/* Record all the refs within the basic block BB_INDEX and scan the instructions if SCAN_INSNS.  */

void
df_bb_refs_record (int bb_index, bool scan_insns)
{
  basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
  rtx_insn *insn;
  int luid = 0;

  if (!df)
    return;

  df_collection_rec collection_rec;
  df_grow_bb_info (df_scan);
  if (scan_insns)
    /* Scan the block an insn at a time from beginning to end.  */
    FOR_BB_INSNS (bb, insn)
      {
	struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
	gcc_assert (!insn_info);

	insn_info = df_insn_create_insn_record (insn);
	if (INSN_P (insn))
	  {
	    /* Record refs within INSN.  */
	    DF_INSN_INFO_LUID (insn_info) = luid++;
	    df_insn_refs_collect (&collection_rec, bb, DF_INSN_INFO_GET (insn));
	    df_refs_add_to_chains (&collection_rec, bb, insn, copy_all);
	  }
	DF_INSN_INFO_LUID (insn_info) = luid;
      }

  /* Other block level artificial refs */
  df_bb_refs_collect (&collection_rec, bb);
  df_refs_add_to_chains (&collection_rec, bb, NULL, copy_all);

  /* Now that the block has been processed, set the block as dirty so
     LR and LIVE will get it processed.  */
  df_set_bb_dirty (bb);
}


/* Get the artificial use set for a regular (i.e. non-exit/non-entry)
   block. */

static void
df_get_regular_block_artificial_uses (bitmap regular_block_artificial_uses)
{
#ifdef EH_USES
  unsigned int i;
#endif

  bitmap_clear (regular_block_artificial_uses);

  if (reload_completed)
    {
      if (frame_pointer_needed)
	bitmap_set_bit (regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM);
    }
  else
    /* Before reload, there are a few registers that must be forced
       live everywhere -- which might not already be the case for
       blocks within infinite loops.  */
    {
      unsigned int picreg = PIC_OFFSET_TABLE_REGNUM;

      /* Any reference to any pseudo before reload is a potential
	 reference of the frame pointer.  */
      bitmap_set_bit (regular_block_artificial_uses, FRAME_POINTER_REGNUM);

      if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
	bitmap_set_bit (regular_block_artificial_uses,
			HARD_FRAME_POINTER_REGNUM);

      /* Pseudos with argument area equivalences may require
	 reloading via the argument pointer.  */
      if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
	  && fixed_regs[ARG_POINTER_REGNUM])
	bitmap_set_bit (regular_block_artificial_uses, ARG_POINTER_REGNUM);

      /* Any constant, or pseudo with constant equivalences, may
	 require reloading from memory using the pic register.  */
      if (picreg != INVALID_REGNUM
	  && fixed_regs[picreg])
	bitmap_set_bit (regular_block_artificial_uses, picreg);
    }
  /* The all-important stack pointer must always be live.  */
  bitmap_set_bit (regular_block_artificial_uses, STACK_POINTER_REGNUM);

#ifdef EH_USES
  /* EH_USES registers are used:
     1) at all insns that might throw (calls or with -fnon-call-exceptions
	trapping insns)
     2) in all EH edges
     3) to support backtraces and/or debugging, anywhere between their
	initialization and where they the saved registers are restored
	from them, including the cases where we don't reach the epilogue
	(noreturn call or infinite loop).  */
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (EH_USES (i))
      bitmap_set_bit (regular_block_artificial_uses, i);
#endif
}


/* Get the artificial use set for an eh block. */

static void
df_get_eh_block_artificial_uses (bitmap eh_block_artificial_uses)
{
  bitmap_clear (eh_block_artificial_uses);

  /* The following code (down through the arg_pointer setting APPEARS
     to be necessary because there is nothing that actually
     describes what the exception handling code may actually need
     to keep alive.  */
  if (reload_completed)
    {
      if (frame_pointer_needed)
	{
	  bitmap_set_bit (eh_block_artificial_uses, FRAME_POINTER_REGNUM);
	  if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
	    bitmap_set_bit (eh_block_artificial_uses,
			    HARD_FRAME_POINTER_REGNUM);
	}
      if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
	  && fixed_regs[ARG_POINTER_REGNUM])
	bitmap_set_bit (eh_block_artificial_uses, ARG_POINTER_REGNUM);
    }
}



/*----------------------------------------------------------------------------
   Specialized hard register scanning functions.
----------------------------------------------------------------------------*/


/* Mark a register in SET.  Hard registers in large modes get all
   of their component registers set as well.  */

static void
df_mark_reg (rtx reg, void *vset)
{
  bitmap_set_range ((bitmap) vset, REGNO (reg), REG_NREGS (reg));
}


/* Set the bit for regs that are considered being defined at the entry. */

static void
df_get_entry_block_def_set (bitmap entry_block_defs)
{
  rtx r;
  int i;

  bitmap_clear (entry_block_defs);

  /* For separate shrink-wrapping we use LIVE to analyze which basic blocks
     need a prologue for some component to be executed before that block,
     and we do not care about any other registers.  Hence, we do not want
     any register for any component defined in the entry block, and we can
     just leave all registers undefined.  */
  if (df_scan->local_flags & DF_SCAN_EMPTY_ENTRY_EXIT)
    return;

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      if (global_regs[i])
	bitmap_set_bit (entry_block_defs, i);
      if (FUNCTION_ARG_REGNO_P (i))
	bitmap_set_bit (entry_block_defs, INCOMING_REGNO (i));
    }

  /* The always important stack pointer.  */
  bitmap_set_bit (entry_block_defs, STACK_POINTER_REGNUM);

  /* Once the prologue has been generated, all of these registers
     should just show up in the first regular block.  */
  if (targetm.have_prologue () && epilogue_completed)
    {
      /* Defs for the callee saved registers are inserted so that the
	 pushes have some defining location.  */
      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	if (!crtl->abi->clobbers_full_reg_p (i)
	    && !fixed_regs[i]
	    && df_regs_ever_live_p (i))
	  bitmap_set_bit (entry_block_defs, i);
    }

  r = targetm.calls.struct_value_rtx (current_function_decl, true);
  if (r && REG_P (r))
    bitmap_set_bit (entry_block_defs, REGNO (r));

  /* If the function has an incoming STATIC_CHAIN, it has to show up
     in the entry def set.  */
  r = rtx_for_static_chain (current_function_decl, true);
  if (r && REG_P (r))
    bitmap_set_bit (entry_block_defs, REGNO (r));

  if ((!reload_completed) || frame_pointer_needed)
    {
      /* Any reference to any pseudo before reload is a potential
	 reference of the frame pointer.  */
      bitmap_set_bit (entry_block_defs, FRAME_POINTER_REGNUM);

      /* If they are different, also mark the hard frame pointer as live.  */
      if (!HARD_FRAME_POINTER_IS_FRAME_POINTER
	  && !LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
	bitmap_set_bit (entry_block_defs, HARD_FRAME_POINTER_REGNUM);
    }

  /* These registers are live everywhere.  */
  if (!reload_completed)
    {
      /* Pseudos with argument area equivalences may require
	 reloading via the argument pointer.  */
      if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
	  && fixed_regs[ARG_POINTER_REGNUM])
	bitmap_set_bit (entry_block_defs, ARG_POINTER_REGNUM);

      /* Any constant, or pseudo with constant equivalences, may
	 require reloading from memory using the pic register.  */
      unsigned int picreg = PIC_OFFSET_TABLE_REGNUM;
      if (picreg != INVALID_REGNUM
	  && fixed_regs[picreg])
	bitmap_set_bit (entry_block_defs, picreg);
    }

#ifdef INCOMING_RETURN_ADDR_RTX
  if (REG_P (INCOMING_RETURN_ADDR_RTX))
    bitmap_set_bit (entry_block_defs, REGNO (INCOMING_RETURN_ADDR_RTX));
#endif

  targetm.extra_live_on_entry (entry_block_defs);
}


/* Return the (conservative) set of hard registers that are defined on
   entry to the function.
   It uses df->entry_block_defs to determine which register
   reference to include.  */

static void
df_entry_block_defs_collect (class df_collection_rec *collection_rec,
			     bitmap entry_block_defs)
{
  unsigned int i;
  bitmap_iterator bi;

  EXECUTE_IF_SET_IN_BITMAP (entry_block_defs, 0, i, bi)
    {
      df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[i], NULL,
		     ENTRY_BLOCK_PTR_FOR_FN (cfun), NULL, DF_REF_REG_DEF, 0);
    }

  df_canonize_collection_rec (collection_rec);
}


/* Record the (conservative) set of hard registers that are defined on
   entry to the function.  */

static void
df_record_entry_block_defs (bitmap entry_block_defs)
{
  class df_collection_rec collection_rec;
  df_entry_block_defs_collect (&collection_rec, entry_block_defs);

  /* Process bb_refs chain */
  df_refs_add_to_chains (&collection_rec,
			 BASIC_BLOCK_FOR_FN (cfun, ENTRY_BLOCK),
			 NULL,
			 copy_defs);
}


/* Update the defs in the entry block.  */

void
df_update_entry_block_defs (void)
{
  bool changed = false;

  auto_bitmap refs (&df_bitmap_obstack);
  df_get_entry_block_def_set (refs);
  gcc_assert (df->entry_block_defs);
  if (!bitmap_equal_p (df->entry_block_defs, refs))
    {
      struct df_scan_bb_info *bb_info = df_scan_get_bb_info (ENTRY_BLOCK);
      df_ref_chain_delete_du_chain (bb_info->artificial_defs);
      df_ref_chain_delete (bb_info->artificial_defs);
      bb_info->artificial_defs = NULL;
      changed = true;
    }

  if (changed)
    {
      df_record_entry_block_defs (refs);
      bitmap_copy (df->entry_block_defs, refs);
      df_set_bb_dirty (BASIC_BLOCK_FOR_FN (cfun, ENTRY_BLOCK));
    }
}


/* Return true if REGNO is used by the epilogue.  */
bool
df_epilogue_uses_p (unsigned int regno)
{
  return (EPILOGUE_USES (regno)
	  || TEST_HARD_REG_BIT (crtl->must_be_zero_on_return, regno));
}

/* Set the bit for regs that are considered being used at the exit. */

static void
df_get_exit_block_use_set (bitmap exit_block_uses)
{
  unsigned int i;
  unsigned int picreg = PIC_OFFSET_TABLE_REGNUM;

  bitmap_clear (exit_block_uses);

  /* For separate shrink-wrapping we use LIVE to analyze which basic blocks
     need an epilogue for some component to be executed after that block,
     and we do not care about any other registers.  Hence, we do not want
     any register for any component seen as used in the exit block, and we
     can just say no registers at all are used.  */
  if (df_scan->local_flags & DF_SCAN_EMPTY_ENTRY_EXIT)
    return;

  /* Stack pointer is always live at the exit.  */
  bitmap_set_bit (exit_block_uses, STACK_POINTER_REGNUM);

  /* Mark the frame pointer if needed at the end of the function.
     If we end up eliminating it, it will be removed from the live
     list of each basic block by reload.  */

  if ((!reload_completed) || frame_pointer_needed)
    {
      bitmap_set_bit (exit_block_uses, FRAME_POINTER_REGNUM);

      /* If they are different, also mark the hard frame pointer as live.  */
      if (!HARD_FRAME_POINTER_IS_FRAME_POINTER
	  && !LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
	bitmap_set_bit (exit_block_uses, HARD_FRAME_POINTER_REGNUM);
    }

  /* Many architectures have a GP register even without flag_pic.
     Assume the pic register is not in use, or will be handled by
     other means, if it is not fixed.  */
  if (!PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
      && picreg != INVALID_REGNUM
      && fixed_regs[picreg])
    bitmap_set_bit (exit_block_uses, picreg);

  /* Mark all global registers, and all registers used by the
     epilogue as being live at the end of the function since they
     may be referenced by our caller.  */
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (global_regs[i] || df_epilogue_uses_p (i))
      bitmap_set_bit (exit_block_uses, i);

  if (targetm.have_epilogue () && epilogue_completed)
    {
      /* Mark all call-saved registers that we actually used.  */
      for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
	if (df_regs_ever_live_p (i)
	    && !LOCAL_REGNO (i)
	    && !crtl->abi->clobbers_full_reg_p (i))
	  bitmap_set_bit (exit_block_uses, i);
    }

  /* Mark the registers that will contain data for the handler.  */
  if (reload_completed && crtl->calls_eh_return)
    for (i = 0; ; ++i)
      {
	unsigned regno = EH_RETURN_DATA_REGNO (i);
	if (regno == INVALID_REGNUM)
	  break;
	bitmap_set_bit (exit_block_uses, regno);
      }

#ifdef EH_RETURN_STACKADJ_RTX
  if ((!targetm.have_epilogue () || ! epilogue_completed)
      && crtl->calls_eh_return)
    {
      rtx tmp = EH_RETURN_STACKADJ_RTX;
      if (tmp && REG_P (tmp))
	df_mark_reg (tmp, exit_block_uses);
    }
#endif

  if ((!targetm.have_epilogue () || ! epilogue_completed)
      && crtl->calls_eh_return)
    {
      rtx tmp = EH_RETURN_HANDLER_RTX;
      if (tmp && REG_P (tmp))
	df_mark_reg (tmp, exit_block_uses);
    }

  /* Mark function return value.  */
  diddle_return_value (df_mark_reg, (void*) exit_block_uses);
}


/* Return the refs of hard registers that are used in the exit block.
   It uses df->exit_block_uses to determine register to include.  */

static void
df_exit_block_uses_collect (class df_collection_rec *collection_rec, bitmap exit_block_uses)
{
  unsigned int i;
  bitmap_iterator bi;

  EXECUTE_IF_SET_IN_BITMAP (exit_block_uses, 0, i, bi)
    df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[i], NULL,
		   EXIT_BLOCK_PTR_FOR_FN (cfun), NULL, DF_REF_REG_USE, 0);

  /* It is deliberate that this is not put in the exit block uses but
     I do not know why.  */
  if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
      && reload_completed
      && !bitmap_bit_p (exit_block_uses, ARG_POINTER_REGNUM)
      && bb_has_eh_pred (EXIT_BLOCK_PTR_FOR_FN (cfun))
      && fixed_regs[ARG_POINTER_REGNUM])
    df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[ARG_POINTER_REGNUM], NULL,
		   EXIT_BLOCK_PTR_FOR_FN (cfun), NULL, DF_REF_REG_USE, 0);

  df_canonize_collection_rec (collection_rec);
}


/* Record the set of hard registers that are used in the exit block.
   It uses df->exit_block_uses to determine which bit to include.  */

static void
df_record_exit_block_uses (bitmap exit_block_uses)
{
  class df_collection_rec collection_rec;
  df_exit_block_uses_collect (&collection_rec, exit_block_uses);

  /* Process bb_refs chain */
  df_refs_add_to_chains (&collection_rec,
			 BASIC_BLOCK_FOR_FN (cfun, EXIT_BLOCK),
			 NULL,
			 copy_uses);
}


/* Update the uses in the exit block.  */

void
df_update_exit_block_uses (void)
{
  bool changed = false;

  auto_bitmap refs (&df_bitmap_obstack);
  df_get_exit_block_use_set (refs);
  gcc_assert (df->exit_block_uses);
  if (!bitmap_equal_p (df->exit_block_uses, refs))
    {
      struct df_scan_bb_info *bb_info = df_scan_get_bb_info (EXIT_BLOCK);
      df_ref_chain_delete_du_chain (bb_info->artificial_uses);
      df_ref_chain_delete (bb_info->artificial_uses);
      bb_info->artificial_uses = NULL;
      changed = true;
    }

  if (changed)
    {
      df_record_exit_block_uses (refs);
      bitmap_copy (df->exit_block_uses, refs);
      df_set_bb_dirty (BASIC_BLOCK_FOR_FN (cfun, EXIT_BLOCK));
    }
}

static bool initialized = false;


/* Initialize some platform specific structures.  */

void
df_hard_reg_init (void)
{
  int i;
  static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;

  if (initialized)
    return;

  /* Record which registers will be eliminated.  We use this in
     mark_used_regs.  */
  CLEAR_HARD_REG_SET (elim_reg_set);

  for (i = 0; i < (int) ARRAY_SIZE (eliminables); i++)
    SET_HARD_REG_BIT (elim_reg_set, eliminables[i].from);

  initialized = true;
}

/* Recompute the parts of scanning that are based on regs_ever_live
   because something changed in that array.  */

void
df_update_entry_exit_and_calls (void)
{
  basic_block bb;

  df_update_entry_block_defs ();
  df_update_exit_block_uses ();

  /* The call insns need to be rescanned because there may be changes
     in the set of registers clobbered across the call.  */
  FOR_EACH_BB_FN (bb, cfun)
    {
      rtx_insn *insn;
      FOR_BB_INSNS (bb, insn)
	{
	  if (INSN_P (insn) && CALL_P (insn))
	    df_insn_rescan (insn);
	}
    }
}


/* Return true if hard REG is actually used in the some instruction.
   There are a fair number of conditions that affect the setting of
   this array.  See the comment in df.h for df->hard_regs_live_count
   for the conditions that this array is set. */

bool
df_hard_reg_used_p (unsigned int reg)
{
  return df->hard_regs_live_count[reg] != 0;
}


/* A count of the number of times REG is actually used in the some
   instruction.  There are a fair number of conditions that affect the
   setting of this array.  See the comment in df.h for
   df->hard_regs_live_count for the conditions that this array is
   set. */


unsigned int
df_hard_reg_used_count (unsigned int reg)
{
  return df->hard_regs_live_count[reg];
}


/* Get the value of regs_ever_live[REGNO].  */

bool
df_regs_ever_live_p (unsigned int regno)
{
  return regs_ever_live[regno];
}

/* Set regs_ever_live[REGNO] to VALUE.  If this cause regs_ever_live
   to change, schedule that change for the next update.  */

void
df_set_regs_ever_live (unsigned int regno, bool value)
{
  if (regs_ever_live[regno] == value)
    return;

  regs_ever_live[regno] = value;
  if (df)
    df->redo_entry_and_exit = true;
}


/* Compute "regs_ever_live" information from the underlying df
   information.  Set the vector to all false if RESET.  */

void
df_compute_regs_ever_live (bool reset)
{
  unsigned int i;
  bool changed = df->redo_entry_and_exit;

  if (reset)
    memset (regs_ever_live, 0, sizeof (regs_ever_live));

  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if ((!regs_ever_live[i]) && df_hard_reg_used_p (i))
      {
	regs_ever_live[i] = true;
	changed = true;
      }
  if (changed)
    df_update_entry_exit_and_calls ();
  df->redo_entry_and_exit = false;
}


/*----------------------------------------------------------------------------
  Dataflow ref information verification functions.

  df_reg_chain_mark (refs, regno, is_def, is_eq_use)
  df_reg_chain_verify_unmarked (refs)
  df_refs_verify (vec<stack, va_df_ref>, ref*, bool)
  df_mws_verify (mw*, mw*, bool)
  df_insn_refs_verify (collection_rec, bb, insn, bool)
  df_bb_refs_verify (bb, refs, bool)
  df_bb_verify (bb)
  df_exit_block_bitmap_verify (bool)
  df_entry_block_bitmap_verify (bool)
  df_scan_verify ()
----------------------------------------------------------------------------*/


/* Mark all refs in the reg chain.  Verify that all of the registers
are in the correct chain.  */

static unsigned int
df_reg_chain_mark (df_ref refs, unsigned int regno,
		   bool is_def, bool is_eq_use)
{
  unsigned int count = 0;
  df_ref ref;
  for (ref = refs; ref; ref = DF_REF_NEXT_REG (ref))
    {
      gcc_assert (!DF_REF_IS_REG_MARKED (ref));

      /* If there are no def-use or use-def chains, make sure that all
	 of the chains are clear.  */
      if (!df_chain)
	gcc_assert (!DF_REF_CHAIN (ref));

      /* Check to make sure the ref is in the correct chain.  */
      gcc_assert (DF_REF_REGNO (ref) == regno);
      if (is_def)
	gcc_assert (DF_REF_REG_DEF_P (ref));
      else
	gcc_assert (!DF_REF_REG_DEF_P (ref));

      if (is_eq_use)
	gcc_assert ((DF_REF_FLAGS (ref) & DF_REF_IN_NOTE));
      else
	gcc_assert ((DF_REF_FLAGS (ref) & DF_REF_IN_NOTE) == 0);

      if (DF_REF_NEXT_REG (ref))
	gcc_assert (DF_REF_PREV_REG (DF_REF_NEXT_REG (ref)) == ref);
      count++;
      DF_REF_REG_MARK (ref);
    }
  return count;
}


/* Verify that all of the registers in the chain are unmarked.  */

static void
df_reg_chain_verify_unmarked (df_ref refs)
{
  df_ref ref;
  for (ref = refs; ref; ref = DF_REF_NEXT_REG (ref))
    gcc_assert (!DF_REF_IS_REG_MARKED (ref));
}


/* Verify that NEW_REC and OLD_REC have exactly the same members. */

static bool
df_refs_verify (const vec<df_ref, va_heap> *new_rec, df_ref old_rec,
		bool abort_if_fail)
{
  unsigned int ix;
  df_ref new_ref;

  FOR_EACH_VEC_ELT (*new_rec, ix, new_ref)
    {
      if (old_rec == NULL || !df_ref_equal_p (new_ref, old_rec))
	{
	  if (abort_if_fail)
	    gcc_assert (0);
	  else
	    return false;
	}

      /* Abort if fail is called from the function level verifier.  If
	 that is the context, mark this reg as being seem.  */
      if (abort_if_fail)
	{
	  gcc_assert (DF_REF_IS_REG_MARKED (old_rec));
	  DF_REF_REG_UNMARK (old_rec);
	}

      old_rec = DF_REF_NEXT_LOC (old_rec);
    }

  if (abort_if_fail)
    gcc_assert (old_rec == NULL);
  else
    return old_rec == NULL;
  return false;
}


/* Verify that NEW_REC and OLD_REC have exactly the same members. */

static bool
df_mws_verify (const vec<df_mw_hardreg *, va_heap> *new_rec,
	       struct df_mw_hardreg *old_rec,
	       bool abort_if_fail)
{
  unsigned int ix;
  struct df_mw_hardreg *new_reg;

  FOR_EACH_VEC_ELT (*new_rec, ix, new_reg)
    {
      if (old_rec == NULL || !df_mw_equal_p (new_reg, old_rec))
	{
	  if (abort_if_fail)
	    gcc_assert (0);
	  else
	    return false;
	}
      old_rec = DF_MWS_NEXT (old_rec);
    }

  if (abort_if_fail)
    gcc_assert (old_rec == NULL);
  else
    return old_rec == NULL;
  return false;
}


/* Return true if the existing insn refs information is complete and
   correct. Otherwise (i.e. if there's any missing or extra refs),
   return the correct df_ref chain in REFS_RETURN.

   If ABORT_IF_FAIL, leave the refs that are verified (already in the
   ref chain) as DF_REF_MARKED(). If it's false, then it's a per-insn
   verification mode instead of the whole function, so unmark
   everything.

   If ABORT_IF_FAIL is set, this function never returns false.  */

static bool
df_insn_refs_verify (class df_collection_rec *collection_rec,
		     basic_block bb,
                     rtx_insn *insn,
		     bool abort_if_fail)
{
  bool ret1, ret2, ret3;
  unsigned int uid = INSN_UID (insn);
  struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);

  df_insn_refs_collect (collection_rec, bb, insn_info);

  /* Unfortunately we cannot opt out early if one of these is not
     right and abort_if_fail is set because the marks will not get cleared.  */
  ret1 = df_refs_verify (&collection_rec->def_vec, DF_INSN_UID_DEFS (uid),
			 abort_if_fail);
  if (!ret1 && !abort_if_fail)
    return false;
  ret2 = df_refs_verify (&collection_rec->use_vec, DF_INSN_UID_USES (uid),
			 abort_if_fail);
  if (!ret2 && !abort_if_fail)
    return false;
  ret3 = df_refs_verify (&collection_rec->eq_use_vec, DF_INSN_UID_EQ_USES (uid),
			 abort_if_fail);
  if (!ret3 && !abort_if_fail)
    return false;
  if (! df_mws_verify (&collection_rec->mw_vec, DF_INSN_UID_MWS (uid),
		       abort_if_fail))
    return false;
  return (ret1 && ret2 && ret3);
}


/* Return true if all refs in the basic block are correct and complete.
   Due to df_ref_chain_verify, it will cause all refs
   that are verified to have DF_REF_MARK bit set.  */

static bool
df_bb_verify (basic_block bb)
{
  rtx_insn *insn;
  struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index);
  class df_collection_rec collection_rec;

  gcc_assert (bb_info);

  /* Scan the block, one insn at a time, from beginning to end.  */
  FOR_BB_INSNS_REVERSE (bb, insn)
    {
      if (!INSN_P (insn))
        continue;
      df_insn_refs_verify (&collection_rec, bb, insn, true);
      df_free_collection_rec (&collection_rec);
    }

  /* Do the artificial defs and uses.  */
  df_bb_refs_collect (&collection_rec, bb);
  df_refs_verify (&collection_rec.def_vec, df_get_artificial_defs (bb->index), true);
  df_refs_verify (&collection_rec.use_vec, df_get_artificial_uses (bb->index), true);
  df_free_collection_rec (&collection_rec);

  return true;
}


/* Returns true if the entry block has correct and complete df_ref set.
   If not it either aborts if ABORT_IF_FAIL is true or returns false.  */

static bool
df_entry_block_bitmap_verify (bool abort_if_fail)
{
  bool is_eq;

  auto_bitmap entry_block_defs (&df_bitmap_obstack);
  df_get_entry_block_def_set (entry_block_defs);

  is_eq = bitmap_equal_p (entry_block_defs, df->entry_block_defs);

  if (!is_eq && abort_if_fail)
    {
      fprintf (stderr, "entry_block_defs = ");
      df_print_regset (stderr, entry_block_defs);
      fprintf (stderr, "df->entry_block_defs = ");
      df_print_regset (stderr, df->entry_block_defs);
      gcc_assert (0);
    }

  return is_eq;
}


/* Returns true if the exit block has correct and complete df_ref set.
   If not it either aborts if ABORT_IF_FAIL is true or returns false. */

static bool
df_exit_block_bitmap_verify (bool abort_if_fail)
{
  bool is_eq;

  auto_bitmap exit_block_uses (&df_bitmap_obstack);
  df_get_exit_block_use_set (exit_block_uses);

  is_eq = bitmap_equal_p (exit_block_uses, df->exit_block_uses);

  if (!is_eq && abort_if_fail)
    {
      fprintf (stderr, "exit_block_uses = ");
      df_print_regset (stderr, exit_block_uses);
      fprintf (stderr, "df->exit_block_uses = ");
      df_print_regset (stderr, df->exit_block_uses);
      gcc_assert (0);
    }

  return is_eq;
}


/* Return true if df_ref information for all insns in all blocks are
   correct and complete.  */

void
df_scan_verify (void)
{
  unsigned int i;
  basic_block bb;

  if (!df)
    return;

  /* Verification is a 4 step process. */

  /* (1) All of the refs are marked by going through the reg chains.  */
  for (i = 0; i < DF_REG_SIZE (df); i++)
    {
      gcc_assert (df_reg_chain_mark (DF_REG_DEF_CHAIN (i), i, true, false)
		  == DF_REG_DEF_COUNT (i));
      gcc_assert (df_reg_chain_mark (DF_REG_USE_CHAIN (i), i, false, false)
		  == DF_REG_USE_COUNT (i));
      gcc_assert (df_reg_chain_mark (DF_REG_EQ_USE_CHAIN (i), i, false, true)
		  == DF_REG_EQ_USE_COUNT (i));
    }

  /* (2) There are various bitmaps whose value may change over the
     course of the compilation.  This step recomputes them to make
     sure that they have not slipped out of date.  */
  auto_bitmap regular_block_artificial_uses (&df_bitmap_obstack);
  auto_bitmap eh_block_artificial_uses (&df_bitmap_obstack);

  df_get_regular_block_artificial_uses (regular_block_artificial_uses);
  df_get_eh_block_artificial_uses (eh_block_artificial_uses);

  bitmap_ior_into (eh_block_artificial_uses,
		   regular_block_artificial_uses);

  /* Check artificial_uses bitmaps didn't change. */
  gcc_assert (bitmap_equal_p (regular_block_artificial_uses,
			      &df->regular_block_artificial_uses));
  gcc_assert (bitmap_equal_p (eh_block_artificial_uses,
			      &df->eh_block_artificial_uses));

  /* Verify entry block and exit block. These only verify the bitmaps,
     the refs are verified in df_bb_verify.  */
  df_entry_block_bitmap_verify (true);
  df_exit_block_bitmap_verify (true);

  /* (3) All of the insns in all of the blocks are traversed and the
     marks are cleared both in the artificial refs attached to the
     blocks and the real refs inside the insns.  It is a failure to
     clear a mark that has not been set as this means that the ref in
     the block or insn was not in the reg chain.  */

  FOR_ALL_BB_FN (bb, cfun)
    df_bb_verify (bb);

  /* (4) See if all reg chains are traversed a second time.  This time
     a check is made that the marks are clear. A set mark would be a
     from a reg that is not in any insn or basic block.  */

  for (i = 0; i < DF_REG_SIZE (df); i++)
    {
      df_reg_chain_verify_unmarked (DF_REG_DEF_CHAIN (i));
      df_reg_chain_verify_unmarked (DF_REG_USE_CHAIN (i));
      df_reg_chain_verify_unmarked (DF_REG_EQ_USE_CHAIN (i));
    }
}
