OSDN Git Service

PR target/27565
[pf3gnuchains/gcc-fork.git] / gcc / df-problems.c
index 257baad..cdf4141 100644 (file)
@@ -42,30 +42,24 @@ Software Foundation, 51 Franklin Street, Fifth Floor, Boston, MA
 #include "bitmap.h"
 #include "timevar.h"
 #include "df.h"
 #include "bitmap.h"
 #include "timevar.h"
 #include "df.h"
+#include "vecprim.h"
+#include "except.h"
+
+#if 0
+#define REG_DEAD_DEBUGGING
+#endif
 
 #define DF_SPARSE_THRESHOLD 32
 
 static bitmap seen_in_block = NULL;
 static bitmap seen_in_insn = NULL;
 
 #define DF_SPARSE_THRESHOLD 32
 
 static bitmap seen_in_block = NULL;
 static bitmap seen_in_insn = NULL;
+static void df_ri_dump (struct dataflow *, FILE *);
 
 \f
 /*----------------------------------------------------------------------------
    Public functions access functions for the dataflow problems.
 ----------------------------------------------------------------------------*/
 
 
 \f
 /*----------------------------------------------------------------------------
    Public functions access functions for the dataflow problems.
 ----------------------------------------------------------------------------*/
 
-/* Get the instance of the problem that DFLOW is dependent on.  */
-
-struct dataflow *
-df_get_dependent_problem (struct dataflow *dflow)
-{
-  struct df *df = dflow->df;
-  struct df_problem *dependent_problem = dflow->problem->dependent_problem;
-
-  gcc_assert (dependent_problem);
-  return df->problems_by_index[dependent_problem->id];
-}
-
-
 /* Create a du or ud chain from SRC to DST and link it into SRC.   */
 
 struct df_link *
 /* Create a du or ud chain from SRC to DST and link it into SRC.   */
 
 struct df_link *
@@ -184,7 +178,7 @@ df_get_live_out (struct df *df, basic_block bb)
 ----------------------------------------------------------------------------*/
 
 /* Generic versions to get the void* version of the block info.  Only
 ----------------------------------------------------------------------------*/
 
 /* Generic versions to get the void* version of the block info.  Only
-   used inside the problem instace vectors.  */
+   used inside the problem instance vectors.  */
 
 /* Grow the bb_info array.  */
 
 
 /* Grow the bb_info array.  */
 
@@ -206,7 +200,7 @@ df_grow_bb_info (struct dataflow *dflow)
 /* Dump a def-use or use-def chain for REF to FILE.  */
 
 void
 /* Dump a def-use or use-def chain for REF to FILE.  */
 
 void
-df_chain_dump (struct df *df ATTRIBUTE_UNUSED, struct df_link *link, FILE *file)
+df_chain_dump (struct df_link *link, FILE *file)
 {
   fprintf (file, "{ ");
   for (; link; link = link->next)
 {
   fprintf (file, "{ ");
   for (; link; link = link->next)
@@ -245,7 +239,9 @@ df_print_bb_index (basic_block bb, FILE *file)
 }
 
 
 }
 
 
-/* Return the set of reference ids in CHAIN, caching the result in *BMAP.  */
+/* Return a bitmap for REGNO from the cache MAPS.  The bitmap is to
+   contain COUNT bits starting at START.  These bitmaps are not to be
+   changed since there is a cache of them.  */
 
 static inline bitmap
 df_ref_bitmap (bitmap *maps, unsigned int regno, int start, int count)
 
 static inline bitmap
 df_ref_bitmap (bitmap *maps, unsigned int regno, int start, int count)
@@ -288,12 +284,41 @@ df_unset_seen (void)
    REACHING USES
 
    Find the locations in the function where each use site for a pseudo
    REACHING USES
 
    Find the locations in the function where each use site for a pseudo
-   can reach backwards.
+   can reach backwards.  In and out bitvectors are built for each basic
+   block.  The id field in the ref is used to index into these sets.
+   See df.h for details.
 
 ----------------------------------------------------------------------------*/
 
 
 ----------------------------------------------------------------------------*/
 
+/* This problem plays a large number of games for the sake of
+   efficiency.  
+   
+   1) The order of the bits in the bitvectors.  After the scanning
+   phase, all of the uses are sorted.  All of the uses for the reg 0
+   are first, followed by all uses for reg 1 and so on.
+   
+   2) There are two kill sets, one if the number of uses is less or
+   equal to DF_SPARSE_THRESHOLD and another if it is greater.
+
+   <= : There is a bitmap for each register, uses_sites[N], that is
+   built on demand.  This bitvector contains a 1 for each use or reg
+   N.
+
+   > : One level of indirection is used to keep from generating long
+   strings of 1 bits in the kill sets.  Bitvectors that are indexed
+   by the regnum are used to represent that there is a killing def
+   for the register.  The confluence and transfer functions use
+   these along with the bitmap_clear_range call to remove ranges of
+   bits without actually generating a knockout vector.
+
+   The kill and sparse_kill and the dense_invalidated_by_call and
+   sparse_invalidated_by call both play this game.  */
+
+/* Private data used to compute the solution for this problem.  These
+   data structures are not accessible outside of this module.  */
 struct df_ru_problem_data
 {
 struct df_ru_problem_data
 {
+
   bitmap *use_sites;            /* Bitmap of uses for each pseudo.  */
   unsigned int use_sites_size;  /* Size of use_sites.  */
   /* The set of defs to regs invalidated by call.  */
   bitmap *use_sites;            /* Bitmap of uses for each pseudo.  */
   unsigned int use_sites_size;  /* Size of use_sites.  */
   /* The set of defs to regs invalidated by call.  */
@@ -345,21 +370,23 @@ df_ru_free_bb_info (struct dataflow *dflow,
    not touched unless the block is new.  */
 
 static void 
    not touched unless the block is new.  */
 
 static void 
-df_ru_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
+df_ru_alloc (struct dataflow *dflow, 
+            bitmap blocks_to_rescan ATTRIBUTE_UNUSED,
+            bitmap all_blocks)
 {
   unsigned int bb_index;
   bitmap_iterator bi;
   unsigned int reg_size = max_reg_num ();
 
 {
   unsigned int bb_index;
   bitmap_iterator bi;
   unsigned int reg_size = max_reg_num ();
 
-  if (! dflow->block_pool)
+  if (!dflow->block_pool)
     dflow->block_pool = create_alloc_pool ("df_ru_block pool", 
                                           sizeof (struct df_ru_bb_info), 50);
 
   if (dflow->problem_data)
     {
       unsigned int i;
     dflow->block_pool = create_alloc_pool ("df_ru_block pool", 
                                           sizeof (struct df_ru_bb_info), 50);
 
   if (dflow->problem_data)
     {
       unsigned int i;
-      struct df_ru_problem_data *problem_data =
-       (struct df_ru_problem_data *) dflow->problem_data;
+      struct df_ru_problem_data *problem_data
+       (struct df_ru_problem_data *) dflow->problem_data;
 
       for (i = 0; i < problem_data->use_sites_size; i++)
        {
 
       for (i = 0; i < problem_data->use_sites_size; i++)
        {
@@ -400,7 +427,7 @@ df_ru_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
      we have to process all of the blocks before doing the
      analysis.  */
 
      we have to process all of the blocks before doing the
      analysis.  */
 
-  EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
+  EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
       struct df_ru_bb_info *bb_info = df_ru_get_bb_info (dflow, bb_index);
       if (bb_info)
     {
       struct df_ru_bb_info *bb_info = df_ru_get_bb_info (dflow, bb_index);
       if (bb_info)
@@ -434,31 +461,33 @@ df_ru_bb_local_compute_process_def (struct dataflow *dflow,
   struct df *df = dflow->df;
   while (def)
     {
   struct df *df = dflow->df;
   while (def)
     {
-      if (top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
+      if ((top_flag == (DF_REF_FLAGS (def) & DF_REF_AT_TOP))
+         /* If the def is to only part of the reg, it is as if it did
+            not happen, since some of the bits may get thru.  */
+         && (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL)))
        {
          unsigned int regno = DF_REF_REGNO (def);
          unsigned int begin = DF_REG_USE_GET (df, regno)->begin;
          unsigned int n_uses = DF_REG_USE_GET (df, regno)->n_refs;
          if (!bitmap_bit_p (seen_in_block, regno))
            {
        {
          unsigned int regno = DF_REF_REGNO (def);
          unsigned int begin = DF_REG_USE_GET (df, regno)->begin;
          unsigned int n_uses = DF_REG_USE_GET (df, regno)->n_refs;
          if (!bitmap_bit_p (seen_in_block, regno))
            {
-             /* The first def for regno, causes the kill info to be
-                generated and the gen information to cleared.  */
+             /* The first def for regno in the insn, causes the kill
+                info to be generated.  Do not modify the gen set
+                because the only values in it are the uses from here
+                to the top of the block and this def does not effect
+                them.  */
              if (!bitmap_bit_p (seen_in_insn, regno))
                {
                  if (n_uses > DF_SPARSE_THRESHOLD)
              if (!bitmap_bit_p (seen_in_insn, regno))
                {
                  if (n_uses > DF_SPARSE_THRESHOLD)
-                   {
-                     bitmap_set_bit (bb_info->sparse_kill, regno);
-                     bitmap_clear_range (bb_info->gen, begin, n_uses);
-                   }
+                   bitmap_set_bit (bb_info->sparse_kill, regno);
                  else
                    {
                  else
                    {
-                     struct df_ru_problem_data * problem_data =
-                       (struct df_ru_problem_data *)dflow->problem_data;
-                     bitmap uses 
-                       df_ref_bitmap (problem_data->use_sites, regno, 
+                     struct df_ru_problem_data * problem_data
+                       (struct df_ru_problem_data *)dflow->problem_data;
+                     bitmap uses 
+                       df_ref_bitmap (problem_data->use_sites, regno, 
                                       begin, n_uses);
                      bitmap_ior_into (bb_info->kill, uses);
                                       begin, n_uses);
                      bitmap_ior_into (bb_info->kill, uses);
-                     bitmap_and_compl_into (bb_info->gen, uses);
                    }
                }
              bitmap_set_bit (seen_in_insn, regno);
                    }
                }
              bitmap_set_bit (seen_in_insn, regno);
@@ -518,18 +547,14 @@ df_ru_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
   FOR_BB_INSNS (bb, insn)
     {
       unsigned int uid = INSN_UID (insn);
   FOR_BB_INSNS (bb, insn)
     {
       unsigned int uid = INSN_UID (insn);
-      if (! INSN_P (insn))
+      if (!INSN_P (insn))
        continue;
 
        continue;
 
-      df_ru_bb_local_compute_process_def (dflow, bb_info, 
-                                         DF_INSN_UID_GET (df, uid)->defs, 0);
-
-      /* The use processing must happen after the defs processing even
-        though the uses logically happen first since the defs clear
-        the gen set. Otherwise, a use for regno occuring in the same
-        instruction as a def for regno would be cleared.  */ 
       df_ru_bb_local_compute_process_use (bb_info, 
       df_ru_bb_local_compute_process_use (bb_info, 
-                                         DF_INSN_UID_GET (df, uid)->uses, 0);
+                                         DF_INSN_UID_USES (df, uid), 0);
+
+      df_ru_bb_local_compute_process_def (dflow, bb_info, 
+                                         DF_INSN_UID_DEFS (df, uid), 0);
 
       bitmap_ior_into (seen_in_block, seen_in_insn);
       bitmap_clear (seen_in_insn);
 
       bitmap_ior_into (seen_in_block, seen_in_insn);
       bitmap_clear (seen_in_insn);
@@ -555,8 +580,8 @@ df_ru_local_compute (struct dataflow *dflow,
   unsigned int bb_index;
   bitmap_iterator bi;
   unsigned int regno;
   unsigned int bb_index;
   bitmap_iterator bi;
   unsigned int regno;
-  struct df_ru_problem_data *problem_data =
-    (struct df_ru_problem_data *) dflow->problem_data;
+  struct df_ru_problem_data *problem_data
+    (struct df_ru_problem_data *) dflow->problem_data;
   bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
   bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
 
   bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
   bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
 
@@ -615,8 +640,8 @@ df_ru_confluence_n (struct dataflow *dflow, edge e)
 
   if (e->flags & EDGE_EH)
     {
 
   if (e->flags & EDGE_EH)
     {
-      struct df_ru_problem_data *problem_data =
-       (struct df_ru_problem_data *) dflow->problem_data;
+      struct df_ru_problem_data *problem_data
+       (struct df_ru_problem_data *) dflow->problem_data;
       bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
       bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
       struct df *df = dflow->df;
       bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
       bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
       struct df *df = dflow->df;
@@ -662,7 +687,7 @@ df_ru_transfer_function (struct dataflow *dflow, int bb_index)
       struct df *df = dflow->df;
       bool changed = false;
       bitmap tmp = BITMAP_ALLOC (NULL);
       struct df *df = dflow->df;
       bool changed = false;
       bitmap tmp = BITMAP_ALLOC (NULL);
-      bitmap_copy (tmp, in);
+      bitmap_copy (tmp, out);
       EXECUTE_IF_SET_IN_BITMAP (sparse_kill, 0, regno, bi)
        {
          bitmap_clear_range (tmp, 
       EXECUTE_IF_SET_IN_BITMAP (sparse_kill, 0, regno, bi)
        {
          bitmap_clear_range (tmp, 
@@ -674,7 +699,7 @@ df_ru_transfer_function (struct dataflow *dflow, int bb_index)
       changed = !bitmap_equal_p (tmp, in);
       if (changed)
        {
       changed = !bitmap_equal_p (tmp, in);
       if (changed)
        {
-         BITMAP_FREE (out);
+         BITMAP_FREE (in);
          bb_info->in = tmp;
        }
       else 
          bb_info->in = tmp;
        }
       else 
@@ -690,8 +715,8 @@ static void
 df_ru_free (struct dataflow *dflow)
 {
   unsigned int i;
 df_ru_free (struct dataflow *dflow)
 {
   unsigned int i;
-  struct df_ru_problem_data *problem_data =
-    (struct df_ru_problem_data *) dflow->problem_data;
+  struct df_ru_problem_data *problem_data
+    (struct df_ru_problem_data *) dflow->problem_data;
 
   if (problem_data)
     {
 
   if (problem_data)
     {
@@ -736,10 +761,13 @@ df_ru_dump (struct dataflow *dflow, FILE *file)
 {
   basic_block bb;
   struct df *df = dflow->df;
 {
   basic_block bb;
   struct df *df = dflow->df;
-  struct df_ru_problem_data *problem_data =
-    (struct df_ru_problem_data *) dflow->problem_data;
+  struct df_ru_problem_data *problem_data
+    (struct df_ru_problem_data *) dflow->problem_data;
   unsigned int m = max_reg_num ();
   unsigned int regno;
   unsigned int m = max_reg_num ();
   unsigned int regno;
+  
+  if (!dflow->block_info) 
+    return;
 
   fprintf (file, "Reaching uses:\n");
 
 
   fprintf (file, "Reaching uses:\n");
 
@@ -760,16 +788,16 @@ df_ru_dump (struct dataflow *dflow, FILE *file)
       struct df_ru_bb_info *bb_info = df_ru_get_bb_info (dflow, bb->index);
       df_print_bb_index (bb, file);
       
       struct df_ru_bb_info *bb_info = df_ru_get_bb_info (dflow, bb->index);
       df_print_bb_index (bb, file);
       
-      if (! bb_info->in)
+      if (!bb_info->in)
        continue;
       
        continue;
       
-      fprintf (file, "  in  \t");
+      fprintf (file, "  in  \t(%d)\n", (int) bitmap_count_bits (bb_info->in));
       dump_bitmap (file, bb_info->in);
       dump_bitmap (file, bb_info->in);
-      fprintf (file, "  gen \t");
+      fprintf (file, "  gen \t(%d)\n", (int) bitmap_count_bits (bb_info->gen));
       dump_bitmap (file, bb_info->gen);
       dump_bitmap (file, bb_info->gen);
-      fprintf (file, "  kill\t");
+      fprintf (file, "  kill\t(%d)\n", (int) bitmap_count_bits (bb_info->kill));
       dump_bitmap (file, bb_info->kill);
       dump_bitmap (file, bb_info->kill);
-      fprintf (file, "  out \t");
+      fprintf (file, "  out \t(%d)\n", (int) bitmap_count_bits (bb_info->out));
       dump_bitmap (file, bb_info->out);
     }
 }
       dump_bitmap (file, bb_info->out);
     }
 }
@@ -792,7 +820,8 @@ static struct df_problem problem_RU =
   NULL,                       /* Finalize function.  */
   df_ru_free,                 /* Free all of the problem information.  */
   df_ru_dump,                 /* Debugging.  */
   NULL,                       /* Finalize function.  */
   df_ru_free,                 /* Free all of the problem information.  */
   df_ru_dump,                 /* Debugging.  */
-  NULL                        /* Dependent problem.  */
+  NULL,                       /* Dependent problem.  */
+  0                           /* Changeable flags.  */
 };
 
 
 };
 
 
@@ -802,9 +831,9 @@ static struct df_problem problem_RU =
    solution.  */
 
 struct dataflow *
    solution.  */
 
 struct dataflow *
-df_ru_add_problem (struct df *df)
+df_ru_add_problem (struct df *df, int flags)
 {
 {
-  return df_add_problem (df, &problem_RU);
+  return df_add_problem (df, &problem_RU, flags);
 }
 
 \f
 }
 
 \f
@@ -812,16 +841,29 @@ df_ru_add_problem (struct df *df)
    REACHING DEFINITIONS
 
    Find the locations in the function where each definition site for a
    REACHING DEFINITIONS
 
    Find the locations in the function where each definition site for a
-   pseudo reaches.
-----------------------------------------------------------------------------*/
+   pseudo reaches.  In and out bitvectors are built for each basic
+   block.  The id field in the ref is used to index into these sets.
+   See df.h for details.
+   ----------------------------------------------------------------------------*/
+
+/* See the comment at the top of the Reaching Uses problem for how the
+   uses are represented in the kill sets. The same games are played
+   here for the defs.  */
 
 
+/* Private data used to compute the solution for this problem.  These
+   data structures are not accessible outside of this module.  */
 struct df_rd_problem_data
 {
 struct df_rd_problem_data
 {
+  /* If the number of defs for regnum N is less than
+     DF_SPARSE_THRESHOLD, uses_sites[N] contains a mask of the all of
+     the defs of reg N indexed by the id in the ref structure.  If
+     there are more than DF_SPARSE_THRESHOLD defs for regnum N a
+     different mechanism is used to mask the def.  */
   bitmap *def_sites;            /* Bitmap of defs for each pseudo.  */
   unsigned int def_sites_size;  /* Size of def_sites.  */
   /* The set of defs to regs invalidated by call.  */
   bitmap sparse_invalidated_by_call;  
   bitmap *def_sites;            /* Bitmap of defs for each pseudo.  */
   unsigned int def_sites_size;  /* Size of def_sites.  */
   /* The set of defs to regs invalidated by call.  */
   bitmap sparse_invalidated_by_call;  
-  /* The set of defs to regs invalidate by call for ru.  */  
+  /* The set of defs to regs invalidate by call for rd.  */  
   bitmap dense_invalidated_by_call;   
 };
 
   bitmap dense_invalidated_by_call;   
 };
 
@@ -868,21 +910,23 @@ df_rd_free_bb_info (struct dataflow *dflow,
    not touched unless the block is new.  */
 
 static void 
    not touched unless the block is new.  */
 
 static void 
-df_rd_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
+df_rd_alloc (struct dataflow *dflow, 
+            bitmap blocks_to_rescan ATTRIBUTE_UNUSED,
+            bitmap all_blocks)
 {
   unsigned int bb_index;
   bitmap_iterator bi;
   unsigned int reg_size = max_reg_num ();
 
 {
   unsigned int bb_index;
   bitmap_iterator bi;
   unsigned int reg_size = max_reg_num ();
 
-  if (! dflow->block_pool)
+  if (!dflow->block_pool)
     dflow->block_pool = create_alloc_pool ("df_rd_block pool", 
                                           sizeof (struct df_rd_bb_info), 50);
 
   if (dflow->problem_data)
     {
       unsigned int i;
     dflow->block_pool = create_alloc_pool ("df_rd_block pool", 
                                           sizeof (struct df_rd_bb_info), 50);
 
   if (dflow->problem_data)
     {
       unsigned int i;
-      struct df_rd_problem_data *problem_data =
-       (struct df_rd_problem_data *) dflow->problem_data;
+      struct df_rd_problem_data *problem_data
+       (struct df_rd_problem_data *) dflow->problem_data;
 
       for (i = 0; i < problem_data->def_sites_size; i++)
        {
 
       for (i = 0; i < problem_data->def_sites_size; i++)
        {
@@ -919,11 +963,11 @@ df_rd_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
 
   df_grow_bb_info (dflow);
 
 
   df_grow_bb_info (dflow);
 
-  /* Because of the clustering of all def sites for the same pseudo,
+  /* Because of the clustering of all use sites for the same pseudo,
      we have to process all of the blocks before doing the
      analysis.  */
 
      we have to process all of the blocks before doing the
      analysis.  */
 
-  EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
+  EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
       struct df_rd_bb_info *bb_info = df_rd_get_bb_info (dflow, bb_index);
       if (bb_info)
     {
       struct df_rd_bb_info *bb_info = df_rd_get_bb_info (dflow, bb_index);
       if (bb_info)
@@ -969,7 +1013,11 @@ df_rd_bb_local_compute_process_def (struct dataflow *dflow,
            {
              /* The first def for regno in insn gets to knock out the
                 defs from other instructions.  */
            {
              /* The first def for regno in insn gets to knock out the
                 defs from other instructions.  */
-             if (!bitmap_bit_p (seen_in_insn, regno))
+             if ((!bitmap_bit_p (seen_in_insn, regno))
+                 /* If the def is to only part of the reg, it does
+                    not kill the other defs that reach here.  */
+                 && (!((DF_REF_FLAGS (def) & DF_REF_PARTIAL)
+                        || (DF_REF_FLAGS (def) & DF_REF_MAY_CLOBBER))))
                {
                  if (n_defs > DF_SPARSE_THRESHOLD)
                    {
                {
                  if (n_defs > DF_SPARSE_THRESHOLD)
                    {
@@ -978,11 +1026,10 @@ df_rd_bb_local_compute_process_def (struct dataflow *dflow,
                    }
                  else
                    {
                    }
                  else
                    {
-                     struct df_rd_problem_data * problem_data =
-                       (struct df_rd_problem_data *)dflow->problem_data;
-                     bitmap defs = 
-                       df_ref_bitmap (problem_data->def_sites, regno, 
-                                      begin, n_defs);
+                     struct df_rd_problem_data * problem_data
+                       = (struct df_rd_problem_data *)dflow->problem_data;
+                     bitmap defs = df_ref_bitmap (problem_data->def_sites, 
+                                                  regno, begin, n_defs);
                      bitmap_ior_into (bb_info->kill, defs);
                      bitmap_and_compl_into (bb_info->gen, defs);
                    }
                      bitmap_ior_into (bb_info->kill, defs);
                      bitmap_and_compl_into (bb_info->gen, defs);
                    }
@@ -991,7 +1038,8 @@ df_rd_bb_local_compute_process_def (struct dataflow *dflow,
              bitmap_set_bit (seen_in_insn, regno);
              /* All defs for regno in the instruction may be put into
                 the gen set.  */
              bitmap_set_bit (seen_in_insn, regno);
              /* All defs for regno in the instruction may be put into
                 the gen set.  */
-             if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
+             if (!(DF_REF_FLAGS (def) 
+                    & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
                bitmap_set_bit (bb_info->gen, DF_REF_ID (def));
            }
        }
                bitmap_set_bit (bb_info->gen, DF_REF_ID (def));
            }
        }
@@ -1019,11 +1067,11 @@ df_rd_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
     {
       unsigned int uid = INSN_UID (insn);
 
     {
       unsigned int uid = INSN_UID (insn);
 
-      if (! INSN_P (insn))
+      if (!INSN_P (insn))
        continue;
 
       df_rd_bb_local_compute_process_def (dflow, bb_info, 
        continue;
 
       df_rd_bb_local_compute_process_def (dflow, bb_info, 
-                                         DF_INSN_UID_GET (df, uid)->defs, 0);
+                                         DF_INSN_UID_DEFS (df, uid), 0);
 
       /* This complex dance with the two bitmaps is required because
         instructions can assign twice to the same pseudo.  This
 
       /* This complex dance with the two bitmaps is required because
         instructions can assign twice to the same pseudo.  This
@@ -1055,8 +1103,8 @@ df_rd_local_compute (struct dataflow *dflow,
   unsigned int bb_index;
   bitmap_iterator bi;
   unsigned int regno;
   unsigned int bb_index;
   bitmap_iterator bi;
   unsigned int regno;
-  struct df_rd_problem_data *problem_data =
-    (struct df_rd_problem_data *) dflow->problem_data;
+  struct df_rd_problem_data *problem_data
+    (struct df_rd_problem_data *) dflow->problem_data;
   bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
   bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
 
   bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
   bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
 
@@ -1116,8 +1164,8 @@ df_rd_confluence_n (struct dataflow *dflow, edge e)
 
   if (e->flags & EDGE_EH)
     {
 
   if (e->flags & EDGE_EH)
     {
-      struct df_rd_problem_data *problem_data =
-       (struct df_rd_problem_data *) dflow->problem_data;
+      struct df_rd_problem_data *problem_data
+       (struct df_rd_problem_data *) dflow->problem_data;
       bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
       bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
       struct df *df = dflow->df;
       bitmap sparse_invalidated = problem_data->sparse_invalidated_by_call;
       bitmap dense_invalidated = problem_data->dense_invalidated_by_call;
       struct df *df = dflow->df;
@@ -1191,8 +1239,8 @@ static void
 df_rd_free (struct dataflow *dflow)
 {
   unsigned int i;
 df_rd_free (struct dataflow *dflow)
 {
   unsigned int i;
-  struct df_rd_problem_data *problem_data =
-    (struct df_rd_problem_data *) dflow->problem_data;
+  struct df_rd_problem_data *problem_data
+    (struct df_rd_problem_data *) dflow->problem_data;
 
   if (problem_data)
     {
 
   if (problem_data)
     {
@@ -1237,11 +1285,14 @@ df_rd_dump (struct dataflow *dflow, FILE *file)
 {
   struct df *df = dflow->df;
   basic_block bb;
 {
   struct df *df = dflow->df;
   basic_block bb;
-  struct df_rd_problem_data *problem_data =
-    (struct df_rd_problem_data *) dflow->problem_data;
+  struct df_rd_problem_data *problem_data
+    (struct df_rd_problem_data *) dflow->problem_data;
   unsigned int m = max_reg_num ();
   unsigned int regno;
   
   unsigned int m = max_reg_num ();
   unsigned int regno;
   
+  if (!dflow->block_info) 
+    return;
+
   fprintf (file, "Reaching defs:\n\n");
 
   fprintf (file, "  sparse invalidated \t");
   fprintf (file, "Reaching defs:\n\n");
 
   fprintf (file, "  sparse invalidated \t");
@@ -1261,16 +1312,16 @@ df_rd_dump (struct dataflow *dflow, FILE *file)
       struct df_rd_bb_info *bb_info = df_rd_get_bb_info (dflow, bb->index);
       df_print_bb_index (bb, file);
       
       struct df_rd_bb_info *bb_info = df_rd_get_bb_info (dflow, bb->index);
       df_print_bb_index (bb, file);
       
-      if (! bb_info->in)
+      if (!bb_info->in)
        continue;
       
        continue;
       
-      fprintf (file, "  in\t(%d)\n", (int) bitmap_count_bits (bb_info->in));
+      fprintf (file, "  in  \t(%d)\n", (int) bitmap_count_bits (bb_info->in));
       dump_bitmap (file, bb_info->in);
       fprintf (file, "  gen \t(%d)\n", (int) bitmap_count_bits (bb_info->gen));
       dump_bitmap (file, bb_info->gen);
       fprintf (file, "  kill\t(%d)\n", (int) bitmap_count_bits (bb_info->kill));
       dump_bitmap (file, bb_info->kill);
       dump_bitmap (file, bb_info->in);
       fprintf (file, "  gen \t(%d)\n", (int) bitmap_count_bits (bb_info->gen));
       dump_bitmap (file, bb_info->gen);
       fprintf (file, "  kill\t(%d)\n", (int) bitmap_count_bits (bb_info->kill));
       dump_bitmap (file, bb_info->kill);
-      fprintf (file, "  out\t(%d)\n", (int) bitmap_count_bits (bb_info->out));
+      fprintf (file, "  out \t(%d)\n", (int) bitmap_count_bits (bb_info->out));
       dump_bitmap (file, bb_info->out);
     }
 }
       dump_bitmap (file, bb_info->out);
     }
 }
@@ -1293,7 +1344,8 @@ static struct df_problem problem_RD =
   NULL,                       /* Finalize function.  */
   df_rd_free,                 /* Free all of the problem information.  */
   df_rd_dump,                 /* Debugging.  */
   NULL,                       /* Finalize function.  */
   df_rd_free,                 /* Free all of the problem information.  */
   df_rd_dump,                 /* Debugging.  */
-  NULL                        /* Dependent problem.  */
+  NULL,                       /* Dependent problem.  */
+  0                           /* Changeable flags.  */
 };
 
 
 };
 
 
@@ -1303,9 +1355,9 @@ static struct df_problem problem_RD =
    solution.  */
 
 struct dataflow *
    solution.  */
 
 struct dataflow *
-df_rd_add_problem (struct df *df)
+df_rd_add_problem (struct df *df, int flags)
 {
 {
-  return df_add_problem (df, &problem_RD);
+  return df_add_problem (df, &problem_RD, flags);
 }
 
 
 }
 
 
@@ -1313,9 +1365,11 @@ df_rd_add_problem (struct df *df)
 /*----------------------------------------------------------------------------
    LIVE REGISTERS
 
 /*----------------------------------------------------------------------------
    LIVE REGISTERS
 
-   Find the locations in the function where any use of a pseudo can reach
-   in the backwards direction.
-----------------------------------------------------------------------------*/
+   Find the locations in the function where any use of a pseudo can
+   reach in the backwards direction.  In and out bitvectors are built
+   for each basic block.  The regnum is used to index into these sets.
+   See df.h for details.
+   ----------------------------------------------------------------------------*/
 
 /* Get basic block info.  */
 
 
 /* Get basic block info.  */
 
@@ -1359,21 +1413,18 @@ df_lr_free_bb_info (struct dataflow *dflow,
    not touched unless the block is new.  */
 
 static void 
    not touched unless the block is new.  */
 
 static void 
-df_lr_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
+df_lr_alloc (struct dataflow *dflow, bitmap blocks_to_rescan,
+            bitmap all_blocks ATTRIBUTE_UNUSED)
 {
   unsigned int bb_index;
   bitmap_iterator bi;
 
 {
   unsigned int bb_index;
   bitmap_iterator bi;
 
-  if (! dflow->block_pool)
+  if (!dflow->block_pool)
     dflow->block_pool = create_alloc_pool ("df_lr_block pool", 
                                           sizeof (struct df_lr_bb_info), 50);
 
   df_grow_bb_info (dflow);
 
     dflow->block_pool = create_alloc_pool ("df_lr_block pool", 
                                           sizeof (struct df_lr_bb_info), 50);
 
   df_grow_bb_info (dflow);
 
-  /* Because of the clustering of all def sites for the same pseudo,
-     we have to process all of the blocks before doing the
-     analysis.  */
-
   EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
     {
       struct df_lr_bb_info *bb_info = df_lr_get_bb_info (dflow, bb_index);
   EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
     {
       struct df_lr_bb_info *bb_info = df_lr_get_bb_info (dflow, bb_index);
@@ -1409,7 +1460,8 @@ df_lr_bb_local_compute (struct dataflow *dflow,
 
   /* Process the registers set in an exception handler.  */
   for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
 
   /* Process the registers set in an exception handler.  */
   for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
-    if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
+    if (((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
+       && (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL)))
       {
        unsigned int dregno = DF_REF_REGNO (def);
        bitmap_set_bit (bb_info->def, dregno);
       {
        unsigned int dregno = DF_REF_REGNO (def);
        bitmap_set_bit (bb_info->def, dregno);
@@ -1426,12 +1478,12 @@ df_lr_bb_local_compute (struct dataflow *dflow,
     {
       unsigned int uid = INSN_UID (insn);
 
     {
       unsigned int uid = INSN_UID (insn);
 
-      if (! INSN_P (insn))
+      if (!INSN_P (insn))
        continue;       
 
       if (CALL_P (insn))
        {
        continue;       
 
       if (CALL_P (insn))
        {
-         for (def = DF_INSN_UID_GET (df, uid)->defs; def; def = def->next_ref)
+         for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
            {
              unsigned int dregno = DF_REF_REGNO (def);
              
            {
              unsigned int dregno = DF_REF_REGNO (def);
              
@@ -1442,15 +1494,19 @@ df_lr_bb_local_compute (struct dataflow *dflow,
                                              current_function_return_rtx,
                                              (rtx *)0)))
                {
                                              current_function_return_rtx,
                                              (rtx *)0)))
                {
-                 /* Add def to set of defs in this BB.  */
-                 bitmap_set_bit (bb_info->def, dregno);
-                 bitmap_clear_bit (bb_info->use, dregno);
+                 /* If the def is to only part of the reg, it does
+                    not kill the other defs that reach here.  */
+                 if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+                   {
+                     bitmap_set_bit (bb_info->def, dregno);
+                     bitmap_clear_bit (bb_info->use, dregno);
+                   }
                }
            }
        }
       else
        {
                }
            }
        }
       else
        {
-         for (def = DF_INSN_UID_GET (df, uid)->defs; def; def = def->next_ref)
+         for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
            {
              unsigned int dregno = DF_REF_REGNO (def);
              
            {
              unsigned int dregno = DF_REF_REGNO (def);
              
@@ -1458,25 +1514,30 @@ df_lr_bb_local_compute (struct dataflow *dflow,
                  && dregno < FIRST_PSEUDO_REGISTER)
                {
                  unsigned int i;
                  && dregno < FIRST_PSEUDO_REGISTER)
                {
                  unsigned int i;
-                 unsigned int end = 
-                   dregno + hard_regno_nregs[dregno][GET_MODE (DF_REF_REG (def))] - 1;
+                 unsigned int end = dregno 
+                   + hard_regno_nregs[dregno][GET_MODE (DF_REF_REG (def))] - 1;
                  for (i = dregno; i <= end; ++i)
                    regs_asm_clobbered[i] = 1;
                }
                  for (i = dregno; i <= end; ++i)
                    regs_asm_clobbered[i] = 1;
                }
-             /* Add def to set of defs in this BB.  */
-             bitmap_set_bit (bb_info->def, dregno);
-             bitmap_clear_bit (bb_info->use, dregno);
+             /* If the def is to only part of the reg, it does
+                    not kill the other defs that reach here.  */
+             if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+               {
+                 bitmap_set_bit (bb_info->def, dregno);
+                 bitmap_clear_bit (bb_info->use, dregno);
+               }
            }
        }
 
            }
        }
 
-      for (use = DF_INSN_UID_GET (df, uid)->uses; use; use = use->next_ref)
+      for (use = DF_INSN_UID_USES (df, uid); use; use = use->next_ref)
        /* Add use to set of uses in this BB.  */
        bitmap_set_bit (bb_info->use, DF_REF_REGNO (use));
     }
 
   /* Process the registers set in an exception handler.  */
   for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
        /* Add use to set of uses in this BB.  */
        bitmap_set_bit (bb_info->use, DF_REF_REGNO (use));
     }
 
   /* Process the registers set in an exception handler.  */
   for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
-    if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+    if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP)
+       && (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL)))
       {
        unsigned int dregno = DF_REF_REGNO (def);
        bitmap_set_bit (bb_info->def, dregno);
       {
        unsigned int dregno = DF_REF_REGNO (def);
        bitmap_set_bit (bb_info->def, dregno);
@@ -1492,6 +1553,7 @@ df_lr_bb_local_compute (struct dataflow *dflow,
 #endif
 }
 
 #endif
 }
 
+
 /* Compute local live register info for each basic block within BLOCKS.  */
 
 static void
 /* Compute local live register info for each basic block within BLOCKS.  */
 
 static void
@@ -1516,7 +1578,7 @@ df_lr_local_compute (struct dataflow *dflow,
   /* 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.  */
   /* 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.  */
-  if (! reload_completed)
+  if (!reload_completed)
     {
       /* Any reference to any pseudo before reload is a potential
         reference of the frame pointer.  */
     {
       /* Any reference to any pseudo before reload is a potential
         reference of the frame pointer.  */
@@ -1585,6 +1647,7 @@ df_lr_confluence_0 (struct dataflow *dflow, basic_block bb)
 
 
 /* Confluence function that ignores fake edges.  */
 
 
 /* Confluence function that ignores fake edges.  */
+
 static void
 df_lr_confluence_n (struct dataflow *dflow, edge e)
 {
 static void
 df_lr_confluence_n (struct dataflow *dflow, edge e)
 {
@@ -1604,6 +1667,7 @@ df_lr_confluence_n (struct dataflow *dflow, edge e)
 
 
 /* Transfer function.  */
 
 
 /* Transfer function.  */
+
 static bool
 df_lr_transfer_function (struct dataflow *dflow, int bb_index)
 {
 static bool
 df_lr_transfer_function (struct dataflow *dflow, int bb_index)
 {
@@ -1641,6 +1705,8 @@ df_lr_free (struct dataflow *dflow)
       dflow->block_info_size = 0;
       free (dflow->block_info);
     }
       dflow->block_info_size = 0;
       free (dflow->block_info);
     }
+
+  free (dflow->problem_data);
   free (dflow);
 }
 
   free (dflow);
 }
 
@@ -1652,6 +1718,9 @@ df_lr_dump (struct dataflow *dflow, FILE *file)
 {
   basic_block bb;
   
 {
   basic_block bb;
   
+  if (!dflow->block_info) 
+    return;
+
   fprintf (file, "Live Registers:\n");
   FOR_ALL_BB (bb)
     {
   fprintf (file, "Live Registers:\n");
   FOR_ALL_BB (bb)
     {
@@ -1690,7 +1759,8 @@ static struct df_problem problem_LR =
   NULL,                       /* Finalize function.  */
   df_lr_free,                 /* Free all of the problem information.  */
   df_lr_dump,                 /* Debugging.  */
   NULL,                       /* Finalize function.  */
   df_lr_free,                 /* Free all of the problem information.  */
   df_lr_dump,                 /* Debugging.  */
-  NULL                        /* Dependent problem.  */
+  NULL,                       /* Dependent problem.  */
+  0
 };
 
 
 };
 
 
@@ -1699,9 +1769,9 @@ static struct df_problem problem_LR =
    solution.  */
 
 struct dataflow *
    solution.  */
 
 struct dataflow *
-df_lr_add_problem (struct df *df)
+df_lr_add_problem (struct df *df, int flags)
 {
 {
-  return df_add_problem (df, &problem_LR);
+  return df_add_problem (df, &problem_LR, flags);
 }
 
 
 }
 
 
@@ -1710,7 +1780,9 @@ df_lr_add_problem (struct df *df)
    UNINITIALIZED REGISTERS
 
    Find the set of uses for registers that are reachable from the entry
    UNINITIALIZED REGISTERS
 
    Find the set of uses for registers that are reachable from the entry
-   block without passing thru a definition.
+   block without passing thru a definition.  In and out bitvectors are built
+   for each basic block.  The regnum is used to index into these sets.
+   See df.h for details.
 ----------------------------------------------------------------------------*/
 
 /* Get basic block info.  */
 ----------------------------------------------------------------------------*/
 
 /* Get basic block info.  */
@@ -1755,21 +1827,18 @@ df_ur_free_bb_info (struct dataflow *dflow,
    not touched unless the block is new.  */
 
 static void 
    not touched unless the block is new.  */
 
 static void 
-df_ur_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
+df_ur_alloc (struct dataflow *dflow, bitmap blocks_to_rescan,
+            bitmap all_blocks ATTRIBUTE_UNUSED)
 {
   unsigned int bb_index;
   bitmap_iterator bi;
 
 {
   unsigned int bb_index;
   bitmap_iterator bi;
 
-  if (! dflow->block_pool)
+  if (!dflow->block_pool)
     dflow->block_pool = create_alloc_pool ("df_ur_block pool", 
                                           sizeof (struct df_ur_bb_info), 100);
 
   df_grow_bb_info (dflow);
 
     dflow->block_pool = create_alloc_pool ("df_ur_block pool", 
                                           sizeof (struct df_ur_bb_info), 100);
 
   df_grow_bb_info (dflow);
 
-  /* Because of the clustering of all def sites for the same pseudo,
-     we have to process all of the blocks before doing the
-     analysis.  */
-
   EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
     {
       struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb_index);
   EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
     {
       struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb_index);
@@ -1822,16 +1891,23 @@ df_ur_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
       if (!INSN_P (insn))
        continue;
 
       if (!INSN_P (insn))
        continue;
 
-      for (def = DF_INSN_UID_GET (df, uid)->defs; def; def = def->next_ref)
+      for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
        {
          unsigned int regno = DF_REF_REGNO (def);
        {
          unsigned int regno = DF_REF_REGNO (def);
-             /* Only the last def counts.  */
+         /* Only the last def counts.  */
          if (!bitmap_bit_p (seen_in_block, regno))
            {
              bitmap_set_bit (seen_in_insn, regno);
              
          if (!bitmap_bit_p (seen_in_block, regno))
            {
              bitmap_set_bit (seen_in_insn, regno);
              
-             if (DF_REF_FLAGS (def) & DF_REF_CLOBBER)
-               bitmap_set_bit (bb_info->kill, regno);
+             if (DF_REF_FLAGS (def) 
+                 & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))
+               {
+                 /* Only must clobbers for the entire reg destroy the
+                    value.  */
+                 if ((DF_REF_FLAGS (def) & DF_REF_MUST_CLOBBER)
+                     && (!DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+                   bitmap_set_bit (bb_info->kill, regno);
+               }
              else
                bitmap_set_bit (bb_info->gen, regno);
            }
              else
                bitmap_set_bit (bb_info->gen, regno);
            }
@@ -1926,7 +2002,7 @@ df_ur_local_finalize (struct dataflow *dflow, bitmap all_blocks)
       bitmap_and_into (bb_info->out, tmp);
 #endif
     }
       bitmap_and_into (bb_info->out, tmp);
 #endif
     }
-  
+
   BITMAP_FREE (tmp);
 }
 
   BITMAP_FREE (tmp);
 }
 
@@ -1997,6 +2073,9 @@ df_ur_dump (struct dataflow *dflow, FILE *file)
 {
   basic_block bb;
   
 {
   basic_block bb;
   
+  if (!dflow->block_info) 
+    return;
+
   fprintf (file, "Undefined regs:\n");
  
   FOR_ALL_BB (bb)
   fprintf (file, "Undefined regs:\n");
  
   FOR_ALL_BB (bb)
@@ -2004,7 +2083,7 @@ df_ur_dump (struct dataflow *dflow, FILE *file)
       struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb->index);
       df_print_bb_index (bb, file);
       
       struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb->index);
       df_print_bb_index (bb, file);
       
-      if (! bb_info->in)
+      if (!bb_info->in)
        continue;
       
       fprintf (file, "  in  \t");
        continue;
       
       fprintf (file, "  in  \t");
@@ -2036,7 +2115,8 @@ static struct df_problem problem_UR =
   df_ur_local_finalize,       /* Finalize function.  */
   df_ur_free,                 /* Free all of the problem information.  */
   df_ur_dump,                 /* Debugging.  */
   df_ur_local_finalize,       /* Finalize function.  */
   df_ur_free,                 /* Free all of the problem information.  */
   df_ur_dump,                 /* Debugging.  */
-  &problem_LR                 /* Dependent problem.  */
+  df_lr_add_problem,          /* Dependent problem.  */
+  0                           /* Changeable flags.  */
 };
 
 
 };
 
 
@@ -2045,9 +2125,9 @@ static struct df_problem problem_UR =
    solution.  */
 
 struct dataflow *
    solution.  */
 
 struct dataflow *
-df_ur_add_problem (struct df *df)
+df_ur_add_problem (struct df *df, int flags)
 {
 {
-  return df_add_problem (df, &problem_UR);
+  return df_add_problem (df, &problem_UR, flags);
 }
 
 
 }
 
 
@@ -2056,12 +2136,18 @@ df_ur_add_problem (struct df *df)
    UNINITIALIZED REGISTERS WITH EARLYCLOBBER
 
    Find the set of uses for registers that are reachable from the entry
    UNINITIALIZED REGISTERS WITH EARLYCLOBBER
 
    Find the set of uses for registers that are reachable from the entry
-   block without passing thru a definition.
+   block without passing thru a definition.  In and out bitvectors are built
+   for each basic block.  The regnum is used to index into these sets.
+   See df.h for details.
 
    This is a variant of the UR problem above that has a lot of special
 
    This is a variant of the UR problem above that has a lot of special
-   features just for the register allocation phase.
-----------------------------------------------------------------------------*/
+   features just for the register allocation phase.  This problem
+   should go a away if someone would fix the interference graph.
 
 
+   ----------------------------------------------------------------------------*/
+
+/* Private data used to compute the solution for this problem.  These
+   data structures are not accessible outside of this module.  */
 struct df_urec_problem_data
 {
   bool earlyclobbers_found;     /* True if any instruction contains an
 struct df_urec_problem_data
 {
   bool earlyclobbers_found;     /* True if any instruction contains an
@@ -2115,14 +2201,16 @@ df_urec_free_bb_info (struct dataflow *dflow,
    not touched unless the block is new.  */
 
 static void 
    not touched unless the block is new.  */
 
 static void 
-df_urec_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
+df_urec_alloc (struct dataflow *dflow, bitmap blocks_to_rescan,
+              bitmap all_blocks ATTRIBUTE_UNUSED)
+
 {
   unsigned int bb_index;
   bitmap_iterator bi;
 {
   unsigned int bb_index;
   bitmap_iterator bi;
-  struct df_urec_problem_data *problem_data =
-    (struct df_urec_problem_data *) dflow->problem_data;
+  struct df_urec_problem_data *problem_data
+    (struct df_urec_problem_data *) dflow->problem_data;
 
 
-  if (! dflow->block_pool)
+  if (!dflow->block_pool)
     dflow->block_pool = create_alloc_pool ("df_urec_block pool", 
                                           sizeof (struct df_urec_bb_info), 50);
 
     dflow->block_pool = create_alloc_pool ("df_urec_block pool", 
                                           sizeof (struct df_urec_bb_info), 50);
 
@@ -2135,10 +2223,6 @@ df_urec_alloc (struct dataflow *dflow, bitmap blocks_to_rescan)
 
   df_grow_bb_info (dflow);
 
 
   df_grow_bb_info (dflow);
 
-  /* Because of the clustering of all def sites for the same pseudo,
-     we have to process all of the blocks before doing the
-     analysis.  */
-
   EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
     {
       struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb_index);
   EXECUTE_IF_SET_IN_BITMAP (blocks_to_rescan, 0, bb_index, bi)
     {
       struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb_index);
@@ -2208,9 +2292,6 @@ df_urec_mark_reg_change (rtx reg, rtx setter, void *data)
 /* Classes of registers which could be early clobbered in the current
    insn.  */
 
 /* Classes of registers which could be early clobbered in the current
    insn.  */
 
-DEF_VEC_I(int);
-DEF_VEC_ALLOC_I(int,heap);
-
 static VEC(int,heap) *earlyclobber_regclass;
 
 /* This function finds and stores register classes that could be early
 static VEC(int,heap) *earlyclobber_regclass;
 
 /* This function finds and stores register classes that could be early
@@ -2378,11 +2459,10 @@ df_urec_bb_local_compute (struct dataflow *dflow, unsigned int bb_index)
       if (INSN_P (insn))
        {
          note_stores (PATTERN (insn), df_urec_mark_reg_change, bb_info);
       if (INSN_P (insn))
        {
          note_stores (PATTERN (insn), df_urec_mark_reg_change, bb_info);
-         if (df_state & (DF_SCAN_GLOBAL | DF_SCAN_POST_ALLOC) 
-             && df_urec_check_earlyclobber (insn))
+         if (df_urec_check_earlyclobber (insn))
            {
            {
-             struct df_urec_problem_data *problem_data =
-               (struct df_urec_problem_data *) dflow->problem_data;
+             struct df_urec_problem_data *problem_data
+               (struct df_urec_problem_data *) dflow->problem_data;
              problem_data->earlyclobbers_found = true;
              note_uses (&PATTERN (insn), 
                         df_urec_mark_reg_use_for_earlyclobber_1, bb_info);
              problem_data->earlyclobbers_found = true;
              note_uses (&PATTERN (insn), 
                         df_urec_mark_reg_use_for_earlyclobber_1, bb_info);
@@ -2412,8 +2492,8 @@ df_urec_local_compute (struct dataflow *dflow,
 #ifdef STACK_REGS
   int i;
   HARD_REG_SET zero, stack_hard_regs, used;
 #ifdef STACK_REGS
   int i;
   HARD_REG_SET zero, stack_hard_regs, used;
-  struct df_urec_problem_data *problem_data =
-    (struct df_urec_problem_data *) dflow->problem_data;
+  struct df_urec_problem_data *problem_data
+    (struct df_urec_problem_data *) dflow->problem_data;
   
   /* Any register that MAY be allocated to a register stack (like the
      387) is treated poorly.  Each such register is marked as being
   
   /* Any register that MAY be allocated to a register stack (like the
      387) is treated poorly.  Each such register is marked as being
@@ -2481,8 +2561,8 @@ df_urec_local_finalize (struct dataflow *dflow, bitmap all_blocks)
   bitmap tmp = BITMAP_ALLOC (NULL);
   bitmap_iterator bi;
   unsigned int bb_index;
   bitmap tmp = BITMAP_ALLOC (NULL);
   bitmap_iterator bi;
   unsigned int bb_index;
-  struct df_urec_problem_data *problem_data =
-    (struct df_urec_problem_data *) dflow->problem_data;
+  struct df_urec_problem_data *problem_data
+    (struct df_urec_problem_data *) dflow->problem_data;
 
   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
 
   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
@@ -2599,6 +2679,9 @@ df_urec_dump (struct dataflow *dflow, FILE *file)
 {
   basic_block bb;
   
 {
   basic_block bb;
   
+  if (!dflow->block_info) 
+    return;
+
   fprintf (file, "Undefined regs:\n");
  
   FOR_ALL_BB (bb)
   fprintf (file, "Undefined regs:\n");
  
   FOR_ALL_BB (bb)
@@ -2606,7 +2689,7 @@ df_urec_dump (struct dataflow *dflow, FILE *file)
       struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb->index);
       df_print_bb_index (bb, file);
       
       struct df_urec_bb_info *bb_info = df_urec_get_bb_info (dflow, bb->index);
       df_print_bb_index (bb, file);
       
-      if (! bb_info->in)
+      if (!bb_info->in)
        continue;
       
       fprintf (file, "  in  \t");
        continue;
       
       fprintf (file, "  in  \t");
@@ -2640,7 +2723,8 @@ static struct df_problem problem_UREC =
   df_urec_local_finalize,     /* Finalize function.  */
   df_urec_free,               /* Free all of the problem information.  */
   df_urec_dump,               /* Debugging.  */
   df_urec_local_finalize,     /* Finalize function.  */
   df_urec_free,               /* Free all of the problem information.  */
   df_urec_dump,               /* Debugging.  */
-  &problem_LR                 /* Dependent problem.  */
+  df_lr_add_problem,          /* Dependent problem.  */
+  0                           /* Changeable flags.  */
 };
 
 
 };
 
 
@@ -2649,9 +2733,9 @@ static struct df_problem problem_UREC =
    solution.  */
 
 struct dataflow *
    solution.  */
 
 struct dataflow *
-df_urec_add_problem (struct df *df)
+df_urec_add_problem (struct df *df, int flags)
 {
 {
-  return df_add_problem (df, &problem_UREC);
+  return df_add_problem (df, &problem_UREC, flags);
 }
 
 
 }
 
 
@@ -2667,22 +2751,16 @@ df_urec_add_problem (struct df *df)
    the reaching defs information (the dependent problem).
 ----------------------------------------------------------------------------*/
 
    the reaching defs information (the dependent problem).
 ----------------------------------------------------------------------------*/
 
-struct df_chain_problem_data
-{
-  int flags;
-};
-
-
 /* Create def-use or use-def chains.  */
 
 static void  
 df_chain_alloc (struct dataflow *dflow, 
 /* Create def-use or use-def chains.  */
 
 static void  
 df_chain_alloc (struct dataflow *dflow, 
-               bitmap blocks_to_rescan ATTRIBUTE_UNUSED)
+               bitmap blocks_to_rescan ATTRIBUTE_UNUSED,
+               bitmap all_blocks ATTRIBUTE_UNUSED)
+
 {
   struct df *df = dflow->df;
   unsigned int i;
 {
   struct df *df = dflow->df;
   unsigned int i;
-  struct df_chain_problem_data *problem_data =
-    (struct df_chain_problem_data *) dflow->problem_data;
 
   /* Wholesale destruction of the old chains.  */ 
   if (dflow->block_pool)
 
   /* Wholesale destruction of the old chains.  */ 
   if (dflow->block_pool)
@@ -2691,7 +2769,7 @@ df_chain_alloc (struct dataflow *dflow,
   dflow->block_pool = create_alloc_pool ("df_chain_chain_block pool", 
                                         sizeof (struct df_link), 100);
 
   dflow->block_pool = create_alloc_pool ("df_chain_chain_block pool", 
                                         sizeof (struct df_link), 100);
 
-  if (problem_data->flags & DF_DU_CHAIN)
+  if (dflow->flags & DF_DU_CHAIN)
     {
       if (!df->def_info.refs_organized)
        df_reorganize_refs (&df->def_info);
     {
       if (!df->def_info.refs_organized)
        df_reorganize_refs (&df->def_info);
@@ -2704,7 +2782,7 @@ df_chain_alloc (struct dataflow *dflow,
        }
     }
   
        }
     }
   
-  if (problem_data->flags & DF_UD_CHAIN)
+  if (dflow->flags & DF_UD_CHAIN)
     {
       if (!df->use_info.refs_organized)
        df_reorganize_refs (&df->use_info);
     {
       if (!df->use_info.refs_organized)
        df_reorganize_refs (&df->use_info);
@@ -2723,8 +2801,6 @@ static void
 df_chain_insn_reset (struct dataflow *dflow, rtx insn)
 {
   struct df *df = dflow->df;
 df_chain_insn_reset (struct dataflow *dflow, rtx insn)
 {
   struct df *df = dflow->df;
-  struct df_chain_problem_data *problem_data =
-    (struct df_chain_problem_data *) dflow->problem_data;
   unsigned int uid = INSN_UID (insn);
   struct df_insn_info *insn_info = NULL;
   struct df_ref *ref;
   unsigned int uid = INSN_UID (insn);
   struct df_insn_info *insn_info = NULL;
   struct df_ref *ref;
@@ -2734,7 +2810,7 @@ df_chain_insn_reset (struct dataflow *dflow, rtx insn)
 
   if (insn_info)
     {
 
   if (insn_info)
     {
-      if (problem_data->flags & DF_DU_CHAIN)
+      if (dflow->flags & DF_DU_CHAIN)
        {
          ref = insn_info->defs;
          while (ref)
        {
          ref = insn_info->defs;
          while (ref)
@@ -2744,7 +2820,7 @@ df_chain_insn_reset (struct dataflow *dflow, rtx insn)
            }
        }
 
            }
        }
 
-      if (problem_data->flags & DF_UD_CHAIN)
+      if (dflow->flags & DF_UD_CHAIN)
        {
          ref = insn_info->uses;
          while (ref) 
        {
          ref = insn_info->uses;
          while (ref) 
@@ -2763,8 +2839,6 @@ static void
 df_chain_bb_reset (struct dataflow *dflow, unsigned int bb_index)
 {
   struct df *df = dflow->df; 
 df_chain_bb_reset (struct dataflow *dflow, unsigned int bb_index)
 {
   struct df *df = dflow->df; 
-  struct df_chain_problem_data *problem_data =
-    (struct df_chain_problem_data *) dflow->problem_data;
   rtx insn;
   basic_block bb = BASIC_BLOCK (bb_index);
 
   rtx insn;
   basic_block bb = BASIC_BLOCK (bb_index);
 
@@ -2781,8 +2855,8 @@ df_chain_bb_reset (struct dataflow *dflow, unsigned int bb_index)
        }
     }
   
        }
     }
   
-  /* Get rid of any chains in artifical uses or defs.  */
-  if (problem_data->flags & DF_DU_CHAIN)
+  /* Get rid of any chains in artificial uses or defs.  */
+  if (dflow->flags & DF_DU_CHAIN)
     {
       struct df_ref *def;
       def = df_get_artificial_defs (df, bb_index);
     {
       struct df_ref *def;
       def = df_get_artificial_defs (df, bb_index);
@@ -2793,7 +2867,7 @@ df_chain_bb_reset (struct dataflow *dflow, unsigned int bb_index)
        }
     }
 
        }
     }
 
-  if (problem_data->flags & DF_UD_CHAIN)
+  if (dflow->flags & DF_UD_CHAIN)
     {
       struct df_ref *use;
       use = df_get_artificial_uses (df, bb_index);
     {
       struct df_ref *use;
       use = df_get_artificial_uses (df, bb_index);
@@ -2829,7 +2903,6 @@ df_chain_reset (struct dataflow *dflow, bitmap blocks_to_clear)
 
 static void
 df_chain_create_bb_process_use (struct dataflow *dflow, 
 
 static void
 df_chain_create_bb_process_use (struct dataflow *dflow, 
-                               struct df_chain_problem_data *problem_data,
                                bitmap local_rd,
                                struct df_ref *use,
                                enum df_ref_flags top_flag)
                                bitmap local_rd,
                                struct df_ref *use,
                                enum df_ref_flags top_flag)
@@ -2857,9 +2930,9 @@ df_chain_create_bb_process_use (struct dataflow *dflow,
                    break;
                  
                  def = DF_DEFS_GET (df, def_index);
                    break;
                  
                  def = DF_DEFS_GET (df, def_index);
-                 if (problem_data->flags & DF_DU_CHAIN)
+                 if (dflow->flags & DF_DU_CHAIN)
                    df_chain_create (dflow, def, use);
                    df_chain_create (dflow, def, use);
-                 if (problem_data->flags & DF_UD_CHAIN)
+                 if (dflow->flags & DF_UD_CHAIN)
                    df_chain_create (dflow, use, def);
                }
            }
                    df_chain_create (dflow, use, def);
                }
            }
@@ -2883,8 +2956,6 @@ df_chain_create_bb (struct dataflow *dflow,
   rtx insn;
   bitmap cpy = BITMAP_ALLOC (NULL);
   struct df *df = dflow->df;
   rtx insn;
   bitmap cpy = BITMAP_ALLOC (NULL);
   struct df *df = dflow->df;
-  struct df_chain_problem_data *problem_data =
-    (struct df_chain_problem_data *) dflow->problem_data;
   struct df_ref *def;
 
   bitmap_copy (cpy, bb_info->in);
   struct df_ref *def;
 
   bitmap_copy (cpy, bb_info->in);
@@ -2895,7 +2966,7 @@ df_chain_create_bb (struct dataflow *dflow,
 #ifdef EH_USES
   /* Create the chains for the artificial uses from the EH_USES at the
      beginning of the block.  */
 #ifdef EH_USES
   /* Create the chains for the artificial uses from the EH_USES at the
      beginning of the block.  */
-  df_chain_create_bb_process_use (dflow, problem_data, cpy,
+  df_chain_create_bb_process_use (dflow, cpy,
                                  df_get_artificial_uses (df, bb->index), 
                                  DF_REF_AT_TOP);
 #endif
                                  df_get_artificial_uses (df, bb->index), 
                                  DF_REF_AT_TOP);
 #endif
@@ -2904,11 +2975,11 @@ df_chain_create_bb (struct dataflow *dflow,
     if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
       {
        unsigned int dregno = DF_REF_REGNO (def);
     if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
       {
        unsigned int dregno = DF_REF_REGNO (def);
-       bitmap_clear_range (cpy, 
-                           DF_REG_DEF_GET (df, dregno)->begin
-                           DF_REG_DEF_GET (df, dregno)->n_refs);
-       if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
-         bitmap_set_bit (cpy, DF_REF_ID (def));
+       if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+         bitmap_clear_range (cpy
+                             DF_REG_DEF_GET (df, dregno)->begin, 
+                             DF_REG_DEF_GET (df, dregno)->n_refs);
+       bitmap_set_bit (cpy, DF_REF_ID (def));
       }
   
   /* Process the regular instructions next.  */
       }
   
   /* Process the regular instructions next.  */
@@ -2917,31 +2988,33 @@ df_chain_create_bb (struct dataflow *dflow,
       struct df_ref *def;
       unsigned int uid = INSN_UID (insn);
 
       struct df_ref *def;
       unsigned int uid = INSN_UID (insn);
 
-      if (! INSN_P (insn))
+      if (!INSN_P (insn))
        continue;
 
       /* Now scan the uses and link them up with the defs that remain
         in the cpy vector.  */
       
        continue;
 
       /* Now scan the uses and link them up with the defs that remain
         in the cpy vector.  */
       
-      df_chain_create_bb_process_use (dflow, problem_data, cpy,                     
-                                    DF_INSN_UID_GET (df, uid)->uses, 0);
+      df_chain_create_bb_process_use (dflow, cpy,
+                                    DF_INSN_UID_USES (df, uid), 0);
 
       /* Since we are going forwards, process the defs second.  This
          pass only changes the bits in cpy.  */
 
       /* Since we are going forwards, process the defs second.  This
          pass only changes the bits in cpy.  */
-      for (def = DF_INSN_UID_GET (df, uid)->defs; def; def = def->next_ref)
+      for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
        {
          unsigned int dregno = DF_REF_REGNO (def);
        {
          unsigned int dregno = DF_REF_REGNO (def);
-         bitmap_clear_range (cpy, 
-                             DF_REG_DEF_GET (df, dregno)->begin, 
-                             DF_REG_DEF_GET (df, dregno)->n_refs);
-         if (! (DF_REF_FLAGS (def) & DF_REF_CLOBBER))
+         if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+           bitmap_clear_range (cpy, 
+                               DF_REG_DEF_GET (df, dregno)->begin, 
+                               DF_REG_DEF_GET (df, dregno)->n_refs);
+         if (!(DF_REF_FLAGS (def) 
+                & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
            bitmap_set_bit (cpy, DF_REF_ID (def));
        }
     }
 
   /* Create the chains for the artificial uses of the hard registers
      at the end of the block.  */
            bitmap_set_bit (cpy, DF_REF_ID (def));
        }
     }
 
   /* Create the chains for the artificial uses of the hard registers
      at the end of the block.  */
-  df_chain_create_bb_process_use (dflow, problem_data, cpy,
+  df_chain_create_bb_process_use (dflow, cpy,
                                  df_get_artificial_uses (df, bb->index), 0);
 }
 
                                  df_get_artificial_uses (df, bb->index), 0);
 }
 
@@ -2969,7 +3042,6 @@ static void
 df_chain_free (struct dataflow *dflow)
 {
   free_alloc_pool (dflow->block_pool);
 df_chain_free (struct dataflow *dflow)
 {
   free_alloc_pool (dflow->block_pool);
-  free (dflow->problem_data);
   free (dflow);
 }
 
   free (dflow);
 }
 
@@ -2981,10 +3053,8 @@ df_chains_dump (struct dataflow *dflow, FILE *file)
 {
   struct df *df = dflow->df;
   unsigned int j;
 {
   struct df *df = dflow->df;
   unsigned int j;
-  struct df_chain_problem_data *problem_data =
-    (struct df_chain_problem_data *) dflow->problem_data;
 
 
-  if (problem_data->flags & DF_DU_CHAIN)
+  if (dflow->flags & DF_DU_CHAIN)
     {
       fprintf (file, "Def-use chains:\n");
       for (j = 0; j < df->def_info.bitmap_size; j++)
     {
       fprintf (file, "Def-use chains:\n");
       for (j = 0; j < df->def_info.bitmap_size; j++)
@@ -2994,18 +3064,20 @@ df_chains_dump (struct dataflow *dflow, FILE *file)
            {
              fprintf (file, "d%d bb %d luid %d insn %d reg %d ",
                       j, DF_REF_BBNO (def),
            {
              fprintf (file, "d%d bb %d luid %d insn %d reg %d ",
                       j, DF_REF_BBNO (def),
-                      DF_INSN_LUID (df, DF_REF_INSN (def)),
+                      DF_REF_INSN (def) ? 
+                      DF_INSN_LUID (df, DF_REF_INSN (def)):
+                      -1,
                       DF_REF_INSN (def) ? DF_REF_INSN_UID (def) : -1,
                       DF_REF_REGNO (def));
              if (def->flags & DF_REF_READ_WRITE)
                fprintf (file, "read/write ");
                       DF_REF_INSN (def) ? DF_REF_INSN_UID (def) : -1,
                       DF_REF_REGNO (def));
              if (def->flags & DF_REF_READ_WRITE)
                fprintf (file, "read/write ");
-             df_chain_dump (df, DF_REF_CHAIN (def), file);
+             df_chain_dump (DF_REF_CHAIN (def), file);
              fprintf (file, "\n");
            }
        }
     }
 
              fprintf (file, "\n");
            }
        }
     }
 
-  if (problem_data->flags & DF_UD_CHAIN)
+  if (dflow->flags & DF_UD_CHAIN)
     {
       fprintf (file, "Use-def chains:\n");
       for (j = 0; j < df->use_info.bitmap_size; j++)
     {
       fprintf (file, "Use-def chains:\n");
       for (j = 0; j < df->use_info.bitmap_size; j++)
@@ -3028,7 +3100,7 @@ df_chains_dump (struct dataflow *dflow, FILE *file)
                fprintf (file, "stripped ");
              if (use->flags & DF_REF_IN_NOTE)
                fprintf (file, "note ");
                fprintf (file, "stripped ");
              if (use->flags & DF_REF_IN_NOTE)
                fprintf (file, "note ");
-             df_chain_dump (df, DF_REF_CHAIN (use), file);
+             df_chain_dump (DF_REF_CHAIN (use), file);
              fprintf (file, "\n");
            }
        }
              fprintf (file, "\n");
            }
        }
@@ -3052,7 +3124,8 @@ static struct df_problem problem_CHAIN =
   df_chain_finalize,          /* Finalize function.  */
   df_chain_free,              /* Free all of the problem information.  */
   df_chains_dump,             /* Debugging.  */
   df_chain_finalize,          /* Finalize function.  */
   df_chain_free,              /* Free all of the problem information.  */
   df_chains_dump,             /* Debugging.  */
-  &problem_RD                 /* Dependent problem.  */
+  df_rd_add_problem,          /* Dependent problem.  */
+  0                           /* Changeable flags.  */
 };
 
 
 };
 
 
@@ -3063,104 +3136,565 @@ static struct df_problem problem_CHAIN =
 struct dataflow *
 df_chain_add_problem (struct df *df, int flags)
 {
 struct dataflow *
 df_chain_add_problem (struct df *df, int flags)
 {
-  struct df_chain_problem_data *problem_data =
-       XNEW (struct df_chain_problem_data);
-  struct dataflow *dflow = df_add_problem (df, &problem_CHAIN);
-
-  dflow->problem_data = problem_data;
-  problem_data->flags = flags;
-  
-  return dflow;
+  return df_add_problem (df, &problem_CHAIN, flags);
 }
 
 
 /*----------------------------------------------------------------------------
    REGISTER INFORMATION
 
 }
 
 
 /*----------------------------------------------------------------------------
    REGISTER INFORMATION
 
-   Currently this consists of only lifetime information.  But the plan is
-   to enhance it so that it produces all of the register information needed
-   by the register allocators.
-----------------------------------------------------------------------------*/
+   This pass properly computes REG_DEAD and REG_UNUSED notes.
 
 
+   If the DF_RI_LIFE flag is set the following vectors containing
+   information about register usage are properly set: REG_N_REFS,
+   REG_N_DEATHS, REG_N_SETS, REG_LIVE_LENGTH, REG_N_CALLS_CROSSED,
+   REG_N_THROWING_CALLS_CROSSED and REG_BASIC_BLOCK.
 
 
-struct df_ri_problem_data
-{
-  int *lifetime;
-};
+   ----------------------------------------------------------------------------*/
 
 
+#ifdef REG_DEAD_DEBUGGING
+static void 
+print_note (char *prefix, rtx insn, rtx note)
+{
+  fprintf (stderr, "%s %d ", prefix, INSN_UID (insn));
+  print_rtl (stderr, note);
+  fprintf (stderr, "\n");
+}
+#endif
 
 /* Allocate the lifetime information.  */
 
 static void 
 
 /* Allocate the lifetime information.  */
 
 static void 
-df_ri_alloc (struct dataflow *dflow, bitmap blocks_to_rescan ATTRIBUTE_UNUSED)
+df_ri_alloc (struct dataflow *dflow, 
+            bitmap blocks_to_rescan ATTRIBUTE_UNUSED,
+            bitmap all_blocks ATTRIBUTE_UNUSED)
 {
 {
-  struct df_ri_problem_data *problem_data =
-    (struct df_ri_problem_data *) dflow->problem_data;
+  int i;
+  struct df *df = dflow->df;
 
 
-  if (!dflow->problem_data)
+  if (dflow->flags & DF_RI_LIFE)
     {
     {
-      struct df_ri_problem_data *problem_data =        XNEW (struct df_ri_problem_data);
-      dflow->problem_data = problem_data;
+      max_regno = max_reg_num ();
+      allocate_reg_info (max_regno, FALSE, FALSE);
+      
+      /* Reset all the data we'll collect.  */
+      for (i = 0; i < max_regno; i++)
+       {
+         REG_N_SETS (i) = DF_REG_DEF_COUNT (df, i);
+         REG_N_REFS (i) = DF_REG_USE_COUNT (df, i) + REG_N_SETS (i);
+         REG_N_DEATHS (i) = 0;
+         REG_N_CALLS_CROSSED (i) = 0;
+         REG_N_THROWING_CALLS_CROSSED (i) = 0;
+         REG_LIVE_LENGTH (i) = 0;
+         REG_FREQ (i) = 0;
+         REG_BASIC_BLOCK (i) = REG_BLOCK_UNKNOWN;
+       }
+    }
+}
+
+
+/* After reg-stack, the x86 floating point stack regs are difficult to
+   analyze because of all of the pushes, pops and rotations.  Thus, we
+   just leave the notes alone. */
+
+static inline bool 
+df_ignore_stack_reg (int regno ATTRIBUTE_UNUSED)
+{
+#ifdef STACK_REGS
+  return (regstack_completed
+         && IN_RANGE (regno, FIRST_STACK_REG, LAST_STACK_REG));
+#else
+  return false;
+#endif
+}
+
+
+/* Remove all of the REG_DEAD or REG_UNUSED notes from INSN.  */
+
+static void
+df_kill_notes (rtx insn, int flags)
+{
+  rtx *pprev = &REG_NOTES (insn);
+  rtx link = *pprev;
+  
+  while (link)
+    {
+      switch (REG_NOTE_KIND (link))
+       {
+       case REG_DEAD:
+         if (flags & DF_RI_LIFE)
+           if (df_ignore_stack_reg (REGNO (XEXP (link, 0))))
+             REG_N_DEATHS (REGNO (XEXP (link, 0)))++;
+
+         /* Fallthru */
+       case REG_UNUSED:
+         if (!df_ignore_stack_reg (REGNO (XEXP (link, 0))))
+           {
+             rtx next = XEXP (link, 1);
+#ifdef REG_DEAD_DEBUGGING
+             print_note ("deleting: ", insn, link);
+#endif
+             free_EXPR_LIST_node (link);
+             *pprev = link = next;
+           }
+         break;
+         
+       default:
+         pprev = &XEXP (link, 1);
+         link = *pprev;
+         break;
+       }
+    }
+}
+
+
+/* Set the REG_UNUSED notes for the multiword hardreg defs in INSN
+   based on the bits in LIVE.  Do not generate notes for registers in
+   artificial uses.  DO_NOT_GEN is updated so that REG_DEAD notes are
+   not generated if the reg is both read and written by the
+   instruction.
+*/
+
+static void
+df_set_unused_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
+                           bitmap live, bitmap do_not_gen, 
+                           bitmap artificial_uses, int flags)
+{
+  bool all_dead = true;
+  struct df_link *regs = mws->regs;
+  unsigned int regno = DF_REF_REGNO (regs->ref);
+  
+#ifdef REG_DEAD_DEBUGGING
+  fprintf (stderr, "mw unused looking at %d\n", DF_REF_REGNO (regs->ref));
+  df_ref_debug (regs->ref, stderr);
+#endif
+  while (regs)
+    {
+      unsigned int regno = DF_REF_REGNO (regs->ref);
+      if ((bitmap_bit_p (live, regno))
+         || bitmap_bit_p (artificial_uses, regno))
+       {
+         all_dead = false;
+         break;
+       }
+      regs = regs->next;
+    }
+  
+  if (all_dead)
+    {
+      struct df_link *regs = mws->regs;
+      rtx note = alloc_EXPR_LIST (REG_UNUSED, *DF_REF_LOC (regs->ref), 
+                                 REG_NOTES (insn));
+      REG_NOTES (insn) = note;
+#ifdef REG_DEAD_DEBUGGING
+      print_note ("adding 1: ", insn, note);
+#endif
+      bitmap_set_bit (do_not_gen, regno);
+      /* Only do this if the value is totally dead.  */
+      if (flags & DF_RI_LIFE)
+       {
+         REG_N_DEATHS (regno) ++;
+         REG_LIVE_LENGTH (regno)++;
+       }
+    }
+  else
+    {
+      struct df_link *regs = mws->regs;
+      while (regs)
+       {
+         struct df_ref *ref = regs->ref;
+         
+         regno = DF_REF_REGNO (ref);
+         if ((!bitmap_bit_p (live, regno))
+             && (!bitmap_bit_p (artificial_uses, regno)))
+           {
+             rtx note = alloc_EXPR_LIST (REG_UNUSED, regno_reg_rtx[regno], 
+                                         REG_NOTES (insn));
+             REG_NOTES (insn) = note;
+#ifdef REG_DEAD_DEBUGGING
+             print_note ("adding 2: ", insn, note);
+#endif
+           }
+         bitmap_set_bit (do_not_gen, regno);
+         regs = regs->next;
+       }
+    }
+}
+
+
+/* Set the REG_DEAD notes for the multiword hardreg use in INSN based
+   on the bits in LIVE.  DO_NOT_GEN is used to keep REG_DEAD notes
+   from being set if the instruction both reads and writes the
+   register.  */
+
+static void
+df_set_dead_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
+                         bitmap live, bitmap do_not_gen,
+                         bitmap artificial_uses, int flags)
+{
+  bool all_dead = true;
+  struct df_link *regs = mws->regs;
+  unsigned int regno = DF_REF_REGNO (regs->ref);
+  
+#ifdef REG_DEAD_DEBUGGING
+  fprintf (stderr, "mw looking at %d\n", DF_REF_REGNO (regs->ref));
+  df_ref_debug (regs->ref, stderr);
+#endif
+  while (regs)
+    {
+      unsigned int regno = DF_REF_REGNO (regs->ref);
+      if ((bitmap_bit_p (live, regno))
+         || bitmap_bit_p (artificial_uses, regno))
+       {
+         all_dead = false;
+         break;
+       }
+      regs = regs->next;
+    }
+  
+  if (all_dead)
+    {
+      if (!bitmap_bit_p (do_not_gen, regno))
+       {
+         /* Add a dead note for the entire multi word register.  */
+         struct df_link *regs = mws->regs;
+         rtx note = alloc_EXPR_LIST (REG_DEAD, *DF_REF_LOC (regs->ref), 
+                                     REG_NOTES (insn));
+         REG_NOTES (insn) = note;
+#ifdef REG_DEAD_DEBUGGING
+         print_note ("adding 1: ", insn, note);
+#endif
+
+         if (flags & DF_RI_LIFE)
+           {
+             struct df_link *regs = mws->regs;
+             while (regs)
+               {
+                 struct df_ref *ref = regs->ref;
+                 regno = DF_REF_REGNO (ref);
+                 REG_N_DEATHS (regno)++;
+                 regs = regs->next;
+               }
+           }
+       }
+    }
+  else
+    {
+      struct df_link *regs = mws->regs;
+      while (regs)
+       {
+         struct df_ref *ref = regs->ref;
+
+         regno = DF_REF_REGNO (ref);
+         if ((!bitmap_bit_p (live, regno))
+             && (!bitmap_bit_p (artificial_uses, regno))
+             && (!bitmap_bit_p (do_not_gen, regno)))
+           {
+             rtx note = alloc_EXPR_LIST (REG_DEAD, regno_reg_rtx[regno], 
+                                         REG_NOTES (insn));
+             REG_NOTES (insn) = note;
+             if (flags & DF_RI_LIFE)
+               REG_N_DEATHS (regno)++;
+#ifdef REG_DEAD_DEBUGGING
+             print_note ("adding 2: ", insn, note);
+#endif
+           }
+
+         regs = regs->next;
+       }
     }
     }
+}
+
+
+/* Create a REG_UNUSED note if necessary for DEF in INSN updating LIVE
+   and DO_NOT_GEN.  Do not generate notes for registers in artificial
+   uses.  */
+
+static void
+df_create_unused_note (basic_block bb, rtx insn, struct df_ref *def, 
+                      bitmap live, bitmap do_not_gen, bitmap artificial_uses, 
+                      bitmap local_live, bitmap local_processed, 
+                      int flags, int luid)
+{
+  unsigned int dregno = DF_REF_REGNO (def);
+  
+#ifdef REG_DEAD_DEBUGGING
+  fprintf (stderr, "  regular looking at def ");
+  df_ref_debug (def, stderr);
+#endif
 
 
-  problem_data->lifetime = xrealloc (problem_data->lifetime, 
-                                    max_reg_num () *sizeof (int));
-  memset (problem_data->lifetime, 0, max_reg_num () *sizeof (int));
+  if (bitmap_bit_p (live, dregno))
+    {
+      if (flags & DF_RI_LIFE)
+       {
+         /* If we have seen this regno, then it has already been
+            processed correctly with the per insn increment.  If we
+            have not seen it we need to add the length from here to
+            the end of the block to the live length.  */
+         if (bitmap_bit_p (local_processed, dregno))
+           {
+             if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+               bitmap_clear_bit (local_live, dregno);
+           }
+         else
+           {
+             bitmap_set_bit (local_processed, dregno);
+             REG_LIVE_LENGTH (dregno) += luid;
+           }
+       }
+    }
+  else if ((!(DF_REF_FLAGS (def) & DF_REF_MW_HARDREG))
+           && (!bitmap_bit_p (artificial_uses, dregno)) 
+           && (!df_ignore_stack_reg (dregno)))
+    {
+      rtx reg = GET_CODE (*DF_REF_LOC (def)) == SUBREG ?
+       SUBREG_REG (*DF_REF_LOC (def)) : *DF_REF_LOC (def);
+      rtx note = alloc_EXPR_LIST (REG_UNUSED, reg, REG_NOTES (insn));
+      REG_NOTES (insn) = note;
+#ifdef REG_DEAD_DEBUGGING
+      print_note ("adding 3: ", insn, note);
+#endif
+      if (flags & DF_RI_LIFE)
+       {
+         REG_N_DEATHS (dregno) ++;
+         REG_LIVE_LENGTH (dregno)++;
+       }
+    }
+  
+  if ((flags & DF_RI_LIFE) && (dregno >= FIRST_PSEUDO_REGISTER))
+    {
+      REG_FREQ (dregno) += REG_FREQ_FROM_BB (bb);
+      if (REG_BASIC_BLOCK (dregno) == REG_BLOCK_UNKNOWN)
+       REG_BASIC_BLOCK (dregno) = bb->index;
+      else if (REG_BASIC_BLOCK (dregno) != bb->index)
+       REG_BASIC_BLOCK (dregno) = REG_BLOCK_GLOBAL;
+    }
+
+  if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER + DF_REF_MAY_CLOBBER)))
+    bitmap_set_bit (do_not_gen, dregno);
+  
+  /* Kill this register if it is not a subreg store.  */
+  if (!(DF_REF_FLAGS (def) & DF_REF_PARTIAL))
+    bitmap_clear_bit (live, dregno);
 }
 
 }
 
-/* Compute register info: lifetime, bb, and number of defs and uses
-   for basic block BB.  */
+
+/* Recompute the REG_DEAD and REG_UNUSED notes and compute register
+   info: lifetime, bb, and number of defs and uses for basic block
+   BB.  The three bitvectors are scratch regs used here.  */
 
 static void
 
 static void
-df_ri_bb_compute (struct dataflow *dflow, unsigned int bb_index, bitmap live)
+df_ri_bb_compute (struct dataflow *dflow, unsigned int bb_index, 
+                 bitmap live, bitmap do_not_gen, bitmap artificial_uses,
+                 bitmap local_live, bitmap local_processed, bitmap setjumps_crossed)
 {
   struct df *df = dflow->df;
 {
   struct df *df = dflow->df;
-  struct df_ur_bb_info *bb_info = df_ur_get_bb_info (dflow, bb_index);
-  struct df_ri_problem_data *problem_data =
-    (struct df_ri_problem_data *) dflow->problem_data;
   basic_block bb = BASIC_BLOCK (bb_index);
   rtx insn;
   basic_block bb = BASIC_BLOCK (bb_index);
   rtx insn;
+  struct df_ref *def;
+  struct df_ref *use;
+  int luid = 0;
 
 
-  bitmap_copy (live, bb_info->out);
+  bitmap_copy (live, df_get_live_out (df, bb));
+  bitmap_clear (artificial_uses);
 
 
+  if (dflow->flags & DF_RI_LIFE)
+    {
+      /* Process the regs live at the end of the block.  Mark them as
+        not local to any one basic block.  */
+      bitmap_iterator bi;
+      unsigned int regno;
+      EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
+       REG_BASIC_BLOCK (regno) = REG_BLOCK_GLOBAL;
+    }
+
+  /* Process the artificial defs and uses at the bottom of the block
+     to begin processing.  */
+  for (def = df_get_artificial_defs (df, bb_index); def; def = def->next_ref)
+    if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
+      bitmap_clear_bit (live, DF_REF_REGNO (def));
+
+  for (use = df_get_artificial_uses (df, bb_index); use; use = use->next_ref)
+    if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
+      {
+       unsigned int regno = DF_REF_REGNO (use);
+       bitmap_set_bit (live, regno);
+
+       /* Notes are not generated for any of the artificial registers
+          at the bottom of the block.  */
+       bitmap_set_bit (artificial_uses, regno);
+      }
+  
   FOR_BB_INSNS_REVERSE (bb, insn)
     {
       unsigned int uid = INSN_UID (insn);
       unsigned int regno;
       bitmap_iterator bi;
   FOR_BB_INSNS_REVERSE (bb, insn)
     {
       unsigned int uid = INSN_UID (insn);
       unsigned int regno;
       bitmap_iterator bi;
-      struct df_ref *def;
-      struct df_ref *use;
-
-      if (! INSN_P (insn))
+      struct df_mw_hardreg *mws;
+      
+      if (!INSN_P (insn))
        continue;
 
        continue;
 
-      for (def = DF_INSN_UID_GET (df, uid)->defs; def; def = def->next_ref)
+      if (dflow->flags & DF_RI_LIFE)
        {
        {
-         unsigned int dregno = DF_REF_REGNO (def);
+         /* Increment the live_length for all of the registers that
+            are are referenced in this block and live at this
+            particular point.  */
+         bitmap_iterator bi;
+         unsigned int regno;
+         EXECUTE_IF_SET_IN_BITMAP (local_live, 0, regno, bi)
+           {
+             REG_LIVE_LENGTH (regno)++;
+           }
+         luid++;
+       }
+
+      bitmap_clear (do_not_gen);
+      df_kill_notes (insn, dflow->flags);
+
+      /* Process the defs.  */
+      if (CALL_P (insn))
+       {
+         if (dflow->flags & DF_RI_LIFE)
+           {
+             bool can_throw = can_throw_internal (insn); 
+             bool set_jump = (find_reg_note (insn, REG_SETJMP, NULL) != NULL);
+             EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
+               {
+                 REG_N_CALLS_CROSSED (regno)++;
+                 if (can_throw)
+                   REG_N_THROWING_CALLS_CROSSED (regno)++;
+
+                 /* We have a problem with any pseudoreg that lives
+                    across the setjmp.  ANSI says that if a user
+                    variable does not change in value between the
+                    setjmp and the longjmp, then the longjmp
+                    preserves it.  This includes longjmp from a place
+                    where the pseudo appears dead.  (In principle,
+                    the value still exists if it is in scope.)  If
+                    the pseudo goes in a hard reg, some other value
+                    may occupy that hard reg where this pseudo is
+                    dead, thus clobbering the pseudo.  Conclusion:
+                    such a pseudo must not go in a hard reg.  */
+                 if (set_jump && regno >= FIRST_PSEUDO_REGISTER)
+                   bitmap_set_bit (setjumps_crossed, regno);
+               }
+           }
+         
+         /* We only care about real sets for calls.  Clobbers only
+            may clobber and cannot be depended on.  */
+         for (mws = DF_INSN_UID_MWS (df, uid); mws; mws = mws->next)
+           {
+             if ((mws->type == DF_REF_REG_DEF) 
+                 && !df_ignore_stack_reg (REGNO (mws->mw_reg)))
+               df_set_unused_notes_for_mw (insn, mws, live, do_not_gen, 
+                                           artificial_uses, dflow->flags);
+           }
+
+         /* All of the defs except the return value are some sort of
+            clobber.  This code is for the return.  */
+         for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
+           if (!(DF_REF_FLAGS (def) & (DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER)))
+             df_create_unused_note (bb, insn, def, live, do_not_gen, 
+                                    artificial_uses, local_live, 
+                                    local_processed, dflow->flags, luid);
 
 
-         /* Kill this register.  */
-         bitmap_clear_bit (live, dregno);
        }
        }
+      else
+       {
+         /* Regular insn.  */
+         for (mws = DF_INSN_UID_MWS (df, uid); mws; mws = mws->next)
+           {
+             if (mws->type == DF_REF_REG_DEF)
+               df_set_unused_notes_for_mw (insn, mws, live, do_not_gen, 
+                                           artificial_uses, dflow->flags);
+           }
 
 
-      for (use = DF_INSN_UID_GET (df, uid)->uses; use; use = use->next_ref)
+         for (def = DF_INSN_UID_DEFS (df, uid); def; def = def->next_ref)
+           df_create_unused_note (bb, insn, def, live, do_not_gen, 
+                                  artificial_uses, local_live, 
+                                  local_processed, dflow->flags, luid);
+       }
+      
+      /* Process the uses.  */
+      for (mws = DF_INSN_UID_MWS (df, uid); mws; mws = mws->next)
+       {
+         if ((mws->type != DF_REF_REG_DEF)  
+             && !df_ignore_stack_reg (REGNO (mws->mw_reg)))
+           df_set_dead_notes_for_mw (insn, mws, live, do_not_gen,
+                                     artificial_uses, dflow->flags);
+       }
+
+      for (use = DF_INSN_UID_USES (df, uid); use; use = use->next_ref)
        {
          unsigned int uregno = DF_REF_REGNO (use);
 
        {
          unsigned int uregno = DF_REF_REGNO (use);
 
+         if ((dflow->flags & DF_RI_LIFE) && (uregno >= FIRST_PSEUDO_REGISTER))
+           {
+             REG_FREQ (uregno) += REG_FREQ_FROM_BB (bb);
+             if (REG_BASIC_BLOCK (uregno) == REG_BLOCK_UNKNOWN)
+               REG_BASIC_BLOCK (uregno) = bb->index;
+             else if (REG_BASIC_BLOCK (uregno) != bb->index)
+               REG_BASIC_BLOCK (uregno) = REG_BLOCK_GLOBAL;
+           }
+         
+#ifdef REG_DEAD_DEBUGGING
+         fprintf (stderr, "  regular looking at use ");
+         df_ref_debug (use, stderr);
+#endif
          if (!bitmap_bit_p (live, uregno))
            {
          if (!bitmap_bit_p (live, uregno))
            {
-             use->flags |= DF_REF_DIES_AFTER_THIS_USE;
+             if ( (!(DF_REF_FLAGS (use) & DF_REF_MW_HARDREG))
+                  && (!bitmap_bit_p (do_not_gen, uregno))
+                  && (!bitmap_bit_p (artificial_uses, uregno))
+                  && (!(DF_REF_FLAGS (use) & DF_REF_READ_WRITE))
+                  && (!df_ignore_stack_reg (uregno)))
+               {
+                 rtx reg = GET_CODE (*DF_REF_LOC (use)) == SUBREG ?
+                   SUBREG_REG (*DF_REF_LOC (use)) : *DF_REF_LOC (use);
+                 rtx note = alloc_EXPR_LIST (REG_DEAD, reg, REG_NOTES (insn));
+                 REG_NOTES (insn) = note;
+                 if (dflow->flags & DF_RI_LIFE)
+                   REG_N_DEATHS (uregno)++;
+
+#ifdef REG_DEAD_DEBUGGING
+                 print_note ("adding 4: ", insn, note);
+#endif
+               }
              /* This register is now live.  */
              bitmap_set_bit (live, uregno);
              /* This register is now live.  */
              bitmap_set_bit (live, uregno);
+
+             if (dflow->flags & DF_RI_LIFE)
+               {
+                 /* If we have seen this regno, then it has already
+                    been processed correctly with the per insn
+                    increment.  If we have not seen it we set the bit
+                    so that begins to get processed locally.  Note
+                    that we don't even get here if the variable was
+                    live at the end of the block since just a ref
+                    inside the block does not effect the
+                    calculations.  */
+                 REG_LIVE_LENGTH (uregno) ++;
+                 bitmap_set_bit (local_live, uregno);
+                 bitmap_set_bit (local_processed, uregno);
+               }
            }
            }
-         else
-           use->flags &= ~DF_REF_DIES_AFTER_THIS_USE;
        }
        }
-
-      /* Increment lifetimes of all live registers.  */
+    }
+  
+  if (dflow->flags & DF_RI_LIFE)
+    {
+      /* Add the length of the block to all of the registers that were
+        not referenced, but still live in this block.  */
+      bitmap_iterator bi;
+      unsigned int regno;
+      bitmap_and_compl_into (live, local_processed);
       EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
        {
       EXECUTE_IF_SET_IN_BITMAP (live, 0, regno, bi)
        {
-         problem_data->lifetime[regno]++;
+         REG_LIVE_LENGTH (regno) += luid;
        }
        }
+      bitmap_clear (local_processed);
+      bitmap_clear (local_live);
     }
 }
 
     }
 }
 
@@ -3172,16 +3706,50 @@ df_ri_compute (struct dataflow *dflow, bitmap all_blocks ATTRIBUTE_UNUSED,
 {
   unsigned int bb_index;
   bitmap_iterator bi;
 {
   unsigned int bb_index;
   bitmap_iterator bi;
-  bitmap live;
+  bitmap live = BITMAP_ALLOC (NULL);
+  bitmap do_not_gen = BITMAP_ALLOC (NULL);
+  bitmap artificial_uses = BITMAP_ALLOC (NULL);
+  bitmap local_live = NULL;
+  bitmap local_processed = NULL;
+  bitmap setjumps_crossed = NULL;
 
 
-  live = BITMAP_ALLOC (NULL);
+  if (dflow->flags & DF_RI_LIFE)
+    {
+      local_live = BITMAP_ALLOC (NULL);
+      local_processed = BITMAP_ALLOC (NULL);
+      setjumps_crossed = BITMAP_ALLOC (NULL);
+    }
+
+
+#ifdef REG_DEAD_DEBUGGING
+  df_lr_dump (dflow->df->problems_by_index [DF_LR], stderr);
+  print_rtl_with_bb (stderr, get_insns());
+#endif
 
   EXECUTE_IF_SET_IN_BITMAP (blocks_to_scan, 0, bb_index, bi)
   {
 
   EXECUTE_IF_SET_IN_BITMAP (blocks_to_scan, 0, bb_index, bi)
   {
-    df_ri_bb_compute (dflow, bb_index, live);
+    df_ri_bb_compute (dflow, bb_index, live, do_not_gen, artificial_uses,
+                     local_live, local_processed, setjumps_crossed);
   }
 
   BITMAP_FREE (live);
   }
 
   BITMAP_FREE (live);
+  BITMAP_FREE (do_not_gen);
+  BITMAP_FREE (artificial_uses);
+  if (dflow->flags & DF_RI_LIFE)
+    {
+      bitmap_iterator bi;
+      unsigned int regno;
+      /* See the setjump comment in df_ri_bb_compute.  */
+      EXECUTE_IF_SET_IN_BITMAP (setjumps_crossed, 0, regno, bi)
+       {
+         REG_BASIC_BLOCK (regno) = REG_BLOCK_UNKNOWN;
+         REG_LIVE_LENGTH (regno) = -1;
+       }         
+
+      BITMAP_FREE (local_live);
+      BITMAP_FREE (local_processed);
+      BITMAP_FREE (setjumps_crossed);
+    }
 }
 
 
 }
 
 
@@ -3190,10 +3758,6 @@ df_ri_compute (struct dataflow *dflow, bitmap all_blocks ATTRIBUTE_UNUSED,
 static void
 df_ri_free (struct dataflow *dflow)
 {
 static void
 df_ri_free (struct dataflow *dflow)
 {
-  struct df_ri_problem_data *problem_data =
-    (struct df_ri_problem_data *) dflow->problem_data;
-
-  free (problem_data->lifetime);
   free (dflow->problem_data);
   free (dflow);
 }
   free (dflow->problem_data);
   free (dflow);
 }
@@ -3204,14 +3768,12 @@ df_ri_free (struct dataflow *dflow)
 static void
 df_ri_dump (struct dataflow *dflow, FILE *file)
 {
 static void
 df_ri_dump (struct dataflow *dflow, FILE *file)
 {
-  struct df_ri_problem_data *problem_data =
-    (struct df_ri_problem_data *) dflow->problem_data;
-  int j;
+  print_rtl_with_bb (file, get_insns ());
 
 
-  fprintf (file, "Register info:\n");
-  for (j = 0; j < max_reg_num (); j++)
+  if (dflow->flags & DF_RI_LIFE)
     {
     {
-      fprintf (file, "reg %d life %d\n", j, problem_data->lifetime[j]);
+      fprintf (file, "Register info:\n");
+      dump_flow_info (file, -1);
     }
 }
 
     }
 }
 
@@ -3233,7 +3795,12 @@ static struct df_problem problem_RI =
   NULL,                       /* Finalize function.  */
   df_ri_free,                 /* Free all of the problem information.  */
   df_ri_dump,                 /* Debugging.  */
   NULL,                       /* Finalize function.  */
   df_ri_free,                 /* Free all of the problem information.  */
   df_ri_dump,                 /* Debugging.  */
-  &problem_UR                 /* Dependent problem.  */
+
+  /* Technically this is only dependent on the live registers problem
+     but it will produce information if built one of uninitialized
+     register problems (UR, UREC) is also run.  */
+  df_lr_add_problem,          /* Dependent problem.  */
+  0                           /* Changeable flags.  */
 };
 
 
 };
 
 
@@ -3242,20 +3809,7 @@ static struct df_problem problem_RI =
    solution.  */
 
 struct dataflow * 
    solution.  */
 
 struct dataflow * 
-df_ri_add_problem (struct df *df)
+df_ri_add_problem (struct df *df, int flags)
 {
 {
-  return df_add_problem (df, &problem_RI);
+  return df_add_problem (df, &problem_RI, flags);
 }
 }
-
-
-/* Return total lifetime (in insns) of REG.  */
-int
-df_reg_lifetime (struct df *df, rtx reg)
-{
-  struct dataflow *dflow = df->problems_by_index[DF_RI];
-  struct df_ri_problem_data *problem_data =
-    (struct df_ri_problem_data *) dflow->problem_data;
-  return problem_data->lifetime[REGNO (reg)];
-}
-
-