Patchwork repost: [DF] Use HARD_REG_SETs instead of bitmaps

login
register
mail settings
Submitter Dimitrios Apostolou
Date Nov. 6, 2011, 2:19 a.m.
Message ID <alpine.LNX.2.02.1110232231420.13386@localhost.localdomain>
Download mbox | patch
Permalink /patch/123909/
State New
Headers show

Comments

Dimitrios Apostolou - Nov. 6, 2011, 2:19 a.m.
Hello, better late than never, an update to my patch that converts most 
bitmaps in DF to HARD_REG_SETs and also refactors hard-reg-set.h.

On Mon, 22 Aug 2011, Jeff Law wrote:
> On 08/22/11 11:16, Dimitrios Apostolou wrote:
>>
>> Any updates will come as a followup to this thread. I still have to
>> do some testing on other platforms. Do we have access to any PA and
>> MIPS machinery? I also wanted to test on architecture with lots of
>> hard registers and small long size, but my 32-bit sparcstation
>> crashed badly, any ideas which arch to try next?
> I thought there was a PA available in the testfarm.

I appreciate the advice Jeff, indeed I've tried running my patch on gcc61 
(PA-RISC), and I'm also running tests on MIPS machines.

Everyone: I attach the latest version of this patch, updated to latest 
trunk and with an obscure bug I had introduced, fixed, together with some 
updates in reorg.c which depended on HARD_REG_SET implementation if 
DELAY_SLOTS was set.

Previously it was tested succesfully on i386, x86_64. Now I tested it on 
on i386 and sparc-linux-gnu, no regressions. I'll report back when testing 
on PA-RISC, MIPS is finished. Changelog and comments from the previous 
email apply here too:

http://gcc.gnu.org/ml/gcc-patches/2011-08/msg01796.html

Additional Changelog:

 	* reorg.c (resource_conflicts_p): Removed code dependant on
 	HARD_REG_SET implementation, replaced with
 	hard_reg_set_intersect_p().


Jakub, Paolo: You had voiced concerns about the struct-ification of 
HARD_REG_SET but I don't think we ended up anywhere? Any updates?

I understand major hassle is when the register file is big, too much data 
is being copied on a function call, when it has a HARD_REG_SET as a pass 
by value parameter. So I did some testing on SPARC, which has the biggest 
register file I know of, and there is a small performance regression 
indeed. On the other hand I really like the code reduction in 
hard-reg-set.h. So how should I proceed? FWIW I'm already testing passing 
the parameter by reference in the hottest functions.

Last but not least, what about the other aspects of this patch?


Thanks,
Dimitris
Paolo Bonzini - Nov. 6, 2011, 12:12 p.m.
On 11/06/2011 03:19 AM, Dimitrios Apostolou wrote:
>
> I understand major hassle is when the register file is big, too much
> data is being copied on a function call, when it has a HARD_REG_SET as a
> pass by value parameter. So I did some testing on SPARC, which has the
> biggest register file I know of, and there is a small performance
> regression indeed. On the other hand I really like the code reduction in
> hard-reg-set.h. So how should I proceed? FWIW I'm already testing
> passing the parameter by reference in the hottest functions.

What about adding a macro indirection to more functions (like you did 
with SET_HARD_REG_BIT and friends), so that pass-by-value can be changed 
to pass-by-reference without affecting all the uses throughout the compiler?

Paolo
Jakub Jelinek - Nov. 6, 2011, 12:55 p.m.
On Sun, Nov 06, 2011 at 01:12:21PM +0100, Paolo Bonzini wrote:
> On 11/06/2011 03:19 AM, Dimitrios Apostolou wrote:
> >
> >I understand major hassle is when the register file is big, too much
> >data is being copied on a function call, when it has a HARD_REG_SET as a
> >pass by value parameter. So I did some testing on SPARC, which has the
> >biggest register file I know of, and there is a small performance
> >regression indeed. On the other hand I really like the code reduction in
> >hard-reg-set.h. So how should I proceed? FWIW I'm already testing
> >passing the parameter by reference in the hottest functions.
> 
> What about adding a macro indirection to more functions (like you
> did with SET_HARD_REG_BIT and friends), so that pass-by-value can be
> changed to pass-by-reference without affecting all the uses
> throughout the compiler?

Or keep HARD_REG_SET type as is and just use a new struct type which
contains HARD_REG_SET or HARD_REG_SET * in it.
struct hard_reg_set_ptr;
void (*live_on_entry) (struct hard_reg_set_ptr *);
in the target* headers and
struct hard_reg_set_ptr { HARD_REG_SET *set; };
as the actual definition.

	Jakub

Patch

=== modified file 'gcc/config/i386/i386.c'
--- gcc/config/i386/i386.c	2011-10-21 19:32:20 +0000

+++ gcc/config/i386/i386.c	2011-10-23 21:13:15 +0000

@@ -11206,12 +11206,12 @@  ix86_expand_split_stack_prologue (void)

    is initializing a scratch register.  */
 
 static void
-ix86_live_on_entry (bitmap regs)

+ix86_live_on_entry (HARD_REG_SET *regs)

 {
   if (cfun->machine->split_stack_varargs_pointer != NULL_RTX)
     {
       gcc_assert (flag_split_stack);
-      bitmap_set_bit (regs, split_stack_prologue_scratch_regno ());

+      SET_HARD_REG_BIT (*regs, split_stack_prologue_scratch_regno ());

     }
 }
 

=== modified file 'gcc/config/mips/mips.c'
--- gcc/config/mips/mips.c	2011-10-02 17:46:11 +0000

+++ gcc/config/mips/mips.c	2011-10-23 21:13:15 +0000

@@ -9419,22 +9419,22 @@  mips_initial_elimination_offset (int fro

 /* Implement TARGET_EXTRA_LIVE_ON_ENTRY.  */
 
 static void
-mips_extra_live_on_entry (bitmap regs)

+mips_extra_live_on_entry (HARD_REG_SET *regs)

 {
   if (TARGET_USE_GOT)
     {
       /* PIC_FUNCTION_ADDR_REGNUM is live if we need it to set up
 	 the global pointer.   */
       if (!TARGET_ABSOLUTE_ABICALLS)
-	bitmap_set_bit (regs, PIC_FUNCTION_ADDR_REGNUM);

+	SET_HARD_REG_BIT (*regs, PIC_FUNCTION_ADDR_REGNUM);

 
       /* The prologue may set MIPS16_PIC_TEMP_REGNUM to the value of
 	 the global pointer.  */
       if (TARGET_MIPS16)
-	bitmap_set_bit (regs, MIPS16_PIC_TEMP_REGNUM);

+	SET_HARD_REG_BIT (*regs, MIPS16_PIC_TEMP_REGNUM);

 
       /* See the comment above load_call<mode> for details.  */
-      bitmap_set_bit (regs, GOT_VERSION_REGNUM);

+      SET_HARD_REG_BIT (*regs, GOT_VERSION_REGNUM);

     }
 }
 

=== modified file 'gcc/config/pa/pa.c'
--- gcc/config/pa/pa.c	2011-10-12 13:08:11 +0000

+++ gcc/config/pa/pa.c	2011-10-23 21:13:15 +0000

@@ -171,7 +171,7 @@  static struct machine_function * pa_init

 static reg_class_t pa_secondary_reload (bool, rtx, reg_class_t,
 					enum machine_mode,
 					secondary_reload_info *);
-static void pa_extra_live_on_entry (bitmap);

+static void pa_extra_live_on_entry (HARD_REG_SET *);

 static enum machine_mode pa_promote_function_mode (const_tree,
 						   enum machine_mode, int *,
 						   const_tree, int);
@@ -5936,10 +5936,10 @@  pa_secondary_reload (bool in_p, rtx x, r

    so we need to mark it here.  */
 
 static void
-pa_extra_live_on_entry (bitmap regs)

+pa_extra_live_on_entry (HARD_REG_SET *regs)

 {
   if (TARGET_64BIT)
-    bitmap_set_bit (regs, ARG_POINTER_REGNUM);

+    SET_HARD_REG_BIT (*regs, ARG_POINTER_REGNUM);

 }
 
 /* Implement EH_RETURN_HANDLER_RTX.  The MEM needs to be volatile

=== modified file 'gcc/dce.c'
--- gcc/dce.c	2011-07-19 17:43:15 +0000

+++ gcc/dce.c	2011-10-23 21:13:15 +0000

@@ -867,7 +867,7 @@  word_dce_process_block (basic_block bb, 

    artificial uses. */
 
 static bool
-dce_process_block (basic_block bb, bool redo_out, bitmap au)

+dce_process_block (basic_block bb, bool redo_out, HARD_REG_SET au)

 {
   bitmap local_live = BITMAP_ALLOC (&dce_tmp_bitmap_obstack);
   rtx insn;
@@ -906,7 +906,8 @@  dce_process_block (basic_block bb, bool 

 	if (!needed)
 	  for (def_rec = DF_INSN_DEFS (insn); *def_rec; def_rec++)
 	    if (bitmap_bit_p (local_live, DF_REF_REGNO (*def_rec))
-		|| bitmap_bit_p (au, DF_REF_REGNO (*def_rec)))

+		|| ( DF_REF_REGNO (*def_rec) < FIRST_PSEUDO_REGISTER

+		     && TEST_HARD_REG_BIT (au, DF_REF_REGNO (*def_rec))))

 	      {
 		needed = true;
 		mark_insn (insn, true);
@@ -952,13 +953,16 @@  fast_dce (bool word_level)

   bool global_changed = true;
 
   /* These regs are considered always live so if they end up dying
-     because of some def, we need to bring the back again.  Calling

+     because of some def, we need to bring them back again.  Calling

      df_simulate_fixup_sets has the disadvantage of calling
      bb_has_eh_pred once per insn, so we cache the information
      here.  */
-  bitmap au = &df->regular_block_artificial_uses;

-  bitmap au_eh = &df->eh_block_artificial_uses;

+  HARD_REG_SET au;

+  HARD_REG_SET au_eh;

   int i;
+ 

+  COPY_HARD_REG_SET (au, df->regular_block_artificial_uses);

+  COPY_HARD_REG_SET (au_eh, df->eh_block_artificial_uses);

 
   prescan_insns_for_dce (true);
 

=== modified file 'gcc/df-core.c'
--- gcc/df-core.c	2011-04-20 18:19:03 +0000

+++ gcc/df-core.c	2011-10-23 21:13:15 +0000

@@ -1885,6 +1885,17 @@  df_print_regset (FILE *file, bitmap r)

   fprintf (file, "\n");
 }
 
+void

+df_print_hard_reg_set (FILE *f, HARD_REG_SET r)

+{

+  unsigned int i;

+  hard_reg_set_iterator iter;

+

+  EXECUTE_IF_SET_IN_HARD_REG_SET (r, 0, i, iter)

+    fprintf (f, " %d [%s]", i, reg_names[i]);

+  fprintf (f, "\n");

+}

+

 
 /* Write information about registers and basic blocks into FILE.  The
    bitmap is in the form used by df_byte_lr.  This is part of making a

=== modified file 'gcc/df-problems.c'
--- gcc/df-problems.c	2011-08-26 14:21:19 +0000

+++ gcc/df-problems.c	2011-10-23 21:13:15 +0000

@@ -432,6 +432,7 @@  df_rd_local_compute (bitmap all_blocks)

 {
   unsigned int bb_index;
   bitmap_iterator bi;
+  hard_reg_set_iterator iter;

   unsigned int regno;
   struct df_rd_problem_data *problem_data
     = (struct df_rd_problem_data *) df_rd->problem_data;
@@ -449,7 +450,7 @@  df_rd_local_compute (bitmap all_blocks)

     }
 
   /* Set up the knockout bit vectors to be applied across EH_EDGES.  */
-  EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, regno, bi)

+  EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, regno, iter)

     {
       if (DF_DEFS_COUNT (regno) > DF_SPARSE_THRESHOLD)
 	bitmap_set_bit (sparse_invalidated, regno);
@@ -887,6 +888,31 @@  df_lr_bb_local_compute (unsigned int bb_

     df_recompute_luids (bb);
 }
 
+/* TODO optimise per-word */

+static void

+bitmap_copy_from_hard_reg_set(bitmap to, HARD_REG_SET from)

+{

+  unsigned int i;

+  hard_reg_set_iterator iter;

+

+  bitmap_clear (to);

+  EXECUTE_IF_SET_IN_HARD_REG_SET (from, 0, i, iter)

+    bitmap_set_bit (to, i);

+}

+

+/* TODO optimise per-word */

+static bool

+bitmap_ior_from_hard_reg_set(bitmap to, HARD_REG_SET from)

+{

+  bool ret= false;

+  hard_reg_set_iterator iter;

+  unsigned int i;

+

+  EXECUTE_IF_SET_IN_HARD_REG_SET (from, 0, i, iter)

+    ret |= bitmap_set_bit (to, i);

+

+  return ret;

+}

 
 /* Compute local live register info for each basic block within BLOCKS.  */
 
@@ -896,10 +922,10 @@  df_lr_local_compute (bitmap all_blocks A

   unsigned int bb_index;
   bitmap_iterator bi;
 
-  bitmap_clear (&df->hardware_regs_used);

+  CLEAR_HARD_REG_SET (df->hardware_regs_used);

 
   /* The all-important stack pointer must always be live.  */
-  bitmap_set_bit (&df->hardware_regs_used, STACK_POINTER_REGNUM);

+  SET_HARD_REG_BIT (df->hardware_regs_used, STACK_POINTER_REGNUM);

 
   /* Before reload, there are a few registers that must be forced
      live everywhere -- which might not already be the case for
@@ -909,20 +935,20 @@  df_lr_local_compute (bitmap all_blocks A

       unsigned int pic_offset_table_regnum = PIC_OFFSET_TABLE_REGNUM;
       /* Any reference to any pseudo before reload is a potential
 	 reference of the frame pointer.  */
-      bitmap_set_bit (&df->hardware_regs_used, FRAME_POINTER_REGNUM);

+      SET_HARD_REG_BIT (df->hardware_regs_used, FRAME_POINTER_REGNUM);

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

+	SET_HARD_REG_BIT (df->hardware_regs_used, ARG_POINTER_REGNUM);

 #endif
 
       /* Any constant, or pseudo with constant equivalences, may
 	 require reloading from memory using the pic register.  */
       if (pic_offset_table_regnum != INVALID_REGNUM
 	  && fixed_regs[pic_offset_table_regnum])
-	bitmap_set_bit (&df->hardware_regs_used, pic_offset_table_regnum);

+	SET_HARD_REG_BIT (df->hardware_regs_used, pic_offset_table_regnum);

     }
 
   EXECUTE_IF_SET_IN_BITMAP (df_lr->out_of_date_transfer_functions, 0, bb_index, bi)
@@ -932,7 +958,7 @@  df_lr_local_compute (bitmap all_blocks A

 	  /* The exit block is special for this problem and its bits are
 	     computed from thin air.  */
 	  struct df_lr_bb_info *bb_info = df_lr_get_bb_info (EXIT_BLOCK);
-	  bitmap_copy (&bb_info->use, df->exit_block_uses);

+	  bitmap_copy_from_hard_reg_set (&bb_info->use, df->exit_block_uses);

 	}
       else
 	df_lr_bb_local_compute (bb_index);
@@ -967,9 +993,32 @@  df_lr_confluence_0 (basic_block bb)

 {
   bitmap op1 = &df_lr_get_bb_info (bb->index)->out;
   if (bb != EXIT_BLOCK_PTR)
-    bitmap_copy (op1, &df->hardware_regs_used);

+    bitmap_copy_from_hard_reg_set (op1, df->hardware_regs_used);

 }
 
+/* to |= from1 & ~from2

+   from2 is of type HARD_REG_SET */

+

+static bool

+bitmap_ior_and_compl_from_hard_reg_set (bitmap to, const_bitmap from1,

+					HARD_REG_SET from2)

+{

+  bool ret;

+  unsigned int i;

+  bitmap_head from1_tmp;

+  hard_reg_set_iterator iter;

+

+  bitmap_initialize (&from1_tmp, &bitmap_default_obstack);

+  bitmap_copy (&from1_tmp, from1);

+

+  /* TODO optimise per-word */

+  EXECUTE_IF_SET_IN_HARD_REG_SET (from2, 0, i, iter)

+    bitmap_clear_bit (&from1_tmp, i);

+  ret = bitmap_ior_into (to, &from1_tmp);

+

+  bitmap_clear (&from1_tmp);

+  return ret;

+}

 
 /* Confluence function that ignores fake edges.  */
 
@@ -984,11 +1033,12 @@  df_lr_confluence_n (edge e)

   /* ??? Abnormal call edges ignored for the moment, as this gets
      confused by sibling call edges, which crashes reg-stack.  */
   if (e->flags & EDGE_EH)
-    changed = bitmap_ior_and_compl_into (op1, op2, regs_invalidated_by_call_regset);

+    changed = bitmap_ior_and_compl_from_hard_reg_set (op1, op2,

+						      regs_invalidated_by_call);

   else
     changed = bitmap_ior_into (op1, op2);
 
-  changed |= bitmap_ior_into (op1, &df->hardware_regs_used);

+  changed |= bitmap_ior_from_hard_reg_set (op1, df->hardware_regs_used);

   return changed;
 }
 
@@ -2507,19 +2557,10 @@  df_word_lr_local_compute (bitmap all_blo

   unsigned int bb_index;
   bitmap_iterator bi;
 
-  EXECUTE_IF_SET_IN_BITMAP (df_word_lr->out_of_date_transfer_functions, 0, bb_index, bi)

-    {

-      if (bb_index == EXIT_BLOCK)

-	{

-	  unsigned regno;

-	  bitmap_iterator bi;

-	  EXECUTE_IF_SET_IN_BITMAP (df->exit_block_uses, FIRST_PSEUDO_REGISTER,

-				    regno, bi)

-	    gcc_unreachable ();

-	}

-      else

-	df_word_lr_bb_local_compute (bb_index);

-    }

+  EXECUTE_IF_SET_IN_BITMAP (df_word_lr->out_of_date_transfer_functions,

+			    0, bb_index, bi)

+    if (bb_index != EXIT_BLOCK)

+      df_word_lr_bb_local_compute (bb_index);

 
   bitmap_clear (df_word_lr->out_of_date_transfer_functions);
 }
@@ -3650,9 +3691,9 @@  df_simulate_fixup_sets (basic_block bb, 

   /* These regs are considered always live so if they end up dying
      because of some def, we need to bring the back again.  */
   if (bb_has_eh_pred (bb))
-    bitmap_ior_into (live, &df->eh_block_artificial_uses);

+    bitmap_ior_from_hard_reg_set (live, df->eh_block_artificial_uses);

   else
-    bitmap_ior_into (live, &df->regular_block_artificial_uses);

+    bitmap_ior_from_hard_reg_set (live, df->regular_block_artificial_uses);

 }
 
 
@@ -4471,8 +4512,8 @@  df_md_confluence_n (edge e)

     return false;
 
   if (e->flags & EDGE_EH)
-    return bitmap_ior_and_compl_into (op1, op2,

-				      regs_invalidated_by_call_regset);

+    return bitmap_ior_and_compl_from_hard_reg_set (op1, op2,

+						   regs_invalidated_by_call);

   else
     return bitmap_ior_into (op1, op2);
 }

=== modified file 'gcc/df-scan.c'
--- gcc/df-scan.c	2011-08-27 17:38:58 +0000

+++ gcc/df-scan.c	2011-10-23 21:13:15 +0000

@@ -131,13 +131,13 @@  static void df_insn_refs_collect (struct

 				  basic_block, struct df_insn_info *);
 static void df_canonize_collection_rec (struct df_collection_rec *);
 
-static void df_get_regular_block_artificial_uses (bitmap);

-static void df_get_eh_block_artificial_uses (bitmap);

+static void df_get_regular_block_artificial_uses (HARD_REG_SET *);

+static void df_get_eh_block_artificial_uses (HARD_REG_SET *);

 
-static void df_record_entry_block_defs (bitmap);

-static void df_record_exit_block_uses (bitmap);

-static void df_get_exit_block_use_set (bitmap);

-static void df_get_entry_block_def_set (bitmap);

+static void df_record_entry_block_defs (HARD_REG_SET);

+static void df_record_exit_block_uses (HARD_REG_SET);

+static void df_get_exit_block_use_set (HARD_REG_SET *);

+static void df_get_entry_block_def_set (HARD_REG_SET *);

 static void df_grow_ref_info (struct df_ref_info *, unsigned int);
 static void df_ref_chain_delete_du_chain (df_ref *);
 static void df_ref_chain_delete (df_ref *);
@@ -146,8 +146,8 @@  static void df_refs_add_to_chains (struc

 				   basic_block, rtx);
 
 static bool df_insn_refs_verify (struct df_collection_rec *, basic_block, rtx, bool);
-static void df_entry_block_defs_collect (struct df_collection_rec *, bitmap);

-static void df_exit_block_uses_collect (struct df_collection_rec *, bitmap);

+static void df_entry_block_defs_collect (struct df_collection_rec *, HARD_REG_SET);

+static void df_exit_block_uses_collect (struct df_collection_rec *, HARD_REG_SET);

 static void df_install_ref (df_ref, struct df_reg_info *,
 			    struct df_ref_info *, bool);
 
@@ -162,7 +162,7 @@  static int df_mw_compare (const void *, 

    regs.  Final uses it to generate the code in the function prologue
    and epilogue to save and restore registers as needed.  */
 
-static bool regs_ever_live[FIRST_PSEUDO_REGISTER];

+static HARD_REG_SET regs_ever_live;

 
 /*----------------------------------------------------------------------------
    SCANNING DATAFLOW PROBLEM
@@ -253,11 +253,9 @@  df_scan_free_internal (void)

   df_scan->block_info = NULL;
   df_scan->block_info_size = 0;
 
-  bitmap_clear (&df->hardware_regs_used);

-  bitmap_clear (&df->regular_block_artificial_uses);

-  bitmap_clear (&df->eh_block_artificial_uses);

-  BITMAP_FREE (df->entry_block_defs);

-  BITMAP_FREE (df->exit_block_uses);

+  CLEAR_HARD_REG_SET (df->hardware_regs_used);

+  CLEAR_HARD_REG_SET (df->regular_block_artificial_uses);

+  CLEAR_HARD_REG_SET (df->eh_block_artificial_uses);

   bitmap_clear (&df->insns_to_delete);
   bitmap_clear (&df->insns_to_rescan);
   bitmap_clear (&df->insns_to_notes_rescan);
@@ -366,11 +364,11 @@  df_scan_alloc (bitmap all_blocks ATTRIBU

       bb_info->artificial_uses = NULL;
     }
 
-  bitmap_initialize (&df->hardware_regs_used, &problem_data->reg_bitmaps);

-  bitmap_initialize (&df->regular_block_artificial_uses, &problem_data->reg_bitmaps);

-  bitmap_initialize (&df->eh_block_artificial_uses, &problem_data->reg_bitmaps);

-  df->entry_block_defs = BITMAP_ALLOC (&problem_data->reg_bitmaps);

-  df->exit_block_uses = BITMAP_ALLOC (&problem_data->reg_bitmaps);

+  CLEAR_HARD_REG_SET (df->hardware_regs_used);

+  CLEAR_HARD_REG_SET (df->regular_block_artificial_uses);

+  CLEAR_HARD_REG_SET (df->eh_block_artificial_uses);

+  CLEAR_HARD_REG_SET (df->entry_block_defs);

+  CLEAR_HARD_REG_SET (df->exit_block_uses);

   bitmap_initialize (&df->insns_to_delete, &problem_data->insn_bitmaps);
   bitmap_initialize (&df->insns_to_rescan, &problem_data->insn_bitmaps);
   bitmap_initialize (&df->insns_to_notes_rescan, &problem_data->insn_bitmaps);
@@ -409,21 +407,28 @@  df_scan_start_dump (FILE *file ATTRIBUTE

   rtx insn;
 
   fprintf (file, ";;  invalidated by call \t");
-  df_print_regset (file, regs_invalidated_by_call_regset);

+  df_print_hard_reg_set (file, regs_invalidated_by_call);

+  

   fprintf (file, ";;  hardware regs used \t");
-  df_print_regset (file, &df->hardware_regs_used);

+  df_print_hard_reg_set (file, df->hardware_regs_used);

+  

   fprintf (file, ";;  regular block artificial uses \t");
-  df_print_regset (file, &df->regular_block_artificial_uses);

+  df_print_hard_reg_set (file, df->regular_block_artificial_uses);

+  

   fprintf (file, ";;  eh block artificial uses \t");
-  df_print_regset (file, &df->eh_block_artificial_uses);

+  df_print_hard_reg_set (file, df->eh_block_artificial_uses);

+  

   fprintf (file, ";;  entry block defs \t");
-  df_print_regset (file, df->entry_block_defs);

+  df_print_hard_reg_set (file, df->entry_block_defs);

+  

   fprintf (file, ";;  exit block uses \t");
-  df_print_regset (file, df->exit_block_uses);

+  df_print_hard_reg_set (file, df->exit_block_uses);

+  

   fprintf (file, ";;  regs ever live \t");
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     if (df_regs_ever_live_p (i))
       fprintf (file, " %d[%s]", i, reg_names[i]);
+  

   fprintf (file, "\n;;  ref usage \t");
 
   for (i = 0; i < (int)df->regs_inited; i++)
@@ -662,13 +667,13 @@  df_scan_blocks (void)

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

-		   &df->regular_block_artificial_uses);

+  IOR_HARD_REG_SET (df->eh_block_artificial_uses,

+		    df->regular_block_artificial_uses);

 
   /* ENTRY and EXIT blocks have special defs/uses.  */
-  df_get_entry_block_def_set (df->entry_block_defs);

+  df_get_entry_block_def_set (&df->entry_block_defs);

   df_record_entry_block_defs (df->entry_block_defs);
-  df_get_exit_block_use_set (df->exit_block_uses);

+  df_get_exit_block_use_set (&df->exit_block_uses);

   df_record_exit_block_uses (df->exit_block_uses);
   df_set_bb_dirty (BASIC_BLOCK (ENTRY_BLOCK));
   df_set_bb_dirty (BASIC_BLOCK (EXIT_BLOCK));
@@ -3318,20 +3323,20 @@  df_get_call_refs (struct df_collection_r

                   int flags)
 {
   rtx note;
-  bitmap_iterator bi;

+  hard_reg_set_iterator iter;

   unsigned int ui;
   bool is_sibling_call;
   unsigned int i;
   df_ref def;
-  bitmap_head defs_generated;

+  HARD_REG_SET defs_generated;

 
-  bitmap_initialize (&defs_generated, &df_bitmap_obstack);

+  CLEAR_HARD_REG_SET(defs_generated);

 
   /* Do not generate clobbers for registers that are the result of the
      call.  This causes ordering problems in the chain building code
      depending on which def is seen first.  */
   FOR_EACH_VEC_ELT (df_ref, collection_rec->def_vec, i, def)
-    bitmap_set_bit (&defs_generated, DF_REF_REGNO (def));

+    SET_HARD_REG_BIT (defs_generated, DF_REF_REGNO (def));

 
   /* Record the registers used to pass arguments, and explicitly
      noted as clobbered.  */
@@ -3346,7 +3351,7 @@  df_get_call_refs (struct df_collection_r

 	  if (REG_P (XEXP (XEXP (note, 0), 0)))
 	    {
 	      unsigned int regno = REGNO (XEXP (XEXP (note, 0), 0));
-	      if (!bitmap_bit_p (&defs_generated, regno))

+	      if (!TEST_HARD_REG_BIT (defs_generated, regno))

 		df_defs_record (collection_rec, XEXP (note, 0), bb,
 				insn_info, flags);
 	    }
@@ -3376,12 +3381,12 @@  df_get_call_refs (struct df_collection_r

 	}
 
   is_sibling_call = SIBLING_CALL_P (insn_info->insn);
-  EXECUTE_IF_SET_IN_BITMAP (regs_invalidated_by_call_regset, 0, ui, bi)

+  EXECUTE_IF_SET_IN_HARD_REG_SET (regs_invalidated_by_call, 0, ui, iter)

     {
       if (!global_regs[ui]
-	  && (!bitmap_bit_p (&defs_generated, ui))

+	  && (!TEST_HARD_REG_BIT (defs_generated, ui))

 	  && (!is_sibling_call
-	      || !bitmap_bit_p (df->exit_block_uses, ui)

+	      || !TEST_HARD_REG_BIT (df->exit_block_uses, ui)

 	      || refers_to_regno_p (ui, ui+1,
 				    crtl->return_rtx, NULL)))
         df_ref_record (DF_REF_BASE, collection_rec, regno_reg_rtx[ui],
@@ -3389,7 +3394,6 @@  df_get_call_refs (struct df_collection_r

 		       DF_REF_MAY_CLOBBER | flags);
     }
 
-  bitmap_clear (&defs_generated);

   return;
 }
 
@@ -3535,13 +3539,13 @@  df_bb_refs_collect (struct df_collection

   /* Add the artificial uses.  */
   if (bb->index >= NUM_FIXED_BLOCKS)
     {
-      bitmap_iterator bi;

+      hard_reg_set_iterator iter;

       unsigned int regno;
-      bitmap au = bb_has_eh_pred (bb)

-	? &df->eh_block_artificial_uses

-	: &df->regular_block_artificial_uses;

+      HARD_REG_SET *au= bb_has_eh_pred (bb)

+	? &(df->eh_block_artificial_uses)

+	: &(df->regular_block_artificial_uses);

 
-      EXECUTE_IF_SET_IN_BITMAP (au, 0, regno, bi)

+      EXECUTE_IF_SET_IN_HARD_REG_SET (*au, 0, regno, iter)

 	{
 	  df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[regno], NULL,
 			 bb, NULL, DF_REF_REG_USE, 0);
@@ -3608,18 +3612,18 @@  df_bb_refs_record (int bb_index, bool sc

    block. */
 
 static void
-df_get_regular_block_artificial_uses (bitmap regular_block_artificial_uses)

+df_get_regular_block_artificial_uses (HARD_REG_SET *regular_block_artificial_uses)

 {
 #ifdef EH_USES
   unsigned int i;
 #endif
 
-  bitmap_clear (regular_block_artificial_uses);

+  CLEAR_HARD_REG_SET (*regular_block_artificial_uses);

 
   if (reload_completed)
     {
       if (frame_pointer_needed)
-	bitmap_set_bit (regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM);

+	SET_HARD_REG_BIT (*regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM);

     }
   else
     /* Before reload, there are a few registers that must be forced
@@ -3630,27 +3634,27 @@  df_get_regular_block_artificial_uses (bi

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

+      SET_HARD_REG_BIT (*regular_block_artificial_uses, FRAME_POINTER_REGNUM);

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

+      SET_HARD_REG_BIT (*regular_block_artificial_uses, HARD_FRAME_POINTER_REGNUM);

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

+	SET_HARD_REG_BIT (*regular_block_artificial_uses, ARG_POINTER_REGNUM);

 #endif
 
       /* Any constant, or pseudo with constant equivalences, may
 	 require reloading from memory using the pic register.  */
       if (picreg != INVALID_REGNUM
 	  && fixed_regs[picreg])
-	bitmap_set_bit (regular_block_artificial_uses, picreg);

+	SET_HARD_REG_BIT (*regular_block_artificial_uses, picreg);

     }
   /* The all-important stack pointer must always be live.  */
-  bitmap_set_bit (regular_block_artificial_uses, STACK_POINTER_REGNUM);

+  SET_HARD_REG_BIT (*regular_block_artificial_uses, STACK_POINTER_REGNUM);

 
 #ifdef EH_USES
   /* EH_USES registers are used:
@@ -3663,7 +3667,7 @@  df_get_regular_block_artificial_uses (bi

 	(noreturn call or infinite loop).  */
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     if (EH_USES (i))
-      bitmap_set_bit (regular_block_artificial_uses, i);

+      SET_HARD_REG_BIT (*regular_block_artificial_uses, i);

 #endif
 }
 
@@ -3671,9 +3675,9 @@  df_get_regular_block_artificial_uses (bi

 /* Get the artificial use set for an eh block. */
 
 static void
-df_get_eh_block_artificial_uses (bitmap eh_block_artificial_uses)

+df_get_eh_block_artificial_uses (HARD_REG_SET *eh_block_artificial_uses)

 {
-  bitmap_clear (eh_block_artificial_uses);

+  CLEAR_HARD_REG_SET (*eh_block_artificial_uses);

 
   /* The following code (down thru the arg_pointer setting APPEARS
      to be necessary because there is nothing that actually
@@ -3683,14 +3687,14 @@  df_get_eh_block_artificial_uses (bitmap 

     {
       if (frame_pointer_needed)
 	{
-	  bitmap_set_bit (eh_block_artificial_uses, FRAME_POINTER_REGNUM);

+	  SET_HARD_REG_BIT (*eh_block_artificial_uses, FRAME_POINTER_REGNUM);

 #if !HARD_FRAME_POINTER_IS_FRAME_POINTER
-	  bitmap_set_bit (eh_block_artificial_uses, HARD_FRAME_POINTER_REGNUM);

+	  SET_HARD_REG_BIT (*eh_block_artificial_uses, HARD_FRAME_POINTER_REGNUM);

 #endif
 	}
 #if FRAME_POINTER_REGNUM != ARG_POINTER_REGNUM
       if (fixed_regs[ARG_POINTER_REGNUM])
-	bitmap_set_bit (eh_block_artificial_uses, ARG_POINTER_REGNUM);

+	SET_HARD_REG_BIT (*eh_block_artificial_uses, ARG_POINTER_REGNUM);

 #endif
     }
 }
@@ -3708,7 +3712,7 @@  df_get_eh_block_artificial_uses (bitmap 

 static void
 df_mark_reg (rtx reg, void *vset)
 {
-  bitmap set = (bitmap) vset;

+  HARD_REG_SET *set = (HARD_REG_SET *) vset;

   int regno = REGNO (reg);
 
   gcc_assert (GET_MODE (reg) != BLKmode);
@@ -3716,29 +3720,34 @@  df_mark_reg (rtx reg, void *vset)

   if (regno < FIRST_PSEUDO_REGISTER)
     {
       int n = hard_regno_nregs[regno][GET_MODE (reg)];
-      bitmap_set_range (set, regno, n);

+      int i;

+      for (i=regno; i<regno+n; i++)

+	SET_HARD_REG_BIT (*set, i);

     }
   else
-    bitmap_set_bit (set, regno);

+    {

+      gcc_assert (0);

+      SET_HARD_REG_BIT (*set, regno); /* WARNING BUG!!! */

+    }

 }
 
 
 /* Set the bit for regs that are considered being defined at the entry. */
 
 static void
-df_get_entry_block_def_set (bitmap entry_block_defs)

+df_get_entry_block_def_set (HARD_REG_SET *entry_block_defs)

 {
   rtx r;
   int i;
 
-  bitmap_clear (entry_block_defs);

+  CLEAR_HARD_REG_SET (*entry_block_defs);

 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     if (FUNCTION_ARG_REGNO_P (i))
-      bitmap_set_bit (entry_block_defs, INCOMING_REGNO (i));

+      SET_HARD_REG_BIT (*entry_block_defs, INCOMING_REGNO (i));

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

+  SET_HARD_REG_BIT (*entry_block_defs, STACK_POINTER_REGNUM);

 
   /* Once the prologue has been generated, all of these registers
      should just show up in the first regular block.  */
@@ -3748,28 +3757,28 @@  df_get_entry_block_def_set (bitmap entry

 	 pushes have some defining location.  */
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
 	if ((call_used_regs[i] == 0) && (df_regs_ever_live_p (i)))
-	  bitmap_set_bit (entry_block_defs, i);

+	  SET_HARD_REG_BIT (*entry_block_defs, i);

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

+    SET_HARD_REG_BIT (*entry_block_defs, REGNO (r));

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

+    SET_HARD_REG_BIT (*entry_block_defs, REGNO (r));

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

+      SET_HARD_REG_BIT (*entry_block_defs, FRAME_POINTER_REGNUM);

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

+	SET_HARD_REG_BIT (*entry_block_defs, HARD_FRAME_POINTER_REGNUM);

 #endif
     }
 
@@ -3784,7 +3793,7 @@  df_get_entry_block_def_set (bitmap entry

       /* Pseudos with argument area equivalences may require
 	 reloading via the argument pointer.  */
       if (fixed_regs[ARG_POINTER_REGNUM])
-	bitmap_set_bit (entry_block_defs, ARG_POINTER_REGNUM);

+	SET_HARD_REG_BIT (*entry_block_defs, ARG_POINTER_REGNUM);

 #endif
 
 #ifdef PIC_OFFSET_TABLE_REGNUM
@@ -3792,13 +3801,13 @@  df_get_entry_block_def_set (bitmap entry

 	 require reloading from memory using the pic register.  */
       if (picreg != INVALID_REGNUM
 	  && fixed_regs[picreg])
-	bitmap_set_bit (entry_block_defs, picreg);

+	SET_HARD_REG_BIT (*entry_block_defs, picreg);

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

+    SET_HARD_REG_BIT (*entry_block_defs, REGNO (INCOMING_RETURN_ADDR_RTX));

 #endif
 
   targetm.extra_live_on_entry (entry_block_defs);
@@ -3812,12 +3821,12 @@  df_get_entry_block_def_set (bitmap entry

 
 static void
 df_entry_block_defs_collect (struct df_collection_rec *collection_rec,
-			     bitmap entry_block_defs)

+			     HARD_REG_SET entry_block_defs)

 {
   unsigned int i;
-  bitmap_iterator bi;

+  hard_reg_set_iterator iter;

 
-  EXECUTE_IF_SET_IN_BITMAP (entry_block_defs, 0, i, bi)

+  EXECUTE_IF_SET_IN_HARD_REG_SET (entry_block_defs, 0, i, iter)

     {
       df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[i], NULL,
 		     ENTRY_BLOCK_PTR, NULL, DF_REF_REG_DEF, 0);
@@ -3831,15 +3840,17 @@  df_entry_block_defs_collect (struct df_c

    entry to the function.  */
 
 static void
-df_record_entry_block_defs (bitmap entry_block_defs)

+df_record_entry_block_defs (HARD_REG_SET entry_block_defs)

 {
   struct df_collection_rec collection_rec;
+  

   memset (&collection_rec, 0, sizeof (struct df_collection_rec));
   collection_rec.def_vec = VEC_alloc (df_ref, stack, FIRST_PSEUDO_REGISTER);
-  df_entry_block_defs_collect (&collection_rec, entry_block_defs);

 
+  df_entry_block_defs_collect (&collection_rec, entry_block_defs);

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

   VEC_free (df_ref, stack, collection_rec.def_vec);
 }
 
@@ -3849,53 +3860,35 @@  df_record_entry_block_defs (bitmap entry

 void
 df_update_entry_block_defs (void)
 {
-  bitmap_head refs;

-  bool changed = false;

+  HARD_REG_SET refs;

 
-  bitmap_initialize (&refs, &df_bitmap_obstack);

   df_get_entry_block_def_set (&refs);
-  if (df->entry_block_defs)

-    {

-      if (!bitmap_equal_p (df->entry_block_defs, &refs))

-	{

-	  struct df_scan_bb_info *bb_info = df_scan_get_bb_info (ENTRY_BLOCK);

-	  df_ref_chain_delete_du_chain (bb_info->artificial_defs);

-	  df_ref_chain_delete (bb_info->artificial_defs);

-	  bb_info->artificial_defs = NULL;

-	  changed = true;

-	}

-    }

-  else

+  if (!hard_reg_set_equal_p (df->entry_block_defs, refs))

     {
-      struct df_scan_problem_data *problem_data

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

-	gcc_unreachable ();

-      df->entry_block_defs = BITMAP_ALLOC (&problem_data->reg_bitmaps);

-      changed = true;

-    }

+      struct df_scan_bb_info *bb_info = df_scan_get_bb_info (ENTRY_BLOCK);

+      df_ref_chain_delete_du_chain (bb_info->artificial_defs);

+      df_ref_chain_delete (bb_info->artificial_defs);

+      bb_info->artificial_defs = NULL;

 
-  if (changed)

-    {

-      df_record_entry_block_defs (&refs);

-      bitmap_copy (df->entry_block_defs, &refs);

+      df_record_entry_block_defs (refs);

+      COPY_HARD_REG_SET (df->entry_block_defs, refs);

       df_set_bb_dirty (BASIC_BLOCK (ENTRY_BLOCK));
     }
-  bitmap_clear (&refs);

 }
 
 
 /* Set the bit for regs that are considered being used at the exit. */
 
 static void
-df_get_exit_block_use_set (bitmap exit_block_uses)

+df_get_exit_block_use_set (HARD_REG_SET *exit_block_uses)

 {
   unsigned int i;
   unsigned int picreg = PIC_OFFSET_TABLE_REGNUM;
 
-  bitmap_clear (exit_block_uses);

+  CLEAR_HARD_REG_SET (*exit_block_uses);

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

+  SET_HARD_REG_BIT (*exit_block_uses, STACK_POINTER_REGNUM);

 
   /* Mark the frame pointer if needed at the end of the function.
      If we end up eliminating it, it will be removed from the live
@@ -3903,11 +3896,11 @@  df_get_exit_block_use_set (bitmap exit_b

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

+      SET_HARD_REG_BIT (*exit_block_uses, FRAME_POINTER_REGNUM);

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

+	SET_HARD_REG_BIT (*exit_block_uses, HARD_FRAME_POINTER_REGNUM);

 #endif
     }
 
@@ -3917,14 +3910,14 @@  df_get_exit_block_use_set (bitmap exit_b

   if (!PIC_OFFSET_TABLE_REG_CALL_CLOBBERED
       && picreg != INVALID_REGNUM
       && fixed_regs[picreg])
-    bitmap_set_bit (exit_block_uses, picreg);

+    SET_HARD_REG_BIT (*exit_block_uses, picreg);

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

+      SET_HARD_REG_BIT (*exit_block_uses, i);

 
   if (HAVE_epilogue && epilogue_completed)
     {
@@ -3932,7 +3925,7 @@  df_get_exit_block_use_set (bitmap exit_b

       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
 	if (df_regs_ever_live_p (i) && !LOCAL_REGNO (i)
 	    && !TEST_HARD_REG_BIT (regs_invalidated_by_call, i))
-	  bitmap_set_bit (exit_block_uses, i);

+	  SET_HARD_REG_BIT (*exit_block_uses, i);

     }
 
 #ifdef EH_RETURN_DATA_REGNO
@@ -3943,7 +3936,7 @@  df_get_exit_block_use_set (bitmap exit_b

 	unsigned regno = EH_RETURN_DATA_REGNO (i);
 	if (regno == INVALID_REGNUM)
 	  break;
-	bitmap_set_bit (exit_block_uses, regno);

+	SET_HARD_REG_BIT (*exit_block_uses, regno);

       }
 #endif
 
@@ -3976,12 +3969,12 @@  df_get_exit_block_use_set (bitmap exit_b

    It uses df->exit_block_uses to determine register to include.  */
 
 static void
-df_exit_block_uses_collect (struct df_collection_rec *collection_rec, bitmap exit_block_uses)

+df_exit_block_uses_collect (struct df_collection_rec *collection_rec, HARD_REG_SET exit_block_uses)

 {
   unsigned int i;
-  bitmap_iterator bi;

+  hard_reg_set_iterator iter;

 
-  EXECUTE_IF_SET_IN_BITMAP (exit_block_uses, 0, i, bi)

+  EXECUTE_IF_SET_IN_HARD_REG_SET (exit_block_uses, 0, i, iter)

     df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[i], NULL,
 		   EXIT_BLOCK_PTR, NULL, DF_REF_REG_USE, 0);
 
@@ -3989,7 +3982,7 @@  df_exit_block_uses_collect (struct df_co

   /* It is deliberate that this is not put in the exit block uses but
      I do not know why.  */
   if (reload_completed
-      && !bitmap_bit_p (exit_block_uses, ARG_POINTER_REGNUM)

+      && !TEST_HARD_REG_BIT (exit_block_uses, ARG_POINTER_REGNUM)

       && bb_has_eh_pred (EXIT_BLOCK_PTR)
       && fixed_regs[ARG_POINTER_REGNUM])
     df_ref_record (DF_REF_ARTIFICIAL, collection_rec, regno_reg_rtx[ARG_POINTER_REGNUM], NULL,
@@ -4004,16 +3997,17 @@  df_exit_block_uses_collect (struct df_co

    It uses df->exit_block_uses to determine which bit to include.  */
 
 static void
-df_record_exit_block_uses (bitmap exit_block_uses)

+df_record_exit_block_uses (HARD_REG_SET exit_block_uses)

 {
   struct df_collection_rec collection_rec;
+

   memset (&collection_rec, 0, sizeof (struct df_collection_rec));
   collection_rec.use_vec = VEC_alloc (df_ref, stack, FIRST_PSEUDO_REGISTER);
 
   df_exit_block_uses_collect (&collection_rec, exit_block_uses);
-

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

   VEC_free (df_ref, stack, collection_rec.use_vec);
 }
 
@@ -4023,38 +4017,20 @@  df_record_exit_block_uses (bitmap exit_b

 void
 df_update_exit_block_uses (void)
 {
-  bitmap_head refs;

-  bool changed = false;

+  HARD_REG_SET refs;

 
-  bitmap_initialize (&refs, &df_bitmap_obstack);

   df_get_exit_block_use_set (&refs);
-  if (df->exit_block_uses)

-    {

-      if (!bitmap_equal_p (df->exit_block_uses, &refs))

-	{

-	  struct df_scan_bb_info *bb_info = df_scan_get_bb_info (EXIT_BLOCK);

-	  df_ref_chain_delete_du_chain (bb_info->artificial_uses);

-	  df_ref_chain_delete (bb_info->artificial_uses);

-	  bb_info->artificial_uses = NULL;

-	  changed = true;

-	}

-    }

-  else

+  if (!hard_reg_set_equal_p (df->exit_block_uses, refs))

     {
-      struct df_scan_problem_data *problem_data

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

-	gcc_unreachable ();

-      df->exit_block_uses = BITMAP_ALLOC (&problem_data->reg_bitmaps);

-      changed = true;

-    }

+      struct df_scan_bb_info *bb_info = df_scan_get_bb_info (EXIT_BLOCK);

+      df_ref_chain_delete_du_chain (bb_info->artificial_uses);

+      df_ref_chain_delete (bb_info->artificial_uses);

+      bb_info->artificial_uses = NULL;

 
-  if (changed)

-    {

-      df_record_exit_block_uses (&refs);

-      bitmap_copy (df->exit_block_uses,& refs);

+      df_record_exit_block_uses (refs);

+      COPY_HARD_REG_SET (df->exit_block_uses, refs);

       df_set_bb_dirty (BASIC_BLOCK (EXIT_BLOCK));
     }
-  bitmap_clear (&refs);

 }
 
 static bool initialized = false;
@@ -4143,7 +4119,7 @@  df_hard_reg_used_count (unsigned int reg

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

+  return TEST_HARD_REG_BIT (regs_ever_live, regno);

 }
 
 
@@ -4153,10 +4129,14 @@  df_regs_ever_live_p (unsigned int regno)

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

+  if (df_regs_ever_live_p (regno) == value)

     return;
 
-  regs_ever_live[regno] = value;

+  if (value)

+    SET_HARD_REG_BIT (regs_ever_live, regno);

+  else

+    CLEAR_HARD_REG_BIT (regs_ever_live, regno);

+

   if (df)
     df->redo_entry_and_exit = true;
 }
@@ -4172,12 +4152,12 @@  df_compute_regs_ever_live (bool reset)

   bool changed = df->redo_entry_and_exit;
 
   if (reset)
-    memset (regs_ever_live, 0, sizeof (regs_ever_live));

+    CLEAR_HARD_REG_SET (regs_ever_live);

 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
-    if ((!regs_ever_live[i]) && df_hard_reg_used_p (i))

+    if ((!df_regs_ever_live_p (i)) && df_hard_reg_used_p (i))

       {
-	regs_ever_live[i] = true;

+	df_set_regs_ever_live (i, true);

 	changed = true;
       }
   if (changed)
@@ -4410,26 +4390,23 @@  df_bb_verify (basic_block bb)

 static bool
 df_entry_block_bitmap_verify (bool abort_if_fail)
 {
-  bitmap_head entry_block_defs;

+  HARD_REG_SET entry_block_defs;

   bool is_eq;
 
-  bitmap_initialize (&entry_block_defs, &df_bitmap_obstack);

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

+  is_eq = hard_reg_set_equal_p (entry_block_defs, df->entry_block_defs);

 
   if (!is_eq && abort_if_fail)
     {
       print_current_pass (stderr);
       fprintf (stderr, "entry_block_defs = ");
-      df_print_regset (stderr, &entry_block_defs);

+      df_print_hard_reg_set (stderr, entry_block_defs);

       fprintf (stderr, "df->entry_block_defs = ");
-      df_print_regset (stderr, df->entry_block_defs);

+      df_print_hard_reg_set (stderr, df->entry_block_defs);

       gcc_assert (0);
     }
 
-  bitmap_clear (&entry_block_defs);

-

   return is_eq;
 }
 
@@ -4440,26 +4417,23 @@  df_entry_block_bitmap_verify (bool abort

 static bool
 df_exit_block_bitmap_verify (bool abort_if_fail)
 {
-  bitmap_head exit_block_uses;

+  HARD_REG_SET exit_block_uses;

   bool is_eq;
 
-  bitmap_initialize (&exit_block_uses, &df_bitmap_obstack);

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

+  is_eq = hard_reg_set_equal_p (exit_block_uses, df->exit_block_uses);

 
   if (!is_eq && abort_if_fail)
     {
       print_current_pass (stderr);
       fprintf (stderr, "exit_block_uses = ");
-      df_print_regset (stderr, &exit_block_uses);

+      df_print_hard_reg_set (stderr, exit_block_uses);

       fprintf (stderr, "df->exit_block_uses = ");
-      df_print_regset (stderr, df->exit_block_uses);

+      df_print_hard_reg_set (stderr, df->exit_block_uses);

       gcc_assert (0);
     }
 
-  bitmap_clear (&exit_block_uses);

-

   return is_eq;
 }
 
@@ -4472,8 +4446,8 @@  df_scan_verify (void)

 {
   unsigned int i;
   basic_block bb;
-  bitmap_head regular_block_artificial_uses;

-  bitmap_head eh_block_artificial_uses;

+  HARD_REG_SET regular_block_artificial_uses;

+  HARD_REG_SET eh_block_artificial_uses;

 
   if (!df)
     return;
@@ -4494,23 +4468,18 @@  df_scan_verify (void)

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

-  bitmap_initialize (&eh_block_artificial_uses, &df_bitmap_obstack);

 
   df_get_regular_block_artificial_uses (&regular_block_artificial_uses);
   df_get_eh_block_artificial_uses (&eh_block_artificial_uses);
 
-  bitmap_ior_into (&eh_block_artificial_uses,

-		   &regular_block_artificial_uses);

+  IOR_HARD_REG_SET (eh_block_artificial_uses,

+		    regular_block_artificial_uses);

 
   /* Check artificial_uses bitmaps didn't change. */
-  gcc_assert (bitmap_equal_p (&regular_block_artificial_uses,

-			      &df->regular_block_artificial_uses));

-  gcc_assert (bitmap_equal_p (&eh_block_artificial_uses,

-			      &df->eh_block_artificial_uses));

-

-  bitmap_clear (&regular_block_artificial_uses);

-  bitmap_clear (&eh_block_artificial_uses);

+  gcc_assert (hard_reg_set_equal_p (regular_block_artificial_uses,

+				    df->regular_block_artificial_uses));

+  gcc_assert (hard_reg_set_equal_p (eh_block_artificial_uses,

+				    df->eh_block_artificial_uses));

 
   /* Verify entry block and exit block. These only verify the bitmaps,
      the refs are verified in df_bb_verify.  */

=== modified file 'gcc/df.h'
--- gcc/df.h	2010-12-14 00:23:40 +0000

+++ gcc/df.h	2011-10-23 21:13:15 +0000

@@ -69,7 +69,7 @@  enum df_flow_dir

 /* Descriminator for the various df_ref types.  */
 enum df_ref_class {DF_REF_BASE, DF_REF_ARTIFICIAL, DF_REF_REGULAR};
 
-/* The first of these us a set of a registers.  The remaining three

+/* The first of these uses a set of a registers.  The remaining three

    are all uses of a register (the mem_load and mem_store relate to
    how the register as an addressing operand).  */
 enum df_ref_type {DF_REF_REG_DEF, DF_REF_REG_USE,
@@ -545,16 +545,17 @@  struct df_d

 
   int num_problems_defined;
 
-  bitmap_head hardware_regs_used;     /* The set of hardware registers used.  */

+  HARD_REG_SET hardware_regs_used;     /* The set of hardware registers used.  */

   /* The set of hard regs that are in the artificial uses at the end
      of a regular basic block.  */
-  bitmap_head regular_block_artificial_uses;

+  HARD_REG_SET regular_block_artificial_uses;

   /* The set of hard regs that are in the artificial uses at the end
      of a basic block that has an EH pred.  */
-  bitmap_head eh_block_artificial_uses;

+  HARD_REG_SET eh_block_artificial_uses;

   /* The set of hardware registers live on entry to the function.  */
-  bitmap entry_block_defs;

-  bitmap exit_block_uses;        /* The set of hardware registers used in exit block.  */

+  HARD_REG_SET entry_block_defs;

+  /* The set of hardware registers used in exit block.  */

+  HARD_REG_SET exit_block_uses;

 
   /* Insns to delete, rescan or reprocess the notes at next
      df_rescan_all or df_process_deferred_rescans. */
@@ -911,6 +912,7 @@  extern bool df_reg_defined (rtx, rtx);

 extern df_ref df_find_use (rtx, rtx);
 extern bool df_reg_used (rtx, rtx);
 extern void df_worklist_dataflow (struct dataflow *,bitmap, int *, int);
+extern void df_print_hard_reg_set (FILE *f, HARD_REG_SET r);

 extern void df_print_regset (FILE *file, bitmap r);
 extern void df_print_word_regset (FILE *file, bitmap r);
 extern void df_dump (FILE *);

=== modified file 'gcc/doc/tm.texi'
--- gcc/doc/tm.texi	2011-10-20 20:10:05 +0000

+++ gcc/doc/tm.texi	2011-10-23 21:13:15 +0000

@@ -4946,7 +4946,7 @@  as the @code{sibcall} md pattern can not

 may vary greatly between different architectures.
 @end deftypefn
 
-@deftypefn {Target Hook} void TARGET_EXTRA_LIVE_ON_ENTRY (bitmap @var{regs})

+@deftypefn {Target Hook} void TARGET_EXTRA_LIVE_ON_ENTRY (HARD_REG_SET *@var{regs})

 Add any hard registers to @var{regs} that are live on entry to the
 function.  This hook only needs to be defined to provide registers that
 cannot be found by examination of FUNCTION_ARG_REGNO_P, the callee saved

=== modified file 'gcc/hard-reg-set.h'
--- gcc/hard-reg-set.h	2011-01-03 20:52:22 +0000

+++ gcc/hard-reg-set.h	2011-10-23 21:13:15 +0000

@@ -24,35 +24,31 @@  along with GCC; see the file COPYING3.  

 /* Define the type of a set of hard registers.  */
 
 /* HARD_REG_ELT_TYPE is a typedef of the unsigned integral type which
-   will be used for hard reg sets, either alone or in an array.

-

-   If HARD_REG_SET is a macro, its definition is HARD_REG_ELT_TYPE,

-   and it has enough bits to represent all the target machine's hard

-   registers.  Otherwise, it is a typedef for a suitably sized array

-   of HARD_REG_ELT_TYPEs.  HARD_REG_SET_LONGS is defined as how many.

+   will be used for hard reg sets.  An HARD_REG_ELT_TYPE, or an

+   array of them is wrapped in a struct.

 
    Note that lots of code assumes that the first part of a regset is
    the same format as a HARD_REG_SET.  To help make sure this is true,
    we only try the widest fast integer mode (HOST_WIDEST_FAST_INT)
-   instead of all the smaller types.  This approach loses only if

-   there are very few registers and then only in the few cases where

-   we have an array of HARD_REG_SETs, so it needn't be as complex as

-   it used to be.  */

-

-typedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE;

-

-#if FIRST_PSEUDO_REGISTER <= HOST_BITS_PER_WIDEST_FAST_INT

-

-#define HARD_REG_SET HARD_REG_ELT_TYPE

+   instead of all the smaller types. */

 
+#ifdef ENABLE_RTL_CHECKING

+#define gcc_rtl_assert(EXPR) gcc_assert (EXPR)

 #else
+#define gcc_rtl_assert(EXPR) ((void)(0 && (EXPR)))

+#endif

+

+typedef unsigned HOST_WIDEST_FAST_INT HARD_REG_ELT_TYPE;

 
 #define HARD_REG_SET_LONGS \
  ((FIRST_PSEUDO_REGISTER + HOST_BITS_PER_WIDEST_FAST_INT - 1)	\
   / HOST_BITS_PER_WIDEST_FAST_INT)
-typedef HARD_REG_ELT_TYPE HARD_REG_SET[HARD_REG_SET_LONGS];

 
-#endif

+#define HARD_REG_SET struct hard_reg_set

+

+struct hard_reg_set {

+  HARD_REG_ELT_TYPE elems[HARD_REG_SET_LONGS];

+};

 
 /* HARD_CONST is used to cast a constant to the appropriate type
    for use with a HARD_REG_SET.  */
@@ -89,343 +85,108 @@  typedef HARD_REG_ELT_TYPE HARD_REG_SET[H

    hard_reg_set_intersect_p (X, Y), which returns true if X and Y intersect.
    hard_reg_set_empty_p (X), which returns true if X is empty.  */
 
-#define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT)

 
-#ifdef HARD_REG_SET

+#define HARD_REG_ELT_BITS ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT)

 
 #define SET_HARD_REG_BIT(SET, BIT)  \
- ((SET) |= HARD_CONST (1) << (BIT))

+  hard_reg_set_set_bit (&(SET), (BIT))

 #define CLEAR_HARD_REG_BIT(SET, BIT)  \
- ((SET) &= ~(HARD_CONST (1) << (BIT)))

+  hard_reg_set_clear_bit(&(SET), (BIT))

 #define TEST_HARD_REG_BIT(SET, BIT)  \
- (!!((SET) & (HARD_CONST (1) << (BIT))))

-

-#define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0))

-#define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0))

-

-#define COPY_HARD_REG_SET(TO, FROM) ((TO) = (FROM))

-#define COMPL_HARD_REG_SET(TO, FROM) ((TO) = ~(FROM))

-

-#define IOR_HARD_REG_SET(TO, FROM) ((TO) |= (FROM))

-#define IOR_COMPL_HARD_REG_SET(TO, FROM) ((TO) |= ~ (FROM))

-#define AND_HARD_REG_SET(TO, FROM) ((TO) &= (FROM))

-#define AND_COMPL_HARD_REG_SET(TO, FROM) ((TO) &= ~ (FROM))

-

-static inline bool

-hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)

-{

-  return (x & ~y) == HARD_CONST (0);

-}

+  hard_reg_set_bit_p((SET), (BIT))

 
-static inline bool

-hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)

-{

-  return x == y;

-}

-

-static inline bool

-hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)

-{

-  return (x & y) != HARD_CONST (0);

-}

-

-static inline bool

-hard_reg_set_empty_p (const HARD_REG_SET x)

+static inline void

+hard_reg_set_set_bit (HARD_REG_SET *s, unsigned int bit)

 {
-  return x == HARD_CONST (0);

-}

-

+#if HARD_REG_SET_LONGS > 1

+  int word = bit / HARD_REG_ELT_BITS;

+  int bitpos = bit % HARD_REG_ELT_BITS;

 #else
-

-#define SET_HARD_REG_BIT(SET, BIT)		\

-  ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT]	\

-   |= HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))

-

-#define CLEAR_HARD_REG_BIT(SET, BIT)		\

-  ((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT]	\

-   &= ~(HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT)))

-

-#define TEST_HARD_REG_BIT(SET, BIT)		\

-  (!!((SET)[(BIT) / UHOST_BITS_PER_WIDE_INT]	\

-      & (HARD_CONST (1) << ((BIT) % UHOST_BITS_PER_WIDE_INT))))

-

-#if FIRST_PSEUDO_REGISTER <= 2*HOST_BITS_PER_WIDEST_FAST_INT

-#define CLEAR_HARD_REG_SET(TO)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\

-     scan_tp_[0] = 0;						\

-     scan_tp_[1] = 0; } while (0)

-

-#define SET_HARD_REG_SET(TO)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\

-     scan_tp_[0] = -1;						\

-     scan_tp_[1] = -1; } while (0)

-

-#define COPY_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);	\

-     scan_tp_[0] = scan_fp_[0];					\

-     scan_tp_[1] = scan_fp_[1]; } while (0)

-

-#define COMPL_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] = ~ scan_fp_[0];				\

-     scan_tp_[1] = ~ scan_fp_[1]; } while (0)

-

-#define AND_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] &= scan_fp_[0];				\

-     scan_tp_[1] &= scan_fp_[1]; } while (0)

-

-#define AND_COMPL_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] &= ~ scan_fp_[0];				\

-     scan_tp_[1] &= ~ scan_fp_[1]; } while (0)

-

-#define IOR_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] |= scan_fp_[0];				\

-     scan_tp_[1] |= scan_fp_[1]; } while (0)

-

-#define IOR_COMPL_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] |= ~ scan_fp_[0];				\

-     scan_tp_[1] |= ~ scan_fp_[1]; } while (0)

-

-static inline bool

-hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)

-{

-  return (x[0] & ~y[0]) == 0 && (x[1] & ~y[1]) == 0;

-}

-

-static inline bool

-hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)

-{

-  return x[0] == y[0] && x[1] == y[1];

-}

-

-static inline bool

-hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)

-{

-  return (x[0] & y[0]) != 0 || (x[1] & y[1]) != 0;

+  int word = 0;

+  int bitpos = bit;

+#endif

+  gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER);

+  (s->elems)[word] |= HARD_CONST (1) << bitpos;

 }
 
-static inline bool

-hard_reg_set_empty_p (const HARD_REG_SET x)

+static inline void

+hard_reg_set_clear_bit (HARD_REG_SET *s, unsigned int bit)

 {
-  return x[0] == 0 && x[1] == 0;

-}

-

+#if HARD_REG_SET_LONGS > 1

+  int word = bit / HARD_REG_ELT_BITS;

+  int bitpos = bit % HARD_REG_ELT_BITS;

 #else
-#if FIRST_PSEUDO_REGISTER <= 3*HOST_BITS_PER_WIDEST_FAST_INT

-#define CLEAR_HARD_REG_SET(TO)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\

-     scan_tp_[0] = 0;						\

-     scan_tp_[1] = 0;						\

-     scan_tp_[2] = 0; } while (0)

-

-#define SET_HARD_REG_SET(TO)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\

-     scan_tp_[0] = -1;						\

-     scan_tp_[1] = -1;						\

-     scan_tp_[2] = -1; } while (0)

-

-#define COPY_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);	\

-     scan_tp_[0] = scan_fp_[0];					\

-     scan_tp_[1] = scan_fp_[1];					\

-     scan_tp_[2] = scan_fp_[2]; } while (0)

-

-#define COMPL_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] = ~ scan_fp_[0];				\

-     scan_tp_[1] = ~ scan_fp_[1];				\

-     scan_tp_[2] = ~ scan_fp_[2]; } while (0)

-

-#define AND_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] &= scan_fp_[0];				\

-     scan_tp_[1] &= scan_fp_[1];				\

-     scan_tp_[2] &= scan_fp_[2]; } while (0)

-

-#define AND_COMPL_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] &= ~ scan_fp_[0];				\

-     scan_tp_[1] &= ~ scan_fp_[1];				\

-     scan_tp_[2] &= ~ scan_fp_[2]; } while (0)

-

-#define IOR_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] |= scan_fp_[0];				\

-     scan_tp_[1] |= scan_fp_[1];				\

-     scan_tp_[2] |= scan_fp_[2]; } while (0)

-

-#define IOR_COMPL_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] |= ~ scan_fp_[0];				\

-     scan_tp_[1] |= ~ scan_fp_[1];				\

-     scan_tp_[2] |= ~ scan_fp_[2]; } while (0)

-

-static inline bool

-hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)

-{

-  return ((x[0] & ~y[0]) == 0

-	  && (x[1] & ~y[1]) == 0

-	  && (x[2] & ~y[2]) == 0);

-}

-

-static inline bool

-hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)

-{

-  return x[0] == y[0] && x[1] == y[1] && x[2] == y[2];

-}

-

-static inline bool

-hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)

-{

-  return ((x[0] & y[0]) != 0

-	  || (x[1] & y[1]) != 0

-	  || (x[2] & y[2]) != 0);

+  int word = 0;

+  int bitpos = bit;

+#endif

+  gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER);

+  (s->elems)[word] &= ~(HARD_CONST (1) << bitpos);

 }
 
 static inline bool
-hard_reg_set_empty_p (const HARD_REG_SET x)

+hard_reg_set_bit_p (const HARD_REG_SET s, unsigned int bit)

 {
-  return x[0] == 0 && x[1] == 0 && x[2] == 0;

-}

-

+#if HARD_REG_SET_LONGS > 1

+  int word = bit / HARD_REG_ELT_BITS;

+  int bitpos = bit % HARD_REG_ELT_BITS;

 #else
-#if FIRST_PSEUDO_REGISTER <= 4*HOST_BITS_PER_WIDEST_FAST_INT

-#define CLEAR_HARD_REG_SET(TO)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\

-     scan_tp_[0] = 0;						\

-     scan_tp_[1] = 0;						\

-     scan_tp_[2] = 0;						\

-     scan_tp_[3] = 0; } while (0)

-

-#define SET_HARD_REG_SET(TO)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\

-     scan_tp_[0] = -1;						\

-     scan_tp_[1] = -1;						\

-     scan_tp_[2] = -1;						\

-     scan_tp_[3] = -1; } while (0)

-

-#define COPY_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);	\

-     scan_tp_[0] = scan_fp_[0];					\

-     scan_tp_[1] = scan_fp_[1];					\

-     scan_tp_[2] = scan_fp_[2];					\

-     scan_tp_[3] = scan_fp_[3]; } while (0)

-

-#define COMPL_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] = ~ scan_fp_[0];				\

-     scan_tp_[1] = ~ scan_fp_[1];				\

-     scan_tp_[2] = ~ scan_fp_[2];				\

-     scan_tp_[3] = ~ scan_fp_[3]; } while (0)

-

-#define AND_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] &= scan_fp_[0];				\

-     scan_tp_[1] &= scan_fp_[1];				\

-     scan_tp_[2] &= scan_fp_[2];				\

-     scan_tp_[3] &= scan_fp_[3]; } while (0)

-

-#define AND_COMPL_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] &= ~ scan_fp_[0];				\

-     scan_tp_[1] &= ~ scan_fp_[1];				\

-     scan_tp_[2] &= ~ scan_fp_[2];				\

-     scan_tp_[3] &= ~ scan_fp_[3]; } while (0)

-

-#define IOR_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] |= scan_fp_[0];				\

-     scan_tp_[1] |= scan_fp_[1];				\

-     scan_tp_[2] |= scan_fp_[2];				\

-     scan_tp_[3] |= scan_fp_[3]; } while (0)

-

-#define IOR_COMPL_HARD_REG_SET(TO, FROM)  \

-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

-     scan_tp_[0] |= ~ scan_fp_[0];				\

-     scan_tp_[1] |= ~ scan_fp_[1];				\

-     scan_tp_[2] |= ~ scan_fp_[2];				\

-     scan_tp_[3] |= ~ scan_fp_[3]; } while (0)

-

-static inline bool

-hard_reg_set_subset_p (const HARD_REG_SET x, const HARD_REG_SET y)

-{

-  return ((x[0] & ~y[0]) == 0

-	  && (x[1] & ~y[1]) == 0

-	  && (x[2] & ~y[2]) == 0

-	  && (x[3] & ~y[3]) == 0);

-}

-

-static inline bool

-hard_reg_set_equal_p (const HARD_REG_SET x, const HARD_REG_SET y)

-{

-  return x[0] == y[0] && x[1] == y[1] && x[2] == y[2] && x[3] == y[3];

-}

-

-static inline bool

-hard_reg_set_intersect_p (const HARD_REG_SET x, const HARD_REG_SET y)

-{

-  return ((x[0] & y[0]) != 0

-	  || (x[1] & y[1]) != 0

-	  || (x[2] & y[2]) != 0

-	  || (x[3] & y[3]) != 0);

-}

-

-static inline bool

-hard_reg_set_empty_p (const HARD_REG_SET x)

-{

-  return x[0] == 0 && x[1] == 0 && x[2] == 0 && x[3] == 0;

+  int word = 0;

+  int bitpos = bit;

+#endif

+  gcc_rtl_assert (bit < FIRST_PSEUDO_REGISTER);

+  return ((s.elems[word] >> bitpos) & HARD_CONST (1));

 }
 
-#else /* FIRST_PSEUDO_REGISTER > 4*HOST_BITS_PER_WIDEST_FAST_INT */

-

 #define CLEAR_HARD_REG_SET(TO)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\

+do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems;			\

      int i;							\
      for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
        *scan_tp_++ = 0; } while (0)
 
 #define SET_HARD_REG_SET(TO)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO);			\

+do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems;			\

      int i;							\
      for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
        *scan_tp_++ = -1; } while (0)
 
 #define COPY_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

+do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems;			\

+     HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems;	        \

      int i;							\
      for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
        *scan_tp_++ = *scan_fp_++; } while (0)
 
 #define COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

+do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems;			\

+     HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems;	        \

      int i;							\
      for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
        *scan_tp_++ = ~ *scan_fp_++; } while (0)
 
 #define AND_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

+do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems;			\

+     HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems;	        \

      int i;							\
      for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
        *scan_tp_++ &= *scan_fp_++; } while (0)
 
 #define AND_COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

+do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems;			\

+     HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems;	        \

      int i;							\
      for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
        *scan_tp_++ &= ~ *scan_fp_++; } while (0)
 
 #define IOR_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

+do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems;			\

+     HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems;	        \

      int i;							\
      for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
        *scan_tp_++ |= *scan_fp_++; } while (0)
 
 #define IOR_COMPL_HARD_REG_SET(TO, FROM)  \
-do { HARD_REG_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM); 	\

+do { HARD_REG_ELT_TYPE *scan_tp_ = (TO).elems;			\

+     HARD_REG_ELT_TYPE *scan_fp_ = (FROM).elems;	        \

      int i;							\
      for (i = 0; i < HARD_REG_SET_LONGS; i++)			\
        *scan_tp_++ |= ~ *scan_fp_++; } while (0)
@@ -436,7 +197,7 @@  hard_reg_set_subset_p (const HARD_REG_SE

   int i;
 
   for (i = 0; i < HARD_REG_SET_LONGS; i++)
-    if ((x[i] & ~y[i]) != 0)

+    if ((x.elems[i] & ~y.elems[i]) != 0)

       return false;
   return true;
 }
@@ -447,7 +208,7 @@  hard_reg_set_equal_p (const HARD_REG_SET

   int i;
 
   for (i = 0; i < HARD_REG_SET_LONGS; i++)
-    if (x[i] != y[i])

+    if (x.elems[i] != y.elems[i])

       return false;
   return true;
 }
@@ -458,7 +219,7 @@  hard_reg_set_intersect_p (const HARD_REG

   int i;
 
   for (i = 0; i < HARD_REG_SET_LONGS; i++)
-    if ((x[i] & y[i]) != 0)

+    if ((x.elems[i] & y.elems[i]) != 0)

       return true;
   return false;
 }
@@ -469,26 +230,19 @@  hard_reg_set_empty_p (const HARD_REG_SET

   int i;
 
   for (i = 0; i < HARD_REG_SET_LONGS; i++)
-    if (x[i] != 0)

+    if (x.elems[i] != 0)

       return false;
   return true;
 }
 
-#endif

-#endif

-#endif

-#endif

 
 /* Iterator for hard register sets.  */
 
 typedef struct
 {
-  /* Pointer to the current element.  */

+  /* Pointer to the array of elements.  */

   HARD_REG_ELT_TYPE *pelt;
 
-  /* The length of the set.  */

-  unsigned short length;

-

   /* Word within the current element.  */
   unsigned short word_no;
 
@@ -498,42 +252,32 @@  typedef struct

   HARD_REG_ELT_TYPE bits;
 } hard_reg_set_iterator;
 
-#define HARD_REG_ELT_BITS UHOST_BITS_PER_WIDE_INT

-

 /* The implementation of the iterator functions is fully analogous to
    the bitmap iterators.  */
 static inline void
-hard_reg_set_iter_init (hard_reg_set_iterator *iter, HARD_REG_SET set,

+hard_reg_set_iter_init (hard_reg_set_iterator *iter, HARD_REG_SET *set,

                         unsigned min, unsigned *regno)
 {
-#ifdef HARD_REG_SET_LONGS

-  iter->pelt = set;

-  iter->length = HARD_REG_SET_LONGS;

-#else

-  iter->pelt = &set;

-  iter->length = 1;

-#endif

+  gcc_rtl_assert (min < FIRST_PSEUDO_REGISTER);

   iter->word_no = min / HARD_REG_ELT_BITS;
-  if (iter->word_no < iter->length)

-    {

-      iter->bits = iter->pelt[iter->word_no];

-      iter->bits >>= min % HARD_REG_ELT_BITS;

+  gcc_rtl_assert (iter->word_no < HARD_REG_SET_LONGS);

+  iter->pelt = &(set->elems[0]);

+

+  iter->bits = iter->pelt[iter->word_no];

+  iter->bits >>= min % HARD_REG_ELT_BITS;

+

+  /* This is required for correct search of the next bit.  */

+  min += !iter->bits;

 
-      /* This is required for correct search of the next bit.  */

-      min += !iter->bits;

-    }

   *regno = min;
 }
 
 static inline bool
 hard_reg_set_iter_set (hard_reg_set_iterator *iter, unsigned *regno)
 {
-  while (1)

+  /* Return false when we're advanced past the end of the set.  */

+  while (iter->word_no < HARD_REG_SET_LONGS)

     {
-      /* Return false when we're advanced past the end of the set.  */

-      if (iter->word_no >= iter->length)

-        return false;

-

       if (iter->bits)
         {
           /* Find the correct bit and return it.  */
@@ -550,7 +294,7 @@  hard_reg_set_iter_set (hard_reg_set_iter

       *regno -= *regno % HARD_REG_ELT_BITS;
 
       /* Find the next non-zero word.  */
-      while (++iter->word_no < iter->length)

+      while (++iter->word_no < HARD_REG_SET_LONGS)

         {
           iter->bits = iter->pelt[iter->word_no];
           if (iter->bits)
@@ -558,6 +302,7 @@  hard_reg_set_iter_set (hard_reg_set_iter

           *regno += HARD_REG_ELT_BITS;
         }
     }
+  return false;

 }
 
 static inline void
@@ -568,7 +313,7 @@  hard_reg_set_iter_next (hard_reg_set_ite

 }
 
 #define EXECUTE_IF_SET_IN_HARD_REG_SET(SET, MIN, REGNUM, ITER)          \
-  for (hard_reg_set_iter_init (&(ITER), (SET), (MIN), &(REGNUM));       \

+  for (hard_reg_set_iter_init (&(ITER), &(SET), (MIN), &(REGNUM));       \

        hard_reg_set_iter_set (&(ITER), &(REGNUM));                      \
        hard_reg_set_iter_next (&(ITER), &(REGNUM)))
 

=== modified file 'gcc/reginfo.c'
--- gcc/reginfo.c	2011-07-19 22:34:31 +0000

+++ gcc/reginfo.c	2011-10-23 21:13:15 +0000

@@ -90,14 +90,6 @@  char global_regs[FIRST_PSEUDO_REGISTER];

 /* Declaration for the global register. */
 static tree GTY(()) global_regs_decl[FIRST_PSEUDO_REGISTER];
 
-/* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used

-   in dataflow more conveniently.  */

-regset regs_invalidated_by_call_regset;

-

-/* The bitmap_obstack is used to hold some static variables that

-   should not be reset after each function is compiled.  */

-static bitmap_obstack persistent_obstack;

-

 /* Used to initialize reg_alloc_order.  */
 #ifdef REG_ALLOC_ORDER
 static int initial_reg_alloc_order[FIRST_PSEUDO_REGISTER] = REG_ALLOC_ORDER;
@@ -444,13 +436,6 @@  init_reg_sets_1 (void)

   CLEAR_HARD_REG_SET (call_used_reg_set);
   CLEAR_HARD_REG_SET (call_fixed_reg_set);
   CLEAR_HARD_REG_SET (regs_invalidated_by_call);
-  if (!regs_invalidated_by_call_regset)

-    {

-      bitmap_obstack_initialize (&persistent_obstack);

-      regs_invalidated_by_call_regset = ALLOC_REG_SET (&persistent_obstack);

-    }

-  else

-    CLEAR_REG_SET (regs_invalidated_by_call_regset);

 
   for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
     {
@@ -480,10 +465,7 @@  init_reg_sets_1 (void)

       if (i == STACK_POINTER_REGNUM)
 	;
       else if (global_regs[i])
-        {

 	  SET_HARD_REG_BIT (regs_invalidated_by_call, i);
-	  SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i);

-	}

       else if (i == FRAME_POINTER_REGNUM)
 	;
 #if !HARD_FRAME_POINTER_IS_FRAME_POINTER
@@ -498,10 +480,7 @@  init_reg_sets_1 (void)

 	       && i == (unsigned) PIC_OFFSET_TABLE_REGNUM && fixed_regs[i])
 	;
       else if (CALL_REALLY_USED_REGNO_P (i))
-        {

 	  SET_HARD_REG_BIT (regs_invalidated_by_call, i);
-	  SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i);

-        }

     }
 
   COPY_HARD_REG_SET(call_fixed_reg_set, fixed_reg_set);
@@ -862,10 +841,7 @@  globalize_reg (tree decl, int i)

      appropriate regs_invalidated_by_call bit, even if it's already
      set in fixed_regs.  */
   if (i != STACK_POINTER_REGNUM)
-    {

       SET_HARD_REG_BIT (regs_invalidated_by_call, i);
-      SET_REGNO_REG_SET (regs_invalidated_by_call_regset, i);

-    }

 
   /* If already fixed, nothing else to do.  */
   if (fixed_regs[i])

=== modified file 'gcc/regset.h'
--- gcc/regset.h	2010-05-22 21:24:53 +0000

+++ gcc/regset.h	2011-10-23 21:13:15 +0000

@@ -110,11 +110,6 @@  typedef bitmap_iterator reg_set_iterator

 #define EXECUTE_IF_AND_IN_REG_SET(REGSET1, REGSET2, MIN, REGNUM, RSI) \
   EXECUTE_IF_AND_IN_BITMAP (REGSET1, REGSET2, MIN, REGNUM, RSI)	\
 
-/* Same information as REGS_INVALIDATED_BY_CALL but in regset form to be used

-   in dataflow more conveniently.  */

-

-extern regset regs_invalidated_by_call_regset;

-

 /* An obstack for regsets.  */
 extern bitmap_obstack reg_obstack;
 

=== modified file 'gcc/reorg.c'
--- gcc/reorg.c	2011-10-15 10:32:33 +0000

+++ gcc/reorg.c	2011-10-23 21:28:05 +0000

@@ -293,18 +293,7 @@  resource_conflicts_p (struct resources *

       || res1->volatil || res2->volatil)
     return 1;
 
-#ifdef HARD_REG_SET

-  return (res1->regs & res2->regs) != HARD_CONST (0);

-#else

-  {

-    int i;

-

-    for (i = 0; i < HARD_REG_SET_LONGS; i++)

-      if ((res1->regs[i] & res2->regs[i]) != 0)

-	return 1;

-    return 0;

-  }

-#endif

+  return hard_reg_set_intersect_p(res1->regs, res2->regs);

 }
 
 /* Return TRUE if any resource marked in RES, a `struct resources', is

=== modified file 'gcc/target.def'
--- gcc/target.def	2011-10-20 20:10:05 +0000

+++ gcc/target.def	2011-10-23 21:13:15 +0000

@@ -2598,8 +2598,8 @@  HOOK_VECTOR_END (target_option)

 DEFHOOK
 (extra_live_on_entry,
  "",
- void, (bitmap regs),

- hook_void_bitmap)

+ void, (HARD_REG_SET *regs),

+ hook_void_hard_reg_set)

 
 /* Determine the type of unwind info to emit for debugging.  */
 DEFHOOK

=== modified file 'gcc/target.h'
--- gcc/target.h	2011-06-16 13:45:47 +0000

+++ gcc/target.h	2011-10-23 21:13:15 +0000

@@ -52,6 +52,11 @@ 

 
 #include "insn-modes.h"
 
+/* We can't include target-dependant hard-reg-set.h thus the opaque struct */

+struct hard_reg_set;

+

+#define HARD_REG_SET struct hard_reg_set

+

 #ifdef ENABLE_CHECKING
 
 typedef struct { void *magic; void *p; } cumulative_args_t;

=== modified file 'gcc/targhooks.c'
--- gcc/targhooks.c	2011-10-06 19:25:53 +0000

+++ gcc/targhooks.c	2011-10-23 21:13:15 +0000

@@ -607,7 +607,7 @@  default_function_arg_round_boundary (enu

 }
 
 void
-hook_void_bitmap (bitmap regs ATTRIBUTE_UNUSED)

+hook_void_hard_reg_set (HARD_REG_SET *regs ATTRIBUTE_UNUSED)

 {
 }
 

=== modified file 'gcc/targhooks.h'
--- gcc/targhooks.h	2011-10-06 19:25:53 +0000

+++ gcc/targhooks.h	2011-10-23 21:13:15 +0000

@@ -128,7 +128,7 @@  extern reg_class_t default_secondary_rel

 					     enum machine_mode,
 					     secondary_reload_info *);
 extern void default_target_option_override (void);
-extern void hook_void_bitmap (bitmap);

+extern void hook_void_hard_reg_set (HARD_REG_SET *);

 extern int default_reloc_rw_mask (void);
 extern tree default_mangle_decl_assembler_name (tree, tree);
 extern tree default_emutls_var_fields (tree, tree *);