/* Scanning of rtl for dataflow analysis.
   Copyright (C) 1999, 2000, 2001, 2002, 2003, 2004, 2005, 2006, 2007,
   2008, 2009  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 "tm.h"
#include "rtl.h"
#include "tm_p.h"
#include "insn-config.h"
#include "recog.h"
#include "function.h"
#include "regs.h"
#include "output.h"
#include "alloc-pool.h"
#include "flags.h"
#include "hard-reg-set.h"
#include "basic-block.h"
#include "sbitmap.h"
#include "bitmap.h"
#include "timevar.h"
#include "tree.h"
#include "target.h"
#include "target-def.h"
#include "df.h"
#include "tree-pass.h"

#ifndef HAVE_epilogue
#define HAVE_epilogue 0
#endif
#ifndef HAVE_prologue
#define HAVE_prologue 0
#endif
#ifndef HAVE_sibcall_epilogue
#define HAVE_sibcall_epilogue 0
#endif

#ifndef EPILOGUE_USES
#define EPILOGUE_USES(REGNO)  0
#endif

/* The following two macros free the vecs that hold either the refs or
   the mw refs.  They are a little tricky because the vec has 0
   elements is special and is not to be freed.  */ 
#define df_scan_free_ref_vec(V) \
  do { \
    if (V && *V) \
      free (V);  \
  } while (0)

#define df_scan_free_mws_vec(V) \
  do { \
    if (V && *V) \
      free (V);  \
  } while (0)

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

struct df_collection_rec
{
  df_ref * def_vec;
  df_ref * use_vec;
  unsigned int next_def;
  unsigned int next_use;
  df_ref * eq_use_vec;
  struct df_mw_hardreg **mw_vec;
  unsigned int next_eq_use;
  unsigned int next_mw;
};

static df_ref df_null_ref_rec[1];
static struct df_mw_hardreg * df_null_mw_rec[1];

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

static df_ref df_ref_create_structure (enum df_ref_class, 
				       struct df_collection_rec *, rtx, rtx *, 
				       basic_block, struct df_insn_info *,
				       enum df_ref_type, enum df_ref_flags,
				       int, int, enum machine_mode);

static void df_insn_refs_collect (struct df_collection_rec*, 
				  basic_block, struct df_insn_info *); 
static void df_canonize_collection_rec (struct 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 (struct df_collection_rec *, 
				   basic_block, rtx);

static bool df_insn_refs_verify (struct df_collection_rec *, basic_block, rtx, bool);
static void df_entry_block_defs_collect (struct df_collection_rec *, bitmap);
static void df_exit_block_uses_collect (struct 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 (const void *, const void *);
static int df_mw_compare (const void *, const void *);

/* 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];

/*----------------------------------------------------------------------------
   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
{
  alloc_pool ref_base_pool;
  alloc_pool ref_artificial_pool;
  alloc_pool ref_regular_pool;
  alloc_pool ref_extract_pool;
  alloc_pool insn_pool;
  alloc_pool reg_pool;
  alloc_pool mw_reg_pool;
  bitmap_obstack reg_bitmaps;
  bitmap_obstack insn_bitmaps;
};

typedef struct df_scan_bb_info *df_scan_bb_info_t;


/* 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;
  unsigned int i;
  basic_block bb;

  /* The vectors that hold the refs are not pool allocated because
     they come in many sizes.  This makes them impossible to delete
     all at once.  */
  for (i = 0; i < DF_INSN_SIZE(); i++)
    {
      struct df_insn_info *insn_info = DF_INSN_UID_GET(i);
      /* Skip the insns that have no insn_info or have been
	 deleted.  */
      if (insn_info)
	{
	  df_scan_free_ref_vec (insn_info->defs);
	  df_scan_free_ref_vec (insn_info->uses);
	  df_scan_free_ref_vec (insn_info->eq_uses);
	  df_scan_free_mws_vec (insn_info->mw_hardregs);
	}
    }

  FOR_ALL_BB (bb)
    {
      unsigned int bb_index = bb->index;
      struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb_index);
      if (bb_info)
	{
	  df_scan_free_ref_vec (bb_info->artificial_defs);
	  df_scan_free_ref_vec (bb_info->artificial_uses);
	}
    }

  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_FREE (df->hardware_regs_used);
  BITMAP_FREE (df->regular_block_artificial_uses);
  BITMAP_FREE (df->eh_block_artificial_uses);
  BITMAP_FREE (df->entry_block_defs);
  BITMAP_FREE (df->exit_block_uses);
  BITMAP_FREE (df->insns_to_delete);
  BITMAP_FREE (df->insns_to_rescan);
  BITMAP_FREE (df->insns_to_notes_rescan);

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


/* Set basic block info.  */

static void
df_scan_set_bb_info (unsigned int index, 
		     struct df_scan_bb_info *bb_info)
{
  gcc_assert (df_scan);
  df_grow_bb_info (df_scan);
  df_scan->block_info[index] = (void *) bb_info;
}


/* 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;
  if (bb_info)
    {
      rtx insn;
      FOR_BB_INSNS (bb, insn)
	{
	  if (INSN_P (insn))
	    /* Record defs within INSN.  */
	    df_insn_delete (bb, 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;
      pool_free (df_scan->block_pool, bb_info);
    }
}


/* 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;
  unsigned int insn_num = get_max_uid () + 1;
  unsigned int block_size = 400;
  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 ();

  df_scan->block_pool 
    = create_alloc_pool ("df_scan_block pool", 
			 sizeof (struct df_scan_bb_info), 
			 block_size);

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

  problem_data->ref_base_pool 
    = create_alloc_pool ("df_scan ref base", 
			 sizeof (struct df_base_ref), block_size);
  problem_data->ref_artificial_pool 
    = create_alloc_pool ("df_scan ref artificial", 
			 sizeof (struct df_artificial_ref), block_size);
  problem_data->ref_regular_pool 
    = create_alloc_pool ("df_scan ref regular", 
			 sizeof (struct df_regular_ref), block_size);
  problem_data->ref_extract_pool 
    = create_alloc_pool ("df_scan ref extract", 
			 sizeof (struct df_extract_ref), block_size);
  problem_data->insn_pool 
    = create_alloc_pool ("df_scan insn", 
			 sizeof (struct df_insn_info), block_size);
  problem_data->reg_pool 
    = create_alloc_pool ("df_scan reg", 
			 sizeof (struct df_reg_info), block_size);
  problem_data->mw_reg_pool 
    = create_alloc_pool ("df_scan mw_reg", 
			 sizeof (struct df_mw_hardreg), block_size);

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

  insn_num += insn_num / 4; 
  df_grow_reg_info ();

  df_grow_insn_info ();
  df_grow_bb_info (df_scan);

  FOR_ALL_BB (bb)
    {
      unsigned int bb_index = bb->index;
      struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb_index);
      if (!bb_info)
	{
	  bb_info = (struct df_scan_bb_info *) pool_alloc (df_scan->block_pool);
	  df_scan_set_bb_info (bb_index, bb_info);
	}
      bb_info->artificial_defs = NULL;
      bb_info->artificial_uses = NULL;
    }

  df->hardware_regs_used = BITMAP_ALLOC (&problem_data->reg_bitmaps);
  df->regular_block_artificial_uses = BITMAP_ALLOC (&problem_data->reg_bitmaps);
  df->eh_block_artificial_uses = BITMAP_ALLOC (&problem_data->reg_bitmaps);
  df->entry_block_defs = BITMAP_ALLOC (&problem_data->reg_bitmaps);
  df->exit_block_uses = BITMAP_ALLOC (&problem_data->reg_bitmaps);
  df->insns_to_delete = BITMAP_ALLOC (&problem_data->insn_bitmaps);
  df->insns_to_rescan = BITMAP_ALLOC (&problem_data->insn_bitmaps);
  df->insns_to_notes_rescan = BITMAP_ALLOC (&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;

  fprintf (file, ";;  invalidated by call \t");
  df_print_regset (file, regs_invalidated_by_call_regset);
  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%dd", sep, DF_REG_EQ_USE_COUNT (i));
	    ecount += DF_REG_EQ_USE_COUNT (i);
	  }
	fprintf (file, "} ");
      }

  FOR_EACH_BB (bb)
    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;
    FOR_BB_INSNS (bb, insn)
      if (INSN_P (insn))
	df_insn_debug (insn, false, file);
  }
#endif
}

static 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,                       /* Incremental solution verify start.  */
  NULL,                       /* Incremental solution verify end.  */
  NULL,                       /* Dependent problem.  */
  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;

      reg_info = (struct df_reg_info *) pool_alloc (problem_data->reg_pool);
      memset (reg_info, 0, sizeof (struct df_reg_info));
      df->def_regs[i] = reg_info;
      reg_info = (struct df_reg_info *) pool_alloc (problem_data->reg_pool);
      memset (reg_info, 0, sizeof (struct df_reg_info));
      df->use_regs[i] = reg_info;
      reg_info = (struct df_reg_info *) pool_alloc (problem_data->reg_pool);
      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 (ENTRY_BLOCK));
  df_set_bb_dirty (BASIC_BLOCK (EXIT_BLOCK));

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


/* Create a new ref of type DF_REF_TYPE for register REG at address
   LOC within INSN of BB.  This function is only used externally. 

   If the REF_FLAGS field contain DF_REF_SIGN_EXTRACT or
   DF_REF_ZERO_EXTRACT.  WIDTH, OFFSET and MODE are used to access the
   fields if they were constants.  Otherwise they should be -1 if
   those flags were set.  */

df_ref 
df_ref_create (rtx reg, rtx *loc, rtx insn, 
	       basic_block bb,
	       enum df_ref_type ref_type, 
	       enum df_ref_flags ref_flags,
	       int width, int offset, enum machine_mode mode)
{
  df_ref ref;
  struct df_reg_info **reg_info;
  struct df_ref_info *ref_info;
  df_ref *ref_rec;
  df_ref **ref_rec_ptr;
  unsigned int count = 0;
  bool add_to_table;
  enum df_ref_class cl;

  df_grow_reg_info ();

  /* You cannot hack artificial refs.  */
  gcc_assert (insn);

  if (width != -1 || offset != -1)
    cl = DF_REF_EXTRACT;
  else if (loc)
    cl = DF_REF_REGULAR;
  else
    cl = DF_REF_BASE;
  ref = df_ref_create_structure (cl, NULL, reg, loc, bb, DF_INSN_INFO_GET (insn),
                                 ref_type, ref_flags, 
				 width, offset, mode);

  if (DF_REF_REG_DEF_P (ref))
    {
      reg_info = df->def_regs;
      ref_info = &df->def_info;
      ref_rec_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_rec_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_rec_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;
      }

  ref_rec = *ref_rec_ptr;
  while (*ref_rec)
    {
      count++;
      ref_rec++;
    }

  ref_rec = *ref_rec_ptr;
  if (count)
    {
      ref_rec = XRESIZEVEC (df_ref, ref_rec, count+2);
      *ref_rec_ptr = ref_rec;
      ref_rec[count] = ref;
      ref_rec[count+1] = NULL;
      qsort (ref_rec, count + 1, sizeof (df_ref), df_ref_compare);
    }
  else
    {
      df_ref *ref_rec = XNEWVEC (df_ref, 2);
      ref_rec[0] = ref;
      ref_rec[1] = NULL;
      *ref_rec_ptr = ref_rec;
    }

#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.  */  
  df_set_bb_dirty (bb);

  return ref;
}



/*----------------------------------------------------------------------------
   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:
      pool_free (problem_data->ref_base_pool, ref);
      break;

    case DF_REF_ARTIFICIAL:
      pool_free (problem_data->ref_artificial_pool, ref);
      break;

    case DF_REF_REGULAR:
      pool_free (problem_data->ref_regular_pool, ref);
      break;

    case DF_REF_EXTRACT:
      pool_free (problem_data->ref_extract_pool, 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);
}


/* Remove REF from VEC.  */

static void
df_ref_compress_rec (df_ref **vec_ptr, df_ref ref)
{
  df_ref *vec = *vec_ptr;

  if (vec[1])
    {
      while (*vec && *vec != ref)
	vec++;
      
      while (*vec)
	{
	  *vec = *(vec+1);
	  vec++;
	}
    }
  else
    {
      free (vec);
      *vec_ptr = df_null_ref_rec;
    }
}


/* Unlink REF from all def-use/use-def chains, etc.  */

void
df_ref_remove (df_ref ref)
{
#if 0
  if (dump_file)
    {
      fprintf (dump_file, "removing ref ");
      df_ref_debug (ref, dump_file);
    }
#endif

  if (DF_REF_REG_DEF_P (ref))
    {
      if (DF_REF_IS_ARTIFICIAL (ref))
	{
	  struct df_scan_bb_info *bb_info 
	    = df_scan_get_bb_info (DF_REF_BBNO (ref));
	  df_ref_compress_rec (&bb_info->artificial_defs, ref);
	}
      else
	{
	  unsigned int uid = DF_REF_INSN_UID (ref);
	  struct df_insn_info *insn_rec = DF_INSN_UID_GET (uid);
	  df_ref_compress_rec (&insn_rec->defs, ref);
	}
    }
  else
    {
      if (DF_REF_IS_ARTIFICIAL (ref))
	{
	  struct df_scan_bb_info *bb_info 
	    = df_scan_get_bb_info (DF_REF_BBNO (ref));
	  df_ref_compress_rec (&bb_info->artificial_uses, ref);
	}
      else 
	{
	  unsigned int uid = DF_REF_INSN_UID (ref);
	  struct df_insn_info *insn_rec = DF_INSN_UID_GET (uid);

	  if (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE)
	    df_ref_compress_rec (&insn_rec->eq_uses, ref);
	  else
	    df_ref_compress_rec (&insn_rec->uses, ref);
	}
    }

  /* By deleting 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.  */  
  df_set_bb_dirty (DF_REF_BB (ref));
  df_reg_chain_unlink (ref);
}


/* 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)
{
  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 = (struct df_insn_info *) pool_alloc (problem_data->insn_pool);
      DF_INSN_INFO_SET (insn, insn_rec);
    }
  memset (insn_rec, 0, sizeof (struct df_insn_info));
  insn_rec->insn = 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_rec)
{
  while (*ref_rec)
    {
      df_ref ref = *ref_rec;
      /* 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);
      ref_rec++;
    }
}


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

static void
df_ref_chain_delete (df_ref *ref_rec)
{
  df_ref *start = ref_rec;
  while (*ref_rec)
    {
      df_reg_chain_unlink (*ref_rec);
      ref_rec++;
    }

  /* If the list is empty, it has a special shared element that is not
     to be deleted.  */
  if (*start)
    free (start);
}


/* Delete the hardreg chain.  */

static void
df_mw_hardreg_chain_delete (struct df_mw_hardreg **hardregs)
{
  struct df_scan_problem_data *problem_data;

  if (!hardregs)
    return;

  problem_data = (struct df_scan_problem_data *) df_scan->problem_data;

  while (*hardregs)
    {
      pool_free (problem_data->mw_reg_pool, *hardregs);
      hardregs++;
    }
}


/* Delete all of the refs information from INSN.  BB must be passed in
   except when called from df_process_deferred_rescans to mark the block
   as dirty.  */

void 
df_insn_delete (basic_block bb, unsigned int uid)
{
  struct df_insn_info *insn_info = NULL;
  if (!df)
    return;

  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.  */
  if (bb)
    df_set_bb_dirty (bb);

  insn_info = DF_INSN_UID_SAFE_GET (uid);

  /* The client has deferred rescanning.  */
  if (df->changeable_flags & DF_DEFER_INSN_RESCAN)
    {
      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);

  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;

      /* 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.  */
      if (insn_info->defs)
	{
	  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);
	}
      pool_free (problem_data->insn_pool, insn_info);
      DF_INSN_UID_SET (uid, NULL);
    }
}


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

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

  if (collection_rec->def_vec)
    for (ref = collection_rec->def_vec; *ref; ref++)
      df_free_ref (*ref);
  if (collection_rec->use_vec)
    for (ref = collection_rec->use_vec; *ref; ref++)
      df_free_ref (*ref);
  if (collection_rec->eq_use_vec)
    for (ref = collection_rec->eq_use_vec; *ref; ref++)
      df_free_ref (*ref);
  if (collection_rec->mw_vec)
    for (mw = collection_rec->mw_vec; *mw; mw++)
      pool_free (problem_data->mw_reg_pool, *mw);
}


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

bool 
df_insn_rescan (rtx insn)
{
  unsigned int uid = INSN_UID (insn);
  struct df_insn_info *insn_info = NULL;
  basic_block bb = BLOCK_FOR_INSN (insn);
  struct df_collection_rec collection_rec;
  collection_rec.def_vec = XALLOCAVEC (df_ref, 1000);
  collection_rec.use_vec = XALLOCAVEC (df_ref, 1000);
  collection_rec.eq_use_vec = XALLOCAVEC (df_ref, 1000);
  collection_rec.mw_vec = XALLOCAVEC (struct df_mw_hardreg *, 100);

  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 = df_null_ref_rec;
	  insn_info->uses = df_null_ref_rec;
	  insn_info->eq_uses = df_null_ref_rec;
	  insn_info->mw_hardregs = df_null_mw_rec;
	}
      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)
    {
      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. */
      df_insn_delete (NULL, uid);
      df_insn_create_insn_record (insn);
    }
  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);
  df_set_bb_dirty (bb);
  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-se
   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;
  bitmap tmp = BITMAP_ALLOC (&df_bitmap_obstack);
  
  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;
    }

  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_delete (NULL, uid);
    }

  BITMAP_FREE (tmp);
  bitmap_clear (df->insns_to_delete);
  bitmap_clear (df->insns_to_rescan);
  bitmap_clear (df->insns_to_notes_rescan);

  FOR_EACH_BB (bb) 
    {
      rtx 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;
  bitmap tmp = BITMAP_ALLOC (&df_bitmap_obstack);
  
  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");

  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_delete (NULL, 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_FREE (tmp);
  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_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_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_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 (bb_index);
      rtx insn;
      df_ref *ref_rec;

      if (include_defs)
	for (ref_rec = df_get_artificial_defs (bb_index); *ref_rec; ref_rec++)
	  {
	    unsigned int regno = DF_REF_REGNO (*ref_rec);
	    ref_info->count[regno]++;
	  }
      if (include_uses)
	for (ref_rec = df_get_artificial_uses (bb_index); *ref_rec; ref_rec++)
	  {
	    unsigned int regno = DF_REF_REGNO (*ref_rec);
	    ref_info->count[regno]++;
	  }

      FOR_BB_INSNS (bb, insn)
	{
	  if (INSN_P (insn))
	    {
	      unsigned int uid = INSN_UID (insn);
	      
	      if (include_defs)
		for (ref_rec = DF_INSN_UID_DEFS (uid); *ref_rec; ref_rec++)
		  {
		    unsigned int regno = DF_REF_REGNO (*ref_rec);
		    ref_info->count[regno]++;
		  }
	      if (include_uses)
		for (ref_rec = DF_INSN_UID_USES (uid); *ref_rec; ref_rec++)
		  {
		    unsigned int regno = DF_REF_REGNO (*ref_rec);
		    ref_info->count[regno]++;
		  }
	      if (include_eq_uses)
		for (ref_rec = DF_INSN_UID_EQ_USES (uid); *ref_rec; ref_rec++)
		  {
		    unsigned int regno = DF_REF_REGNO (*ref_rec);
		    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 (bb_index);
      rtx insn;
      df_ref *ref_rec;

      if (include_defs)
	for (ref_rec = df_get_artificial_defs (bb_index); *ref_rec; ref_rec++)
	  {
	    df_ref ref = *ref_rec;
	    unsigned int regno = DF_REF_REGNO (ref);
	    if (regno >= start)
	      {
		unsigned int id
		  = ref_info->begin[regno] + ref_info->count[regno]++;
		DF_REF_ID (ref) = id;
		ref_info->refs[id] = ref;
	      }
	  }
      if (include_uses)
	for (ref_rec = df_get_artificial_uses (bb_index); *ref_rec; ref_rec++)
	  {
	    df_ref ref = *ref_rec;
	    unsigned int regno = DF_REF_REGNO (ref);
	    if (regno >= start)
	      {
		unsigned int id
		  = ref_info->begin[regno] + ref_info->count[regno]++;
		DF_REF_ID (ref) = id;
		ref_info->refs[id] = ref;
	      }
	  }

      FOR_BB_INSNS (bb, insn)
	{
	  if (INSN_P (insn))
	    {
	      unsigned int uid = INSN_UID (insn);
	      
	      if (include_defs)
		for (ref_rec = DF_INSN_UID_DEFS (uid); *ref_rec; ref_rec++)
		  {
		    df_ref ref = *ref_rec;
		    unsigned int regno = DF_REF_REGNO (ref);
		    if (regno >= start)
		      {
			unsigned int id
			  = ref_info->begin[regno] + ref_info->count[regno]++;
			DF_REF_ID (ref) = id;
			ref_info->refs[id] = ref;
		      }
		  }
	      if (include_uses)
		for (ref_rec = DF_INSN_UID_USES (uid); *ref_rec; ref_rec++)
		  {
		    df_ref ref = *ref_rec;
		    unsigned int regno = DF_REF_REGNO (ref);
		    if (regno >= start)
		      {
			unsigned int id
			  = ref_info->begin[regno] + ref_info->count[regno]++;
			DF_REF_ID (ref) = id;
			ref_info->refs[id] = ref;
		      }
		  }
	      if (include_eq_uses)
		for (ref_rec = DF_INSN_UID_EQ_USES (uid); *ref_rec; ref_rec++)
		  {
		    df_ref ref = *ref_rec;
		    unsigned int regno = DF_REF_REGNO (ref);
		    if (regno >= start)
		      {
			unsigned int id
			  = ref_info->begin[regno] + ref_info->count[regno]++;
			DF_REF_ID (ref) = id;
			ref_info->refs[id] = ref;
		      }
		  }
	    }
	}
    }

  /* 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_vec)
{
  while (*ref_vec)
    {
      df_ref ref = *ref_vec;
      if ((!(df->changeable_flags & DF_NO_HARD_REGS))
	  || (DF_REF_REGNO (ref) >= FIRST_PSEUDO_REGISTER))
	{
	  ref_info->refs[offset] = ref;
	  DF_REF_ID (*ref_vec) = offset++;
	}
      ref_vec++;
    }
  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;

  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 (index), offset, ref_info, 
						  include_defs, include_uses, 
						  include_eq_uses);
	}

      ref_info->table_size = offset;
    }
  else
    {
      FOR_ALL_BB (bb)
	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, 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,
			      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_vec, *ref_vec_t;
	  struct df_insn_info *insn_info = DF_REF_INSN_INFO (the_ref);
	  unsigned int count = 0;

	  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_FLAGS (the_ref) & DF_REF_IN_NOTE)
	    ref_vec = insn_info->eq_uses;
	  else
	    ref_vec = insn_info->uses;
	  if (dump_file)
	    fprintf (dump_file, "changing reg in insn %d\n", 
		     DF_REF_INSN_UID (the_ref)); 
      
	  ref_vec_t = ref_vec;
	  
	  /* Find the length.  */
	  while (*ref_vec_t)
	    {
	      count++;
	      ref_vec_t++;
	    }
	  qsort (ref_vec, count, sizeof (df_ref ), df_ref_compare);

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


/* Change the regno of all refs that contained LOC from OLD_REGNO to
   NEW_REGNO.  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 (int old_regno, int new_regno, rtx loc)
{
  if ((!df) || (old_regno == -1) || (old_regno == new_regno))
    return;

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


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

static unsigned int
df_mw_hardreg_chain_delete_eq_uses (struct df_insn_info *insn_info)
{
  struct df_mw_hardreg **mw_vec = insn_info->mw_hardregs;
  unsigned int deleted = 0;
  unsigned int count = 0;
  struct df_scan_problem_data *problem_data 
    = (struct df_scan_problem_data *) df_scan->problem_data;

  if (!*mw_vec)
    return 0;

  while (*mw_vec)
    {
      if ((*mw_vec)->flags & DF_REF_IN_NOTE)
	{
	  struct df_mw_hardreg **temp_vec = mw_vec;

	  pool_free (problem_data->mw_reg_pool, *mw_vec);
	  temp_vec = mw_vec;
	  /* Shove the remaining ones down one to fill the gap.  While
	     this looks n**2, it is highly unusual to have any mw regs
	     in eq_notes and the chances of more than one are almost
	     non existent.  */ 
	  while (*temp_vec)
	    {
	      *temp_vec = *(temp_vec + 1);
	      temp_vec++;
	    }
	  deleted++;
	}
      else
	{
	  mw_vec++;
	  count++;
	}
    }

  if (count == 0)
    {
      df_scan_free_mws_vec (insn_info->mw_hardregs);
      insn_info->mw_hardregs = df_null_mw_rec;
      return 0;
    }
  return deleted;
}


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

void
df_notes_rescan (rtx 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 = df_null_ref_rec;
	  insn_info->uses = df_null_ref_rec;
	  insn_info->eq_uses = df_null_ref_rec;
	  insn_info->mw_hardregs = df_null_mw_rec;
	}
      
      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;
      struct df_collection_rec collection_rec;
      unsigned int num_deleted;

      memset (&collection_rec, 0, sizeof (struct df_collection_rec));
      collection_rec.eq_use_vec = XALLOCAVEC (df_ref, 1000);
      collection_rec.mw_vec = XALLOCAVEC (struct df_mw_hardreg *, 1000);

      num_deleted = 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 (DF_REF_REGULAR, &collection_rec,
			      &XEXP (note, 0), DF_REF_REG_USE,
			      bb, insn_info, DF_REF_IN_NOTE, -1, -1, 0);
	    default:
	      break;
	    }
	}

      /* Find some place to put any new mw_hardregs.  */
      df_canonize_collection_rec (&collection_rec);
      if (collection_rec.next_mw)
	{
	  unsigned int count = 0;
	  struct df_mw_hardreg **mw_rec = insn_info->mw_hardregs;
	  while (*mw_rec)
	    {
	      count++;
	      mw_rec++;
	    }

	  if (count)
	    {
	      /* Append to the end of the existing record after
		 expanding it if necessary.  */
	      if (collection_rec.next_mw > num_deleted)
		{
		  insn_info->mw_hardregs = 
		    XRESIZEVEC (struct df_mw_hardreg *,
				insn_info->mw_hardregs, 
				count + 1 + collection_rec.next_mw);
		}
	      memcpy (&insn_info->mw_hardregs[count], collection_rec.mw_vec, 
		      (collection_rec.next_mw + 1) * sizeof (struct df_mw_hardreg *));
	      qsort (insn_info->mw_hardregs, count + collection_rec.next_mw, 
		     sizeof (struct df_mw_hardreg *), df_mw_compare);
	    }
	  else
	    {
	      /* No vector there. */  
	      insn_info->mw_hardregs 
		= XNEWVEC (struct df_mw_hardreg*, 
			   count + 1 + collection_rec.next_mw);
	      memcpy (insn_info->mw_hardregs, collection_rec.mw_vec, 
		      (collection_rec.next_mw + 1) * sizeof (struct df_mw_hardreg *));
	    }
	}
      /* Get rid of the mw_rec so that df_refs_add_to_chains will
	 ignore it.  */
      collection_rec.mw_vec = NULL;
      collection_rec.next_mw = 0;
      df_refs_add_to_chains (&collection_rec, bb, insn);
    }
  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_EXTRACT:
      if ((DF_REF_EXTRACT_OFFSET (ref1) != DF_REF_EXTRACT_OFFSET (ref2))
	  || (DF_REF_EXTRACT_WIDTH (ref1) != DF_REF_EXTRACT_WIDTH (ref2))
	  || (DF_REF_EXTRACT_MODE (ref1) != DF_REF_EXTRACT_MODE (ref2)))
	return false;
      /* fallthru.  */

    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 (const void *r1, const void *r2)
{
  const df_ref ref1 = *(const df_ref *)r1;
  const df_ref ref2 = *(const df_ref *)r2;

  if (ref1 == ref2)
    return 0;

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

  /* The classes are the same at this point so it is safe to only look
     at ref1.  */
  if (DF_REF_CLASS (ref1) == DF_REF_EXTRACT)
    {
      if (DF_REF_EXTRACT_OFFSET (ref1) != DF_REF_EXTRACT_OFFSET (ref2))
	return DF_REF_EXTRACT_OFFSET (ref1) - DF_REF_EXTRACT_OFFSET (ref2);
      if (DF_REF_EXTRACT_WIDTH (ref1) != DF_REF_EXTRACT_WIDTH (ref2))
	return DF_REF_EXTRACT_WIDTH (ref1) - DF_REF_EXTRACT_WIDTH (ref2);
      if (DF_REF_EXTRACT_MODE (ref1) != DF_REF_EXTRACT_MODE (ref2))
	return DF_REF_EXTRACT_MODE (ref1) - DF_REF_EXTRACT_MODE (ref2);
    }
  return 0;
}

static void
df_swap_refs (df_ref *ref_vec, int i, int j)
{
  df_ref tmp = ref_vec[i];
  ref_vec[i] = ref_vec[j];
  ref_vec[j] = tmp;
}

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

static unsigned int
df_sort_and_compress_refs (df_ref *ref_vec, unsigned int count)
{
  unsigned int i;
  unsigned int dist = 0;

  ref_vec[count] = NULL;
  /* If there are 1 or 0 elements, there is nothing to do.  */
  if (count < 2)
    return count;
  else if (count == 2)
    {
      if (df_ref_compare (&ref_vec[0], &ref_vec[1]) > 0)
        df_swap_refs (ref_vec, 0, 1);
    }
  else
    {
      for (i = 0; i < count - 1; i++)
        if (df_ref_compare (&ref_vec[i], &ref_vec[i+1]) >= 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 count;
      qsort (ref_vec, count, sizeof (df_ref), df_ref_compare);
    }

  for (i=0; i<count-dist; i++)
    {
      /* Find the next ref that is not equal to the current ref.  */
      while (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)
	ref_vec[i+1] = ref_vec[i + dist + 1];
    }

  count -= dist;
  ref_vec[count] = NULL;
  return 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 void *m1, const void *m2)
{
  const struct df_mw_hardreg *const mw1 = *(const struct df_mw_hardreg *const*)m1;
  const struct df_mw_hardreg *const mw2 = *(const struct df_mw_hardreg *const*)m2;

  if (mw1 == mw2)
    return 0;

  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;

  if (mw1->mw_reg != mw2->mw_reg)
    return mw1->mw_order - mw2->mw_order;

  return 0;
}


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

static unsigned int
df_sort_and_compress_mws (struct df_mw_hardreg **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;
  mw_vec[count] = NULL;

  if (count < 2)
    return count;
  else if (count == 2)
    {
      if (df_mw_compare (&mw_vec[0], &mw_vec[1]) > 0)
        {
          struct df_mw_hardreg *tmp = mw_vec[0];
          mw_vec[0] = mw_vec[1];
          mw_vec[1] = tmp;
        }
    }
  else
    qsort (mw_vec, count, sizeof (struct df_mw_hardreg *), df_mw_compare);

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

  count -= dist;
  mw_vec[count] = NULL;
  return count;
}


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

static void
df_canonize_collection_rec (struct df_collection_rec *collection_rec)
{
  if (collection_rec->def_vec)
    collection_rec->next_def 
      = df_sort_and_compress_refs (collection_rec->def_vec,
				   collection_rec->next_def);
  if (collection_rec->use_vec)
    collection_rec->next_use 
      = df_sort_and_compress_refs (collection_rec->use_vec,
				   collection_rec->next_use);
  if (collection_rec->eq_use_vec)
    collection_rec->next_eq_use 
      = df_sort_and_compress_refs (collection_rec->eq_use_vec,
				   collection_rec->next_eq_use);
  if (collection_rec->mw_vec)
    collection_rec->next_mw 
      = df_sort_and_compress_mws (collection_rec->mw_vec,
				  collection_rec->next_mw);
}


/* 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_assert (DF_REF_NEXT_REG (this_ref) == NULL);
  gcc_assert (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,
		 df_ref *old_vec, unsigned int count, 
		 struct df_reg_info **reg_info, 
		 struct df_ref_info *ref_info,
		 bool is_notes)
{
  if (count)
    {
      unsigned int i;
      df_ref *new_vec = XNEWVEC (df_ref, count + 1);
      bool 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;
	  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 (i = 0; i < count; i++)
	{
	  df_ref this_ref = old_vec[i];
	  new_vec[i] = this_ref;
	  df_install_ref (this_ref, reg_info[DF_REF_REGNO (this_ref)], 
			  ref_info, add_to_table);
	}
      
      new_vec[count] = NULL;
      return new_vec;
    }
  else
    return df_null_ref_rec;
}


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

static struct df_mw_hardreg **
df_install_mws (struct df_mw_hardreg **old_vec, unsigned int count)
{
  if (count)
    {
      struct df_mw_hardreg **new_vec 
	= XNEWVEC (struct df_mw_hardreg*, count + 1);
      memcpy (new_vec, old_vec, 
	      sizeof (struct df_mw_hardreg*) * (count + 1));
      return new_vec;
    }
  else
    return df_null_mw_rec;
}


/* 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 (struct df_collection_rec *collection_rec, 
		       basic_block bb, rtx insn)
{
  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 (collection_rec->def_vec)
	{
	  df_scan_free_ref_vec (insn_rec->defs);
	  insn_rec->defs 
	    = df_install_refs (bb, collection_rec->def_vec, 
			       collection_rec->next_def,
			       df->def_regs,
			       &df->def_info, false);
	}
      if (collection_rec->use_vec)
	{
	  df_scan_free_ref_vec (insn_rec->uses);
	  insn_rec->uses 
	    = df_install_refs (bb, collection_rec->use_vec, 
			       collection_rec->next_use,
			       df->use_regs,
			       &df->use_info, false);
	}
      if (collection_rec->eq_use_vec)
	{
	  df_scan_free_ref_vec (insn_rec->eq_uses);
	  insn_rec->eq_uses 
	    = df_install_refs (bb, collection_rec->eq_use_vec, 
			       collection_rec->next_eq_use,
			       df->eq_use_regs,
			       &df->use_info, true);
	}
      if (collection_rec->mw_vec)
	{
	  df_scan_free_mws_vec (insn_rec->mw_hardregs);
	  insn_rec->mw_hardregs 
	    = df_install_mws (collection_rec->mw_vec, 
			      collection_rec->next_mw);
	}
    }
  else
    {
      struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index);

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


/* Allocate a ref and initialize its fields. 

   If the REF_FLAGS field contain DF_REF_SIGN_EXTRACT or
   DF_REF_ZERO_EXTRACT.  WIDTH, OFFSET and MODE are used to access the fields
   if they were constants.  Otherwise they should be -1 if those flags
   were set.  */

static df_ref 
df_ref_create_structure (enum df_ref_class cl, 
			 struct df_collection_rec *collection_rec,
			 rtx reg, rtx *loc, 
			 basic_block bb, struct df_insn_info *info,
			 enum df_ref_type ref_type, 
			 enum df_ref_flags ref_flags,
			 int width, int offset, enum machine_mode mode)
{
  df_ref this_ref = NULL;
  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) pool_alloc (problem_data->ref_base_pool);
      gcc_assert (loc == NULL);
      break;

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

    case DF_REF_REGULAR:
      this_ref = (df_ref) pool_alloc (problem_data->ref_regular_pool);
      this_ref->regular_ref.loc = loc;
      gcc_assert (loc);
      break;

    case DF_REF_EXTRACT:
      this_ref = (df_ref) pool_alloc (problem_data->ref_extract_pool);
      DF_REF_EXTRACT_WIDTH (this_ref) = width;
      DF_REF_EXTRACT_OFFSET (this_ref) = offset;
      DF_REF_EXTRACT_MODE (this_ref) = mode;
      this_ref->regular_ref.loc = loc;
      gcc_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)))
    {
      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[collection_rec->next_def++] = this_ref;
      else if (DF_REF_FLAGS (this_ref) & DF_REF_IN_NOTE)
	collection_rec->eq_use_vec[collection_rec->next_eq_use++] = this_ref;
      else
	collection_rec->use_vec[collection_rec->next_use++] = 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. 

   If the REF_FLAGS field contain DF_REF_SIGN_EXTRACT or
   DF_REF_ZERO_EXTRACT.  WIDTH, OFFSET and MODE are used to access the
   fields if they were constants.  Otherwise they should be -1 if
   those flags were set.  */


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

  gcc_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)
	{
	  regno += subreg_regno_offset (regno, GET_MODE (SUBREG_REG (reg)),
					SUBREG_BYTE (reg), GET_MODE (reg));
	  endregno = regno + subreg_nregs (reg);
	}
      else
	endregno = END_HARD_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 ((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;

	  hardreg = (struct df_mw_hardreg *) pool_alloc (problem_data->mw_reg_pool);
	  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[collection_rec->next_mw++] = 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, 
					 width, offset, mode);

          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, width, offset, mode);
    }
}


/* A set to a non-paradoxical SUBREG for which the number of word_mode units
   covered by the outer mode is smaller than that covered by the inner mode,
   is a read-modify-write operation.
   This function returns true iff the SUBREG X is such a SUBREG.  */

bool
df_read_modify_subreg_p (rtx x)
{
  unsigned int isize, osize;
  if (GET_CODE (x) != SUBREG)
    return false;
  isize = GET_MODE_SIZE (GET_MODE (SUBREG_REG (x)));
  osize = GET_MODE_SIZE (GET_MODE (x));
  return isize > osize
	 && isize > REGMODE_NATURAL_SIZE (GET_MODE (SUBREG_REG (x)));
}


/* Process all the registers defined in the rtx, X.
   Autoincrement/decrement definitions will be picked up by
   df_uses_record.  */

static void
df_def_record_1 (struct df_collection_rec *collection_rec,
                 rtx x, basic_block bb, struct df_insn_info *insn_info,
		 enum df_ref_flags flags)
{
  rtx *loc;
  rtx dst;
  int offset = -1;
  int width = -1;
  enum machine_mode mode = 0;
  enum df_ref_class cl = DF_REF_REGULAR;

 /* We may recursively call ourselves on EXPR_LIST when dealing with PARALLEL
     construct.  */
  if (GET_CODE (x) == EXPR_LIST || GET_CODE (x) == CLOBBER)
    loc = &XEXP (x, 0);
  else
    loc = &SET_DEST (x);
  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);
	  if (GET_CODE (temp) == EXPR_LIST || GET_CODE (temp) == CLOBBER
	      || GET_CODE (temp) == SET)
	    df_def_record_1 (collection_rec,
                             temp, bb, insn_info, 
			     GET_CODE (temp) == CLOBBER 
			     ? flags | DF_REF_MUST_CLOBBER : 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;
      
      if (GET_CODE (XEXP (dst, 1)) == CONST_INT
	  && GET_CODE (XEXP (dst, 2)) == CONST_INT)
	{
	  width = INTVAL (XEXP (dst, 1));
	  offset = INTVAL (XEXP (dst, 2));
	  mode = GET_MODE (dst);
	  cl = DF_REF_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 (cl, collection_rec, 
		     dst, loc, bb, insn_info, DF_REF_REG_DEF, flags, 
		     width, offset, mode);

      /* 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, 
		       width, offset, mode);
    }
  else if (GET_CODE (dst) == SUBREG && REG_P (SUBREG_REG (dst)))
    {
      if (df_read_modify_subreg_p (dst))
	flags |= DF_REF_READ_WRITE | DF_REF_PARTIAL;

      flags |= DF_REF_SUBREG;

      df_ref_record (cl, collection_rec, 
		     dst, loc, bb, insn_info, DF_REF_REG_DEF, flags, 
		     width, offset, mode);
    }
}


/* Process all the registers defined in the pattern rtx, X.  */

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

  if (code == SET || code == CLOBBER)
    {
      /* Mark the single def within the pattern.  */
      enum df_ref_flags clobber_flags = flags;
      clobber_flags |= (code == CLOBBER) ? DF_REF_MUST_CLOBBER : 0;
      df_def_record_1 (collection_rec, x, bb, insn_info, clobber_flags);
    }
  else if (code == COND_EXEC)
    {
      df_defs_record (collection_rec, COND_EXEC_CODE (x), 
		      bb, insn_info, DF_REF_CONDITIONAL);
    }
  else if (code == PARALLEL)
    {
      int i;

      /* Mark the multiple defs within the pattern.  */
      for (i = XVECLEN (x, 0) - 1; i >= 0; i--)
	df_defs_record (collection_rec, XVECEXP (x, 0, i), bb, insn_info, flags);
    }
}


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

   If the REF_FLAGS field contain DF_REF_SIGN_EXTRACT or
   DF_REF_ZERO_EXTRACT.  WIDTH, OFFSET and MODE are used to access the
   fields if they were constants.  Otherwise they should be -1 if
   those flags were set.  */

static void
df_uses_record (enum df_ref_class cl, struct df_collection_rec *collection_rec,
                rtx *loc, enum df_ref_type ref_type,
		basic_block bb, struct df_insn_info *insn_info,
		enum df_ref_flags flags,
		int width, int offset, enum machine_mode mode)
{
  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_INT:
    case CONST:
    case CONST_DOUBLE:
    case CONST_FIXED:
    case CONST_VECTOR:
    case PC:
    case CC0:
    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 (cl, collection_rec,
			&XEXP (XEXP (x, 0), 0),
			DF_REF_REG_MEM_STORE,
		        bb, insn_info,
			flags, width, offset, mode);

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

    case MEM:
      df_uses_record (cl, collection_rec,
		      &XEXP (x, 0), DF_REF_REG_MEM_LOAD, 
		      bb, insn_info, flags & DF_REF_IN_NOTE, 
		      width, offset, mode);
      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 (cl, collection_rec, loc, ref_type, bb, insn_info, flags, 
			  width, offset, mode);
	  return;
	}
      /* ... Fall through ...  */

    case REG:
      df_ref_record (cl, collection_rec, 
		     x, loc, bb, insn_info,
		     ref_type, flags, 
		     width, offset, mode);
      return;

    case SIGN_EXTRACT:
    case ZERO_EXTRACT:
      {
	/* 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 (GET_CODE (XEXP (x, 1)) == CONST_INT
	    && GET_CODE (XEXP (x, 2)) == CONST_INT)
	  {
	    width = INTVAL (XEXP (x, 1));
	    offset = INTVAL (XEXP (x, 2));
	    mode = GET_MODE (x);

	    if (code == ZERO_EXTRACT)
	      flags |= DF_REF_ZERO_EXTRACT;
	    else
	      flags |= DF_REF_SIGN_EXTRACT;

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

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

	switch (GET_CODE (dst))
	  {
	    case SUBREG:
	      if (df_read_modify_subreg_p (dst))
		{
		  df_uses_record (cl, collection_rec, &SUBREG_REG (dst), 
				  DF_REF_REG_USE, bb, insn_info, 
				  flags | DF_REF_READ_WRITE | DF_REF_SUBREG, 
				  width, offset, mode);
		  break;
		}
	      /* Fall through.  */
	    case REG:
	    case PARALLEL:
	    case SCRATCH:
	    case PC:
	    case CC0:
		break;
	    case MEM:
	      df_uses_record (cl, collection_rec, &XEXP (dst, 0),
			      DF_REF_REG_MEM_STORE, bb, insn_info, flags, 
			      width, offset, mode);
	      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 (cl, 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, 
				width, offset, mode);
	      }
	      break;
	    case ZERO_EXTRACT:
	      {
		if (GET_CODE (XEXP (dst, 1)) == CONST_INT
		    && GET_CODE (XEXP (dst, 2)) == CONST_INT)
		  {
		    width = INTVAL (XEXP (dst, 1));
		    offset = INTVAL (XEXP (dst, 2));
		    mode = GET_MODE (dst);
		    df_uses_record (DF_REF_EXTRACT, collection_rec, &XEXP (dst, 0), 
				DF_REF_REG_USE, bb, insn_info, 
				DF_REF_READ_WRITE | DF_REF_ZERO_EXTRACT, 
				width, offset, mode);
		  }
		else 
		  {
		    df_uses_record (cl, collection_rec, &XEXP (dst, 1), 
				    DF_REF_REG_USE, bb, insn_info, flags, 
				    width, offset, mode);
		    df_uses_record (cl, collection_rec, &XEXP (dst, 2), 
				    DF_REF_REG_USE, bb, insn_info, flags, 
				    width, offset, mode);
		    df_uses_record (cl, collection_rec, &XEXP (dst, 0), 
				    DF_REF_REG_USE, bb, insn_info, 
				    DF_REF_READ_WRITE | DF_REF_ZERO_EXTRACT, 
				    width, offset, mode);
		  }

	      }
	      break;

	    default:
	      gcc_unreachable ();
	  }
	return;
      }

    case 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 can not 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 (cl, collection_rec, &ASM_OPERANDS_INPUT (x, j),
			      DF_REF_REG_USE, bb, insn_info, flags, 
			      width, offset, mode);
	    return;
	  }
	break;
      }

    case PRE_DEC:
    case POST_DEC:
    case PRE_INC:
    case POST_INC:
    case PRE_MODIFY:
    case POST_MODIFY:
      /* Catch the def of the register being modified.  */
      df_ref_record (cl, 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, 
		     width, offset, mode);

      /* ... 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 (cl, collection_rec, &XEXP (x, i), ref_type, 
			    bb, insn_info, flags, 
			    width, offset, mode);
	  }
	else if (fmt[i] == 'E')
	  {
	    int j;
	    for (j = 0; j < XVECLEN (x, i); j++)
	      df_uses_record (cl, collection_rec,
			      &XVECEXP (x, i, j), ref_type, 
			      bb, insn_info, flags, 
			      width, offset, mode);
	  }
      }
  }

  return;
}


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

static void
df_get_conditional_uses (struct df_collection_rec *collection_rec)
{
  unsigned int i;
  for (i = 0; i < collection_rec->next_def; i++)
    {
      df_ref ref = collection_rec->def_vec[i];
      if (DF_REF_FLAGS_IS_SET (ref, DF_REF_CONDITIONAL))
        {
	  int width = -1;
	  int offset = -1;
	  enum machine_mode mode = 0;
          df_ref use;

	  if (DF_REF_FLAGS_IS_SET (ref, DF_REF_SIGN_EXTRACT | DF_REF_ZERO_EXTRACT))
	    {
	      width = DF_REF_EXTRACT_WIDTH (ref);
	      offset = DF_REF_EXTRACT_OFFSET (ref);
	      mode = DF_REF_EXTRACT_MODE (ref);
	    }

          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,
					 width, offset, mode);
          DF_REF_REGNO (use) = DF_REF_REGNO (ref);
        }
    }
}


/* Get call's extra defs and uses. */

static void
df_get_call_refs (struct df_collection_rec * collection_rec,
                  basic_block bb, 
                  struct df_insn_info *insn_info,
                  enum df_ref_flags flags)
{
  rtx note;
  bitmap_iterator bi;
  unsigned int ui;
  bool is_sibling_call;
  unsigned int i;
  bitmap defs_generated = BITMAP_ALLOC (&df_bitmap_obstack);

  /* Do not generate clobbers for registers that are the result of the
     call.  This causes ordering problems in the chain building code
     depending on which def is seen first.  */
  for (i=0; i<collection_rec->next_def; i++)
    {
      df_ref def = collection_rec->def_vec[i];
      bitmap_set_bit (defs_generated, DF_REF_REGNO (def));
    }

  /* 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 (DF_REF_REGULAR, collection_rec, &XEXP (XEXP (note, 0), 0),
			DF_REF_REG_USE, bb, insn_info, flags, -1, -1, 0);
      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 (!bitmap_bit_p (defs_generated, regno))
		df_defs_record (collection_rec, XEXP (note, 0), bb,
				insn_info, flags);
	    }
	  else
	    df_uses_record (DF_REF_REGULAR, collection_rec, &XEXP (note, 0),
		            DF_REF_REG_USE, bb, insn_info, flags, -1, -1, 0);
	}
    }

  /* The stack ptr is used (honorarily) by a CALL insn.  */
  df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[STACK_POINTER_REGNUM],
		 NULL, bb, insn_info, DF_REF_REG_USE,
		 DF_REF_CALL_STACK_USAGE | flags, 
		 -1, -1, 0);

  /* Calls may also reference any of the global registers,
     so they are recorded as used.  */
  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    if (global_regs[i])
      {
	df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
		       NULL, bb, insn_info, DF_REF_REG_USE, flags, -1, -1, 0);
	df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
		       NULL, bb, insn_info, DF_REF_REG_DEF, flags, -1, -1, 0);
      }

  is_sibling_call = SIBLING_CALL_P (insn_info->insn);
  EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, ui, bi)
    {
      if (!global_regs[ui]
	  && (!bitmap_bit_p (defs_generated, ui))
	  && (!is_sibling_call
	      || !bitmap_bit_p (df->exit_block_uses, ui)
	      || refers_to_regno_p (ui, ui+1, 
				    crtl->return_rtx, NULL)))
        df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[ui], 
		       NULL, bb, insn_info, DF_REF_REG_DEF,
		       DF_REF_MAY_CLOBBER | flags, 
		       -1, -1, 0);
    }

  BITMAP_FREE (defs_generated);
  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 (struct 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->next_def = 0;
  collection_rec->next_use = 0;
  collection_rec->next_eq_use = 0;
  collection_rec->next_mw = 0;

  /* Record register defs.  */
  df_defs_record (collection_rec, PATTERN (insn_info->insn), bb, insn_info, 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 (DF_REF_REGULAR, collection_rec,
                          &XEXP (note, 0), DF_REF_REG_USE,
                          bb, insn_info, DF_REF_IN_NOTE, -1, -1, 0);
          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, -1, -1, 0);
#if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
          df_ref_record (DF_REF_BASE, collection_rec,
                         regno_reg_rtx[HARD_FRAME_POINTER_REGNUM],
                         NULL, bb, insn_info,
                         DF_REF_REG_USE, 0, -1, -1, 0);
#endif
          break;
        default:
          break;
        }
    }

  if (CALL_P (insn_info->insn))
    df_get_call_refs (collection_rec, bb, insn_info, 
		      (is_cond_exec) ? DF_REF_CONDITIONAL : 0);

  /* Record the register uses.  */
  df_uses_record (DF_REF_REGULAR, collection_rec,
		  &PATTERN (insn_info->insn), DF_REF_REG_USE, bb, insn_info, 0, 
		  -1, -1, 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;
  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++;
    }
}


/* Returns true if the function entry needs to 
   define the static chain register.  */

static bool
df_need_static_chain_reg (struct function *fun)
{
  tree fun_context = decl_function_context (fun->decl);
  return fun_context
         && DECL_NO_STATIC_CHAIN (fun_context) == false;
}


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

static void
df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb)
{
  collection_rec->next_def = 0;
  collection_rec->next_use = 0;
  collection_rec->next_eq_use = 0;
  collection_rec->next_mw = 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;
    }

#ifdef EH_RETURN_DATA_REGNO
  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, -1, -1, 0);
	}
    }
#endif

  /* 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, -1, -1, 0);
 
  /* 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, -1, -1, 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 (bb_index);
  rtx insn;
  int luid = 0;
  struct df_scan_bb_info *bb_info;
  struct df_collection_rec collection_rec;
  collection_rec.def_vec = XALLOCAVEC (df_ref, 1000);
  collection_rec.use_vec = XALLOCAVEC (df_ref, 1000);
  collection_rec.eq_use_vec = XALLOCAVEC (df_ref, 1000);
  collection_rec.mw_vec = XALLOCAVEC (struct df_mw_hardreg *, 100);

  if (!df)
    return;

  bb_info = df_scan_get_bb_info (bb_index);

  /* Need to make sure that there is a record in the basic block info. */  
  if (!bb_info)
    {
      bb_info = (struct df_scan_bb_info *) pool_alloc (df_scan->block_pool);
      df_scan_set_bb_info (bb_index, bb_info);
      bb_info->artificial_defs = NULL;
      bb_info->artificial_uses = NULL;
    }

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

  /* 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.  */
    {
      /* 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 FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
      bitmap_set_bit (regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM);
#endif

#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
      /* Pseudos with argument area equivalences may require
	 reloading via the argument pointer.  */
      if (fixed_regs[ARG_POINTER_REGNUM])
	bitmap_set_bit (regular_block_artificial_uses, ARG_POINTER_REGNUM);
#endif
      
      /* Any constant, or pseudo with constant equivalences, may
	 require reloading from memory using the pic register.  */
      if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
	  && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
	bitmap_set_bit (regular_block_artificial_uses, PIC_OFFSET_TABLE_REGNUM);
    }
  /* 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 thru 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 FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
	  bitmap_set_bit (eh_block_artificial_uses, HARD_FRAME_POINTER_REGNUM);
#endif
	}
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
      if (fixed_regs[ARG_POINTER_REGNUM])
	bitmap_set_bit (eh_block_artificial_uses, ARG_POINTER_REGNUM);
#endif
    }
}



/*----------------------------------------------------------------------------
   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 = (bitmap) vset;
  int regno = REGNO (reg);

  gcc_assert (GET_MODE (reg) != BLKmode);

  bitmap_set_bit (set, regno);
  if (regno < FIRST_PSEUDO_REGISTER)
    {
      int n = hard_regno_nregs[regno][GET_MODE (reg)];
      while (--n > 0)
	bitmap_set_bit  (set, regno + n);
    }
}


/* 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 (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
    {
      if (FUNCTION_ARG_REGNO_P (i))
#ifdef INCOMING_REGNO
	bitmap_set_bit (entry_block_defs, INCOMING_REGNO (i));
#else
	bitmap_set_bit (entry_block_defs, i);
#endif
    }
      
  /* 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 (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 ((call_used_regs[i] == 0) && (df_regs_ever_live_p (i)))
	  bitmap_set_bit (entry_block_defs, i);
    }
  else
    {
      /* If STATIC_CHAIN_INCOMING_REGNUM == STATIC_CHAIN_REGNUM
	 only STATIC_CHAIN_REGNUM is defined.  If they are different,
	 we only care about the STATIC_CHAIN_INCOMING_REGNUM.  */
#ifdef STATIC_CHAIN_INCOMING_REGNUM
      bitmap_set_bit (entry_block_defs, STATIC_CHAIN_INCOMING_REGNUM);
#else 
#ifdef STATIC_CHAIN_REGNUM
      bitmap_set_bit (entry_block_defs, STATIC_CHAIN_REGNUM);
#endif
#endif
    }

  r = targetm.calls.struct_value_rtx (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 FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
      /* If they are different, also mark the hard frame pointer as live.  */
      if (!LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
	bitmap_set_bit (entry_block_defs, HARD_FRAME_POINTER_REGNUM);
#endif
    }

  /* These registers are live everywhere.  */
  if (!reload_completed)
    {
#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
      /* Pseudos with argument area equivalences may require
	 reloading via the argument pointer.  */
      if (fixed_regs[ARG_POINTER_REGNUM])
	bitmap_set_bit (entry_block_defs, ARG_POINTER_REGNUM);
#endif
	  
#ifdef PIC_OFFSET_TABLE_REGNUM
      /* Any constant, or pseudo with constant equivalences, may
	 require reloading from memory using the pic register.  */
      if ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
	  && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
	bitmap_set_bit (entry_block_defs, PIC_OFFSET_TABLE_REGNUM);
#endif
    }

#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.live_on_entry (entry_block_defs);

  /* If the function has an incoming STATIC_CHAIN,
     it has to show up in the entry def set.  */
  if (df_need_static_chain_reg (cfun))
    {
#ifdef STATIC_CHAIN_INCOMING_REGNUM
      bitmap_set_bit (entry_block_defs, STATIC_CHAIN_INCOMING_REGNUM);
#else 
#ifdef STATIC_CHAIN_REGNUM
      bitmap_set_bit (entry_block_defs, STATIC_CHAIN_REGNUM);
#endif
#endif
    }
}


/* 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 (struct 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, NULL, DF_REF_REG_DEF, 0, -1, -1, 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)
{
  struct df_collection_rec collection_rec;
  memset (&collection_rec, 0, sizeof (struct df_collection_rec));
  collection_rec.def_vec = XALLOCAVEC (df_ref, FIRST_PSEUDO_REGISTER);

  df_entry_block_defs_collect (&collection_rec, entry_block_defs);

  /* Process bb_refs chain */
  df_refs_add_to_chains (&collection_rec, BASIC_BLOCK (ENTRY_BLOCK), NULL);
}


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

void
df_update_entry_block_defs (void)
{
  bitmap refs = BITMAP_ALLOC (&df_bitmap_obstack);
  bool changed = false;

  df_get_entry_block_def_set (refs);
  if (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;
	}
    }
  else
    {
      struct df_scan_problem_data *problem_data
	= (struct df_scan_problem_data *) df_scan->problem_data;
      df->entry_block_defs = BITMAP_ALLOC (&problem_data->reg_bitmaps);
      changed = true;
    }

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


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

  bitmap_clear (exit_block_uses);

  /* 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 FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
      /* If they are different, also mark the hard frame pointer as live.  */
      if (!LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
	bitmap_set_bit (exit_block_uses, HARD_FRAME_POINTER_REGNUM);
#endif
    }

#ifndef PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
  /* 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 ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
      && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
    bitmap_set_bit (exit_block_uses, PIC_OFFSET_TABLE_REGNUM);
#endif
  
  /* 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] || EPILOGUE_USES (i))
      bitmap_set_bit (exit_block_uses, i);
  
  if (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)
	    && !TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
	  bitmap_set_bit (exit_block_uses, i);
    }
  
#ifdef EH_RETURN_DATA_REGNO
  /* 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);
      }
#endif

#ifdef EH_RETURN_STACKADJ_RTX
  if ((!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

#ifdef EH_RETURN_HANDLER_RTX
  if ((!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);
    }
#endif 

  /* 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 (struct 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, NULL, DF_REF_REG_USE, 0, -1, -1, 0);

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

  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)
{
  struct df_collection_rec collection_rec;
  memset (&collection_rec, 0, sizeof (struct df_collection_rec));
  collection_rec.use_vec = XALLOCAVEC (df_ref, FIRST_PSEUDO_REGISTER);

  df_exit_block_uses_collect (&collection_rec, exit_block_uses);

  /* Process bb_refs chain */
  df_refs_add_to_chains (&collection_rec, BASIC_BLOCK (EXIT_BLOCK), NULL);
}


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

void
df_update_exit_block_uses (void)
{
  bitmap refs = BITMAP_ALLOC (&df_bitmap_obstack);
  bool changed = false;

  df_get_exit_block_use_set (refs);
  if (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;
	}
    }
  else
    {
      struct df_scan_problem_data *problem_data
	= (struct df_scan_problem_data *) df_scan->problem_data;
      df->exit_block_uses = BITMAP_ALLOC (&problem_data->reg_bitmaps);
      changed = true;
    }

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

static bool initialized = false;


/* Initialize some platform specific structures.  */

void 
df_hard_reg_init (void)
{
#ifdef ELIMINABLE_REGS
  int i;
  static const struct {const int from, to; } eliminables[] = ELIMINABLE_REGS;
#endif
  if (initialized)
    return;

  /* Record which registers will be eliminated.  We use this in
     mark_used_regs.  */
  CLEAR_HARD_REG_SET (elim_reg_set);
  
#ifdef ELIMINABLE_REGS
  for (i = 0; i < (int) ARRAY_SIZE (eliminables); i++)
    SET_HARD_REG_BIT (elim_reg_set, eliminables[i].from);
#else
  SET_HARD_REG_BIT (elim_reg_set, FRAME_POINTER_REGNUM);
#endif
  
  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 (bb) 
    {
      rtx 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)
{
  gcc_assert (df);
  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)
{
  gcc_assert (df);
  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 (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 (df_ref *new_rec, df_ref *old_rec,
		bool abort_if_fail)
{
  while ((*new_rec) && (*old_rec))
    {
      if (!df_ref_equal_p (*new_rec, *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);
	}

      new_rec++;
      old_rec++;
    }

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


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

static bool
df_mws_verify (struct df_mw_hardreg **new_rec, struct df_mw_hardreg **old_rec,
	       bool abort_if_fail)
{
  while ((*new_rec) && (*old_rec))
    {
      if (!df_mw_equal_p (*new_rec, *old_rec))
	{
	  if (abort_if_fail)
	    gcc_assert (0);
	  else
	    return false;
	}
      new_rec++;
      old_rec++;
    }

  if (abort_if_fail)
    gcc_assert ((*new_rec == NULL) && (*old_rec == NULL));
  else
    return ((*new_rec == NULL) && (*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 (struct df_collection_rec *collection_rec,
		     basic_block bb, 
                     rtx insn,
		     bool abort_if_fail)
{
  bool ret1, ret2, ret3, ret4;
  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);

  if (!DF_INSN_UID_DEFS (uid))
    {
      /* The insn_rec was created but it was never filled out.  */
      if (abort_if_fail)
	gcc_assert (0);
      else 
	return false;
    }

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


/* 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;
  struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index);
  struct df_collection_rec collection_rec;
  
  memset (&collection_rec, 0, sizeof (struct df_collection_rec));
  collection_rec.def_vec = XALLOCAVEC (df_ref, 1000);
  collection_rec.use_vec = XALLOCAVEC (df_ref, 1000);
  collection_rec.eq_use_vec = XALLOCAVEC (df_ref, 1000);
  collection_rec.mw_vec = XALLOCAVEC (struct df_mw_hardreg *, 100);

  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)
{
  bitmap entry_block_defs = BITMAP_ALLOC (&df_bitmap_obstack);
  bool is_eq;

  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)
    {
      print_current_pass (stderr);
      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);
    }

  BITMAP_FREE (entry_block_defs);

  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)
{
  bitmap exit_block_uses = BITMAP_ALLOC (&df_bitmap_obstack);
  bool is_eq;

  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)
    {
      print_current_pass (stderr);
      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);
    }

  BITMAP_FREE (exit_block_uses);

  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;
  bitmap regular_block_artificial_uses;
  bitmap eh_block_artificial_uses;

  if (!df)
    return;

  /* Verification is a 4 step process. */

  /* (1) All of the refs are marked by going thru 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.  */
  regular_block_artificial_uses = BITMAP_ALLOC (&df_bitmap_obstack);
  eh_block_artificial_uses = BITMAP_ALLOC (&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));

  BITMAP_FREE (regular_block_artificial_uses);
  BITMAP_FREE (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 (bb)
    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));
    }
}
