]> git.ipfire.org Git - thirdparty/gcc.git/blobdiff - gcc/df-scan.c
2015-10-29 Andrew MacLeod <amacleod@redhat.com>
[thirdparty/gcc.git] / gcc / df-scan.c
index 5f0ba4aaa7ee270d750ab84f67b4c0f3445ad337..e0f41a285cbb72199aad9b67279e74ce83e693b8 100644 (file)
@@ -1,5 +1,5 @@
 /* Scanning of rtl for dataflow analysis.
-   Copyright (C) 1999-2013 Free Software Foundation, Inc.
+   Copyright (C) 1999-2015 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)
@@ -24,59 +24,21 @@ along with GCC; see the file COPYING3.  If not see
 #include "config.h"
 #include "system.h"
 #include "coretypes.h"
-#include "tm.h"
+#include "backend.h"
+#include "target.h"
 #include "rtl.h"
+#include "tree.h"
+#include "df.h"
 #include "tm_p.h"
 #include "insn-config.h"
-#include "recog.h"
-#include "function.h"
 #include "regs.h"
-#include "alloc-pool.h"
+#include "emit-rtl.h"  /* FIXME: Can go away once crtl is moved to rtl.h.  */
+#include "recog.h"
+#include "alias.h"
 #include "flags.h"
-#include "hard-reg-set.h"
-#include "basic-block.h"
-#include "sbitmap.h"
-#include "bitmap.h"
 #include "dumpfile.h"
-#include "tree.h"
-#include "target.h"
-#include "target-def.h"
-#include "df.h"
-#include "emit-rtl.h"  /* FIXME: Can go away once crtl is moved to rtl.h.  */
-
-
-typedef struct df_mw_hardreg *df_mw_hardreg_ptr;
 
 
-#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;
@@ -86,15 +48,12 @@ static HARD_REG_SET elim_reg_set;
 
 struct df_collection_rec
 {
-  stack_vec<df_ref, 128> def_vec;
-  stack_vec<df_ref, 32> use_vec;
-  stack_vec<df_ref, 32> eq_use_vec;
-  stack_vec<df_mw_hardreg_ptr, 32> mw_vec;
+  auto_vec<df_ref, 128> def_vec;
+  auto_vec<df_ref, 32> use_vec;
+  auto_vec<df_ref, 32> eq_use_vec;
+  auto_vec<df_mw_hardreg *, 32> mw_vec;
 };
 
-static 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 *,
@@ -111,10 +70,6 @@ static void df_uses_record (struct df_collection_rec *,
                            int ref_flags);
 
 static void df_install_ref_incremental (df_ref);
-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, int ref_flags);
 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 *);
@@ -127,20 +82,23 @@ 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_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, unsigned int);
+                                  basic_block, rtx_insn *, unsigned int);
 
-static bool df_insn_refs_verify (struct df_collection_rec *, basic_block, rtx, bool);
+static bool df_insn_refs_verify (struct df_collection_rec *, basic_block,
+                                rtx_insn *, 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 *);
+static int df_ref_compare (df_ref, df_ref);
+static int df_ref_ptr_compare (const void *, const void *);
+static int df_mw_compare (const df_mw_hardreg *, const df_mw_hardreg *);
+static int df_mw_ptr_compare (const void *, const void *);
 
 static void df_insn_info_delete (unsigned int);
 
@@ -174,55 +132,23 @@ static const unsigned int copy_all = copy_defs | copy_uses | copy_eq_uses
 /* 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 insn_pool;
-  alloc_pool reg_pool;
-  alloc_pool mw_reg_pool;
+  object_allocator<df_base_ref> *ref_base_pool;
+  object_allocator<df_artificial_ref> *ref_artificial_pool;
+  object_allocator<df_regular_ref> *ref_regular_pool;
+  object_allocator<df_insn_info> *insn_pool;
+  object_allocator<df_reg_info> *reg_pool;
+  object_allocator<df_mw_hardreg> *mw_reg_pool;
+
   bitmap_obstack reg_bitmaps;
   bitmap_obstack insn_bitmaps;
 };
 
-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);
@@ -260,12 +186,12 @@ df_scan_free_internal (void)
   bitmap_clear (&df->insns_to_rescan);
   bitmap_clear (&df->insns_to_notes_rescan);
 
-  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->insn_pool);
-  free_alloc_pool (problem_data->reg_pool);
-  free_alloc_pool (problem_data->mw_reg_pool);
+  delete problem_data->ref_base_pool;
+  delete problem_data->ref_artificial_pool;
+  delete problem_data->ref_regular_pool;
+  delete problem_data->insn_pool;
+  delete problem_data->reg_pool;
+  delete problem_data->mw_reg_pool;
   bitmap_obstack_release (&problem_data->reg_bitmaps);
   bitmap_obstack_release (&problem_data->insn_bitmaps);
   free (df_scan->problem_data);
@@ -279,31 +205,22 @@ df_scan_free_bb_info (basic_block bb, void *vbb_info)
 {
   struct df_scan_bb_info *bb_info = (struct df_scan_bb_info *) vbb_info;
   unsigned int bb_index = bb->index;
+  rtx_insn *insn;
 
-  /* See if bb_info is initialized.  */
-  if (bb_info->artificial_defs)
-    {
-      rtx insn;
-      FOR_BB_INSNS (bb, insn)
-       {
-         if (INSN_P (insn))
-           df_insn_info_delete (INSN_UID (insn));
-       }
-
-      if (bb_index < df_scan->block_info_size)
-       bb_info = df_scan_get_bb_info (bb_index);
-
-      /* Get rid of any artificial uses or defs.  */
-      if (bb_info->artificial_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;
-       }
-    }
+  FOR_BB_INSNS (bb, insn)
+    if (INSN_P (insn))
+      df_insn_info_delete (INSN_UID (insn));
+
+  if (bb_index < df_scan->block_info_size)
+    bb_info = df_scan_get_bb_info (bb_index);
+
+  /* Get rid of any artificial uses or defs.  */
+  df_ref_chain_delete_du_chain (bb_info->artificial_defs);
+  df_ref_chain_delete_du_chain (bb_info->artificial_uses);
+  df_ref_chain_delete (bb_info->artificial_defs);
+  df_ref_chain_delete (bb_info->artificial_uses);
+  bb_info->artificial_defs = NULL;
+  bb_info->artificial_uses = NULL;
 }
 
 
@@ -315,7 +232,6 @@ 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 = 512;
   basic_block bb;
 
   /* Given the number of pools, this is really faster than tearing
@@ -327,24 +243,18 @@ df_scan_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
   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->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 / 16);
+  problem_data->ref_base_pool = new object_allocator<df_base_ref>
+    ("df_scan ref base");
+  problem_data->ref_artificial_pool = new object_allocator<df_artificial_ref>
+    ("df_scan ref artificial");
+  problem_data->ref_regular_pool = new object_allocator<df_regular_ref>
+    ("df_scan ref regular");
+  problem_data->insn_pool = new object_allocator<df_insn_info>
+    ("df_scan insn");
+  problem_data->reg_pool = new object_allocator<df_reg_info>
+    ("df_scan reg");
+  problem_data->mw_reg_pool = new object_allocator<df_mw_hardreg>
+    ("df_scan mw_reg");
 
   bitmap_obstack_initialize (&problem_data->reg_bitmaps);
   bitmap_obstack_initialize (&problem_data->insn_bitmaps);
@@ -355,7 +265,7 @@ df_scan_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
   df_grow_insn_info ();
   df_grow_bb_info (df_scan);
 
-  FOR_ALL_BB (bb)
+  FOR_ALL_BB_FN (bb, cfun)
     {
       unsigned int bb_index = bb->index;
       struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb_index);
@@ -403,7 +313,7 @@ df_scan_start_dump (FILE *file ATTRIBUTE_UNUSED)
   int icount = 0;
   int ccount = 0;
   basic_block bb;
-  rtx insn;
+  rtx_insn *insn;
 
   fprintf (file, ";;  invalidated by call \t");
   df_print_regset (file, regs_invalidated_by_call_regset);
@@ -420,7 +330,7 @@ df_scan_start_dump (FILE *file ATTRIBUTE_UNUSED)
   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, " %d [%s]", i, reg_names[i]);
   fprintf (file, "\n;;  ref usage \t");
 
   for (i = 0; i < (int)df->regs_inited; i++)
@@ -449,7 +359,7 @@ df_scan_start_dump (FILE *file ATTRIBUTE_UNUSED)
        fprintf (file, "} ");
       }
 
-  FOR_EACH_BB (bb)
+  FOR_EACH_BB_FN (bb, cfun)
     FOR_BB_INSNS (bb, insn)
       if (INSN_P (insn))
        {
@@ -482,7 +392,7 @@ df_scan_start_block (basic_block bb, FILE *file)
     }
 #if 0
   {
-    rtx insn;
+    rtx_insn *insn;
     FOR_BB_INSNS (bb, insn)
       if (INSN_P (insn))
        df_insn_debug (insn, false, file);
@@ -570,13 +480,14 @@ df_grow_reg_info (void)
     {
       struct df_reg_info *reg_info;
 
-      reg_info = (struct df_reg_info *) pool_alloc (problem_data->reg_pool);
+      // TODO
+      reg_info = problem_data->reg_pool->allocate ();
       memset (reg_info, 0, sizeof (struct df_reg_info));
       df->def_regs[i] = reg_info;
-      reg_info = (struct df_reg_info *) pool_alloc (problem_data->reg_pool);
+      reg_info = problem_data->reg_pool->allocate ();
       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);
+      reg_info = problem_data->reg_pool->allocate ();
       memset (reg_info, 0, sizeof (struct df_reg_info));
       df->eq_use_regs[i] = reg_info;
       df->def_info.begin[i] = 0;
@@ -673,7 +584,7 @@ df_scan_blocks (void)
   df_set_bb_dirty (BASIC_BLOCK_FOR_FN (cfun, EXIT_BLOCK));
 
   /* Regular blocks */
-  FOR_EACH_BB (bb)
+  FOR_EACH_BB_FN (bb, cfun)
     {
       unsigned int bb_index = bb->index;
       df_bb_refs_record (bb_index, true);
@@ -685,7 +596,7 @@ df_scan_blocks (void)
    depending on whether LOC is inside PATTERN (INSN) or a note.  */
 
 void
-df_uses_create (rtx *loc, rtx insn, int ref_flags)
+df_uses_create (rtx *loc, rtx_insn *insn, int ref_flags)
 {
   gcc_assert (!(ref_flags & ~DF_REF_IN_NOTE));
   df_uses_record (NULL, loc, DF_REF_REG_USE,
@@ -694,57 +605,29 @@ df_uses_create (rtx *loc, rtx insn, int ref_flags)
                   ref_flags);
 }
 
-/* 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.  */
-
-df_ref
-df_ref_create (rtx reg, rtx *loc, rtx insn,
-              basic_block bb,
-              enum df_ref_type ref_type,
-              int ref_flags)
-{
-  enum df_ref_class cl;
-
-  df_grow_reg_info ();
-
-  /* You cannot hack artificial refs.  */
-  gcc_assert (insn);
-
-  if (loc)
-    cl = DF_REF_REGULAR;
-  else
-    cl = DF_REF_BASE;
-
-  return df_ref_create_structure (cl, NULL, reg, loc, bb,
-                                  DF_INSN_INFO_GET (insn),
-                                  ref_type, ref_flags);
-}
-
 static void
 df_install_ref_incremental (df_ref ref)
 {
   struct df_reg_info **reg_info;
   struct df_ref_info *ref_info;
-  df_ref *ref_rec;
-  df_ref **ref_rec_ptr;
-  unsigned int count = 0;
+  df_ref *ref_ptr;
   bool add_to_table;
 
-  rtx insn = DF_REF_INSN (ref);
+  rtx_insn *insn = DF_REF_INSN (ref);
   basic_block bb = BLOCK_FOR_INSN (insn);
 
   if (DF_REF_REG_DEF_P (ref))
     {
       reg_info = df->def_regs;
       ref_info = &df->def_info;
-      ref_rec_ptr = &DF_INSN_DEFS (insn);
+      ref_ptr = &DF_INSN_DEFS (insn);
       add_to_table = ref_info->ref_order != DF_REF_ORDER_NO_TABLE;
     }
   else if (DF_REF_FLAGS (ref) & DF_REF_IN_NOTE)
     {
       reg_info = df->eq_use_regs;
       ref_info = &df->use_info;
-      ref_rec_ptr = &DF_INSN_EQ_USES (insn);
+      ref_ptr = &DF_INSN_EQ_USES (insn);
       switch (ref_info->ref_order)
        {
        case DF_REF_ORDER_UNORDERED_WITH_NOTES:
@@ -761,7 +644,7 @@ df_install_ref_incremental (df_ref ref)
     {
       reg_info = df->use_regs;
       ref_info = &df->use_info;
-      ref_rec_ptr = &DF_INSN_USES (insn);
+      ref_ptr = &DF_INSN_USES (insn);
       add_to_table = ref_info->ref_order != DF_REF_ORDER_NO_TABLE;
     }
 
@@ -784,29 +667,11 @@ df_install_ref_incremental (df_ref ref)
        break;
       }
 
-  ref_rec = *ref_rec_ptr;
-  while (*ref_rec)
-    {
-      count++;
-      ref_rec++;
-    }
+  while (*ref_ptr && df_ref_compare (*ref_ptr, ref) < 0)
+    ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr);
 
-  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;
-    }
+  DF_REF_NEXT_LOC (ref) = *ref_ptr;
+  *ref_ptr = ref;
 
 #if 0
   if (dump_file)
@@ -837,15 +702,17 @@ df_free_ref (df_ref ref)
   switch (DF_REF_CLASS (ref))
     {
     case DF_REF_BASE:
-      pool_free (problem_data->ref_base_pool, ref);
+      problem_data->ref_base_pool->remove ((df_base_ref *) (ref));
       break;
 
     case DF_REF_ARTIFICIAL:
-      pool_free (problem_data->ref_artificial_pool, ref);
+      problem_data->ref_artificial_pool->remove
+       ((df_artificial_ref *) (ref));
       break;
 
     case DF_REF_REGULAR:
-      pool_free (problem_data->ref_regular_pool, ref);
+      problem_data->ref_regular_pool->remove
+       ((df_regular_ref *) (ref));
       break;
     }
 }
@@ -933,95 +800,20 @@ df_reg_chain_unlink (df_ref ref)
   df_free_ref (ref);
 }
 
-
-/* Remove REF from VEC.  */
+/* Initialize INSN_INFO to describe INSN.  */
 
 static void
-df_ref_compress_rec (df_ref **vec_ptr, df_ref ref)
+df_insn_info_init_fields (df_insn_info *insn_info, rtx_insn *insn)
 {
-  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;
-    }
+  memset (insn_info, 0, sizeof (struct df_insn_info));
+  insn_info->insn = insn;
 }
 
-
-/* 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.  */
-  if (!DEBUG_INSN_P (DF_REF_INSN (ref)))
-    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)
+df_insn_create_insn_record (rtx_insn *insn)
 {
   struct df_scan_problem_data *problem_data
     = (struct df_scan_problem_data *) df_scan->problem_data;
@@ -1031,11 +823,10 @@ df_insn_create_insn_record (rtx insn)
   insn_rec = DF_INSN_INFO_GET (insn);
   if (!insn_rec)
     {
-      insn_rec = (struct df_insn_info *) pool_alloc (problem_data->insn_pool);
+      insn_rec = problem_data->insn_pool->allocate ();
       DF_INSN_INFO_SET (insn, insn_rec);
     }
-  memset (insn_rec, 0, sizeof (struct df_insn_info));
-  insn_rec->insn = insn;
+  df_insn_info_init_fields (insn_rec, insn);
   return insn_rec;
 }
 
@@ -1043,58 +834,69 @@ df_insn_create_insn_record (rtx insn)
 /* 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)
+df_ref_chain_delete_du_chain (df_ref ref)
 {
-  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++;
-    }
+  for (; ref; ref = DF_REF_NEXT_LOC (ref))
+    /* CHAIN is allocated by DF_CHAIN. So make sure to
+       pass df_scan instance for the problem.  */
+    if (DF_REF_CHAIN (ref))
+      df_chain_unlink (ref);
 }
 
 
 /* Delete all refs in the ref chain.  */
 
 static void
-df_ref_chain_delete (df_ref *ref_rec)
+df_ref_chain_delete (df_ref ref)
 {
-  df_ref *start = ref_rec;
-  while (*ref_rec)
+  df_ref next;
+  for (; ref; ref = next)
     {
-      df_reg_chain_unlink (*ref_rec);
-      ref_rec++;
+      next = DF_REF_NEXT_LOC (ref);
+      df_reg_chain_unlink (ref);
     }
-
-  /* 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)
+df_mw_hardreg_chain_delete (struct df_mw_hardreg *hardregs)
 {
-  struct df_scan_problem_data *problem_data;
+  struct df_scan_problem_data *problem_data
+    = (struct df_scan_problem_data *) df_scan->problem_data;
+  df_mw_hardreg *next;
 
-  if (!hardregs)
-    return;
+  for (; hardregs; hardregs = next)
+    {
+      next = DF_MWS_NEXT (hardregs);
+      problem_data->mw_reg_pool->remove (hardregs);
+    }
+}
 
-  problem_data = (struct df_scan_problem_data *) df_scan->problem_data;
+/* Remove the contents of INSN_INFO (but don't free INSN_INFO itself).  */
+
+static void
+df_insn_info_free_fields (df_insn_info *insn_info)
+{
+  /* In general, notes do not have the insn_info fields
+     initialized.  However, combine deletes insns by changing them
+     to notes.  How clever.  So we cannot just check if it is a
+     valid insn before short circuiting this code, we need to see
+     if we actually initialized it.  */
+  df_mw_hardreg_chain_delete (insn_info->mw_hardregs);
 
-  while (*hardregs)
+  if (df_chain)
     {
-      pool_free (problem_data->mw_reg_pool, *hardregs);
-      hardregs++;
+      df_ref_chain_delete_du_chain (insn_info->defs);
+      df_ref_chain_delete_du_chain (insn_info->uses);
+      df_ref_chain_delete_du_chain (insn_info->eq_uses);
     }
-}
 
+  df_ref_chain_delete (insn_info->defs);
+  df_ref_chain_delete (insn_info->uses);
+  df_ref_chain_delete (insn_info->eq_uses);
+}
 
 /* Delete all of the refs information from the insn with UID.
    Internal helper for df_insn_delete, df_insn_rescan, and other
@@ -1114,28 +916,8 @@ df_insn_info_delete (unsigned int uid)
       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);
-         df_scan_free_mws_vec (insn_info->mw_hardregs);
-       }
-      pool_free (problem_data->insn_pool, insn_info);
+      df_insn_info_free_fields (insn_info);
+      problem_data->insn_pool->remove (insn_info);
       DF_INSN_UID_SET (uid, NULL);
     }
 }
@@ -1144,7 +926,7 @@ df_insn_info_delete (unsigned int uid)
    or marked for later in deferred mode.  */
 
 void
-df_insn_delete (rtx insn)
+df_insn_delete (rtx_insn *insn)
 {
   unsigned int uid;
   basic_block bb;
@@ -1219,7 +1001,7 @@ df_free_collection_rec (struct df_collection_rec *collection_rec)
   FOR_EACH_VEC_ELT (collection_rec->eq_use_vec, ix, ref)
     df_free_ref (ref);
   FOR_EACH_VEC_ELT (collection_rec->mw_vec, ix, mw)
-    pool_free (problem_data->mw_reg_pool, mw);
+    problem_data->mw_reg_pool->remove (mw);
 
   collection_rec->def_vec.release ();
   collection_rec->use_vec.release ();
@@ -1230,7 +1012,7 @@ df_free_collection_rec (struct df_collection_rec *collection_rec)
 /* Rescan INSN.  Return TRUE if the rescanning produced any changes.  */
 
 bool
-df_insn_rescan (rtx insn)
+df_insn_rescan (rtx_insn *insn)
 {
   unsigned int uid = INSN_UID (insn);
   struct df_insn_info *insn_info = NULL;
@@ -1262,10 +1044,10 @@ df_insn_rescan (rtx insn)
       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;
+         insn_info->defs = 0;
+         insn_info->uses = 0;
+         insn_info->eq_uses = 0;
+         insn_info->mw_hardregs = 0;
        }
       if (dump_file)
        fprintf (dump_file, "deferring rescan insn with uid = %d.\n", uid);
@@ -1297,8 +1079,8 @@ df_insn_rescan (rtx insn)
       /* There's change - we need to delete the existing info.
         Since the insn isn't moved, we can salvage its LUID.  */
       luid = DF_INSN_LUID (insn);
-      df_insn_info_delete (uid);
-      df_insn_create_insn_record (insn);
+      df_insn_info_free_fields (insn_info);
+      df_insn_info_init_fields (insn_info, insn);
       DF_INSN_LUID (insn) = luid;
     }
   else
@@ -1320,7 +1102,7 @@ df_insn_rescan (rtx insn)
    dirty.  */
 
 bool
-df_insn_rescan_debug_internal (rtx insn)
+df_insn_rescan_debug_internal (rtx_insn *insn)
 {
   unsigned int uid = INSN_UID (insn);
   struct df_insn_info *insn_info;
@@ -1342,13 +1124,10 @@ df_insn_rescan_debug_internal (rtx insn)
   bitmap_clear_bit (&df->insns_to_rescan, uid);
   bitmap_clear_bit (&df->insns_to_notes_rescan, uid);
 
-  if (!insn_info->defs)
-    return false;
-
-  if (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 (insn_info->defs == 0
+      && insn_info->uses == 0
+      && insn_info->eq_uses == 0
+      && insn_info->mw_hardregs == 0)
     return false;
 
   df_mw_hardreg_chain_delete (insn_info->mw_hardregs);
@@ -1363,12 +1142,11 @@ df_insn_rescan_debug_internal (rtx insn)
   df_ref_chain_delete (insn_info->defs);
   df_ref_chain_delete (insn_info->uses);
   df_ref_chain_delete (insn_info->eq_uses);
-  df_scan_free_mws_vec (insn_info->mw_hardregs);
 
-  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;
+  insn_info->defs = 0;
+  insn_info->uses = 0;
+  insn_info->eq_uses = 0;
+  insn_info->mw_hardregs = 0;
 
   return true;
 }
@@ -1415,9 +1193,9 @@ df_insn_rescan_all (void)
   bitmap_clear (&df->insns_to_rescan);
   bitmap_clear (&df->insns_to_notes_rescan);
 
-  FOR_EACH_BB (bb)
+  FOR_EACH_BB_FN (bb, cfun)
     {
-      rtx insn;
+      rtx_insn *insn;
       FOR_BB_INSNS (bb, insn)
        {
          df_insn_rescan (insn);
@@ -1638,19 +1416,19 @@ df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info,
   EXECUTE_IF_SET_IN_BITMAP (df->blocks_to_analyze, 0, bb_index, bi)
     {
       basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
-      rtx insn;
-      df_ref *ref_rec;
+      rtx_insn *insn;
+      df_ref def, use;
 
       if (include_defs)
-       for (ref_rec = df_get_artificial_defs (bb_index); *ref_rec; ref_rec++)
+       FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
          {
-           unsigned int regno = DF_REF_REGNO (*ref_rec);
+           unsigned int regno = DF_REF_REGNO (def);
            ref_info->count[regno]++;
          }
       if (include_uses)
-       for (ref_rec = df_get_artificial_uses (bb_index); *ref_rec; ref_rec++)
+       FOR_EACH_ARTIFICIAL_USE (use, bb_index)
          {
-           unsigned int regno = DF_REF_REGNO (*ref_rec);
+           unsigned int regno = DF_REF_REGNO (use);
            ref_info->count[regno]++;
          }
 
@@ -1658,24 +1436,24 @@ df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info,
        {
          if (INSN_P (insn))
            {
-             unsigned int uid = INSN_UID (insn);
+             struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
 
              if (include_defs)
-               for (ref_rec = DF_INSN_UID_DEFS (uid); *ref_rec; ref_rec++)
+               FOR_EACH_INSN_INFO_DEF (def, insn_info)
                  {
-                   unsigned int regno = DF_REF_REGNO (*ref_rec);
+                   unsigned int regno = DF_REF_REGNO (def);
                    ref_info->count[regno]++;
                  }
              if (include_uses)
-               for (ref_rec = DF_INSN_UID_USES (uid); *ref_rec; ref_rec++)
+               FOR_EACH_INSN_INFO_USE (use, insn_info)
                  {
-                   unsigned int regno = DF_REF_REGNO (*ref_rec);
+                   unsigned int regno = DF_REF_REGNO (use);
                    ref_info->count[regno]++;
                  }
              if (include_eq_uses)
-               for (ref_rec = DF_INSN_UID_EQ_USES (uid); *ref_rec; ref_rec++)
+               FOR_EACH_INSN_INFO_EQ_USE (use, insn_info)
                  {
-                   unsigned int regno = DF_REF_REGNO (*ref_rec);
+                   unsigned int regno = DF_REF_REGNO (use);
                    ref_info->count[regno]++;
                  }
            }
@@ -1692,33 +1470,31 @@ df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info,
   EXECUTE_IF_SET_IN_BITMAP (df->blocks_to_analyze, 0, bb_index, bi)
     {
       basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
-      rtx insn;
-      df_ref *ref_rec;
+      rtx_insn *insn;
+      df_ref def, use;
 
       if (include_defs)
-       for (ref_rec = df_get_artificial_defs (bb_index); *ref_rec; ref_rec++)
+       FOR_EACH_ARTIFICIAL_DEF (def, bb_index)
          {
-           df_ref ref = *ref_rec;
-           unsigned int regno = DF_REF_REGNO (ref);
+           unsigned int regno = DF_REF_REGNO (def);
            if (regno >= start)
              {
                unsigned int id
                  = ref_info->begin[regno] + ref_info->count[regno]++;
-               DF_REF_ID (ref) = id;
-               ref_info->refs[id] = ref;
+               DF_REF_ID (def) = id;
+               ref_info->refs[id] = def;
              }
          }
       if (include_uses)
-       for (ref_rec = df_get_artificial_uses (bb_index); *ref_rec; ref_rec++)
+       FOR_EACH_ARTIFICIAL_USE (use, bb_index)
          {
-           df_ref ref = *ref_rec;
-           unsigned int regno = DF_REF_REGNO (ref);
+           unsigned int regno = DF_REF_REGNO (def);
            if (regno >= start)
              {
                unsigned int id
                  = ref_info->begin[regno] + ref_info->count[regno]++;
-               DF_REF_ID (ref) = id;
-               ref_info->refs[id] = ref;
+               DF_REF_ID (use) = id;
+               ref_info->refs[id] = use;
              }
          }
 
@@ -1726,45 +1502,42 @@ df_reorganize_refs_by_reg_by_insn (struct df_ref_info *ref_info,
        {
          if (INSN_P (insn))
            {
-             unsigned int uid = INSN_UID (insn);
+             struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
 
              if (include_defs)
-               for (ref_rec = DF_INSN_UID_DEFS (uid); *ref_rec; ref_rec++)
+               FOR_EACH_INSN_INFO_DEF (def, insn_info)
                  {
-                   df_ref ref = *ref_rec;
-                   unsigned int regno = DF_REF_REGNO (ref);
+                   unsigned int regno = DF_REF_REGNO (def);
                    if (regno >= start)
                      {
                        unsigned int id
                          = ref_info->begin[regno] + ref_info->count[regno]++;
-                       DF_REF_ID (ref) = id;
-                       ref_info->refs[id] = ref;
+                       DF_REF_ID (def) = id;
+                       ref_info->refs[id] = def;
                      }
                  }
              if (include_uses)
-               for (ref_rec = DF_INSN_UID_USES (uid); *ref_rec; ref_rec++)
+               FOR_EACH_INSN_INFO_USE (use, insn_info)
                  {
-                   df_ref ref = *ref_rec;
-                   unsigned int regno = DF_REF_REGNO (ref);
+                   unsigned int regno = DF_REF_REGNO (use);
                    if (regno >= start)
                      {
                        unsigned int id
                          = ref_info->begin[regno] + ref_info->count[regno]++;
-                       DF_REF_ID (ref) = id;
-                       ref_info->refs[id] = ref;
+                       DF_REF_ID (use) = id;
+                       ref_info->refs[id] = use;
                      }
                  }
              if (include_eq_uses)
-               for (ref_rec = DF_INSN_UID_EQ_USES (uid); *ref_rec; ref_rec++)
+               FOR_EACH_INSN_INFO_EQ_USE (use, insn_info)
                  {
-                   df_ref ref = *ref_rec;
-                   unsigned int regno = DF_REF_REGNO (ref);
+                   unsigned int regno = DF_REF_REGNO (use);
                    if (regno >= start)
                      {
                        unsigned int id
                          = ref_info->begin[regno] + ref_info->count[regno]++;
-                       DF_REF_ID (ref) = id;
-                       ref_info->refs[id] = ref;
+                       DF_REF_ID (use) = id;
+                       ref_info->refs[id] = use;
                      }
                  }
            }
@@ -1800,19 +1573,15 @@ df_reorganize_refs_by_reg (struct df_ref_info *ref_info,
 static unsigned int
 df_add_refs_to_table (unsigned int offset,
                      struct df_ref_info *ref_info,
-                     df_ref *ref_vec)
+                     df_ref ref)
 {
-  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++;
-    }
+  for (; ref; ref = DF_REF_NEXT_LOC (ref))
+    if (!(df->changeable_flags & DF_NO_HARD_REGS)
+       || (DF_REF_REGNO (ref) >= FIRST_PSEUDO_REGISTER))
+      {
+       ref_info->refs[offset] = ref;
+       DF_REF_ID (ref) = offset++;
+      }
   return offset;
 }
 
@@ -1827,7 +1596,7 @@ df_reorganize_refs_by_insn_bb (basic_block bb, unsigned int offset,
                               bool include_defs, bool include_uses,
                               bool include_eq_uses)
 {
-  rtx insn;
+  rtx_insn *insn;
 
   if (include_defs)
     offset = df_add_refs_to_table (offset, ref_info,
@@ -1887,7 +1656,7 @@ df_reorganize_refs_by_insn (struct df_ref_info *ref_info,
     }
   else
     {
-      FOR_ALL_BB (bb)
+      FOR_ALL_BB_FN (bb, cfun)
        offset = df_reorganize_refs_by_insn_bb (bb, offset, ref_info,
                                                include_defs, include_uses,
                                                include_eq_uses);
@@ -1979,7 +1748,7 @@ df_maybe_reorganize_def_refs (enum df_ref_order order)
    instructions from one block to another.  */
 
 void
-df_insn_change_bb (rtx insn, basic_block new_bb)
+df_insn_change_bb (rtx_insn *insn, basic_block new_bb)
 {
   basic_block old_bb = BLOCK_FOR_INSN (insn);
   struct df_insn_info *insn_info;
@@ -2027,7 +1796,7 @@ df_insn_change_bb (rtx insn, basic_block new_bb)
 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)
+                             unsigned int new_regno, rtx loc)
 {
   df_ref the_ref = old_df->reg_chain;
 
@@ -2039,9 +1808,8 @@ df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df,
        {
          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;
+         df_ref *ref_ptr;
          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];
@@ -2068,23 +1836,42 @@ df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df,
          /* 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;
+         if (DF_REF_REG_DEF_P (the_ref))
+           ref_ptr = &insn_info->defs;
+         else if (DF_REF_FLAGS (the_ref) & DF_REF_IN_NOTE)
+           ref_ptr = &insn_info->eq_uses;
          else
-           ref_vec = insn_info->uses;
+           ref_ptr = &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)
+         /* Stop if we find the current reference or where the reference
+            needs to be.  */
+         while (*ref_ptr != the_ref && df_ref_compare (*ref_ptr, the_ref) < 0)
+           ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr);
+         if (*ref_ptr != the_ref)
            {
-             count++;
-             ref_vec_t++;
+             /* The reference needs to be promoted up the list.  */
+             df_ref next = DF_REF_NEXT_LOC (the_ref);
+             DF_REF_NEXT_LOC (the_ref) = *ref_ptr;
+             *ref_ptr = the_ref;
+             do
+               ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr);
+             while (*ref_ptr != the_ref);
+             *ref_ptr = next;
+           }
+         else if (DF_REF_NEXT_LOC (the_ref)
+                  && df_ref_compare (the_ref, DF_REF_NEXT_LOC (the_ref)) > 0)
+           {
+             /* The reference needs to be demoted down the list.  */
+             *ref_ptr = DF_REF_NEXT_LOC (the_ref);
+             do
+               ref_ptr = &DF_REF_NEXT_LOC (*ref_ptr);
+             while (*ref_ptr && df_ref_compare (the_ref, *ref_ptr) > 0);
+             DF_REF_NEXT_LOC (the_ref) = *ref_ptr;
+             *ref_ptr = the_ref;
            }
-         qsort (ref_vec, count, sizeof (df_ref ), df_ref_compare);
 
          the_ref = next_ref;
        }
@@ -2094,82 +1881,63 @@ df_ref_change_reg_with_loc_1 (struct df_reg_info *old_df,
 }
 
 
-/* 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. */
+/* Change the regno of register LOC to NEW_REGNO and update the df
+   information accordingly.  Refs that do not match LOC are not changed
+   which means that artificial refs are not changed since they have no loc.
+   This call is to support the SET_REGNO macro. */
 
 void
-df_ref_change_reg_with_loc (int old_regno, int new_regno, rtx loc)
+df_ref_change_reg_with_loc (rtx loc, unsigned int new_regno)
 {
-  if ((!df) || (old_regno == -1) || (old_regno == new_regno))
+  unsigned int old_regno = REGNO (loc);
+  if (old_regno == new_regno)
     return;
 
-  df_grow_reg_info ();
+  if (df)
+    {
+      df_grow_reg_info ();
 
-  df_ref_change_reg_with_loc_1 (DF_REG_DEF_GET (old_regno),
-                               DF_REG_DEF_GET (new_regno), new_regno, loc);
-  df_ref_change_reg_with_loc_1 (DF_REG_USE_GET (old_regno),
-                               DF_REG_USE_GET (new_regno), new_regno, loc);
-  df_ref_change_reg_with_loc_1 (DF_REG_EQ_USE_GET (old_regno),
-                               DF_REG_EQ_USE_GET (new_regno), new_regno, loc);
+      df_ref_change_reg_with_loc_1 (DF_REG_DEF_GET (old_regno),
+                                   DF_REG_DEF_GET (new_regno),
+                                   new_regno, loc);
+      df_ref_change_reg_with_loc_1 (DF_REG_USE_GET (old_regno),
+                                   DF_REG_USE_GET (new_regno),
+                                   new_regno, loc);
+      df_ref_change_reg_with_loc_1 (DF_REG_EQ_USE_GET (old_regno),
+                                   DF_REG_EQ_USE_GET (new_regno),
+                                   new_regno, loc);
+    }
+  set_mode_and_regno (loc, GET_MODE (loc), new_regno);
 }
 
 
 /* Delete the mw_hardregs that point into the eq_notes.  */
 
-static unsigned int
+static void
 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_mw_hardreg **mw_ptr = &insn_info->mw_hardregs;
   struct df_scan_problem_data *problem_data
     = (struct df_scan_problem_data *) df_scan->problem_data;
 
-  if (!*mw_vec)
-    return 0;
-
-  while (*mw_vec)
+  while (*mw_ptr)
     {
-      if ((*mw_vec)->flags & DF_REF_IN_NOTE)
+      df_mw_hardreg *mw = *mw_ptr;
+      if (mw->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++;
+         *mw_ptr = DF_MWS_NEXT (mw);
+         problem_data->mw_reg_pool->remove (mw);
        }
       else
-       {
-         mw_vec++;
-         count++;
-       }
+       mw_ptr = &DF_MWS_NEXT (mw);
     }
-
-  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)
+df_notes_rescan (rtx_insn *insn)
 {
   struct df_insn_info *insn_info;
   unsigned int uid = INSN_UID (insn);
@@ -2196,10 +1964,10 @@ df_notes_rescan (rtx insn)
       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;
+         insn_info->defs = 0;
+         insn_info->uses = 0;
+         insn_info->eq_uses = 0;
+         insn_info->mw_hardregs = 0;
        }
 
       bitmap_clear_bit (&df->insns_to_delete, uid);
@@ -2218,10 +1986,9 @@ df_notes_rescan (rtx insn)
       basic_block bb = BLOCK_FOR_INSN (insn);
       rtx note;
       struct df_collection_rec collection_rec;
-      unsigned int num_deleted;
-      unsigned int mw_len;
+      unsigned int i;
 
-      num_deleted = df_mw_hardreg_chain_delete_eq_uses (insn_info);
+      df_mw_hardreg_chain_delete_eq_uses (insn_info);
       df_ref_chain_delete (insn_info->eq_uses);
       insn_info->eq_uses = NULL;
 
@@ -2243,45 +2010,14 @@ df_notes_rescan (rtx insn)
 
       /* Find some place to put any new mw_hardregs.  */
       df_canonize_collection_rec (&collection_rec);
-      mw_len = collection_rec.mw_vec.length ();
-      if (mw_len)
+      struct df_mw_hardreg **mw_ptr = &insn_info->mw_hardregs, *mw;
+      FOR_EACH_VEC_ELT (collection_rec.mw_vec, i, 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 (mw_len > num_deleted)
-               {
-                 insn_info->mw_hardregs =
-                   XRESIZEVEC (struct df_mw_hardreg *,
-                               insn_info->mw_hardregs,
-                               count + 1 + mw_len);
-               }
-             memcpy (&insn_info->mw_hardregs[count],
-                     collection_rec.mw_vec.address (),
-                     mw_len * sizeof (struct df_mw_hardreg *));
-             insn_info->mw_hardregs[count + mw_len] = NULL;
-             qsort (insn_info->mw_hardregs, count + mw_len,
-                    sizeof (struct df_mw_hardreg *), df_mw_compare);
-           }
-         else
-           {
-             /* No vector there. */
-             insn_info->mw_hardregs
-               = XNEWVEC (struct df_mw_hardreg*, 1 + mw_len);
-             memcpy (insn_info->mw_hardregs,
-                     collection_rec.mw_vec.address (),
-                     mw_len * sizeof (struct df_mw_hardreg *));
-             insn_info->mw_hardregs[mw_len] = NULL;
-           }
+         while (*mw_ptr && df_mw_compare (*mw_ptr, mw) < 0)
+           mw_ptr = &DF_MWS_NEXT (*mw_ptr);
+         DF_MWS_NEXT (mw) = *mw_ptr;
+         *mw_ptr = mw;
+         mw_ptr = &DF_MWS_NEXT (mw);
        }
       df_refs_add_to_chains (&collection_rec, bb, insn, copy_eq_uses);
     }
@@ -2340,14 +2076,8 @@ df_ref_equal_p (df_ref ref1, df_ref ref2)
    have the same bb.  So these fields are not checked.  */
 
 static int
-df_ref_compare (const void *r1, const void *r2)
+df_ref_compare (df_ref ref1, df_ref ref2)
 {
-  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);
 
@@ -2382,12 +2112,12 @@ df_ref_compare (const void *r1, const void *r2)
   return (int)DF_REF_ORDER (ref1) - (int)DF_REF_ORDER (ref2);
 }
 
-static void
-df_swap_refs (vec<df_ref, va_heap> *ref_vec, int i, int j)
+/* Like df_ref_compare, but compare two df_ref* pointers R1 and R2.  */
+
+static int
+df_ref_ptr_compare (const void *r1, const void *r2)
 {
-  df_ref tmp = (*ref_vec)[i];
-  (*ref_vec)[i] = (*ref_vec)[j];
-  (*ref_vec)[j] = tmp;
+  return df_ref_compare (*(const df_ref *) r1, *(const df_ref *) r2);
 }
 
 /* Sort and compress a set of refs.  */
@@ -2408,8 +2138,8 @@ df_sort_and_compress_refs (vec<df_ref, va_heap> *ref_vec)
     {
       df_ref r0 = (*ref_vec)[0];
       df_ref r1 = (*ref_vec)[1];
-      if (df_ref_compare (&r0, &r1) > 0)
-        df_swap_refs (ref_vec, 0, 1);
+      if (df_ref_compare (r0, r1) > 0)
+       std::swap ((*ref_vec)[0], (*ref_vec)[1]);
     }
   else
     {
@@ -2417,7 +2147,7 @@ df_sort_and_compress_refs (vec<df_ref, va_heap> *ref_vec)
        {
          df_ref r0 = (*ref_vec)[i];
          df_ref r1 = (*ref_vec)[i + 1];
-         if (df_ref_compare (&r0, &r1) >= 0)
+         if (df_ref_compare (r0, r1) >= 0)
            break;
        }
       /* If the array is already strictly ordered,
@@ -2429,7 +2159,7 @@ df_sort_and_compress_refs (vec<df_ref, va_heap> *ref_vec)
          of DF_REF_COMPARE.  */
       if (i == count - 1)
         return;
-      ref_vec->qsort (df_ref_compare);
+      ref_vec->qsort (df_ref_ptr_compare);
     }
 
   for (i=0; i<count-dist; i++)
@@ -2472,14 +2202,8 @@ df_mw_equal_p (struct df_mw_hardreg *mw1, struct df_mw_hardreg *mw2)
 /* Compare MW1 and MW2 for sorting.  */
 
 static int
-df_mw_compare (const void *m1, const void *m2)
+df_mw_compare (const df_mw_hardreg *mw1, const df_mw_hardreg *mw2)
 {
-  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;
 
@@ -2498,11 +2222,19 @@ df_mw_compare (const void *m1, const void *m2)
   return 0;
 }
 
+/* Like df_mw_compare, but compare two df_mw_hardreg** pointers R1 and R2.  */
+
+static int
+df_mw_ptr_compare (const void *m1, const void *m2)
+{
+  return df_mw_compare (*(const df_mw_hardreg *const *) m1,
+                       *(const df_mw_hardreg *const *) m2);
+}
 
 /* Sort and compress a set of refs.  */
 
 static void
-df_sort_and_compress_mws (vec<df_mw_hardreg_ptr, va_heap> *mw_vec)
+df_sort_and_compress_mws (vec<df_mw_hardreg *, va_heap> *mw_vec)
 {
   unsigned int count;
   struct df_scan_problem_data *problem_data
@@ -2517,7 +2249,7 @@ df_sort_and_compress_mws (vec<df_mw_hardreg_ptr, va_heap> *mw_vec)
     {
       struct df_mw_hardreg *m0 = (*mw_vec)[0];
       struct df_mw_hardreg *m1 = (*mw_vec)[1];
-      if (df_mw_compare (&m0, &m1) > 0)
+      if (df_mw_compare (m0, m1) > 0)
         {
           struct df_mw_hardreg *tmp = (*mw_vec)[0];
          (*mw_vec)[0] = (*mw_vec)[1];
@@ -2525,7 +2257,7 @@ df_sort_and_compress_mws (vec<df_mw_hardreg_ptr, va_heap> *mw_vec)
         }
     }
   else
-    mw_vec->qsort (df_mw_compare);
+    mw_vec->qsort (df_mw_ptr_compare);
 
   for (i=0; i<count-dist; i++)
     {
@@ -2533,8 +2265,7 @@ df_sort_and_compress_mws (vec<df_mw_hardreg_ptr, va_heap> *mw_vec)
       while (i + dist + 1 < count
             && df_mw_equal_p ((*mw_vec)[i], (*mw_vec)[i + dist + 1]))
        {
-         pool_free (problem_data->mw_reg_pool,
-                    (*mw_vec)[i + dist + 1]);
+         problem_data->mw_reg_pool->remove ((*mw_vec)[i + dist + 1]);
          dist++;
        }
       /* Copy it down to the next position.  */
@@ -2611,7 +2342,7 @@ df_install_ref (df_ref this_ref,
    eq_uses) and installs the entire group into the insn.  It also adds
    each of these refs into the appropriate chains.  */
 
-static df_ref *
+static df_ref
 df_install_refs (basic_block bb,
                 const vec<df_ref, va_heap> *old_vec,
                 struct df_reg_info **reg_info,
@@ -2621,7 +2352,6 @@ df_install_refs (basic_block bb,
   unsigned int count = old_vec->length ();
   if (count)
     {
-      df_ref *new_vec = XNEWVEC (df_ref, count + 1);
       bool add_to_table;
       df_ref this_ref;
       unsigned int ix;
@@ -2651,37 +2381,35 @@ df_install_refs (basic_block bb,
 
       FOR_EACH_VEC_ELT (*old_vec, ix, this_ref)
        {
-         new_vec[ix] = this_ref;
+         DF_REF_NEXT_LOC (this_ref) = (ix + 1 < old_vec->length ()
+                                       ? (*old_vec)[ix + 1]
+                                       : NULL);
          df_install_ref (this_ref, reg_info[DF_REF_REGNO (this_ref)],
                          ref_info, add_to_table);
        }
-
-      new_vec[count] = NULL;
-      return new_vec;
+      return (*old_vec)[0];
     }
   else
-    return df_null_ref_rec;
+    return 0;
 }
 
 
 /* This function takes the mws installs the entire group into the
    insn.  */
 
-static struct df_mw_hardreg **
-df_install_mws (const vec<df_mw_hardreg_ptr, va_heap> *old_vec)
+static struct df_mw_hardreg *
+df_install_mws (const vec<df_mw_hardreg *, va_heap> *old_vec)
 {
   unsigned int count = old_vec->length ();
   if (count)
     {
-      struct df_mw_hardreg **new_vec
-       = XNEWVEC (struct df_mw_hardreg*, count + 1);
-      memcpy (new_vec, old_vec->address (),
-             sizeof (struct df_mw_hardreg*) * count);
-      new_vec[count] = NULL;
-      return new_vec;
+      for (unsigned int i = 0; i < count - 1; i++)
+       DF_MWS_NEXT ((*old_vec)[i]) = (*old_vec)[i + 1];
+      DF_MWS_NEXT ((*old_vec)[count - 1]) = 0;
+      return (*old_vec)[0];
     }
   else
-    return df_null_mw_rec;
+    return 0;
 }
 
 
@@ -2690,7 +2418,7 @@ df_install_mws (const vec<df_mw_hardreg_ptr, va_heap> *old_vec)
 
 static void
 df_refs_add_to_chains (struct df_collection_rec *collection_rec,
-                      basic_block bb, rtx insn, unsigned int flags)
+                      basic_block bb, rtx_insn *insn, unsigned int flags)
 {
   if (insn)
     {
@@ -2700,7 +2428,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec,
         chain specially.  */
       if (flags & copy_defs)
        {
-         df_scan_free_ref_vec (insn_rec->defs);
+         gcc_checking_assert (!insn_rec->defs);
          insn_rec->defs
            = df_install_refs (bb, &collection_rec->def_vec,
                               df->def_regs,
@@ -2708,7 +2436,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec,
        }
       if (flags & copy_uses)
        {
-         df_scan_free_ref_vec (insn_rec->uses);
+         gcc_checking_assert (!insn_rec->uses);
          insn_rec->uses
            = df_install_refs (bb, &collection_rec->use_vec,
                               df->use_regs,
@@ -2716,7 +2444,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec,
        }
       if (flags & copy_eq_uses)
        {
-         df_scan_free_ref_vec (insn_rec->eq_uses);
+         gcc_checking_assert (!insn_rec->eq_uses);
          insn_rec->eq_uses
            = df_install_refs (bb, &collection_rec->eq_use_vec,
                               df->eq_use_regs,
@@ -2724,7 +2452,7 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec,
        }
       if (flags & copy_mw)
        {
-         df_scan_free_mws_vec (insn_rec->mw_hardregs);
+         gcc_checking_assert (!insn_rec->mw_hardregs);
          insn_rec->mw_hardregs
            = df_install_mws (&collection_rec->mw_vec);
        }
@@ -2733,12 +2461,12 @@ df_refs_add_to_chains (struct df_collection_rec *collection_rec,
     {
       struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index);
 
-      df_scan_free_ref_vec (bb_info->artificial_defs);
+      gcc_checking_assert (!bb_info->artificial_defs);
       bb_info->artificial_defs
        = df_install_refs (bb, &collection_rec->def_vec,
                           df->def_regs,
                           &df->def_info, false);
-      df_scan_free_ref_vec (bb_info->artificial_uses);
+      gcc_checking_assert (!bb_info->artificial_uses);
       bb_info->artificial_uses
        = df_install_refs (bb, &collection_rec->use_vec,
                           df->use_regs,
@@ -2765,18 +2493,18 @@ df_ref_create_structure (enum df_ref_class cl,
   switch (cl)
     {
     case DF_REF_BASE:
-      this_ref = (df_ref) pool_alloc (problem_data->ref_base_pool);
+      this_ref = (df_ref) (problem_data->ref_base_pool->allocate ());
       gcc_checking_assert (loc == NULL);
       break;
 
     case DF_REF_ARTIFICIAL:
-      this_ref = (df_ref) pool_alloc (problem_data->ref_artificial_pool);
+      this_ref = (df_ref) (problem_data->ref_artificial_pool->allocate ());
       this_ref->artificial_ref.bb = bb;
       gcc_checking_assert (loc == NULL);
       break;
 
     case DF_REF_REGULAR:
-      this_ref = (df_ref) pool_alloc (problem_data->ref_regular_pool);
+      this_ref = (df_ref) (problem_data->ref_regular_pool->allocate ());
       this_ref->regular_ref.loc = loc;
       gcc_checking_assert (loc);
       break;
@@ -2864,7 +2592,7 @@ df_ref_record (enum df_ref_class cl,
          endregno = regno + subreg_nregs (reg);
        }
       else
-       endregno = END_HARD_REGNO (reg);
+       endregno = END_REGNO (reg);
 
       /*  If this is a multiword hardreg, we create some extra
          datastructures that will enable us to easily build REG_DEAD
@@ -2878,7 +2606,7 @@ df_ref_record (enum df_ref_class cl,
            ref_flags |= DF_REF_PARTIAL;
          ref_flags |= DF_REF_MW_HARDREG;
 
-         hardreg = (struct df_mw_hardreg *) pool_alloc (problem_data->mw_reg_pool);
+         hardreg = problem_data->mw_reg_pool->allocate ();
          hardreg->type = ref_type;
          hardreg->flags = ref_flags;
          hardreg->mw_reg = reg;
@@ -3385,10 +3113,13 @@ df_get_call_refs (struct df_collection_rec *collection_rec,
   bool is_sibling_call;
   unsigned int i;
   HARD_REG_SET defs_generated;
+  HARD_REG_SET fn_reg_set_usage;
 
   CLEAR_HARD_REG_SET (defs_generated);
   df_find_hard_reg_defs (PATTERN (insn_info->insn), &defs_generated);
   is_sibling_call = SIBLING_CALL_P (insn_info->insn);
+  get_call_reg_set_usage (insn_info->insn, &fn_reg_set_usage,
+                         regs_invalidated_by_call);
 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     {
@@ -3412,13 +3143,12 @@ df_get_call_refs (struct df_collection_rec *collection_rec,
                               NULL, bb, insn_info, DF_REF_REG_DEF, flags);
            }
        }
-      else if (TEST_HARD_REG_BIT (regs_invalidated_by_call, i)
+      else if (TEST_HARD_REG_BIT (fn_reg_set_usage, i)
               /* no clobbers for regs that are the result of the call */
               && !TEST_HARD_REG_BIT (defs_generated, i)
               && (!is_sibling_call
                   || !bitmap_bit_p (df->exit_block_uses, i)
-                  || refers_to_regno_p (i, i+1,
-                                        crtl->return_rtx, NULL)))
+                  || refers_to_regno_p (i, crtl->return_rtx)))
          df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[i],
                         NULL, bb, insn_info, DF_REF_REG_DEF,
                         DF_REF_MAY_CLOBBER | flags);
@@ -3486,12 +3216,11 @@ df_insn_refs_collect (struct df_collection_rec *collection_rec,
                          regno_reg_rtx[FRAME_POINTER_REGNUM],
                          NULL, bb, insn_info,
                          DF_REF_REG_USE, 0);
-#if !HARD_FRAME_POINTER_IS_FRAME_POINTER
-          df_ref_record (DF_REF_BASE, collection_rec,
-                         regno_reg_rtx[HARD_FRAME_POINTER_REGNUM],
-                         NULL, bb, insn_info,
-                         DF_REF_REG_USE, 0);
-#endif
+         if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
+           df_ref_record (DF_REF_BASE, collection_rec,
+                          regno_reg_rtx[HARD_FRAME_POINTER_REGNUM],
+                          NULL, bb, insn_info,
+                          DF_REF_REG_USE, 0);
           break;
         default:
           break;
@@ -3525,7 +3254,7 @@ df_insn_refs_collect (struct df_collection_rec *collection_rec,
 void
 df_recompute_luids (basic_block bb)
 {
-  rtx insn;
+  rtx_insn *insn;
   int luid = 0;
 
   df_grow_insn_info ();
@@ -3571,7 +3300,6 @@ df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb)
       return;
     }
 
-#ifdef EH_RETURN_DATA_REGNO
   if (bb_has_eh_pred (bb))
     {
       unsigned int i;
@@ -3585,7 +3313,6 @@ df_bb_refs_collect (struct df_collection_rec *collection_rec, basic_block bb)
                         bb, NULL, DF_REF_REG_DEF, DF_REF_AT_TOP);
        }
     }
-#endif
 
   /* Add the hard_frame_pointer if this block is the target of a
      non-local goto.  */
@@ -3619,7 +3346,7 @@ void
 df_bb_refs_record (int bb_index, bool scan_insns)
 {
   basic_block bb = BASIC_BLOCK_FOR_FN (cfun, bb_index);
-  rtx insn;
+  rtx_insn *insn;
   int luid = 0;
 
   if (!df)
@@ -3683,16 +3410,15 @@ df_get_regular_block_artificial_uses (bitmap regular_block_artificial_uses)
         reference of the frame pointer.  */
       bitmap_set_bit (regular_block_artificial_uses, FRAME_POINTER_REGNUM);
 
-#if !HARD_FRAME_POINTER_IS_FRAME_POINTER
-      bitmap_set_bit (regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM);
-#endif
+      if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
+       bitmap_set_bit (regular_block_artificial_uses,
+                       HARD_FRAME_POINTER_REGNUM);
 
-#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])
+      if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+         && 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.  */
@@ -3735,14 +3461,13 @@ df_get_eh_block_artificial_uses (bitmap eh_block_artificial_uses)
       if (frame_pointer_needed)
        {
          bitmap_set_bit (eh_block_artificial_uses, FRAME_POINTER_REGNUM);
-#if !HARD_FRAME_POINTER_IS_FRAME_POINTER
-         bitmap_set_bit (eh_block_artificial_uses, HARD_FRAME_POINTER_REGNUM);
-#endif
+         if (!HARD_FRAME_POINTER_IS_FRAME_POINTER)
+           bitmap_set_bit (eh_block_artificial_uses,
+                           HARD_FRAME_POINTER_REGNUM);
        }
-#if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
-      if (fixed_regs[ARG_POINTER_REGNUM])
+      if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+         && fixed_regs[ARG_POINTER_REGNUM])
        bitmap_set_bit (eh_block_artificial_uses, ARG_POINTER_REGNUM);
-#endif
     }
 }
 
@@ -3759,18 +3484,7 @@ df_get_eh_block_artificial_uses (bitmap eh_block_artificial_uses)
 static void
 df_mark_reg (rtx reg, void *vset)
 {
-  bitmap set = (bitmap) vset;
-  int regno = REGNO (reg);
-
-  gcc_assert (GET_MODE (reg) != BLKmode);
-
-  if (regno < FIRST_PSEUDO_REGISTER)
-    {
-      int n = hard_regno_nregs[regno][GET_MODE (reg)];
-      bitmap_set_range (set, regno, n);
-    }
-  else
-    bitmap_set_bit (set, regno);
+  bitmap_set_range ((bitmap) vset, REGNO (reg), REG_NREGS (reg));
 }
 
 
@@ -3797,7 +3511,7 @@ df_get_entry_block_def_set (bitmap entry_block_defs)
 
   /* Once the prologue has been generated, all of these registers
      should just show up in the first regular block.  */
-  if (HAVE_prologue && epilogue_completed)
+  if (targetm.have_prologue () && epilogue_completed)
     {
       /* Defs for the callee saved registers are inserted so that the
         pushes have some defining location.  */
@@ -3821,34 +3535,28 @@ df_get_entry_block_def_set (bitmap entry_block_defs)
       /* 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 !HARD_FRAME_POINTER_IS_FRAME_POINTER
+
       /* If they are different, also mark the hard frame pointer as live.  */
-      if (!LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
+      if (!HARD_FRAME_POINTER_IS_FRAME_POINTER
+         && !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)
     {
-#ifdef PIC_OFFSET_TABLE_REGNUM
-      unsigned int picreg = PIC_OFFSET_TABLE_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])
+      if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+         && 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.  */
+      unsigned int picreg = PIC_OFFSET_TABLE_REGNUM;
       if (picreg != INVALID_REGNUM
          && fixed_regs[picreg])
        bitmap_set_bit (entry_block_defs, picreg);
-#endif
     }
 
 #ifdef INCOMING_RETURN_ADDR_RTX
@@ -3959,11 +3667,11 @@ df_get_exit_block_use_set (bitmap exit_block_uses)
   if ((!reload_completed) || frame_pointer_needed)
     {
       bitmap_set_bit (exit_block_uses, FRAME_POINTER_REGNUM);
-#if !HARD_FRAME_POINTER_IS_FRAME_POINTER
+
       /* If they are different, also mark the hard frame pointer as live.  */
-      if (!LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
+      if (!HARD_FRAME_POINTER_IS_FRAME_POINTER
+         && !LOCAL_REGNO (HARD_FRAME_POINTER_REGNUM))
        bitmap_set_bit (exit_block_uses, HARD_FRAME_POINTER_REGNUM);
-#endif
     }
 
   /* Many architectures have a GP register even without flag_pic.
@@ -3981,7 +3689,7 @@ df_get_exit_block_use_set (bitmap exit_block_uses)
     if (global_regs[i] || EPILOGUE_USES (i))
       bitmap_set_bit (exit_block_uses, i);
 
-  if (HAVE_epilogue && epilogue_completed)
+  if (targetm.have_epilogue () && epilogue_completed)
     {
       /* Mark all call-saved registers that we actually used.  */
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
@@ -3990,7 +3698,6 @@ df_get_exit_block_use_set (bitmap exit_block_uses)
          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)
@@ -4000,10 +3707,9 @@ df_get_exit_block_use_set (bitmap exit_block_uses)
          break;
        bitmap_set_bit (exit_block_uses, regno);
       }
-#endif
 
 #ifdef EH_RETURN_STACKADJ_RTX
-  if ((!HAVE_epilogue || ! epilogue_completed)
+  if ((!targetm.have_epilogue () || ! epilogue_completed)
       && crtl->calls_eh_return)
     {
       rtx tmp = EH_RETURN_STACKADJ_RTX;
@@ -4013,7 +3719,7 @@ df_get_exit_block_use_set (bitmap exit_block_uses)
 #endif
 
 #ifdef EH_RETURN_HANDLER_RTX
-  if ((!HAVE_epilogue || ! epilogue_completed)
+  if ((!targetm.have_epilogue () || ! epilogue_completed)
       && crtl->calls_eh_return)
     {
       rtx tmp = EH_RETURN_HANDLER_RTX;
@@ -4040,16 +3746,15 @@ df_exit_block_uses_collect (struct df_collection_rec *collection_rec, bitmap exi
     df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[i], NULL,
                   EXIT_BLOCK_PTR_FOR_FN (cfun), NULL, DF_REF_REG_USE, 0);
 
-#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
+  if (FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
+      && reload_completed
       && !bitmap_bit_p (exit_block_uses, ARG_POINTER_REGNUM)
       && bb_has_eh_pred (EXIT_BLOCK_PTR_FOR_FN (cfun))
       && fixed_regs[ARG_POINTER_REGNUM])
     df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[ARG_POINTER_REGNUM], NULL,
                   EXIT_BLOCK_PTR_FOR_FN (cfun), NULL, DF_REF_REG_USE, 0);
-#endif
 
   df_canonize_collection_rec (collection_rec);
 }
@@ -4154,9 +3859,9 @@ df_update_entry_exit_and_calls (void)
 
   /* 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)
+  FOR_EACH_BB_FN (bb, cfun)
     {
-      rtx insn;
+      rtx_insn *insn;
       FOR_BB_INSNS (bb, insn)
        {
          if (INSN_P (insn) && CALL_P (insn))
@@ -4309,7 +4014,7 @@ df_reg_chain_verify_unmarked (df_ref refs)
 /* Verify that NEW_REC and OLD_REC have exactly the same members. */
 
 static bool
-df_refs_verify (const vec<df_ref, va_heap> *new_rec, df_ref *old_rec,
+df_refs_verify (const vec<df_ref, va_heap> *new_rec, df_ref old_rec,
                bool abort_if_fail)
 {
   unsigned int ix;
@@ -4317,7 +4022,7 @@ df_refs_verify (const vec<df_ref, va_heap> *new_rec, df_ref *old_rec,
 
   FOR_EACH_VEC_ELT (*new_rec, ix, new_ref)
     {
-      if (*old_rec == NULL || !df_ref_equal_p (new_ref, *old_rec))
+      if (old_rec == NULL || !df_ref_equal_p (new_ref, old_rec))
        {
          if (abort_if_fail)
            gcc_assert (0);
@@ -4329,17 +4034,17 @@ df_refs_verify (const vec<df_ref, va_heap> *new_rec, df_ref *old_rec,
         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);
+         gcc_assert (DF_REF_IS_REG_MARKED (old_rec));
+         DF_REF_REG_UNMARK (old_rec);
        }
 
-      old_rec++;
+      old_rec = DF_REF_NEXT_LOC (old_rec);
     }
 
   if (abort_if_fail)
-    gcc_assert (*old_rec == NULL);
+    gcc_assert (old_rec == NULL);
   else
-    return *old_rec == NULL;
+    return old_rec == NULL;
   return false;
 }
 
@@ -4347,8 +4052,8 @@ df_refs_verify (const vec<df_ref, va_heap> *new_rec, df_ref *old_rec,
 /* Verify that NEW_REC and OLD_REC have exactly the same members. */
 
 static bool
-df_mws_verify (const vec<df_mw_hardreg_ptr, va_heap> *new_rec,
-              struct df_mw_hardreg **old_rec,
+df_mws_verify (const vec<df_mw_hardreg *, va_heap> *new_rec,
+              struct df_mw_hardreg *old_rec,
               bool abort_if_fail)
 {
   unsigned int ix;
@@ -4356,20 +4061,20 @@ df_mws_verify (const vec<df_mw_hardreg_ptr, va_heap> *new_rec,
 
   FOR_EACH_VEC_ELT (*new_rec, ix, new_reg)
     {
-      if (*old_rec == NULL || !df_mw_equal_p (new_reg, *old_rec))
+      if (old_rec == NULL || !df_mw_equal_p (new_reg, old_rec))
        {
          if (abort_if_fail)
            gcc_assert (0);
          else
            return false;
        }
-      old_rec++;
+      old_rec = DF_MWS_NEXT (old_rec);
     }
 
   if (abort_if_fail)
-    gcc_assert (*old_rec == NULL);
+    gcc_assert (old_rec == NULL);
   else
-    return *old_rec == NULL;
+    return old_rec == NULL;
   return false;
 }
 
@@ -4388,7 +4093,7 @@ df_mws_verify (const vec<df_mw_hardreg_ptr, va_heap> *new_rec,
 static bool
 df_insn_refs_verify (struct df_collection_rec *collection_rec,
                     basic_block bb,
-                     rtx insn,
+                     rtx_insn *insn,
                     bool abort_if_fail)
 {
   bool ret1, ret2, ret3, ret4;
@@ -4397,15 +4102,6 @@ df_insn_refs_verify (struct df_collection_rec *collection_rec,
 
   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),
@@ -4427,7 +4123,7 @@ df_insn_refs_verify (struct df_collection_rec *collection_rec,
 static bool
 df_bb_verify (basic_block bb)
 {
-  rtx insn;
+  rtx_insn *insn;
   struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index);
   struct df_collection_rec collection_rec;
 
@@ -4569,7 +4265,7 @@ df_scan_verify (void)
      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)
+  FOR_ALL_BB_FN (bb, cfun)
     df_bb_verify (bb);
 
   /* (4) See if all reg chains are traversed a second time.  This time