diff mbox

[RFC] Replace some bitmaps with HARD_REG_SETs

Message ID alpine.LNX.2.02.1107241852140.1374@localhost.localdomain
State New
Headers show

Commit Message

Dimitrios Apostolou July 24, 2011, 4:08 p.m. UTC
Hello all,

attached is my attempt to replace bitmaps, that we are *sure* they will 
never map any pseudo regs, with HARD_REG_SETs. Jakub, I have moved the 
check you suggested, for never surpassing FIRST_PSEUDO_REGS, into 
hard-reg-set.h, that's one of the two patches.

Unfortunately the other patch is a little intrusive and it breaks 
something. I'm out of ideas for some days now, can you spot what's wrong? 
Here is gdb dissecting the breakage:

(gdb) run
Starting program: /mnt/scratch2/jimis/opt/objtmp-gcc-local-co/gcc/xgcc 
-B/home/jimis/dist/opt/objtmp-gcc-local-co/./gcc/ 
-B/usr/local/i686-pc-linux-gnu/bin/ -B/usr/local/i686-pc-linux-gnu/lib/ 
-isystem /usr/local/i686-pc-linux-gnu/include -isystem 
/usr/local/i686-pc-linux-gnu/sys-include -DHAVE_CONFIG_H -I. 
-I/home/jimis/dist/src/gcc-local-co/libgomp 
-I/home/jimis/dist/src/gcc-local-co/libgomp/config/linux/x86 
-I/home/jimis/dist/src/gcc-local-co/libgomp/config/linux 
-I/home/jimis/dist/src/gcc-local-co/libgomp/config/posix 
-I/home/jimis/dist/src/gcc-local-co/libgomp -Wall -Werror 
-ftls-model=initial-exec -march=i486 -pthread -mtune=i686 -O2 -g3 
-march=i686 -mtune=generic -fno-inline -fno-inline-small-functions 
-fno-indirect-inlining -fno-inline-functions -Wno-unused-function -MT 
fortran.lo -MD -MP -MF .deps/fortran.Tpo -c 
/home/jimis/dist/src/gcc-local-co/libgomp/fortran.c -fPIC -DPIC -o 
.libs/fortran.o
[New process 14170]
process 14170 is executing new program: 
/mnt/scratch2/jimis/opt/objtmp-gcc-local-co/gcc/cc1
[Switching to process 14170]

Breakpoint 1, fancy_abort (file=0x8a29e90 
"/home/jimis/dist/src/gcc-local-co/gcc/reg-stack.c", line=2810, 
function=0x8a2a4cc "compensate_edge")
     at /home/jimis/dist/src/gcc-local-co/gcc/diagnostic.c:893
893       internal_error ("in %s, at %s:%d", function, trim_filename 
(file), line);
(gdb) bt
#0  fancy_abort (file=0x8a29e90 
"/home/jimis/dist/src/gcc-local-co/gcc/reg-stack.c", line=2810, 
function=0x8a2a4cc "compensate_edge")
     at /home/jimis/dist/src/gcc-local-co/gcc/diagnostic.c:893
#1  0x083d18d9 in compensate_edge (e=<value optimized out>) at 
/home/jimis/dist/src/gcc-local-co/gcc/reg-stack.c:2810
#2  0x083d1948 in compensate_edges () at 
/home/jimis/dist/src/gcc-local-co/gcc/reg-stack.c:2865
#3  0x083d3c4b in convert_regs () at 
/home/jimis/dist/src/gcc-local-co/gcc/reg-stack.c:3177
#4  0x083d3f6b in reg_to_stack () at 
/home/jimis/dist/src/gcc-local-co/gcc/reg-stack.c:3291
#5  0x083d3f8b in rest_of_handle_stack_regs () at 
/home/jimis/dist/src/gcc-local-co/gcc/reg-stack.c:3333
#6  0x083ac8fa in execute_one_pass (pass=0x8bdb520) at 
/home/jimis/dist/src/gcc-local-co/gcc/passes.c:1899
#7  0x083acb4d in execute_pass_list (pass=0x8bdb520) at 
/home/jimis/dist/src/gcc-local-co/gcc/passes.c:1953
#8  0x083acb60 in execute_pass_list (pass=0x8bdb4e0) at 
/home/jimis/dist/src/gcc-local-co/gcc/passes.c:1954
#9  0x083acb60 in execute_pass_list (pass=0x8bdb200) at 
/home/jimis/dist/src/gcc-local-co/gcc/passes.c:1954
#10 0x083acb60 in execute_pass_list (pass=0x8bdb1c0) at 
/home/jimis/dist/src/gcc-local-co/gcc/passes.c:1954
#11 0x084c88ac in tree_rest_of_compilation (fndecl=0xb7e4c000) at 
/home/jimis/dist/src/gcc-local-co/gcc/tree-optimize.c:417
#12 0x0817ceef in cgraph_expand_function (node=0xb7e4b140) at 
/home/jimis/dist/src/gcc-local-co/gcc/cgraphunit.c:1635
#13 0x0817daf1 in cgraph_expand_all_functions () at 
/home/jimis/dist/src/gcc-local-co/gcc/cgraphunit.c:1694
#14 0x0817e5a9 in cgraph_optimize () at 
/home/jimis/dist/src/gcc-local-co/gcc/cgraphunit.c:1957
#15 0x0817e81e in cgraph_finalize_compilation_unit () at 
/home/jimis/dist/src/gcc-local-co/gcc/cgraphunit.c:1131
#16 0x08067dec in c_write_global_declarations () at 
/home/jimis/dist/src/gcc-local-co/gcc/c-decl.c:9844
#17 0x0844e581 in compile_file () at 
/home/jimis/dist/src/gcc-local-co/gcc/toplev.c:586
#18 0x084507fc in do_compile () at 
/home/jimis/dist/src/gcc-local-co/gcc/toplev.c:1923
#19 0x08450971 in toplev_main (argc=60, argv=0xbfffea54) at 
/home/jimis/dist/src/gcc-local-co/gcc/toplev.c:1995
#20 0x08100bfb in main (argc=60, argv=0xbfffea54) at 
/home/jimis/dist/src/gcc-local-co/gcc/main.c:36
(gdb) frame 1
#1  0x083d18d9 in compensate_edge (e=<value optimized out>) at 
/home/jimis/dist/src/gcc-local-co/gcc/reg-stack.c:2810
2810      gcc_assert (! (e->flags & EDGE_ABNORMAL));



All comments are welcome,
Dimitris
------------------------------------------------------------
revno: 109441 [merge]
committer: Dimitrios Apostolou <jimis@gmx.net>
branch nick: hardregs
timestamp: Sun 2011-07-24 18:10:41 +0300
message:
  Added some asserts in HARD_REG_SET test, set and clear operations
------------------------------------------------------------
Use --include-merges or -n0 to see merged revisions.
------------------------------------------------------------
revno: 109440
committer: Dimitrios Apostolou <jimis@gmx.net>
branch nick: hardregs
timestamp: Sun 2011-07-24 17:23:14 +0300
message:
  Convert several bitmaps to HARD_REG_SETs, because we are sure they are never used for bits above FIRST_PSEUDO_REGISTER
diff:
=== 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-07-24 14:23:14 +0000
@@ -11597,12 +11597,12 @@
    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-07-24 14:23:14 +0000
@@ -9414,22 +9414,22 @@
 /* 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-07-24 14:23:14 +0000
@@ -172,7 +172,7 @@
 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 @@
    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-07-24 14:23:14 +0000
@@ -867,7 +867,7 @@
    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 @@
 	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 @@
   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-07-24 14:23:14 +0000
@@ -1885,6 +1885,17 @@
   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-07-24 14:23:14 +0000
@@ -887,6 +887,31 @@
     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 +921,10 @@
   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 +933,20 @@
     {
       /* 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 +956,7 @@
 	  /* 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,10 +991,9 @@
 {
   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);
 }
 
-
 /* Confluence function that ignores fake edges.  */
 
 static bool
@@ -987,7 +1011,7 @@
   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;
 }
 
@@ -2511,9 +2535,9 @@
       if (bb_index == EXIT_BLOCK)
 	{
 	  unsigned regno;
-	  bitmap_iterator bi;
-	  EXECUTE_IF_SET_IN_BITMAP (df->exit_block_uses, FIRST_PSEUDO_REGISTER,
-				    regno, bi)
+	  hard_reg_set_iterator iter;
+	  EXECUTE_IF_SET_IN_HARD_REG_SET (df->exit_block_uses, FIRST_PSEUDO_REGISTER,
+					  regno, iter)
 	    gcc_unreachable ();
 	}
       else
@@ -3629,9 +3653,9 @@
   /* 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);
 }
 
 

=== modified file 'gcc/df-scan.c'
--- gcc/df-scan.c	2011-02-02 20:08:06 +0000
+++ gcc/df-scan.c	2011-07-24 14:23:14 +0000
@@ -131,13 +131,13 @@
 				  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 @@
 				   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 @@
    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->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 @@
       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 @@
   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_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 @@
                   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 @@
 	  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 @@
 	}
 
   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_REF_MAY_CLOBBER | flags);
     }
 
-  bitmap_clear (&defs_generated);
   return;
 }
 
@@ -3534,13 +3538,13 @@
   /* 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 @@
    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 @@
     {
       /* 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 @@
 	(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 @@
 /* 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 @@
     {
       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 @@
 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 @@
   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<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 @@
 	 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 @@
       /* 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 @@
 	 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,18 +3820,19 @@
 
 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);
     }
 
   df_canonize_collection_rec (collection_rec);
+  /* df_sort_and_compress_refs (&collection_rec->def_vec); */
 }
 
 
@@ -3830,15 +3840,25 @@
    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;
+  /* basic_block bb= BASIC_BLOCK (ENTRY_BLOCK); */
+  /* struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index); */
+  
   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);
-
   /* Process bb_refs chain */
   df_refs_add_to_chains (&collection_rec, BASIC_BLOCK (ENTRY_BLOCK), NULL);
+  /* WARNING THAT CHANGE MEANS WE'LL NEVER ADD ANYTHING FROM use_vec IS IT CORRECT??? */
+  /* df_scan_free_ref_vec (bb_info->artificial_defs); */
+  /* bb_info->artificial_defs */
+  /*   = df_install_refs (bb, collection_rec.def_vec, */
+  /* 		       df->def_regs, */
+  /* 		       &df->def_info, false); */
+
   VEC_free (df_ref, stack, collection_rec.def_vec);
 }
 
@@ -3848,52 +3868,48 @@
 void
 df_update_entry_block_defs (void)
 {
-  bitmap_head refs;
+  HARD_REG_SET refs;
   bool changed = false;
 
-  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
-    {
-      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);
+  /* if (df->entry_block_defs) */
+  /*   { */
+  if (!hard_reg_set_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 */
+  /*   { */
+  /* 	gcc_unreachable (); */
+  /* 	CLEAR_HARD_REG_SET (df->entry_block_defs); */
+  /* 	changed = true; */
+  /*   } */
 
   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 +3917,11 @@
 
   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 +3931,14 @@
   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 +3946,7 @@
       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 +3957,7 @@
 	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
 
@@ -3951,7 +3967,7 @@
     {
       rtx tmp = EH_RETURN_STACKADJ_RTX;
       if (tmp && REG_P (tmp))
-	df_mark_reg (tmp, exit_block_uses);
+	df_mark_reg (tmp, &exit_block_uses);
     }
 #endif
 
@@ -3961,12 +3977,12 @@
     {
       rtx tmp = EH_RETURN_HANDLER_RTX;
       if (tmp && REG_P (tmp))
-	df_mark_reg (tmp, exit_block_uses);
+	df_mark_reg (tmp, &exit_block_uses);
     }
 #endif
 
   /* Mark function return value.  */
-  diddle_return_value (df_mark_reg, (void*) exit_block_uses);
+  diddle_return_value (df_mark_reg, (void*) &exit_block_uses);
 }
 
 
@@ -3974,12 +3990,12 @@
    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 +4003,7 @@
   /* 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,
@@ -3995,6 +4011,7 @@
 #endif
 
   df_canonize_collection_rec (collection_rec);
+  /* df_sort_and_compress_refs (&collection_rec->use_vec); */
 }
 
 
@@ -4002,16 +4019,25 @@
    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;
+  /* basic_block bb= BASIC_BLOCK (ENTRY_BLOCK); */
+  /* struct df_scan_bb_info *bb_info = df_scan_get_bb_info (bb->index); */
+
   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);
+  /* WARNING */
+  /* df_scan_free_ref_vec (bb_info->artificial_uses); */
+  /* bb_info->artificial_uses */
+  /*   = df_install_refs (bb, collection_rec.use_vec, */
+  /* 		       df->use_regs, */
+  /* 		       &df->use_info, false); */
+
   VEC_free (df_ref, stack, collection_rec.use_vec);
 }
 
@@ -4021,38 +4047,34 @@
 void
 df_update_exit_block_uses (void)
 {
-  bitmap_head refs;
+  HARD_REG_SET refs;
   bool changed = false;
 
-  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
-    {
-      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);
+  /* if (df->exit_block_uses) */
+  /*   { */
+  if (!hard_reg_set_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 */
+  /*   { */
+  /*     gcc_unreachable (); */
+  /*     CLEAR_HARD_REG_SET (df->exit_block_uses); */
+  /*     changed = true; */
+  /*   } */
 
   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 +4163,7 @@
 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 +4173,14 @@
 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;
 }
@@ -4173,9 +4199,9 @@
     memset (regs_ever_live, 0, sizeof (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 +4434,23 @@
 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 +4461,23 @@
 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 +4490,8 @@
 {
   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 +4512,18 @@
   /* (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-07-24 14:23:14 +0000
@@ -69,7 +69,7 @@
 /* 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 @@
 
   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 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-07-24 14:23:14 +0000
@@ -4911,7 +4911,7 @@
 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/target.def'
--- gcc/target.def	2011-06-03 01:41:54 +0000
+++ gcc/target.def	2011-07-24 14:23:14 +0000
@@ -2615,8 +2615,8 @@
 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-07-24 14:23:14 +0000
@@ -50,6 +50,7 @@
 #define GCC_TARGET_H
 
 #include "tm.h"
+#include "hard-reg-set.h"
 #include "insn-modes.h"
 
 /* Types used by the record_gcc_switches() target function.  */

=== modified file 'gcc/targhooks.c'
--- gcc/targhooks.c	2011-05-04 12:01:21 +0000
+++ gcc/targhooks.c	2011-07-24 14:23:14 +0000
@@ -615,7 +615,7 @@
 }
 
 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-07-24 14:23:14 +0000
@@ -128,7 +128,7 @@
 					     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 *);

Comments

Steven Bosscher July 24, 2011, 4:43 p.m. UTC | #1
On Sun, Jul 24, 2011 at 6:08 PM, Dimitrios Apostolou <jimis@gmx.net> wrote:
> Hello all,
>
> attached is my attempt to replace bitmaps, that we are *sure* they will
> never map any pseudo regs, with HARD_REG_SETs. Jakub, I have moved the check
> you suggested, for never surpassing FIRST_PSEUDO_REGS, into hard-reg-set.h,
> that's one of the two patches.
>
> Unfortunately the other patch is a little intrusive and it breaks something.
> I'm out of ideas for some days now, can you spot what's wrong?

Hi Jimis,

Can you please create your patches with the -p option, so that it's
easier to see what function you are changing? Also, even for an RFC
patch a ChangeLog is more than just nice to have ;-)

This hunk in df-problems looks odd:

@@ -2511,9 +2535,9 @@
       if (bb_index == EXIT_BLOCK)
 	{
 	  unsigned regno;
-	  bitmap_iterator bi;
-	  EXECUTE_IF_SET_IN_BITMAP (df->exit_block_uses, FIRST_PSEUDO_REGISTER,
-				    regno, bi)

So this EXECUTE_IF_SET_IN_BITMAP starts with FIRST_PSEUDO_REGISTER
(i.e. works on pseudo registers) ...

+	  hard_reg_set_iterator iter;
+	  EXECUTE_IF_SET_IN_HARD_REG_SET (df->exit_block_uses, FIRST_PSEUDO_REGISTER,
+					  regno, iter)
 	    gcc_unreachable ();
 	}
       else

... and you change it to work only on hard registers. That code looked
like a check to verify that exit_block_uses only contains hard
registers. So you can probably just drop this check.

The only suggestion that I can make for now to investigate the ICE in
reg-stack, is to compare the DF info before your patch and after.
Since your patch does not (or rather: should not) change the logic in
DF, the DF info at reg-stack should be the same. Your ICE suggests
that the register allocator has left a stack register live across an
abnormal edge, and that may be due to changed DF info.

Ciao!
Steven
Dimitrios Apostolou July 24, 2011, 4:57 p.m. UTC | #2
Hi Steven,

On Sun, 24 Jul 2011, Steven Bosscher wrote:
> Can you please create your patches with the -p option, so that it's
> easier to see what function you are changing? Also, even for an RFC
> patch a ChangeLog is more than just nice to have ;-)

Do you mean an entry in Changelog file in root directory? I should update 
my tree to latest every time, for my patch to be valid, right?

>
> This hunk in df-problems looks odd:
>
> @@ -2511,9 +2535,9 @@
>       if (bb_index == EXIT_BLOCK)
> 	{
> 	  unsigned regno;
> -	  bitmap_iterator bi;
> -	  EXECUTE_IF_SET_IN_BITMAP (df->exit_block_uses, FIRST_PSEUDO_REGISTER,
> -				    regno, bi)
>
> So this EXECUTE_IF_SET_IN_BITMAP starts with FIRST_PSEUDO_REGISTER
> (i.e. works on pseudo registers) ...
>
> +	  hard_reg_set_iterator iter;
> +	  EXECUTE_IF_SET_IN_HARD_REG_SET (df->exit_block_uses, FIRST_PSEUDO_REGISTER,
> +					  regno, iter)
> 	    gcc_unreachable ();
> 	}
>       else
>
> ... and you change it to work only on hard registers. That code looked
> like a check to verify that exit_block_uses only contains hard
> registers. So you can probably just drop this check.

Thanks for reminding me this, I had indeed removed this check, I just 
didn't commit to my VCS :-)

Should I resend my patch with all the suggestions you made?


Thanks,
Dimitris
diff mbox

Patch

diff:
=== 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-07-23 18:32:12 +0000
@@ -91,14 +91,36 @@ 
 
 #define UHOST_BITS_PER_WIDE_INT ((unsigned) HOST_BITS_PER_WIDEST_FAST_INT)
 
-#ifdef HARD_REG_SET
-
 #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))))
+  hard_reg_set_bit_p((SET), (BIT))
+
+
+#ifdef HARD_REG_SET
+
+static inline void
+hard_reg_set_set_bit (HARD_REG_SET *s, unsigned int bit)
+{
+  gcc_checking_assert (bit < FIRST_PSEUDO_REGISTER);
+  (*s) |= HARD_CONST (1) << bit;
+}
+
+static inline void
+hard_reg_set_clear_bit (HARD_REG_SET *s, unsigned int bit)
+{
+  gcc_checking_assert (bit < FIRST_PSEUDO_REGISTER);
+  (*s) &= ~(HARD_CONST (1) << bit);
+}
+
+static inline bool
+hard_reg_set_bit_p (const HARD_REG_SET s, unsigned int bit)
+{
+  gcc_checking_assert (bit < FIRST_PSEUDO_REGISTER);
+  return ((s >> bit) & HARD_CONST (1));
+}
 
 #define CLEAR_HARD_REG_SET(TO) ((TO) = HARD_CONST (0))
 #define SET_HARD_REG_SET(TO) ((TO) = ~ HARD_CONST (0))
@@ -137,17 +159,32 @@ 
 
 #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))))
+static inline void
+hard_reg_set_set_bit (HARD_REG_SET *s, unsigned int bit)
+{
+  int byte = bit / UHOST_BITS_PER_WIDE_INT;
+  int bitpos = bit % UHOST_BITS_PER_WIDE_INT;
+  gcc_checking_assert (bit < FIRST_PSEUDO_REGISTER);
+  (*s)[byte] |= HARD_CONST (1) << bitpos;
+}
+
+static inline void
+hard_reg_set_clear_bit (HARD_REG_SET *s, unsigned int bit)
+{
+  int byte = bit / UHOST_BITS_PER_WIDE_INT;
+  int bitpos = bit % UHOST_BITS_PER_WIDE_INT;
+  gcc_checking_assert (bit < FIRST_PSEUDO_REGISTER);
+  (*s)[byte] &= ~(HARD_CONST (1) << bitpos);
+}
+
+static inline bool
+hard_reg_set_bit_p (const HARD_REG_SET s, unsigned int bit)
+{
+  int byte = bit / UHOST_BITS_PER_WIDE_INT;
+  int bitpos = bit % UHOST_BITS_PER_WIDE_INT;
+  gcc_checking_assert (bit < FIRST_PSEUDO_REGISTER);
+  return ((s[byte] >> bitpos) & HARD_CONST (1));
+}
 
 #if FIRST_PSEUDO_REGISTER <= 2*HOST_BITS_PER_WIDEST_FAST_INT
 #define CLEAR_HARD_REG_SET(TO)  \