OSDN Git Service

For Marcus - Implement sync primitives inline for ARM.
[pf3gnuchains/gcc-fork.git] / gcc / df-problems.c
index 1a28e9d..e18ffe3 100644 (file)
@@ -100,22 +100,6 @@ df_get_live_in (basic_block bb)
 /* Generic versions to get the void* version of the block info.  Only
    used inside the problem instance vectors.  */
 
-/* Grow the bb_info array.  */
-
-void
-df_grow_bb_info (struct dataflow *dflow)
-{
-  unsigned int new_size = last_basic_block + 1;
-  if (dflow->block_info_size < new_size)
-    {
-      new_size += new_size / 4;
-      dflow->block_info = XRESIZEVEC (void *, dflow->block_info, new_size);
-      memset (dflow->block_info + dflow->block_info_size, 0,
-             (new_size - dflow->block_info_size) *sizeof (void *));
-      dflow->block_info_size = new_size;
-    }
-}
-
 /* Dump a def-use or use-def chain for REF to FILE.  */
 
 void
@@ -202,17 +186,6 @@ struct df_rd_problem_data
   bitmap_obstack rd_bitmaps;
 };
 
-/* Set basic block info.  */
-
-static void
-df_rd_set_bb_info (unsigned int index,
-                  struct df_rd_bb_info *bb_info)
-{
-  gcc_assert (df_rd);
-  gcc_assert (index < df_rd->block_info_size);
-  df_rd->block_info[index] = bb_info;
-}
-
 
 /* Free basic block info.  */
 
@@ -228,7 +201,6 @@ df_rd_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
       bitmap_clear (&bb_info->gen);
       bitmap_clear (&bb_info->in);
       bitmap_clear (&bb_info->out);
-      pool_free (df_rd->block_pool, bb_info);
     }
 }
 
@@ -243,10 +215,6 @@ df_rd_alloc (bitmap all_blocks)
   bitmap_iterator bi;
   struct df_rd_problem_data *problem_data;
 
-  if (!df_rd->block_pool)
-    df_rd->block_pool = create_alloc_pool ("df_rd_block pool",
-                                          sizeof (struct df_rd_bb_info), 50);
-
   if (df_rd->problem_data)
     {
       problem_data = (struct df_rd_problem_data *) df_rd->problem_data;
@@ -274,7 +242,9 @@ df_rd_alloc (bitmap all_blocks)
   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
       struct df_rd_bb_info *bb_info = df_rd_get_bb_info (bb_index);
-      if (bb_info)
+      
+      /* When bitmaps are already initialized, just clear them.  */
+      if (bb_info->kill.obstack)
        {
          bitmap_clear (&bb_info->kill);
          bitmap_clear (&bb_info->sparse_kill);
@@ -282,8 +252,6 @@ df_rd_alloc (bitmap all_blocks)
        }
       else
        {
-         bb_info = (struct df_rd_bb_info *) pool_alloc (df_rd->block_pool);
-         df_rd_set_bb_info (bb_index, bb_info);
          bitmap_initialize (&bb_info->kill, &problem_data->rd_bitmaps);
          bitmap_initialize (&bb_info->sparse_kill, &problem_data->rd_bitmaps);
          bitmap_initialize (&bb_info->gen, &problem_data->rd_bitmaps);
@@ -511,14 +479,15 @@ df_rd_init_solution (bitmap all_blocks)
 
 /* In of target gets or of out of source.  */
 
-static void
+static bool
 df_rd_confluence_n (edge e)
 {
   bitmap op1 = &df_rd_get_bb_info (e->dest->index)->in;
   bitmap op2 = &df_rd_get_bb_info (e->src->index)->out;
+  bool changed = false;
 
   if (e->flags & EDGE_FAKE)
-    return;
+    return false;
 
   if (e->flags & EDGE_EH)
     {
@@ -540,11 +509,12 @@ df_rd_confluence_n (edge e)
                              DF_DEFS_BEGIN (regno),
                              DF_DEFS_COUNT (regno));
        }
-      bitmap_ior_into (op1, &tmp);
+      changed |= bitmap_ior_into (op1, &tmp);
       bitmap_clear (&tmp);
+      return changed;
     }
   else
-    bitmap_ior_into (op1, op2);
+    return bitmap_ior_into (op1, op2);
 }
 
 
@@ -607,11 +577,11 @@ df_rd_free (void)
 
   if (problem_data)
     {
-      free_alloc_pool (df_rd->block_pool);
       bitmap_obstack_release (&problem_data->rd_bitmaps);
 
       df_rd->block_info_size = 0;
       free (df_rd->block_info);
+      df_rd->block_info = NULL;
       free (df_rd->problem_data);
     }
   free (df_rd);
@@ -703,6 +673,7 @@ static struct df_problem problem_RD =
   NULL,                       /* Incremental solution verify start.  */
   NULL,                       /* Incremental solution verify end.  */
   NULL,                       /* Dependent problem.  */
+  sizeof (struct df_rd_bb_info),/* Size of entry of block_info array.  */
   TV_DF_RD,                   /* Timing variable.  */
   true                        /* Reset blocks on dropping out of blocks_to_analyze.  */
 };
@@ -738,19 +709,6 @@ struct df_lr_problem_data
   bitmap_obstack lr_bitmaps;
 };
 
-
-/* Set basic block info.  */
-
-static void
-df_lr_set_bb_info (unsigned int index,
-                  struct df_lr_bb_info *bb_info)
-{
-  gcc_assert (df_lr);
-  gcc_assert (index < df_lr->block_info_size);
-  df_lr->block_info[index] = bb_info;
-}
-
-
 /* Free basic block info.  */
 
 static void
@@ -764,7 +722,6 @@ df_lr_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
       bitmap_clear (&bb_info->def);
       bitmap_clear (&bb_info->in);
       bitmap_clear (&bb_info->out);
-      pool_free (df_lr->block_pool, bb_info);
     }
 }
 
@@ -779,10 +736,6 @@ df_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
   bitmap_iterator bi;
   struct df_lr_problem_data *problem_data;
 
-  if (!df_lr->block_pool)
-    df_lr->block_pool = create_alloc_pool ("df_lr_block pool",
-                                          sizeof (struct df_lr_bb_info), 50);
-
   df_grow_bb_info (df_lr);
   if (df_lr->problem_data)
     problem_data = (struct df_lr_problem_data *) df_lr->problem_data;
@@ -799,15 +752,15 @@ df_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
   EXECUTE_IF_SET_IN_BITMAP (df_lr->out_of_date_transfer_functions, 0, bb_index, bi)
     {
       struct df_lr_bb_info *bb_info = df_lr_get_bb_info (bb_index);
-      if (bb_info)
+      
+      /* When bitmaps are already initialized, just clear them.  */
+      if (bb_info->use.obstack)
        {
          bitmap_clear (&bb_info->def);
          bitmap_clear (&bb_info->use);
        }
       else
        {
-         bb_info = (struct df_lr_bb_info *) pool_alloc (df_lr->block_pool);
-         df_lr_set_bb_info (bb_index, bb_info);
          bitmap_initialize (&bb_info->use, &problem_data->lr_bitmaps);
          bitmap_initialize (&bb_info->def, &problem_data->lr_bitmaps);
          bitmap_initialize (&bb_info->in, &problem_data->lr_bitmaps);
@@ -1015,21 +968,23 @@ df_lr_confluence_0 (basic_block bb)
 
 /* Confluence function that ignores fake edges.  */
 
-static void
+static bool
 df_lr_confluence_n (edge e)
 {
   bitmap op1 = &df_lr_get_bb_info (e->src->index)->out;
   bitmap op2 = &df_lr_get_bb_info (e->dest->index)->in;
+  bool changed = false;
 
   /* Call-clobbered registers die across exception and call edges.  */
   /* ??? Abnormal call edges ignored for the moment, as this gets
      confused by sibling call edges, which crashes reg-stack.  */
   if (e->flags & EDGE_EH)
-    bitmap_ior_and_compl_into (op1, op2, regs_invalidated_by_call_regset);
+    changed = bitmap_ior_and_compl_into (op1, op2, regs_invalidated_by_call_regset);
   else
-    bitmap_ior_into (op1, op2);
+    changed = bitmap_ior_into (op1, op2);
 
-  bitmap_ior_into (op1, &df->hardware_regs_used);
+  changed |= bitmap_ior_into (op1, &df->hardware_regs_used);
+  return changed;
 }
 
 
@@ -1091,10 +1046,10 @@ df_lr_free (void)
     = (struct df_lr_problem_data *) df_lr->problem_data;
   if (df_lr->block_info)
     {
-      free_alloc_pool (df_lr->block_pool);
 
       df_lr->block_info_size = 0;
       free (df_lr->block_info);
+      df_lr->block_info = NULL;
       bitmap_obstack_release (&problem_data->lr_bitmaps);
       free (df_lr->problem_data);
       df_lr->problem_data = NULL;
@@ -1253,6 +1208,7 @@ static struct df_problem problem_LR =
   df_lr_verify_solution_start,/* Incremental solution verify start.  */
   df_lr_verify_solution_end,  /* Incremental solution verify end.  */
   NULL,                       /* Dependent problem.  */
+  sizeof (struct df_lr_bb_info),/* Size of entry of block_info array.  */
   TV_DF_LR,                   /* Timing variable.  */
   false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
 };
@@ -1370,17 +1326,6 @@ struct df_live_problem_data
    combined lr and live analysis.  */
 static bitmap_head df_live_scratch;
 
-/* Set basic block info.  */
-
-static void
-df_live_set_bb_info (unsigned int index,
-                  struct df_live_bb_info *bb_info)
-{
-  gcc_assert (df_live);
-  gcc_assert (index < df_live->block_info_size);
-  df_live->block_info[index] = bb_info;
-}
-
 
 /* Free basic block info.  */
 
@@ -1395,7 +1340,6 @@ df_live_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
       bitmap_clear (&bb_info->kill);
       bitmap_clear (&bb_info->in);
       bitmap_clear (&bb_info->out);
-      pool_free (df_live->block_pool, bb_info);
     }
 }
 
@@ -1410,9 +1354,6 @@ df_live_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
   bitmap_iterator bi;
   struct df_live_problem_data *problem_data;
 
-  if (!df_live->block_pool)
-    df_live->block_pool = create_alloc_pool ("df_live_block pool",
-                                          sizeof (struct df_live_bb_info), 100);
   if (df_live->problem_data)
     problem_data = (struct df_live_problem_data *) df_live->problem_data;
   else
@@ -1431,15 +1372,15 @@ df_live_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
   EXECUTE_IF_SET_IN_BITMAP (df_live->out_of_date_transfer_functions, 0, bb_index, bi)
     {
       struct df_live_bb_info *bb_info = df_live_get_bb_info (bb_index);
-      if (bb_info)
+      
+      /* When bitmaps are already initialized, just clear them.  */
+      if (bb_info->kill.obstack)
        {
          bitmap_clear (&bb_info->kill);
          bitmap_clear (&bb_info->gen);
        }
       else
        {
-         bb_info = (struct df_live_bb_info *) pool_alloc (df_live->block_pool);
-         df_live_set_bb_info (bb_index, bb_info);
          bitmap_initialize (&bb_info->kill, &problem_data->live_bitmaps);
          bitmap_initialize (&bb_info->gen, &problem_data->live_bitmaps);
          bitmap_initialize (&bb_info->in, &problem_data->live_bitmaps);
@@ -1566,16 +1507,16 @@ df_live_init (bitmap all_blocks)
 
 /* Forward confluence function that ignores fake edges.  */
 
-static void
+static bool
 df_live_confluence_n (edge e)
 {
   bitmap op1 = &df_live_get_bb_info (e->dest->index)->in;
   bitmap op2 = &df_live_get_bb_info (e->src->index)->out;
 
   if (e->flags & EDGE_FAKE)
-    return;
+    return false;
 
-  bitmap_ior_into (op1, op2);
+  return bitmap_ior_into (op1, op2);
 }
 
 
@@ -1639,9 +1580,9 @@ df_live_free (void)
     = (struct df_live_problem_data *) df_live->problem_data;
   if (df_live->block_info)
     {
-      free_alloc_pool (df_live->block_pool);
       df_live->block_info_size = 0;
       free (df_live->block_info);
+      df_live->block_info = NULL;
       bitmap_clear (&df_live_scratch);
       bitmap_obstack_release (&problem_data->live_bitmaps);
       free (problem_data);
@@ -1796,6 +1737,7 @@ static struct df_problem problem_LIVE =
   df_live_verify_solution_start,/* Incremental solution verify start.  */
   df_live_verify_solution_end,  /* Incremental solution verify end.  */
   &problem_LR,                  /* Dependent problem.  */
+  sizeof (struct df_live_bb_info),/* Size of entry of block_info array.  */
   TV_DF_LIVE,                   /* Timing variable.  */
   false                         /* Reset blocks on dropping out of blocks_to_analyze.  */
 };
@@ -2322,6 +2264,7 @@ static struct df_problem problem_CHAIN =
   NULL,                       /* Incremental solution verify start.  */
   NULL,                       /* Incremental solution verify end.  */
   &problem_RD,                /* Dependent problem.  */
+  sizeof (struct df_scan_bb_info),/* Size of entry of block_info array.  */
   TV_DF_CHAIN,                /* Timing variable.  */
   false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
 };
@@ -2343,170 +2286,56 @@ df_chain_add_problem (unsigned int chain_flags)
 
 \f
 /*----------------------------------------------------------------------------
-   BYTE LEVEL LIVE REGISTERS
+   WORD LEVEL LIVE REGISTERS
 
    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.  There are two mapping functions,
-   df_byte_lr_get_regno_start and df_byte_lr_get_regno_len that are
-   used to map regnos into bit vector positions.
-
-   This problem differs from the regular df_lr function in the way
-   that subregs, *_extracts and strict_low_parts are handled. In lr
-   these are consider partial kills, here, the exact set of bytes is
-   modeled.  Note that any reg that has none of these operations is
-   only modeled with a single bit since all operations access the
-   entire register.
-
-   This problem is more brittle that the regular lr.  It currently can
-   be used in dce incrementally, but cannot be used in an environment
-   where insns are created or modified.  The problem is that the
-   mapping of regnos to bitmap positions is relatively compact, in
-   that if a pseudo does not do any of the byte wise operations, only
-   one slot is allocated, rather than a slot for each byte.  If insn
-   are created, where a subreg is used for a reg that had no subregs,
-   the mapping would be wrong.  Likewise, there are no checks to see
-   that new pseudos have been added.  These issues could be addressed
-   by adding a problem specific flag to not use the compact mapping,
-   if there was a need to do so.
+   for each basic block.  We only track pseudo registers that have a
+   size of 2 * UNITS_PER_WORD; bitmaps are indexed by 2 * regno and
+   contain two bits corresponding to each of the subwords.
 
    ----------------------------------------------------------------------------*/
 
 /* Private data used to verify the solution for this problem.  */
-struct df_byte_lr_problem_data
+struct df_word_lr_problem_data
 {
-  /* Expanded versions of bitvectors used in lr.  */
-  bitmap_head invalidated_by_call;
-  bitmap_head hardware_regs_used;
-
-  /* Indexed by regno, this is true if there are subregs, extracts or
-     strict_low_parts for this regno.  */
-  bitmap_head needs_expansion;
-
-  /* The start position and len for each regno in the various bit
-     vectors.  */
-  unsigned int* regno_start;
-  unsigned int* regno_len;
   /* An obstack for the bitmaps we need for this problem.  */
-  bitmap_obstack byte_lr_bitmaps;
+  bitmap_obstack word_lr_bitmaps;
 };
 
 
-/* Get the starting location for REGNO in the df_byte_lr bitmaps.  */
-
-int
-df_byte_lr_get_regno_start (unsigned int regno)
-{
-  struct df_byte_lr_problem_data *problem_data
-    = (struct df_byte_lr_problem_data *)df_byte_lr->problem_data;;
-  return problem_data->regno_start[regno];
-}
-
-
-/* Get the len for REGNO in the df_byte_lr bitmaps.  */
-
-int
-df_byte_lr_get_regno_len (unsigned int regno)
-{
-  struct df_byte_lr_problem_data *problem_data
-    = (struct df_byte_lr_problem_data *)df_byte_lr->problem_data;;
-  return problem_data->regno_len[regno];
-}
-
-
-/* Set basic block info.  */
-
-static void
-df_byte_lr_set_bb_info (unsigned int index,
-                       struct df_byte_lr_bb_info *bb_info)
-{
-  gcc_assert (df_byte_lr);
-  gcc_assert (index < df_byte_lr->block_info_size);
-  df_byte_lr->block_info[index] = bb_info;
-}
-
-
 /* Free basic block info.  */
 
 static void
-df_byte_lr_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
+df_word_lr_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
                         void *vbb_info)
 {
-  struct df_byte_lr_bb_info *bb_info = (struct df_byte_lr_bb_info *) vbb_info;
+  struct df_word_lr_bb_info *bb_info = (struct df_word_lr_bb_info *) vbb_info;
   if (bb_info)
     {
       bitmap_clear (&bb_info->use);
       bitmap_clear (&bb_info->def);
       bitmap_clear (&bb_info->in);
       bitmap_clear (&bb_info->out);
-      pool_free (df_byte_lr->block_pool, bb_info);
-    }
-}
-
-
-/* Check all of the refs in REF_REC to see if any of them are
-   extracts, subregs or strict_low_parts.  */
-
-static void
-df_byte_lr_check_regs (df_ref *ref_rec)
-{
-  struct df_byte_lr_problem_data *problem_data
-    = (struct df_byte_lr_problem_data *)df_byte_lr->problem_data;
-
-  for (; *ref_rec; ref_rec++)
-    {
-      df_ref ref = *ref_rec;
-      if (DF_REF_FLAGS_IS_SET (ref, DF_REF_SIGN_EXTRACT
-                              | DF_REF_ZERO_EXTRACT
-                              | DF_REF_STRICT_LOW_PART)
-         || GET_CODE (DF_REF_REG (ref)) == SUBREG)
-       bitmap_set_bit (&problem_data->needs_expansion, DF_REF_REGNO (ref));
-    }
-}
-
-
-/* Expand bitmap SRC which is indexed by regno to DEST which is indexed by
-   regno_start and regno_len.  */
-
-static void
-df_byte_lr_expand_bitmap (bitmap dest, bitmap src)
-{
-  struct df_byte_lr_problem_data *problem_data
-    = (struct df_byte_lr_problem_data *)df_byte_lr->problem_data;
-  bitmap_iterator bi;
-  unsigned int i;
-
-  bitmap_clear (dest);
-  EXECUTE_IF_SET_IN_BITMAP (src, 0, i, bi)
-    {
-      bitmap_set_range (dest, problem_data->regno_start[i],
-                       problem_data->regno_len[i]);
     }
 }
 
 
-/* Allocate or reset bitmaps for DF_BYTE_LR blocks. The solution bits are
+/* Allocate or reset bitmaps for DF_WORD_LR blocks. The solution bits are
    not touched unless the block is new.  */
 
 static void
-df_byte_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
+df_word_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
 {
   unsigned int bb_index;
   bitmap_iterator bi;
   basic_block bb;
-  unsigned int regno;
-  unsigned int index = 0;
-  unsigned int max_reg = max_reg_num();
-  struct df_byte_lr_problem_data *problem_data
-    = XNEW (struct df_byte_lr_problem_data);
+  struct df_word_lr_problem_data *problem_data
+    = XNEW (struct df_word_lr_problem_data);
 
-  df_byte_lr->problem_data = problem_data;
+  df_word_lr->problem_data = problem_data;
 
-  if (!df_byte_lr->block_pool)
-    df_byte_lr->block_pool = create_alloc_pool ("df_byte_lr_block pool",
-                                          sizeof (struct df_byte_lr_bb_info), 50);
-
-  df_grow_bb_info (df_byte_lr);
+  df_grow_bb_info (df_word_lr);
 
   /* Create the mapping from regnos to slots. This does not change
      unless the problem is destroyed and recreated.  In particular, if
@@ -2514,144 +2343,137 @@ df_byte_lr_alloc (bitmap all_blocks ATTRIBUTE_UNUSED)
      want to redo the mapping because this would invalidate everything
      else.  */
 
-  bitmap_obstack_initialize (&problem_data->byte_lr_bitmaps);
-  problem_data->regno_start = XNEWVEC (unsigned int, max_reg);
-  problem_data->regno_len = XNEWVEC (unsigned int, max_reg);
-  bitmap_initialize (&problem_data->hardware_regs_used,
-                    &problem_data->byte_lr_bitmaps);
-  bitmap_initialize (&problem_data->invalidated_by_call,
-                    &problem_data->byte_lr_bitmaps);
-  bitmap_initialize (&problem_data->needs_expansion,
-                    &problem_data->byte_lr_bitmaps);
-
-  /* Discover which regno's use subregs, extracts or
-     strict_low_parts.  */
-  FOR_EACH_BB (bb)
-    {
-      rtx insn;
-      FOR_BB_INSNS (bb, insn)
-       {
-         if (INSN_P (insn))
-           {
-             struct df_insn_info *insn_info = DF_INSN_INFO_GET (insn);
-             df_byte_lr_check_regs (DF_INSN_INFO_DEFS (insn_info));
-             df_byte_lr_check_regs (DF_INSN_INFO_USES (insn_info));
-           }
-       }
-      bitmap_set_bit (df_byte_lr->out_of_date_transfer_functions, bb->index);
-    }
+  bitmap_obstack_initialize (&problem_data->word_lr_bitmaps);
 
-  bitmap_set_bit (df_byte_lr->out_of_date_transfer_functions, ENTRY_BLOCK);
-  bitmap_set_bit (df_byte_lr->out_of_date_transfer_functions, EXIT_BLOCK);
-
-  /* Allocate the slots for each regno.  */
-  for (regno = 0; regno < max_reg; regno++)
-    {
-      int len;
-      problem_data->regno_start[regno] = index;
-      if (bitmap_bit_p (&problem_data->needs_expansion, regno))
-       len = GET_MODE_SIZE (GET_MODE (regno_reg_rtx[regno]));
-      else
-       len = 1;
-
-      problem_data->regno_len[regno] = len;
-      index += len;
-    }
+  FOR_EACH_BB (bb)
+    bitmap_set_bit (df_word_lr->out_of_date_transfer_functions, bb->index);
 
-  df_byte_lr_expand_bitmap (&problem_data->hardware_regs_used,
-                           &df->hardware_regs_used);
-  df_byte_lr_expand_bitmap (&problem_data->invalidated_by_call,
-                           regs_invalidated_by_call_regset);
+  bitmap_set_bit (df_word_lr->out_of_date_transfer_functions, ENTRY_BLOCK);
+  bitmap_set_bit (df_word_lr->out_of_date_transfer_functions, EXIT_BLOCK);
 
-  EXECUTE_IF_SET_IN_BITMAP (df_byte_lr->out_of_date_transfer_functions, 0, bb_index, bi)
+  EXECUTE_IF_SET_IN_BITMAP (df_word_lr->out_of_date_transfer_functions, 0, bb_index, bi)
     {
-      struct df_byte_lr_bb_info *bb_info = df_byte_lr_get_bb_info (bb_index);
-      if (bb_info)
+      struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
+      
+      /* When bitmaps are already initialized, just clear them.  */
+      if (bb_info->use.obstack)
        {
          bitmap_clear (&bb_info->def);
          bitmap_clear (&bb_info->use);
        }
       else
        {
-         bb_info = (struct df_byte_lr_bb_info *) pool_alloc (df_byte_lr->block_pool);
-         df_byte_lr_set_bb_info (bb_index, bb_info);
-         bitmap_initialize (&bb_info->use, &problem_data->byte_lr_bitmaps);
-         bitmap_initialize (&bb_info->def, &problem_data->byte_lr_bitmaps);
-         bitmap_initialize (&bb_info->in, &problem_data->byte_lr_bitmaps);
-         bitmap_initialize (&bb_info->out, &problem_data->byte_lr_bitmaps);
+         bitmap_initialize (&bb_info->use, &problem_data->word_lr_bitmaps);
+         bitmap_initialize (&bb_info->def, &problem_data->word_lr_bitmaps);
+         bitmap_initialize (&bb_info->in, &problem_data->word_lr_bitmaps);
+         bitmap_initialize (&bb_info->out, &problem_data->word_lr_bitmaps);
        }
     }
 
-  df_byte_lr->optional_p = true;
+  df_word_lr->optional_p = true;
 }
 
 
 /* Reset the global solution for recalculation.  */
 
 static void
-df_byte_lr_reset (bitmap all_blocks)
+df_word_lr_reset (bitmap all_blocks)
 {
   unsigned int bb_index;
   bitmap_iterator bi;
 
   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
-      struct df_byte_lr_bb_info *bb_info = df_byte_lr_get_bb_info (bb_index);
+      struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
       gcc_assert (bb_info);
       bitmap_clear (&bb_info->in);
       bitmap_clear (&bb_info->out);
     }
 }
 
+/* Examine REF, and if it is for a reg we're interested in, set or
+   clear the bits corresponding to its subwords from the bitmap
+   according to IS_SET.  LIVE is the bitmap we should update.  We do
+   not track hard regs or pseudos of any size other than 2 *
+   UNITS_PER_WORD.
+   We return true if we changed the bitmap, or if we encountered a register
+   we're not tracking.  */
+
+bool
+df_word_lr_mark_ref (df_ref ref, bool is_set, regset live)
+{
+  rtx orig_reg = DF_REF_REG (ref);
+  rtx reg = orig_reg;
+  enum machine_mode reg_mode;
+  unsigned regno;
+  /* Left at -1 for whole accesses.  */
+  int which_subword = -1;
+  bool changed = false;
+
+  if (GET_CODE (reg) == SUBREG)
+    reg = SUBREG_REG (orig_reg);
+  regno = REGNO (reg);
+  reg_mode = GET_MODE (reg);
+  if (regno < FIRST_PSEUDO_REGISTER
+      || GET_MODE_SIZE (reg_mode) != 2 * UNITS_PER_WORD)
+    return true;
+
+  if (GET_CODE (orig_reg) == SUBREG
+      && df_read_modify_subreg_p (orig_reg))
+    {
+      gcc_assert (DF_REF_FLAGS_IS_SET (ref, DF_REF_PARTIAL));
+      if (subreg_lowpart_p (orig_reg))
+       which_subword = 0;
+      else
+       which_subword = 1;
+    }
+  if (is_set)
+    {
+      if (which_subword != 1)
+       changed |= bitmap_set_bit (live, regno * 2);
+      if (which_subword != 0)
+       changed |= bitmap_set_bit (live, regno * 2 + 1);
+    }
+  else
+    {
+      if (which_subword != 1)
+       changed |= bitmap_clear_bit (live, regno * 2);
+      if (which_subword != 0)
+       changed |= bitmap_clear_bit (live, regno * 2 + 1);
+    }
+  return changed;
+}
 
 /* Compute local live register info for basic block BB.  */
 
 static void
-df_byte_lr_bb_local_compute (unsigned int bb_index)
+df_word_lr_bb_local_compute (unsigned int bb_index)
 {
-  struct df_byte_lr_problem_data *problem_data
-    = (struct df_byte_lr_problem_data *)df_byte_lr->problem_data;
   basic_block bb = BASIC_BLOCK (bb_index);
-  struct df_byte_lr_bb_info *bb_info = df_byte_lr_get_bb_info (bb_index);
+  struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
   rtx insn;
   df_ref *def_rec;
   df_ref *use_rec;
 
-  /* Process the registers set in an exception handler.  */
+  /* Ensure that artificial refs don't contain references to pseudos.  */
   for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
     {
       df_ref def = *def_rec;
-      if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
-       {
-         unsigned int dregno = DF_REF_REGNO (def);
-         unsigned int start = problem_data->regno_start[dregno];
-         unsigned int len = problem_data->regno_len[dregno];
-         bitmap_set_range (&bb_info->def, start, len);
-         bitmap_clear_range (&bb_info->use, start, len);
-       }
+      gcc_assert (DF_REF_REGNO (def) < FIRST_PSEUDO_REGISTER);
     }
 
-  /* Process the hardware registers that are always live.  */
   for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
     {
       df_ref use = *use_rec;
-      /* Add use to set of uses in this BB.  */
-      if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
-       {
-         unsigned int uregno = DF_REF_REGNO (use);
-         unsigned int start = problem_data->regno_start[uregno];
-         unsigned int len = problem_data->regno_len[uregno];
-         bitmap_set_range (&bb_info->use, start, len);
-       }
+      gcc_assert (DF_REF_REGNO (use) < FIRST_PSEUDO_REGISTER);
     }
 
   FOR_BB_INSNS_REVERSE (bb, insn)
     {
       unsigned int uid = INSN_UID (insn);
 
-      if (!INSN_P (insn))
+      if (!NONDEBUG_INSN_P (insn))
        continue;
-
       for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
        {
          df_ref def = *def_rec;
@@ -2659,161 +2481,80 @@ df_byte_lr_bb_local_compute (unsigned int bb_index)
             not kill the other defs that reach here.  */
          if (!(DF_REF_FLAGS (def) & (DF_REF_CONDITIONAL)))
            {
-             unsigned int dregno = DF_REF_REGNO (def);
-             unsigned int start = problem_data->regno_start[dregno];
-             unsigned int len = problem_data->regno_len[dregno];
-             unsigned int sb;
-             unsigned int lb;
-             if (!df_compute_accessed_bytes (def, DF_MM_MUST, &sb, &lb))
-               {
-                 start += sb;
-                 len = lb - sb;
-               }
-             if (len)
-               {
-                 bitmap_set_range (&bb_info->def, start, len);
-                 bitmap_clear_range (&bb_info->use, start, len);
-               }
+             df_word_lr_mark_ref (def, true, &bb_info->def);
+             df_word_lr_mark_ref (def, false, &bb_info->use);
            }
        }
-
       for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
        {
          df_ref use = *use_rec;
-         unsigned int uregno = DF_REF_REGNO (use);
-         unsigned int start = problem_data->regno_start[uregno];
-         unsigned int len = problem_data->regno_len[uregno];
-         unsigned int sb;
-         unsigned int lb;
-         if (!df_compute_accessed_bytes (use, DF_MM_MAY, &sb, &lb))
-           {
-             start += sb;
-             len = lb - sb;
-           }
-         /* Add use to set of uses in this BB.  */
-         if (len)
-           bitmap_set_range (&bb_info->use, start, len);
-       }
-    }
-
-  /* Process the registers set in an exception handler or the hard
-     frame pointer if this block is the target of a non local
-     goto.  */
-  for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
-    {
-      df_ref def = *def_rec;
-      if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
-       {
-         unsigned int dregno = DF_REF_REGNO (def);
-         unsigned int start = problem_data->regno_start[dregno];
-         unsigned int len = problem_data->regno_len[dregno];
-         bitmap_set_range (&bb_info->def, start, len);
-         bitmap_clear_range (&bb_info->use, start, len);
+         df_word_lr_mark_ref (use, true, &bb_info->use);
        }
     }
-
-#ifdef EH_USES
-  /* Process the uses that are live into an exception handler.  */
-  for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
-    {
-      df_ref use = *use_rec;
-      /* Add use to set of uses in this BB.  */
-      if (DF_REF_FLAGS (use) & DF_REF_AT_TOP)
-       {
-         unsigned int uregno = DF_REF_REGNO (use);
-         unsigned int start = problem_data->regno_start[uregno];
-         unsigned int len = problem_data->regno_len[uregno];
-         bitmap_set_range (&bb_info->use, start, len);
-       }
-    }
-#endif
 }
 
 
 /* Compute local live register info for each basic block within BLOCKS.  */
 
 static void
-df_byte_lr_local_compute (bitmap all_blocks ATTRIBUTE_UNUSED)
+df_word_lr_local_compute (bitmap all_blocks ATTRIBUTE_UNUSED)
 {
   unsigned int bb_index;
   bitmap_iterator bi;
 
-  EXECUTE_IF_SET_IN_BITMAP (df_byte_lr->out_of_date_transfer_functions, 0, bb_index, bi)
+  EXECUTE_IF_SET_IN_BITMAP (df_word_lr->out_of_date_transfer_functions, 0, bb_index, bi)
     {
       if (bb_index == EXIT_BLOCK)
        {
-         /* The exit block is special for this problem and its bits are
-            computed from thin air.  */
-         struct df_byte_lr_bb_info *bb_info = df_byte_lr_get_bb_info (EXIT_BLOCK);
-         df_byte_lr_expand_bitmap (&bb_info->use, df->exit_block_uses);
+         unsigned regno;
+         bitmap_iterator bi;
+         EXECUTE_IF_SET_IN_BITMAP (df->exit_block_uses, FIRST_PSEUDO_REGISTER,
+                                   regno, bi)
+           gcc_unreachable ();
        }
       else
-       df_byte_lr_bb_local_compute (bb_index);
+       df_word_lr_bb_local_compute (bb_index);
     }
 
-  bitmap_clear (df_byte_lr->out_of_date_transfer_functions);
+  bitmap_clear (df_word_lr->out_of_date_transfer_functions);
 }
 
 
 /* Initialize the solution vectors.  */
 
 static void
-df_byte_lr_init (bitmap all_blocks)
+df_word_lr_init (bitmap all_blocks)
 {
   unsigned int bb_index;
   bitmap_iterator bi;
 
   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
-      struct df_byte_lr_bb_info *bb_info = df_byte_lr_get_bb_info (bb_index);
+      struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
       bitmap_copy (&bb_info->in, &bb_info->use);
       bitmap_clear (&bb_info->out);
     }
 }
 
 
-/* Confluence function that processes infinite loops.  This might be a
-   noreturn function that throws.  And even if it isn't, getting the
-   unwind info right helps debugging.  */
-static void
-df_byte_lr_confluence_0 (basic_block bb)
-{
-  struct df_byte_lr_problem_data *problem_data
-    = (struct df_byte_lr_problem_data *)df_byte_lr->problem_data;
-  bitmap op1 = &df_byte_lr_get_bb_info (bb->index)->out;
-  if (bb != EXIT_BLOCK_PTR)
-    bitmap_copy (op1, &problem_data->hardware_regs_used);
-}
-
-
 /* Confluence function that ignores fake edges.  */
 
-static void
-df_byte_lr_confluence_n (edge e)
+static bool
+df_word_lr_confluence_n (edge e)
 {
-  struct df_byte_lr_problem_data *problem_data
-    = (struct df_byte_lr_problem_data *)df_byte_lr->problem_data;
-  bitmap op1 = &df_byte_lr_get_bb_info (e->src->index)->out;
-  bitmap op2 = &df_byte_lr_get_bb_info (e->dest->index)->in;
-
-  /* Call-clobbered registers die across exception and call edges.  */
-  /* ??? Abnormal call edges ignored for the moment, as this gets
-     confused by sibling call edges, which crashes reg-stack.  */
-  if (e->flags & EDGE_EH)
-    bitmap_ior_and_compl_into (op1, op2, &problem_data->invalidated_by_call);
-  else
-    bitmap_ior_into (op1, op2);
+  bitmap op1 = &df_word_lr_get_bb_info (e->src->index)->out;
+  bitmap op2 = &df_word_lr_get_bb_info (e->dest->index)->in;
 
-  bitmap_ior_into (op1, &problem_data->hardware_regs_used);
+  return bitmap_ior_into (op1, op2);
 }
 
 
 /* Transfer function.  */
 
 static bool
-df_byte_lr_transfer_function (int bb_index)
+df_word_lr_transfer_function (int bb_index)
 {
-  struct df_byte_lr_bb_info *bb_info = df_byte_lr_get_bb_info (bb_index);
+  struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb_index);
   bitmap in = &bb_info->in;
   bitmap out = &bb_info->out;
   bitmap use = &bb_info->use;
@@ -2826,85 +2567,83 @@ df_byte_lr_transfer_function (int bb_index)
 /* Free all storage associated with the problem.  */
 
 static void
-df_byte_lr_free (void)
+df_word_lr_free (void)
 {
-  struct df_byte_lr_problem_data *problem_data
-    = (struct df_byte_lr_problem_data *)df_byte_lr->problem_data;
+  struct df_word_lr_problem_data *problem_data
+    = (struct df_word_lr_problem_data *)df_word_lr->problem_data;
 
-
-  if (df_byte_lr->block_info)
+  if (df_word_lr->block_info)
     {
-      free_alloc_pool (df_byte_lr->block_pool);
-      df_byte_lr->block_info_size = 0;
-      free (df_byte_lr->block_info);
+      df_word_lr->block_info_size = 0;
+      free (df_word_lr->block_info);
+      df_word_lr->block_info = NULL;
     }
 
-  BITMAP_FREE (df_byte_lr->out_of_date_transfer_functions);
-  bitmap_obstack_release (&problem_data->byte_lr_bitmaps);
-  free (problem_data->regno_start);
-  free (problem_data->regno_len);
+  BITMAP_FREE (df_word_lr->out_of_date_transfer_functions);
+  bitmap_obstack_release (&problem_data->word_lr_bitmaps);
   free (problem_data);
-  free (df_byte_lr);
+  free (df_word_lr);
 }
 
 
 /* Debugging info at top of bb.  */
 
 static void
-df_byte_lr_top_dump (basic_block bb, FILE *file)
+df_word_lr_top_dump (basic_block bb, FILE *file)
 {
-  struct df_byte_lr_bb_info *bb_info = df_byte_lr_get_bb_info (bb->index);
+  struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb->index);
   if (!bb_info)
     return;
 
   fprintf (file, ";; blr  in  \t");
-  df_print_byte_regset (file, &bb_info->in);
+  df_print_word_regset (file, &bb_info->in);
   fprintf (file, ";; blr  use \t");
-  df_print_byte_regset (file, &bb_info->use);
+  df_print_word_regset (file, &bb_info->use);
   fprintf (file, ";; blr  def \t");
-  df_print_byte_regset (file, &bb_info->def);
+  df_print_word_regset (file, &bb_info->def);
 }
 
 
 /* Debugging info at bottom of bb.  */
 
 static void
-df_byte_lr_bottom_dump (basic_block bb, FILE *file)
+df_word_lr_bottom_dump (basic_block bb, FILE *file)
 {
-  struct df_byte_lr_bb_info *bb_info = df_byte_lr_get_bb_info (bb->index);
+  struct df_word_lr_bb_info *bb_info = df_word_lr_get_bb_info (bb->index);
   if (!bb_info)
     return;
 
   fprintf (file, ";; blr  out \t");
-  df_print_byte_regset (file, &bb_info->out);
+  df_print_word_regset (file, &bb_info->out);
 }
 
 
 /* All of the information associated with every instance of the problem.  */
 
-static struct df_problem problem_BYTE_LR =
+static struct df_problem problem_WORD_LR =
 {
-  DF_BYTE_LR,                      /* Problem id.  */
+  DF_WORD_LR,                      /* Problem id.  */
   DF_BACKWARD,                     /* Direction.  */
-  df_byte_lr_alloc,                /* Allocate the problem specific data.  */
-  df_byte_lr_reset,                /* Reset global information.  */
-  df_byte_lr_free_bb_info,         /* Free basic block info.  */
-  df_byte_lr_local_compute,        /* Local compute function.  */
-  df_byte_lr_init,                 /* Init the solution specific data.  */
+  df_word_lr_alloc,                /* Allocate the problem specific data.  */
+  df_word_lr_reset,                /* Reset global information.  */
+  df_word_lr_free_bb_info,         /* Free basic block info.  */
+  df_word_lr_local_compute,        /* Local compute function.  */
+  df_word_lr_init,                 /* Init the solution specific data.  */
   df_worklist_dataflow,            /* Worklist solver.  */
-  df_byte_lr_confluence_0,         /* Confluence operator 0.  */
-  df_byte_lr_confluence_n,         /* Confluence operator n.  */
-  df_byte_lr_transfer_function,    /* Transfer function.  */
+  NULL,                            /* Confluence operator 0.  */
+  df_word_lr_confluence_n,         /* Confluence operator n.  */
+  df_word_lr_transfer_function,    /* Transfer function.  */
   NULL,                            /* Finalize function.  */
-  df_byte_lr_free,                 /* Free all of the problem information.  */
-  df_byte_lr_free,                 /* Remove this problem from the stack of dataflow problems.  */
+  df_word_lr_free,                 /* Free all of the problem information.  */
+  df_word_lr_free,                 /* Remove this problem from the stack of dataflow problems.  */
   NULL,                            /* Debugging.  */
-  df_byte_lr_top_dump,             /* Debugging start block.  */
-  df_byte_lr_bottom_dump,          /* Debugging end block.  */
+  df_word_lr_top_dump,             /* Debugging start block.  */
+  df_word_lr_bottom_dump,          /* Debugging end block.  */
   NULL,                            /* Incremental solution verify start.  */
   NULL,                            /* Incremental solution verify end.  */
-  NULL,                            /* Dependent problem.  */
-  TV_DF_BYTE_LR,                   /* Timing variable.  */
+  NULL,                       /* Dependent problem.  */
+  sizeof (struct df_word_lr_bb_info),/* Size of entry of block_info array.  */
+  TV_DF_WORD_LR,                   /* Timing variable.  */
   false                            /* Reset blocks on dropping out of blocks_to_analyze.  */
 };
 
@@ -2914,163 +2653,50 @@ static struct df_problem problem_BYTE_LR =
    solution.  */
 
 void
-df_byte_lr_add_problem (void)
+df_word_lr_add_problem (void)
 {
-  df_add_problem (&problem_BYTE_LR);
+  df_add_problem (&problem_WORD_LR);
   /* These will be initialized when df_scan_blocks processes each
      block.  */
-  df_byte_lr->out_of_date_transfer_functions = BITMAP_ALLOC (NULL);
+  df_word_lr->out_of_date_transfer_functions = BITMAP_ALLOC (NULL);
 }
 
 
-/* Simulate the effects of the defs of INSN on LIVE.  */
+/* Simulate the effects of the defs of INSN on LIVE.  Return true if we changed
+   any bits, which is used by the caller to determine whether a set is
+   necessary.  We also return true if there are other reasons not to delete
+   an insn.  */
 
-void
-df_byte_lr_simulate_defs (rtx insn, bitmap live)
+bool
+df_word_lr_simulate_defs (rtx insn, bitmap live)
 {
-  struct df_byte_lr_problem_data *problem_data
-    = (struct df_byte_lr_problem_data *)df_byte_lr->problem_data;
+  bool changed = false;
   df_ref *def_rec;
   unsigned int uid = INSN_UID (insn);
 
   for (def_rec = DF_INSN_UID_DEFS (uid); *def_rec; def_rec++)
     {
       df_ref def = *def_rec;
-
-      /* 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_CONDITIONAL))
-       {
-         unsigned int dregno = DF_REF_REGNO (def);
-         unsigned int start = problem_data->regno_start[dregno];
-         unsigned int len = problem_data->regno_len[dregno];
-         unsigned int sb;
-         unsigned int lb;
-         if (!df_compute_accessed_bytes (def, DF_MM_MUST, &sb, &lb))
-           {
-             start += sb;
-             len = lb - sb;
-           }
-
-         if (len)
-           bitmap_clear_range (live, start, len);
-       }
+      if (DF_REF_FLAGS (def) & DF_REF_CONDITIONAL)
+       changed = true;
+      else
+       changed |= df_word_lr_mark_ref (*def_rec, false, live);
     }
+  return changed;
 }
 
 
 /* Simulate the effects of the uses of INSN on LIVE.  */
 
 void
-df_byte_lr_simulate_uses (rtx insn, bitmap live)
+df_word_lr_simulate_uses (rtx insn, bitmap live)
 {
-  struct df_byte_lr_problem_data *problem_data
-    = (struct df_byte_lr_problem_data *)df_byte_lr->problem_data;
   df_ref *use_rec;
   unsigned int uid = INSN_UID (insn);
 
   for (use_rec = DF_INSN_UID_USES (uid); *use_rec; use_rec++)
-    {
-      df_ref use = *use_rec;
-      unsigned int uregno = DF_REF_REGNO (use);
-      unsigned int start = problem_data->regno_start[uregno];
-      unsigned int len = problem_data->regno_len[uregno];
-      unsigned int sb;
-      unsigned int lb;
-
-      if (!df_compute_accessed_bytes (use, DF_MM_MAY, &sb, &lb))
-       {
-         start += sb;
-         len = lb - sb;
-       }
-
-      /* Add use to set of uses in this BB.  */
-      if (len)
-       bitmap_set_range (live, start, len);
-    }
+    df_word_lr_mark_ref (*use_rec, true, live);
 }
-
-
-/* Apply the artificial uses and defs at the top of BB in a forwards
-   direction.  */
-
-void
-df_byte_lr_simulate_artificial_refs_at_top (basic_block bb, bitmap live)
-{
-  struct df_byte_lr_problem_data *problem_data
-    = (struct df_byte_lr_problem_data *)df_byte_lr->problem_data;
-  df_ref *def_rec;
-#ifdef EH_USES
-  df_ref *use_rec;
-#endif
-  int bb_index = bb->index;
-
-#ifdef EH_USES
-  for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
-    {
-      df_ref use = *use_rec;
-      if (DF_REF_FLAGS (use) & DF_REF_AT_TOP)
-       {
-         unsigned int uregno = DF_REF_REGNO (use);
-         unsigned int start = problem_data->regno_start[uregno];
-         unsigned int len = problem_data->regno_len[uregno];
-         bitmap_set_range (live, start, len);
-       }
-    }
-#endif
-
-  for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
-    {
-      df_ref def = *def_rec;
-      if (DF_REF_FLAGS (def) & DF_REF_AT_TOP)
-       {
-         unsigned int dregno = DF_REF_REGNO (def);
-         unsigned int start = problem_data->regno_start[dregno];
-         unsigned int len = problem_data->regno_len[dregno];
-         bitmap_clear_range (live, start, len);
-       }
-    }
-}
-
-
-/* Apply the artificial uses and defs at the end of BB in a backwards
-   direction.  */
-
-void
-df_byte_lr_simulate_artificial_refs_at_end (basic_block bb, bitmap live)
-{
-  struct df_byte_lr_problem_data *problem_data
-    = (struct df_byte_lr_problem_data *)df_byte_lr->problem_data;
-  df_ref *def_rec;
-  df_ref *use_rec;
-  int bb_index = bb->index;
-
-  for (def_rec = df_get_artificial_defs (bb_index); *def_rec; def_rec++)
-    {
-      df_ref def = *def_rec;
-      if ((DF_REF_FLAGS (def) & DF_REF_AT_TOP) == 0)
-       {
-         unsigned int dregno = DF_REF_REGNO (def);
-         unsigned int start = problem_data->regno_start[dregno];
-         unsigned int len = problem_data->regno_len[dregno];
-         bitmap_clear_range (live, start, len);
-       }
-    }
-
-  for (use_rec = df_get_artificial_uses (bb_index); *use_rec; use_rec++)
-    {
-      df_ref use = *use_rec;
-      if ((DF_REF_FLAGS (use) & DF_REF_AT_TOP) == 0)
-       {
-         unsigned int uregno = DF_REF_REGNO (use);
-         unsigned int start = problem_data->regno_start[uregno];
-         unsigned int len = problem_data->regno_len[uregno];
-         bitmap_set_range (live, start, len);
-       }
-    }
-}
-
-
 \f
 /*----------------------------------------------------------------------------
    This problem computes REG_DEAD and REG_UNUSED notes.
@@ -3120,12 +2746,10 @@ df_ignore_stack_reg (int regno ATTRIBUTE_UNUSED)
    them to OLD_DEAD_NOTES and OLD_UNUSED_NOTES.  */
 
 static void
-df_kill_notes (rtx insn, rtx *old_dead_notes, rtx *old_unused_notes)
+df_kill_notes (rtx insn)
 {
   rtx *pprev = &REG_NOTES (insn);
   rtx link = *pprev;
-  rtx dead = NULL;
-  rtx unused = NULL;
 
   while (link)
     {
@@ -3145,8 +2769,7 @@ df_kill_notes (rtx insn, rtx *old_dead_notes, rtx *old_unused_notes)
 #ifdef REG_DEAD_DEBUGGING
              df_print_note ("deleting: ", insn, link);
 #endif
-             XEXP (link, 1) = dead;
-             dead = link;
+             free_EXPR_LIST_node (link);
              *pprev = link = next;
            }
          break;
@@ -3165,8 +2788,7 @@ df_kill_notes (rtx insn, rtx *old_dead_notes, rtx *old_unused_notes)
 #ifdef REG_DEAD_DEBUGGING
              df_print_note ("deleting: ", insn, link);
 #endif
-             XEXP (link, 1) = unused;
-             unused = link;
+             free_EXPR_LIST_node (link);
              *pprev = link = next;
            }
          break;
@@ -3177,43 +2799,16 @@ df_kill_notes (rtx insn, rtx *old_dead_notes, rtx *old_unused_notes)
          break;
        }
     }
-
-  *old_dead_notes = dead;
-  *old_unused_notes = unused;
 }
 
 
-/* Set a NOTE_TYPE note for REG in INSN.  Try to pull it from the OLD
-   list, otherwise create a new one.  */
+/* Set a NOTE_TYPE note for REG in INSN.  */
 
-static inline rtx
-df_set_note (enum reg_note note_type, rtx insn, rtx old, rtx reg)
+static inline void
+df_set_note (enum reg_note note_type, rtx insn, rtx reg)
 {
-  rtx curr = old;
-  rtx prev = NULL;
-
-  gcc_assert (!DEBUG_INSN_P (insn));
-
-  while (curr)
-    if (XEXP (curr, 0) == reg)
-      {
-       if (prev)
-         XEXP (prev, 1) = XEXP (curr, 1);
-       else
-         old = XEXP (curr, 1);
-       XEXP (curr, 1) = REG_NOTES (insn);
-       REG_NOTES (insn) = curr;
-       return old;
-      }
-    else
-      {
-       prev = curr;
-       curr = XEXP (curr, 1);
-      }
-
-  /* Did not find the note.  */
+  gcc_checking_assert (!DEBUG_INSN_P (insn));
   add_reg_note (insn, note_type, reg);
-  return old;
 }
 
 /* A subroutine of df_set_unused_notes_for_mw, with a selection of its
@@ -3249,8 +2844,8 @@ df_whole_mw_reg_unused_p (struct df_mw_hardreg *mws,
    instruction.
 */
 
-static rtx
-df_set_unused_notes_for_mw (rtx insn, rtx old, struct df_mw_hardreg *mws,
+static void
+df_set_unused_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
                            bitmap live, bitmap do_not_gen,
                            bitmap artificial_uses)
 {
@@ -3265,7 +2860,7 @@ df_set_unused_notes_for_mw (rtx insn, rtx old, struct df_mw_hardreg *mws,
   if (df_whole_mw_reg_unused_p (mws, live, artificial_uses))
     {
       unsigned int regno = mws->start_regno;
-      old = df_set_note (REG_UNUSED, insn, old, mws->mw_reg);
+      df_set_note (REG_UNUSED, insn, mws->mw_reg);
 
 #ifdef REG_DEAD_DEBUGGING
       df_print_note ("adding 1: ", insn, REG_NOTES (insn));
@@ -3279,14 +2874,13 @@ df_set_unused_notes_for_mw (rtx insn, rtx old, struct df_mw_hardreg *mws,
        if (!bitmap_bit_p (live, r)
            && !bitmap_bit_p (artificial_uses, r))
          {
-           old = df_set_note (REG_UNUSED, insn, old, regno_reg_rtx[r]);
+           df_set_note (REG_UNUSED, insn, regno_reg_rtx[r]);
 #ifdef REG_DEAD_DEBUGGING
            df_print_note ("adding 2: ", insn, REG_NOTES (insn));
 #endif
          }
        bitmap_set_bit (do_not_gen, r);
       }
-  return old;
 }
 
 
@@ -3323,8 +2917,8 @@ df_whole_mw_reg_dead_p (struct df_mw_hardreg *mws,
    from being set if the instruction both reads and writes the
    register.  */
 
-static rtx
-df_set_dead_notes_for_mw (rtx insn, rtx old, struct df_mw_hardreg *mws,
+static void
+df_set_dead_notes_for_mw (rtx insn, struct df_mw_hardreg *mws,
                          bitmap live, bitmap do_not_gen,
                          bitmap artificial_uses, bool *added_notes_p)
 {
@@ -3352,9 +2946,9 @@ df_set_dead_notes_for_mw (rtx insn, rtx old, struct df_mw_hardreg *mws,
       if (is_debug)
        {
          *added_notes_p = true;
-         return old;
+         return;
        }
-      old = df_set_note (REG_DEAD, insn, old, mws->mw_reg);
+      df_set_note (REG_DEAD, insn, mws->mw_reg);
 #ifdef REG_DEAD_DEBUGGING
       df_print_note ("adding 1: ", insn, REG_NOTES (insn));
 #endif
@@ -3369,23 +2963,23 @@ df_set_dead_notes_for_mw (rtx insn, rtx old, struct df_mw_hardreg *mws,
            if (is_debug)
              {
                *added_notes_p = true;
-               return old;
+               return;
              }
-           old = df_set_note (REG_DEAD, insn, old, regno_reg_rtx[r]);
+           df_set_note (REG_DEAD, insn, regno_reg_rtx[r]);
 #ifdef REG_DEAD_DEBUGGING
            df_print_note ("adding 2: ", insn, REG_NOTES (insn));
 #endif
          }
     }
-  return old;
+  return;
 }
 
 
 /* Create a REG_UNUSED note if necessary for DEF in INSN updating
    LIVE.  Do not generate notes for registers in ARTIFICIAL_USES.  */
 
-static rtx
-df_create_unused_note (rtx insn, rtx old, df_ref def,
+static void
+df_create_unused_note (rtx insn, df_ref def,
                       bitmap live, bitmap artificial_uses)
 {
   unsigned int dregno = DF_REF_REGNO (def);
@@ -3405,13 +2999,13 @@ df_create_unused_note (rtx insn, rtx old, df_ref def,
     {
       rtx reg = (DF_REF_LOC (def))
                 ? *DF_REF_REAL_LOC (def): DF_REF_REG (def);
-      old = df_set_note (REG_UNUSED, insn, old, reg);
+      df_set_note (REG_UNUSED, insn, reg);
 #ifdef REG_DEAD_DEBUGGING
       df_print_note ("adding 3: ", insn, REG_NOTES (insn));
 #endif
     }
 
-  return old;
+  return;
 }
 
 /* Node of a linked list of uses of dead REGs in debug insns.  */
@@ -3634,8 +3228,6 @@ df_note_bb_compute (unsigned int bb_index,
     {
       unsigned int uid = INSN_UID (insn);
       struct df_mw_hardreg **mws_rec;
-      rtx old_dead_notes;
-      rtx old_unused_notes;
       int debug_insn;
 
       if (!INSN_P (insn))
@@ -3644,7 +3236,7 @@ df_note_bb_compute (unsigned int bb_index,
       debug_insn = DEBUG_INSN_P (insn);
 
       bitmap_clear (do_not_gen);
-      df_kill_notes (insn, &old_dead_notes, &old_unused_notes);
+      df_kill_notes (insn);
 
       /* Process the defs.  */
       if (CALL_P (insn))
@@ -3664,10 +3256,9 @@ df_note_bb_compute (unsigned int bb_index,
              struct df_mw_hardreg *mws = *mws_rec;
              if ((DF_MWS_REG_DEF_P (mws))
                  && !df_ignore_stack_reg (mws->start_regno))
-               old_unused_notes
-                 = df_set_unused_notes_for_mw (insn, old_unused_notes,
-                                               mws, live, do_not_gen,
-                                               artificial_uses);
+             df_set_unused_notes_for_mw (insn,
+                                         mws, live, do_not_gen,
+                                         artificial_uses);
              mws_rec++;
            }
 
@@ -3679,9 +3270,8 @@ df_note_bb_compute (unsigned int bb_index,
              unsigned int dregno = DF_REF_REGNO (def);
              if (!DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))
                {
-                 old_unused_notes
-                   = df_create_unused_note (insn, old_unused_notes,
-                                            def, live, artificial_uses);
+                 df_create_unused_note (insn,
+                                        def, live, artificial_uses);
                  bitmap_set_bit (do_not_gen, dregno);
                }
 
@@ -3697,10 +3287,9 @@ df_note_bb_compute (unsigned int bb_index,
            {
              struct df_mw_hardreg *mws = *mws_rec;
              if (DF_MWS_REG_DEF_P (mws))
-               old_unused_notes
-                 = df_set_unused_notes_for_mw (insn, old_unused_notes,
-                                               mws, live, do_not_gen,
-                                               artificial_uses);
+               df_set_unused_notes_for_mw (insn,
+                                           mws, live, do_not_gen,
+                                           artificial_uses);
              mws_rec++;
            }
 
@@ -3708,9 +3297,8 @@ df_note_bb_compute (unsigned int bb_index,
            {
              df_ref def = *def_rec;
              unsigned int dregno = DF_REF_REGNO (def);
-             old_unused_notes
-               = df_create_unused_note (insn, old_unused_notes,
-                                        def, live, artificial_uses);
+             df_create_unused_note (insn,
+                                    def, live, artificial_uses);
 
              if (!DF_REF_FLAGS_IS_SET (def, DF_REF_MUST_CLOBBER | DF_REF_MAY_CLOBBER))
                bitmap_set_bit (do_not_gen, dregno);
@@ -3730,11 +3318,10 @@ df_note_bb_compute (unsigned int bb_index,
            {
              bool really_add_notes = debug_insn != 0;
 
-             old_dead_notes
-               = df_set_dead_notes_for_mw (insn, old_dead_notes,
-                                           mws, live, do_not_gen,
-                                           artificial_uses,
-                                           &really_add_notes);
+             df_set_dead_notes_for_mw (insn,
+                                       mws, live, do_not_gen,
+                                       artificial_uses,
+                                       &really_add_notes);
 
              if (really_add_notes)
                debug_insn = -1;
@@ -3776,7 +3363,7 @@ df_note_bb_compute (unsigned int bb_index,
                {
                  rtx reg = (DF_REF_LOC (use))
                             ? *DF_REF_REAL_LOC (use) : DF_REF_REG (use);
-                 old_dead_notes = df_set_note (REG_DEAD, insn, old_dead_notes, reg);
+                 df_set_note (REG_DEAD, insn, reg);
 
 #ifdef REG_DEAD_DEBUGGING
                  df_print_note ("adding 4: ", insn, REG_NOTES (insn));
@@ -3787,19 +3374,6 @@ df_note_bb_compute (unsigned int bb_index,
            }
        }
 
-      while (old_unused_notes)
-       {
-         rtx next = XEXP (old_unused_notes, 1);
-         free_EXPR_LIST_node (old_unused_notes);
-         old_unused_notes = next;
-       }
-      while (old_dead_notes)
-       {
-         rtx next = XEXP (old_dead_notes, 1);
-         free_EXPR_LIST_node (old_dead_notes);
-         old_dead_notes = next;
-       }
-
       if (debug_insn == -1)
        {
          /* ??? We could probably do better here, replacing dead
@@ -3874,6 +3448,7 @@ static struct df_problem problem_NOTE =
   NULL,                       /* Incremental solution verify start.  */
   NULL,                       /* Incremental solution verify end.  */
   &problem_LR,                /* Dependent problem.  */
+  sizeof (struct df_scan_bb_info),/* Size of entry of block_info array.  */
   TV_DF_NOTE,                 /* Timing variable.  */
   false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
 };
@@ -4213,17 +3788,6 @@ struct df_md_problem_data
    only for live registers.  */
 static bitmap_head df_md_scratch;
 
-/* Set basic block info.  */
-
-static void
-df_md_set_bb_info (unsigned int index,
-                   struct df_md_bb_info *bb_info)
-{
-  gcc_assert (df_md);
-  gcc_assert (index < df_md->block_info_size);
-  df_md->block_info[index] = bb_info;
-}
-
 
 static void
 df_md_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
@@ -4237,7 +3801,6 @@ df_md_free_bb_info (basic_block bb ATTRIBUTE_UNUSED,
       bitmap_clear (&bb_info->init);
       bitmap_clear (&bb_info->in);
       bitmap_clear (&bb_info->out);
-      pool_free (df_md->block_pool, bb_info);
     }
 }
 
@@ -4252,10 +3815,6 @@ df_md_alloc (bitmap all_blocks)
   bitmap_iterator bi;
   struct df_md_problem_data *problem_data;
 
-  if (!df_md->block_pool)
-    df_md->block_pool = create_alloc_pool ("df_md_block pool",
-                                           sizeof (struct df_md_bb_info), 50);
-
   df_grow_bb_info (df_md);
   if (df_md->problem_data)
     problem_data = (struct df_md_problem_data *) df_md->problem_data;
@@ -4270,7 +3829,8 @@ df_md_alloc (bitmap all_blocks)
   EXECUTE_IF_SET_IN_BITMAP (all_blocks, 0, bb_index, bi)
     {
       struct df_md_bb_info *bb_info = df_md_get_bb_info (bb_index);
-      if (bb_info)
+      /* When bitmaps are already initialized, just clear them.  */
+      if (bb_info->init.obstack)
         {
           bitmap_clear (&bb_info->init);
           bitmap_clear (&bb_info->gen);
@@ -4280,8 +3840,6 @@ df_md_alloc (bitmap all_blocks)
         }
       else
         {
-          bb_info = (struct df_md_bb_info *) pool_alloc (df_md->block_pool);
-          df_md_set_bb_info (bb_index, bb_info);
          bitmap_initialize (&bb_info->init, &problem_data->md_bitmaps);
          bitmap_initialize (&bb_info->gen, &problem_data->md_bitmaps);
          bitmap_initialize (&bb_info->kill, &problem_data->md_bitmaps);
@@ -4519,19 +4077,20 @@ df_md_confluence_0 (basic_block bb)
 
 /* In of target gets or of out of source.  */
 
-static void
+static bool
 df_md_confluence_n (edge e)
 {
   bitmap op1 = &df_md_get_bb_info (e->dest->index)->in;
   bitmap op2 = &df_md_get_bb_info (e->src->index)->out;
 
   if (e->flags & EDGE_FAKE)
-    return;
+    return false;
 
   if (e->flags & EDGE_EH)
-    bitmap_ior_and_compl_into (op1, op2, regs_invalidated_by_call_regset);
+    return bitmap_ior_and_compl_into (op1, op2,
+                                     regs_invalidated_by_call_regset);
   else
-    bitmap_ior_into (op1, op2);
+    return bitmap_ior_into (op1, op2);
 }
 
 /* Free all storage associated with the problem.  */
@@ -4543,12 +4102,12 @@ df_md_free (void)
     = (struct df_md_problem_data *) df_md->problem_data;
 
   bitmap_obstack_release (&problem_data->md_bitmaps);
-  free_alloc_pool (df_md->block_pool);
   free (problem_data);
   df_md->problem_data = NULL;
 
   df_md->block_info_size = 0;
   free (df_md->block_info);
+  df_md->block_info = NULL;
   free (df_md);
 }
 
@@ -4607,6 +4166,7 @@ static struct df_problem problem_MD =
   NULL,                              /* Incremental solution verify start.  */
   NULL,                              /* Incremental solution verify end.  */
   NULL,                       /* Dependent problem.  */
+  sizeof (struct df_md_bb_info),/* Size of entry of block_info array.  */
   TV_DF_MD,                   /* Timing variable.  */
   false                       /* Reset blocks on dropping out of blocks_to_analyze.  */
 };