Patchwork repost: [DF] Use HARD_REG_SETs instead of bitmaps

login
register
mail settings
Submitter Dimitrios Apostolou
Date Aug. 22, 2011, 5:16 p.m.
Message ID <alpine.LNX.2.02.1108221923570.1374@localhost.localdomain>
Download mbox | patch
Permalink /patch/110965/
State New
Headers show

Comments

Dimitrios Apostolou - Aug. 22, 2011, 5:16 p.m.
Hello,

This is the latest version of a previously posted patch that converts 
several bitmaps in DF to HARD_REG_SETs. It adds only some small 
fixes/style issues.

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?

Besides testing, I will also update this patch to current trunk, expect 
this in about a week or so.

Paolo, Jakub, this version has HARD_REG_SET defined as a struct. I'm not 
sure I understand where our discussion concluded so I left this one that I 
like since it simplifies code a lot. If I don't measure runtime overhead 
on alternative archs (which ones?) do you think it's OK? Have I forgotten 
to try any cases?


2011-07-27  Dimitrios Apostolou  <jimis@gmx.net>

 	* DataFlow: Use HARD_REG_SETs instead of bitmaps where we are
 	certain that we don't map regs above FIRST_PSEUDO_REGISTER.
 	Detailed changelog follows.

 	* regset.h:   Eliminated regs_invalidated_by_call_regset bitmap,
 	use instead the original regs_invalidated_by_call HARD_REG_SET.
 	* reginfo.c (initial_reg_alloc_order, init_reg_sets_1)
 	(globalize_reg): Eliminate all initialising and handling of
 	regs_invalidated_by_call_regset.
 	* df.h: changed the following variables from bitmaps to
 	HARD_REG_SETs: hardware_regs_used, regular_block_artificial_uses,
 	eh_block_artificial_uses, entry_block_defs,
 	exit_block_uses. Declared new function df_print_hard_reg_set.
 	* target.def: removed hook_void_bitmap, added
 	hook_void_hard_reg_set to be used by TARGET_EXTRA_LIVE_ON_ENTRY.
 	* target.h: Defined HARD_REG_SET as opaque struct.
 	* targhooks.h, targhooks.c: Removed hook_void_bitmap, added
 	hook_void_hard_reg_set.
 	* i386.c (ix86_live_on_entry), mips.c (mips_extra_live_on_entry),
 	pa.c (pa_extra_live_on_entry) : changed argument from bitmap to
 	HARD_REG_SET *, also changed relevant set_bit operations.
 	* tm.texi: Documented type of TARGET_EXTRA_LIVE_ON_ENTRY is now
 	HARD_REG_SET * instead of bitmap.
 	* dce.c (dce_process_block, fast_dce):
 	* df-core.c (df_print_hard_reg_set): new function to print
 	HARD_REG_SET to file.
 	* df-problems.c (df_rd_local_compute, df_lr_local_compute)
 	(df_lr_confluence_0, df_lr_confluence_n, df_word_lr_local_compute)
 	(df_simulate_fixup_sets, df_md_confluence_n): replaced old bitmap
 	operations with HARD_REG_SET ones, appropriate for new types.
 	(df_word_lr_local_compute): eliminated unreachable code.
 	(bitmap_copy_from_hard_reg_set, bitmap_ior_from_hard_reg_set)
 	(bitmap_ior_and_compl_from_hard_reg_set): new functions for
 	operations between bitmaps and hard_reg_sets.
 	* df-scan.c: regs_ever_live converted from bool array to
 	HARD_REG_SET.
 	(df_regs_ever_live_p, df_set_regs_ever_live)
 	(df_compute_regs_ever_live, ): use HARD_REG_SET_BIT,
 	HARD_REG_CLEAR_BIT and HARD_REG_TEST_BIT instead of bitmap
 	operations, to access regs_ever_live.
 	(df_scan_free_internal, df_scan_alloc)
 	(df_scan_start_dump, df_scan_blocks, df_get_call_refs)
 	(df_bb_refs_collect, df_get_regular_block_artificial_uses)
 	(df_get_regular_block_artificial_uses)
 	(df_get_eh_block_artificial_uses, df_mark_reg)
 	(df_get_entry_block_def_set, df_entry_block_defs_collect)
 	(df_record_entry_block_defs, df_update_entry_block_defs)
 	(df_get_exit_block_use_set, df_exit_block_uses_collect)
 	(df_record_exit_block_uses, df_update_exit_block_uses)
 	(df_entry_block_bitmap_verify, df_exit_block_bitmap_verify)
 	(df_scan_verify): use HARD_REG_SET operations instead of bitmap
 	ones to access changed types.
 	(df_update_entry_block_defs, df_update_exit_block_uses):
 	eliminate some dead code.

 	* hard-reg-set.h : HARD_REG_SET is now always a struct containing
 	an array of longs, so that it can be used in files where we don't
 	want to include tm.h. Removed duplicate versions of most
 	functions.
 	(gcc_rtl_assert): New macro.
         (TEST_HARD_REG_BIT, SET_HARD_REG_BIT)
         (CLEAR_HARD_REG_BIT): Define independent of HARD_REG_SET,
         forwarding to...
         (hard_reg_set_set_bit, hard_reg_set_clear_bit)
 	(hard_reg_set_bit_p): ... these new functions.  Add range
 	assertions on bit argument enabled when --enable-checking=rtl.



Thanks,
Dimitris
Jeff Law - Aug. 22, 2011, 5:18 p.m.
-----BEGIN PGP SIGNED MESSAGE-----
Hash: SHA1

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.

jeff
-----BEGIN PGP SIGNATURE-----
Version: GnuPG v1.4.11 (GNU/Linux)
Comment: Using GnuPG with Mozilla - http://enigmail.mozdev.org/

iQEcBAEBAgAGBQJOUo9iAAoJEBRtltQi2kC7qLsH/RDhJIi0iK4WSYIyGk/KiG15
4m/1vJzCN0u2E0Aw92ArpQtzFSU3/wMvLJFvJMZQcyWKJ73H0Ri0k81POCXBnEmd
nMDoQ8/T1xXTyYRCrnh7Y4ZuVxAhXUqL2V5ONnfiayqCR+z5jeKPZGu9GOStPGhI
ysGP+rzSQAwgCF9lrXgy7+zaetnK230BmNw4P5C/yLYhySP5zTTEZ3e1JCCHWSbt
fg2Hjt7FKHdzgeSs9X8LpUCZd2QWFDaunlYzOJTrrDj1TatIz9WL+e7NH3+gsrQ9
enL8+CKUeOE63zKOfvarHw3ucxHZn8hYZriCZzdB+RbKnoikCjWCNnGdH8pDj6c=
=qSqA
-----END PGP SIGNATURE-----

Patch

=== modified file 'gcc/config/i386/i386.c'
--- gcc/config/i386/i386.c	2011-06-02 17:43:22 +0000

+++ gcc/config/i386/i386.c	2011-08-22 15:41:12 +0000

@@ -11597,12 +11597,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-05-29 17:41:50 +0000

+++ gcc/config/mips/mips.c	2011-08-22 15:41:12 +0000

@@ -9414,22 +9414,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-05-25 11:00:14 +0000

+++ gcc/config/pa/pa.c	2011-08-22 15:41:12 +0000

@@ -172,7 +172,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);
@@ -5964,10 +5964,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-06-06 13:25:06 +0000

+++ gcc/dce.c	2011-08-22 15:41:12 +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-08-22 15:41:12 +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-05-04 20:24:15 +0000

+++ gcc/df-problems.c	2011-08-22 15:41:12 +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
@@ -908,20 +934,20 @@  df_lr_local_compute (bitmap all_blocks A

     {
       /* 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 ((unsigned) 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)
@@ -931,7 +957,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);
@@ -966,9 +992,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.  */
 
@@ -983,11 +1032,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;
 }
 
@@ -2506,19 +2556,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);
 }
@@ -3629,9 +3670,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);

 }
 
 
@@ -4450,8 +4491,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-02-02 20:08:06 +0000

+++ gcc/df-scan.c	2011-08-22 15:41:12 +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));
@@ -3317,20 +3322,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.  */
@@ -3345,7 +3350,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);
 	    }
@@ -3375,12 +3380,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],
@@ -3388,7 +3393,6 @@  df_get_call_refs (struct df_collection_r

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

   return;
 }
 
@@ -3534,13 +3538,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);
@@ -3607,18 +3611,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
@@ -3627,27 +3631,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 ((unsigned) PIC_OFFSET_TABLE_REGNUM != INVALID_REGNUM
 	  && fixed_regs[PIC_OFFSET_TABLE_REGNUM])
-	bitmap_set_bit (regular_block_artificial_uses, PIC_OFFSET_TABLE_REGNUM);

+	SET_HARD_REG_BIT (*regular_block_artificial_uses, PIC_OFFSET_TABLE_REGNUM);

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

+  SET_HARD_REG_BIT (*regular_block_artificial_uses, STACK_POINTER_REGNUM);

 
 #ifdef EH_USES
   /* EH_USES registers are used:
@@ -3660,7 +3664,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
 }
 
@@ -3668,9 +3672,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
@@ -3680,14 +3684,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
     }
 }
@@ -3705,7 +3709,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);
@@ -3713,35 +3717,40 @@  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))
 #ifdef INCOMING_REGNO
-	bitmap_set_bit (entry_block_defs, INCOMING_REGNO (i));

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

 #else
-	bitmap_set_bit (entry_block_defs, i);

+	SET_HARD_REG_BIT (*entry_block_defs, i);

 #endif
     }
 
   /* 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.  */
@@ -3751,28 +3760,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
     }
 
@@ -3783,7 +3792,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
@@ -3791,13 +3800,13 @@  df_get_entry_block_def_set (bitmap entry

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

+	SET_HARD_REG_BIT (*entry_block_defs, PIC_OFFSET_TABLE_REGNUM);

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

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

 #endif
 
   targetm.extra_live_on_entry (entry_block_defs);
@@ -3811,12 +3820,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);
@@ -3830,15 +3839,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);
 }
 
@@ -3848,52 +3859,34 @@  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;
 
-  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
@@ -3901,11 +3894,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
     }
 
@@ -3915,14 +3908,14 @@  df_get_exit_block_use_set (bitmap exit_b

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

+    SET_HARD_REG_BIT (*exit_block_uses, PIC_OFFSET_TABLE_REGNUM);

 
   /* 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)
     {
@@ -3930,7 +3923,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
@@ -3941,7 +3934,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
 
@@ -3974,12 +3967,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);
 
@@ -3987,7 +3980,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,
@@ -4002,16 +3995,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);
 }
 
@@ -4021,38 +4015,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;
@@ -4141,7 +4117,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);

 }
 
 
@@ -4151,10 +4127,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;
 }
@@ -4170,12 +4150,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)
@@ -4408,26 +4388,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;
 }
 
@@ -4438,26 +4415,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;
 }
 
@@ -4470,8 +4444,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;
@@ -4492,23 +4466,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-08-22 15:41:12 +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-06-03 18:30:39 +0000

+++ gcc/doc/tm.texi	2011-08-22 15:41:12 +0000

@@ -4911,7 +4911,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-08-22 16:10:49 +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,15 +230,11 @@  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.  */
 
@@ -486,9 +243,6 @@  typedef struct

   /* Pointer to the current element.  */
   HARD_REG_ELT_TYPE *pelt;
 
-  /* The length of the set.  */

-  unsigned short length;

-

   /* Word within the current element.  */
   unsigned short word_no;
 
@@ -498,30 +252,26 @@  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,
                         unsigned min, unsigned *regno)
 {
-#ifdef HARD_REG_SET_LONGS

-  iter->pelt = set;

-  iter->length = HARD_REG_SET_LONGS;

+  gcc_rtl_assert (min < FIRST_PSEUDO_REGISTER);

+#if HARD_REG_SET_LONGS > 1

+  iter->word_no = min / HARD_REG_ELT_BITS;

 #else
-  iter->pelt = &set;

-  iter->length = 1;

+  iter->word_no = 0;

 #endif
-  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;

+  iter->pelt = set.elems;

+

+  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;
 }
 
@@ -531,7 +281,7 @@  hard_reg_set_iter_set (hard_reg_set_iter

   while (1)
     {
       /* Return false when we're advanced past the end of the set.  */
-      if (iter->word_no >= iter->length)

+      if (iter->word_no >= HARD_REG_SET_LONGS)

         return false;
 
       if (iter->bits)
@@ -550,7 +300,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)

=== modified file 'gcc/reginfo.c'
--- gcc/reginfo.c	2011-05-01 12:33:13 +0000

+++ gcc/reginfo.c	2011-08-22 15:41:12 +0000

@@ -87,14 +87,6 @@  static const char initial_call_really_us

    and are also considered fixed.  */
 char global_regs[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;
@@ -441,13 +433,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++)
     {
@@ -477,10 +462,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
@@ -495,10 +477,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);
@@ -853,10 +832,7 @@  globalize_reg (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-08-22 15:41:12 +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/target.def'
--- gcc/target.def	2011-06-03 01:41:54 +0000

+++ gcc/target.def	2011-08-22 15:41:12 +0000

@@ -2615,8 +2615,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-04-06 11:08:17 +0000

+++ gcc/target.h	2011-08-22 16:10:49 +0000

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

 #include "tm.h"
 #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

+

 /* Types used by the record_gcc_switches() target function.  */
 typedef enum
 {

=== modified file 'gcc/targhooks.c'
--- gcc/targhooks.c	2011-05-04 12:01:21 +0000

+++ gcc/targhooks.c	2011-08-22 15:41:12 +0000

@@ -615,7 +615,7 @@  default_function_arg_boundary (enum mach

 }
 
 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-04-06 11:08:17 +0000

+++ gcc/targhooks.h	2011-08-22 15:41:12 +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 *);