OSDN Git Service

abstract regset stuff into macros
authormeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 5 Jun 1997 10:24:03 +0000 (10:24 +0000)
committermeissner <meissner@138bc75d-0d04-0410-961f-82ee72b054a4>
Thu, 5 Jun 1997 10:24:03 +0000 (10:24 +0000)
git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@14147 138bc75d-0d04-0410-961f-82ee72b054a4

gcc/basic-block.h
gcc/caller-save.c
gcc/flow.c
gcc/global.c
gcc/reorg.c
gcc/sched.c

index 3d1f3a9..a6b8cf9 100644 (file)
@@ -19,9 +19,11 @@ the Free Software Foundation, 59 Temple Place - Suite 330,
 Boston, MA 02111-1307, USA.  */
 
 
-/* Number of bits in each actual element of a regset.  */
+/* Number of bits in each actual element of a regset.  We get slightly
+   better code for reg%bits and reg/bits if bits is unsigned, assuming
+   it is a power of 2.  */
 
-#define REGSET_ELT_BITS HOST_BITS_PER_WIDE_INT
+#define REGSET_ELT_BITS ((unsigned) HOST_BITS_PER_WIDE_INT)
 
 /* Type to use for a regset element.  Note that lots of code assumes
    that the initial part of a regset that contains information on the
@@ -40,6 +42,221 @@ typedef REGSET_ELT_TYPE *regset;
 extern int regset_bytes;
 extern int regset_size;
 
+/* clear a register set */
+#define CLEAR_REG_SET(TO)                                              \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO);                                \
+     register int i_;                                                  \
+     for (i_ = 0; i_ < regset_size; i_++)                              \
+       *scan_tp_++ = 0; } while (0)
+
+/* copy a register to another register */
+#define COPY_REG_SET(TO, FROM)                                         \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
+     register int i_;                                                  \
+     for (i_ = 0; i_ < regset_size; i_++)                              \
+       *scan_tp_++ = *scan_fp_++; } while (0)
+
+/* complent a register set, storing it in a second register set.  */
+#define COMPL_REG_SET(TO, FROM)                                                \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
+     register int i_;                                                  \
+     for (i_ = 0; i_ < regset_size; i_++)                              \
+       *scan_tp_++ = ~ *scan_fp_++; } while (0)
+
+/* and a register set with a second register set.  */
+#define AND_REG_SET(TO, FROM)                                          \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
+     register int i_;                                                  \
+     for (i_ = 0; i_ < regset_size; i_++)                              \
+       *scan_tp_++ &= *scan_fp_++; } while (0)
+
+/* and the complement of a register set to a register set.  */
+#define AND_COMPL_REG_SET(TO, FROM)                                    \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
+     register int i_;                                                  \
+     for (i_ = 0; i_ < regset_size; i_++)                              \
+       *scan_tp_++ &= ~ *scan_fp_++; } while (0)
+
+/* inclusive or a register set with a second register set.  */
+#define IOR_REG_SET(TO, FROM)                                          \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO), *scan_fp_ = (FROM);    \
+     register int i_;                                                  \
+     for (i_ = 0; i_ < regset_size; i_++)                              \
+       *scan_tp_++ |= *scan_fp_++; } while (0)
+
+/* complement two register sets and or in the result into a third.  */
+#define IOR_AND_COMPL_REG_SET(TO, FROM1, FROM2)                                \
+do { register REGSET_ELT_TYPE *scan_tp_ = (TO);                                \
+     register REGSET_ELT_TYPE *scan_fp1_ = (FROM1);                    \
+     register REGSET_ELT_TYPE *scan_fp2_ = (FROM2);                    \
+     register int i_;                                                  \
+     for (i_ = 0; i_ < regset_size; i_++)                              \
+       *scan_tp_++ |= *scan_fp1_++ & ~ *scan_fp2_++; } while (0)
+
+/* Clear a single register in a register set.  */
+#define CLEAR_REGNO_REG_SET(TO, REG)                                   \
+do {                                                                   \
+  register REGSET_ELT_TYPE *tp_ = (TO);                                        \
+  tp_[ (REG) / REGSET_ELT_BITS ]                                       \
+    &= ~ ((REGSET_ELT_TYPE) 1 << ((REG) % REGSET_ELT_BITS)); } while (0);
+
+/* Set a single register in a register set.  */
+#define SET_REGNO_REG_SET(TO, REG)                                     \
+do {                                                                   \
+  register REGSET_ELT_TYPE *tp_ = (TO);                                        \
+  tp_[ (REG) / REGSET_ELT_BITS ]                                       \
+    |= ((REGSET_ELT_TYPE) 1 << ((REG) % REGSET_ELT_BITS)); } while (0);
+
+/* Return true if a register is set in a register set.  */
+#define REGNO_REG_SET_P(TO, REG)                                       \
+ (((TO)[ (REG) / REGSET_ELT_BITS ]                                     \
+   & (((REGSET_ELT_TYPE)1) << (REG) % REGSET_ELT_BITS)) != 0)
+
+/* Copy the hard registers in a register set to the hard register set.  */
+#define REG_SET_TO_HARD_REG_SET(TO, FROM)                              \
+do {                                                                   \
+  int i_;                                                              \
+  CLEAR_HARD_REG_SET (TO);                                             \
+  for (i_ = 0; i < FIRST_PSEUDO_REGISTER; i++)                         \
+    if (REGNO_REG_SET_P (FROM, i_))                                    \
+      SET_HARD_REG_BIT (TO, i_);                                       \
+} while (0)
+
+/* Loop over all registers in REGSET, starting with MIN, setting REGNUM to the
+   register number and executing CODE for all registers that are set. */
+#define EXECUTE_IF_SET_IN_REG_SET(REGSET, MIN, REGNUM, CODE)           \
+do {                                                                   \
+  register REGSET_ELT_TYPE *scan_rs_ = (REGSET);                       \
+  register int i_;                                                     \
+  register int shift_ = (MIN) % REGSET_ELT_BITS;                       \
+  for (i_ = (MIN) / REGSET_ELT_BITS; i_ < regset_size; i_++)           \
+    {                                                                  \
+      REGSET_ELT_TYPE word_ = *scan_rs_++;                             \
+      if (word_)                                                       \
+       {                                                               \
+         REGSET_ELT_TYPE j_;                                           \
+         REGNUM = (i_ * REGSET_ELT_BITS) + shift_;                     \
+         for (j_ = ((REGSET_ELT_TYPE)1) << shift_;                     \
+              j_ != 0;                                                 \
+              (j_ <<= 1), REGNUM++)                                    \
+           {                                                           \
+             if (word_ & j_)                                           \
+               {                                                       \
+                 CODE;                                                 \
+                 word_ &= ~ j_;                                        \
+                 if (!word_)                                           \
+                   break;                                              \
+               }                                                       \
+           }                                                           \
+       }                                                               \
+      shift_ = 0;                                                      \
+    }                                                                  \
+} while (0)
+
+/* Like EXECUTE_IF_SET_IN_REG_SET, but also clear the register set.  */
+#define EXECUTE_IF_SET_AND_RESET_IN_REG_SET(REGSET, MIN, REGNUM, CODE) \
+do {                                                                   \
+  register REGSET_ELT_TYPE *scan_rs_ = (REGSET);                       \
+  register int i_;                                                     \
+  register int shift_ = (MIN) % REGSET_ELT_BITS;                       \
+  for (i_ = (MIN) / REGSET_ELT_BITS; i_ < regset_size; i_++)           \
+    {                                                                  \
+      REGSET_ELT_TYPE word_ = *scan_rs_++;                             \
+      if (word_)                                                       \
+       {                                                               \
+         REGSET_ELT_TYPE j_;                                           \
+         REGNUM = (i_ * REGSET_ELT_BITS) + shift_;                     \
+         scan_rs_[-1] = 0;                                             \
+         for (j_ = ((REGSET_ELT_TYPE)1) << shift_;                     \
+              j_ != 0;                                                 \
+              (j_ <<= 1), REGNUM++)                                    \
+           {                                                           \
+             if (word_ & j_)                                           \
+               {                                                       \
+                 CODE;                                                 \
+                 word_ &= ~ j_;                                        \
+                 if (!word_)                                           \
+                   break;                                              \
+               }                                                       \
+           }                                                           \
+       }                                                               \
+      shift_ = 0;                                                      \
+    }                                                                  \
+} while (0)
+
+/* Loop over all registers in REGSET1 and REGSET2, starting with MIN, setting
+   REGNUM to the register number and executing CODE for all registers that are
+   set in both regsets. */
+#define EXECUTE_IF_AND_IN_REG_SET(REGSET1, REGSET2, MIN, REGNUM, CODE) \
+do {                                                                   \
+  register REGSET_ELT_TYPE *scan_rs1_ = (REGSET1);                     \
+  register REGSET_ELT_TYPE *scan_rs2_ = (REGSET2);                     \
+  register int i_;                                                     \
+  register int shift_ = (MIN) % REGSET_ELT_BITS;                       \
+  for (i_ = (MIN) / REGSET_ELT_BITS; i_ < regset_size; i_++)           \
+    {                                                                  \
+      REGSET_ELT_TYPE word_ = *scan_rs1_++ & *scan_rs2_++;             \
+      if (word_)                                                       \
+       {                                                               \
+         REGSET_ELT_TYPE j_;                                           \
+         REGNUM = (i_ * REGSET_ELT_BITS) + shift_;                     \
+         for (j_ = ((REGSET_ELT_TYPE)1) << shift_;                     \
+              j_ != 0;                                                 \
+              (j_ <<= 1), REGNUM++)                                    \
+           {                                                           \
+             if (word_ & j_)                                           \
+               {                                                       \
+                 CODE;                                                 \
+                 word_ &= ~ j_;                                        \
+                 if (!word_)                                           \
+                   break;                                              \
+               }                                                       \
+           }                                                           \
+       }                                                               \
+      shift_ = 0;                                                      \
+    }                                                                  \
+} while (0)
+
+/* Loop over all registers in REGSET1 and REGSET2, starting with MIN, setting
+   REGNUM to the register number and executing CODE for all registers that are
+   set in the first regset and not set in the second. */
+#define EXECUTE_IF_AND_COMPL_IN_REG_SET(REGSET1, REGSET2, MIN, REGNUM, CODE) \
+do {                                                                   \
+  register REGSET_ELT_TYPE *scan_rs1_ = (REGSET1);                     \
+  register REGSET_ELT_TYPE *scan_rs2_ = (REGSET2);                     \
+  register int i_;                                                     \
+  register int shift_ = (MIN) % REGSET_ELT_BITS;                       \
+  for (i_ = (MIN) / REGSET_ELT_BITS; i_ < regset_size; i_++)           \
+    {                                                                  \
+      REGSET_ELT_TYPE word_ = *scan_rs1_++ & ~ *scan_rs2_++;           \
+      if (word_)                                                       \
+       {                                                               \
+         REGSET_ELT_TYPE j_;                                           \
+         REGNUM = (i_ * REGSET_ELT_BITS) + shift_;                     \
+         for (j_ = ((REGSET_ELT_TYPE)1) << shift_;                     \
+              j_ != 0;                                                 \
+              (j_ <<= 1), REGNUM++)                                    \
+           {                                                           \
+             if (word_ & j_)                                           \
+               {                                                       \
+                 CODE;                                                 \
+                 word_ &= ~ j_;                                        \
+                 if (!word_)                                           \
+                   break;                                              \
+               }                                                       \
+           }                                                           \
+       }                                                               \
+      shift_ = 0;                                                      \
+    }                                                                  \
+} while (0)
+
+/* Allocate a register set with oballoc.  */
+#define OBALLOC_REG_SET()                                              \
+  ((regset) obstack_alloc (&flow_obstack, regset_bytes))
+
+/* Allocate a register set with alloca.  */
+#define ALLOCA_REG_SET() ((regset) alloca (regset_bytes))
+
 /* Number of basic blocks in the current function.  */
 
 extern int n_basic_blocks;
index f05f327..51b9d5a 100644 (file)
@@ -367,31 +367,20 @@ save_call_clobbered_regs (insn_mode)
         saved because we restore all of them before the end of the basic
         block.  */
 
-#ifdef HARD_REG_SET
-      hard_regs_live = *regs_live;
-#else
-      COPY_HARD_REG_SET (hard_regs_live, regs_live);
-#endif
-
+      REG_SET_TO_HARD_REG_SET (hard_regs_live, regs_live);
       CLEAR_HARD_REG_SET (hard_regs_saved);
       CLEAR_HARD_REG_SET (hard_regs_need_restore);
       n_regs_saved = 0;
 
-      for (offset = 0, i = 0; offset < regset_size; offset++)
-       {
-         if (regs_live[offset] == 0)
-           i += REGSET_ELT_BITS;
-         else
-           for (bit = 1; bit && i < max_regno; bit <<= 1, i++)
-             if ((regs_live[offset] & bit)
-                 && (regno = reg_renumber[i]) >= 0)
-               for (j = regno;
-                    j < regno + HARD_REGNO_NREGS (regno,
-                                                  PSEUDO_REGNO_MODE (i));
-                    j++)
-                 SET_HARD_REG_BIT (hard_regs_live, j);
-
-       }
+      EXECUTE_IF_SET_IN_REG_SET (regs_live, 0, i,
+                                {
+                                  if ((regno = reg_renumber[i]) >= 0)
+                                    for (j = regno;
+                                         j < regno + HARD_REGNO_NREGS (regno,
+                                                                       PSEUDO_REGNO_MODE (i));
+                                         j++)
+                                      SET_HARD_REG_BIT (hard_regs_live, j);
+                                });
 
       /* Now scan the insns in the block, keeping track of what hard
         regs are live as we go.  When we see a call, save the live
index 355a35e..d39b784 100644 (file)
@@ -1024,12 +1024,10 @@ life_analysis (f, nregs)
       {
        /* If exiting needs the right stack value,
           consider the stack pointer live at the end of the function.  */
-       basic_block_live_at_end[n_basic_blocks - 1]
-         [STACK_POINTER_REGNUM / REGSET_ELT_BITS]
-           |= (REGSET_ELT_TYPE) 1 << (STACK_POINTER_REGNUM % REGSET_ELT_BITS);
-       basic_block_new_live_at_end[n_basic_blocks - 1]
-         [STACK_POINTER_REGNUM / REGSET_ELT_BITS]
-           |= (REGSET_ELT_TYPE) 1 << (STACK_POINTER_REGNUM % REGSET_ELT_BITS);
+       SET_REGNO_REG_SET (basic_block_live_at_end[n_basic_blocks - 1],
+                          STACK_POINTER_REGNUM);
+       SET_REGNO_REG_SET (basic_block_new_live_at_end[n_basic_blocks - 1],
+                          STACK_POINTER_REGNUM);
       }
 
   /* Mark the frame pointer is needed at the end of the function.  If
@@ -1038,22 +1036,16 @@ life_analysis (f, nregs)
 
   if (n_basic_blocks > 0)
     {
-      basic_block_live_at_end[n_basic_blocks - 1]
-       [FRAME_POINTER_REGNUM / REGSET_ELT_BITS]
-         |= (REGSET_ELT_TYPE) 1 << (FRAME_POINTER_REGNUM % REGSET_ELT_BITS);
-      basic_block_new_live_at_end[n_basic_blocks - 1]
-       [FRAME_POINTER_REGNUM / REGSET_ELT_BITS]
-         |= (REGSET_ELT_TYPE) 1 << (FRAME_POINTER_REGNUM % REGSET_ELT_BITS);
+      SET_REGNO_REG_SET (basic_block_live_at_end[n_basic_blocks - 1],
+                        FRAME_POINTER_REGNUM);
+      SET_REGNO_REG_SET (basic_block_new_live_at_end[n_basic_blocks - 1],
+                        FRAME_POINTER_REGNUM);
 #if FRAME_POINTER_REGNUM != HARD_FRAME_POINTER_REGNUM
       /* If they are different, also mark the hard frame pointer as live */
-      basic_block_live_at_end[n_basic_blocks - 1]
-       [HARD_FRAME_POINTER_REGNUM / REGSET_ELT_BITS]
-         |= (REGSET_ELT_TYPE) 1 << (HARD_FRAME_POINTER_REGNUM
-                                    % REGSET_ELT_BITS);
-      basic_block_new_live_at_end[n_basic_blocks - 1]
-       [HARD_FRAME_POINTER_REGNUM / REGSET_ELT_BITS]
-         |= (REGSET_ELT_TYPE) 1 << (HARD_FRAME_POINTER_REGNUM
-                                    % REGSET_ELT_BITS);
+      SET_REGNO_REG_SET (basic_block_live_at_end[n_basic_blocks - 1],
+                        HARD_FRAME_POINTER_REGNUM);
+      SET_REGNO_REG_SET (basic_block_new_live_at_end[n_basic_blocks - 1],
+                        HARD_FRAME_POINTER_REGNUM);
 #endif      
       }
 
@@ -1069,12 +1061,8 @@ life_analysis (f, nregs)
 #endif
          )
        {
-         basic_block_live_at_end[n_basic_blocks - 1]
-           [i / REGSET_ELT_BITS]
-             |= (REGSET_ELT_TYPE) 1 << (i % REGSET_ELT_BITS);
-         basic_block_new_live_at_end[n_basic_blocks - 1]
-           [i / REGSET_ELT_BITS]
-             |= (REGSET_ELT_TYPE) 1 << (i % REGSET_ELT_BITS);
+         SET_REGNO_REG_SET (basic_block_live_at_end[n_basic_blocks - 1], i);
+         SET_REGNO_REG_SET (basic_block_new_live_at_end[n_basic_blocks - 1], i);
        }
 
   /* Propagate life info through the basic blocks
@@ -1109,21 +1097,18 @@ life_analysis (f, nregs)
                 reg that is live at the end now but was not live there before
                 is one of the significant regs of this basic block).  */
 
-             for (j = 0; j < regset_size; j++)
-               {
-                 register REGSET_ELT_TYPE x
-                   = (basic_block_new_live_at_end[i][j]
-                      & ~basic_block_live_at_end[i][j]);
-                 if (x)
-                   consider = 1;
-                 if (x & basic_block_significant[i][j])
-                   {
-                     must_rescan = 1;
-                     consider = 1;
-                     break;
-                   }
-               }
-
+             EXECUTE_IF_AND_COMPL_IN_REG_SET (basic_block_new_live_at_end[i],
+                                              basic_block_live_at_end[i],
+                                              0, j,
+                                              {
+                                                consider = 1;
+                                                if (REGNO_REG_SET_P (basic_block_significant[i], j))
+                                                  {
+                                                    must_rescan = 1;
+                                                    goto done;
+                                                  }
+                                              });
+           done:
              if (! consider)
                continue;
            }
@@ -1137,23 +1122,22 @@ life_analysis (f, nregs)
              /* No complete rescan needed;
                 just record those variables newly known live at end
                 as live at start as well.  */
-             for (j = 0; j < regset_size; j++)
-               {
-                 register REGSET_ELT_TYPE x
-                   = (basic_block_new_live_at_end[i][j]
-                      & ~basic_block_live_at_end[i][j]);
-                 basic_block_live_at_start[i][j] |= x;
-                 basic_block_live_at_end[i][j] |= x;
-               }
+             IOR_AND_COMPL_REG_SET (basic_block_live_at_start[i],
+                                    basic_block_new_live_at_end[i],
+                                    basic_block_live_at_end[i]);
+
+             IOR_AND_COMPL_REG_SET (basic_block_live_at_end[i],
+                                    basic_block_new_live_at_end[i],
+                                    basic_block_live_at_end[i]);
            }
          else
            {
              /* Update the basic_block_live_at_start
                 by propagation backwards through the block.  */
-             bcopy ((char *) basic_block_new_live_at_end[i],
-                    (char *) basic_block_live_at_end[i], regset_bytes);
-             bcopy ((char *) basic_block_live_at_end[i],
-                    (char *) basic_block_live_at_start[i], regset_bytes);
+             COPY_REG_SET (basic_block_live_at_end[i],
+                           basic_block_new_live_at_end[i]);
+             COPY_REG_SET (basic_block_live_at_start[i],
+                           basic_block_live_at_end[i]);
              propagate_block (basic_block_live_at_start[i],
                               basic_block_head[i], basic_block_end[i], 0,
                               first_pass ? basic_block_significant[i]
@@ -1168,12 +1152,8 @@ life_analysis (f, nregs)
               that falls through into this one (if any).  */
            head = basic_block_head[i];
            if (basic_block_drops_in[i])
-             {
-               register int j;
-               for (j = 0; j < regset_size; j++)
-                 basic_block_new_live_at_end[i-1][j]
-                   |= basic_block_live_at_start[i][j];
-             }
+             IOR_REG_SET (basic_block_new_live_at_end[i-1],
+                          basic_block_live_at_start[i]);
 
            /* Update the basic_block_new_live_at_end's of
               all the blocks that jump to this one.  */
@@ -1183,10 +1163,8 @@ life_analysis (f, nregs)
                   jump = LABEL_NEXTREF (jump))
                {
                  register int from_block = BLOCK_NUM (CONTAINING_INSN (jump));
-                 register int j;
-                 for (j = 0; j < regset_size; j++)
-                   basic_block_new_live_at_end[from_block][j]
-                     |= basic_block_live_at_start[i][j];
+                 IOR_REG_SET (basic_block_new_live_at_end[from_block],
+                              basic_block_live_at_start[i]);
                }
          }
 #ifdef USE_C_ALLOCA
@@ -1202,10 +1180,11 @@ life_analysis (f, nregs)
      one basic block.  */
 
   if (n_basic_blocks > 0)
-    for (i = FIRST_PSEUDO_REGISTER; i < max_regno; i++)
-      if (basic_block_live_at_start[0][i / REGSET_ELT_BITS]
-         & ((REGSET_ELT_TYPE) 1 << (i % REGSET_ELT_BITS)))
-       REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;
+    EXECUTE_IF_SET_IN_REG_SET (basic_block_live_at_start[0],
+                              FIRST_PSEUDO_REGISTER, i,
+                              {
+                                REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;
+                              });
 
   /* Now the life information is accurate.
      Make one more pass over each basic block
@@ -1236,14 +1215,16 @@ life_analysis (f, nregs)
      But we don't need to do this for the user's variables, since
      ANSI says only volatile variables need this.  */
 #ifdef LONGJMP_RESTORE_FROM_STACK
-  for (i = FIRST_PSEUDO_REGISTER; i < nregs; i++)
-    if (regs_live_at_setjmp[i / REGSET_ELT_BITS]
-       & ((REGSET_ELT_TYPE) 1 << (i % REGSET_ELT_BITS))
-       && regno_reg_rtx[i] != 0 && ! REG_USERVAR_P (regno_reg_rtx[i]))
-      {
-       REG_LIVE_LENGTH (i) = -1;
-       REG_BASIC_BLOCK (i) = -1;
-      }
+  EXECUTE_IF_SET_IN_REG_SET (regs_live_at_setjmp,
+                            FIRST_PSEUDO_REGISTER, i,
+                            {
+                              if (regno_reg_rtx[i] != 0
+                                  && ! REG_USERVAR_P (regno_reg_rtx[i]))
+                                {
+                                  REG_LIVE_LENGTH (i) = -1;
+                                  REG_BASIC_BLOCK (i) = -1;
+                                }
+                            });
 #endif
 #endif
 
@@ -1256,14 +1237,15 @@ life_analysis (f, nregs)
      If the pseudo goes in a hard reg, some other value may occupy
      that hard reg where this pseudo is dead, thus clobbering the pseudo.
      Conclusion: such a pseudo must not go in a hard reg.  */
-  for (i = FIRST_PSEUDO_REGISTER; i < nregs; i++)
-    if ((regs_live_at_setjmp[i / REGSET_ELT_BITS]
-        & ((REGSET_ELT_TYPE) 1 << (i % REGSET_ELT_BITS)))
-       && regno_reg_rtx[i] != 0)
-      {
-       REG_LIVE_LENGTH (i) = -1;
-       REG_BASIC_BLOCK (i) = -1;
-      }
+  EXECUTE_IF_SET_IN_REG_SET (regs_live_at_setjmp,
+                            FIRST_PSEUDO_REGISTER, i,
+                            {
+                              if (regno_reg_rtx[i] != 0)
+                                {
+                                  REG_LIVE_LENGTH (i) = -1;
+                                  REG_BASIC_BLOCK (i) = -1;
+                                }
+                            });
 
   obstack_free (&flow_obstack, NULL_PTR);
 }
@@ -1360,11 +1342,8 @@ propagate_block (old, first, last, final, significant, bnum)
   /* The following variables are used only if FINAL is nonzero.  */
   /* This vector gets one element for each reg that has been live
      at any point in the basic block that has been scanned so far.
-     SOMETIMES_MAX says how many elements are in use so far.
-     In each element, OFFSET is the byte-number within a regset
-     for the register described by the element, and BIT is a mask
-     for that register's bit within the byte.  */
-  register struct sometimes { short offset; short bit; } *regs_sometimes_live;
+     SOMETIMES_MAX says how many elements are in use so far.  */
+  register int *regs_sometimes_live;
   int sometimes_max = 0;
   /* This regset has 1 for each reg that we have seen live so far.
      It and REGS_SOMETIMES_LIVE are updated together.  */
@@ -1396,32 +1375,22 @@ propagate_block (old, first, last, final, significant, bnum)
 
   if (final)
     {
-      register int i, offset;
-      REGSET_ELT_TYPE bit;
+      register int i;
 
       num_scratch = 0;
       maxlive = (regset) alloca (regset_bytes);
-      bcopy ((char *) old, (char *) maxlive, regset_bytes);
-      regs_sometimes_live
-       = (struct sometimes *) alloca (max_regno * sizeof (struct sometimes));
+      COPY_REG_SET (maxlive, old);
+      regs_sometimes_live = (int *) alloca (max_regno * sizeof (int));
 
       /* Process the regs live at the end of the block.
         Enter them in MAXLIVE and REGS_SOMETIMES_LIVE.
-        Also mark them as not local to any one basic block.  */
-
-      for (offset = 0, i = 0; offset < regset_size; offset++)
-       for (bit = 1; bit; bit <<= 1, i++)
-         {
-           if (i == max_regno)
-             break;
-           if (old[offset] & bit)
-             {
-               REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;
-               regs_sometimes_live[sometimes_max].offset = offset;
-               regs_sometimes_live[sometimes_max].bit = i % REGSET_ELT_BITS;
-               sometimes_max++;
-             }
-         }
+        Also mark them as not local to any one basic block. */
+      EXECUTE_IF_SET_IN_REG_SET (old, 0, i,
+                                {
+                                  REG_BASIC_BLOCK (i) = REG_BLOCK_GLOBAL;
+                                  regs_sometimes_live[sometimes_max] = i;
+                                  sometimes_max++;
+                                });
     }
 
   /* Scan the block an insn at a time from end to beginning.  */
@@ -1448,11 +1417,7 @@ propagate_block (old, first, last, final, significant, bnum)
             warn if any non-volatile datum is live.  */
 
          if (final && NOTE_LINE_NUMBER (insn) == NOTE_INSN_SETJMP)
-           {
-             int i;
-             for (i = 0; i < regset_size; i++)
-               regs_live_at_setjmp[i] |= old[i];
-           }
+           IOR_REG_SET (regs_live_at_setjmp, old);
        }
 
       /* Update the life-status of regs for this insn.
@@ -1508,11 +1473,8 @@ propagate_block (old, first, last, final, significant, bnum)
              goto flushed;
            }
 
-         for (i = 0; i < regset_size; i++)
-           {
-             dead[i] = 0;      /* Faster than bzero here */
-             live[i] = 0;      /* since regset_size is usually small */
-           }
+         CLEAR_REG_SET (dead);
+         CLEAR_REG_SET (live);
 
          /* See if this is an increment or decrement that can be
             merged into a following memory address.  */
@@ -1602,13 +1564,10 @@ propagate_block (old, first, last, final, significant, bnum)
                  for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
                    if (call_used_regs[i] && ! global_regs[i]
                        && ! fixed_regs[i])
-                     dead[i / REGSET_ELT_BITS]
-                       |= ((REGSET_ELT_TYPE) 1 << (i % REGSET_ELT_BITS));
+                     SET_REGNO_REG_SET (dead, i);
 
                  /* The stack ptr is used (honorarily) by a CALL insn.  */
-                 live[STACK_POINTER_REGNUM / REGSET_ELT_BITS]
-                   |= ((REGSET_ELT_TYPE) 1
-                       << (STACK_POINTER_REGNUM % REGSET_ELT_BITS));
+                 SET_REGNO_REG_SET (live, STACK_POINTER_REGNUM);
 
                  /* Calls may also reference any of the global registers,
                     so they are made live.  */
@@ -1623,11 +1582,8 @@ propagate_block (old, first, last, final, significant, bnum)
                }
 
              /* Update OLD for the registers used or set.  */
-             for (i = 0; i < regset_size; i++)
-               {
-                 old[i] &= ~dead[i];
-                 old[i] |= live[i];
-               }
+             AND_COMPL_REG_SET (old, dead);
+             IOR_REG_SET (old, live);
 
              if (GET_CODE (insn) == CALL_INSN && final)
                {
@@ -1635,11 +1591,11 @@ propagate_block (old, first, last, final, significant, bnum)
                     must not go in a register clobbered by calls.
                     Find all regs now live and record this for them.  */
 
-                 register struct sometimes *p = regs_sometimes_live;
+                 register int *p = regs_sometimes_live;
 
                  for (i = 0; i < sometimes_max; i++, p++)
-                   if (old[p->offset] & ((REGSET_ELT_TYPE) 1 << p->bit))
-                     REG_N_CALLS_CROSSED (p->offset * REGSET_ELT_BITS + p->bit)++;
+                   if (REGNO_REG_SET_P (old, *p))
+                     REG_N_CALLS_CROSSED (*p)++;
                }
            }
 
@@ -1649,33 +1605,22 @@ propagate_block (old, first, last, final, significant, bnum)
 
          if (final)
            {
-             for (i = 0; i < regset_size; i++)
-               {
-                 register REGSET_ELT_TYPE diff = live[i] & ~maxlive[i];
+             register int regno;
+             register int *p;
 
-                 if (diff)
-                   {
-                     register int regno;
-                     maxlive[i] |= diff;
-                     for (regno = 0; diff && regno < REGSET_ELT_BITS; regno++)
-                       if (diff & ((REGSET_ELT_TYPE) 1 << regno))
-                         {
-                           regs_sometimes_live[sometimes_max].offset = i;
-                           regs_sometimes_live[sometimes_max].bit = regno;
-                           diff &= ~ ((REGSET_ELT_TYPE) 1 << regno);
-                           sometimes_max++;
-                         }
-                   }
-               }
+             EXECUTE_IF_AND_COMPL_IN_REG_SET (live, maxlive, 0, regno,
+                                              {
+                                                regs_sometimes_live[sometimes_max++] = regno;
+                                                SET_REGNO_REG_SET (maxlive, regno);
+                                              });
 
-             {
-               register struct sometimes *p = regs_sometimes_live;
-               for (i = 0; i < sometimes_max; i++, p++)
-                 {
-                   if (old[p->offset] & ((REGSET_ELT_TYPE) 1 << p->bit))
-                     REG_LIVE_LENGTH (p->offset * REGSET_ELT_BITS + p->bit)++;
-                 }
-             }
+             p = regs_sometimes_live;
+             for (i = 0; i < sometimes_max; i++)
+               {
+                 regno = *p++;
+                 if (REGNO_REG_SET_P (old, regno))
+                   REG_LIVE_LENGTH (regno)++;
+               }
            }
        }
     flushed: ;
@@ -1728,9 +1673,6 @@ insn_dead_p (x, needed, call_ok)
       if (GET_CODE (r) == REG)
        {
          register int regno = REGNO (r);
-         register int offset = regno / REGSET_ELT_BITS;
-         register REGSET_ELT_TYPE bit
-           = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
 
          /* Don't delete insns to set global regs.  */
          if ((regno < FIRST_PSEUDO_REGISTER && global_regs[regno])
@@ -1745,7 +1687,7 @@ insn_dead_p (x, needed, call_ok)
                 it, so we can treat it normally).  */
              || (regno == ARG_POINTER_REGNUM && fixed_regs[regno])
 #endif
-             || (needed[offset] & bit) != 0)
+             || REGNO_REG_SET_P (needed, regno))
            return 0;
 
          /* If this is a hard register, verify that subsequent words are
@@ -1755,9 +1697,7 @@ insn_dead_p (x, needed, call_ok)
              int n = HARD_REGNO_NREGS (regno, GET_MODE (r));
 
              while (--n > 0)
-               if ((needed[(regno + n) / REGSET_ELT_BITS]
-                    & ((REGSET_ELT_TYPE) 1
-                       << ((regno + n) % REGSET_ELT_BITS))) != 0)
+               if (REGNO_REG_SET_P (needed, regno+n))
                  return 0;
            }
 
@@ -1866,8 +1806,7 @@ regno_uninitialized (regno)
          && (global_regs[regno] || FUNCTION_ARG_REGNO_P (regno))))
     return 0;
 
-  return (basic_block_live_at_start[0][regno / REGSET_ELT_BITS]
-         & ((REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS)));
+  return REGNO_REG_SET_P (basic_block_live_at_start[0], regno);
 }
 
 /* 1 if register REGNO was alive at a place where `setjmp' was called
@@ -1882,10 +1821,8 @@ regno_clobbered_at_setjmp (regno)
     return 0;
 
   return ((REG_N_SETS (regno) > 1
-          || (basic_block_live_at_start[0][regno / REGSET_ELT_BITS]
-              & ((REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS))))
-         && (regs_live_at_setjmp[regno / REGSET_ELT_BITS]
-             & ((REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS))));
+          || REGNO_REG_SET_P (basic_block_live_at_start[0], regno))
+         && REGNO_REG_SET_P (regs_live_at_setjmp, regno));
 }
 \f
 /* Process the registers that are set within X.
@@ -1978,18 +1915,15 @@ mark_set_1 (needed, dead, x, insn, significant)
       && ! (regno < FIRST_PSEUDO_REGISTER && global_regs[regno]))
     /* && regno != STACK_POINTER_REGNUM) -- let's try without this.  */
     {
-      register int offset = regno / REGSET_ELT_BITS;
-      register REGSET_ELT_TYPE bit
-       = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
-      REGSET_ELT_TYPE some_needed = (needed[offset] & bit);
-      REGSET_ELT_TYPE some_not_needed = (~ needed[offset]) & bit;
+      int some_needed = REGNO_REG_SET_P (needed, regno);
+      int some_not_needed = ! some_needed;
 
       /* Mark it as a significant register for this basic block.  */
       if (significant)
-       significant[offset] |= bit;
+       SET_REGNO_REG_SET (significant, regno);
 
       /* Mark it as as dead before this insn.  */
-      dead[offset] |= bit;
+      SET_REGNO_REG_SET (dead, regno);
 
       /* A hard reg in a wide mode may really be multiple registers.
         If so, mark all of them just like the first.  */
@@ -2005,17 +1939,14 @@ mark_set_1 (needed, dead, x, insn, significant)
          n = HARD_REGNO_NREGS (regno, GET_MODE (reg));
          while (--n > 0)
            {
-             REGSET_ELT_TYPE n_bit
-               = (REGSET_ELT_TYPE) 1 << ((regno + n) % REGSET_ELT_BITS);
-
+             int regno_n = regno + n;
+             int needed_regno = REGNO_REG_SET_P (needed, regno_n);
              if (significant)
-               significant[(regno + n) / REGSET_ELT_BITS] |= n_bit;
+               SET_REGNO_REG_SET (significant, regno_n);
 
-             dead[(regno + n) / REGSET_ELT_BITS] |= n_bit;
-             some_needed
-               |= (needed[(regno + n) / REGSET_ELT_BITS] & n_bit);
-             some_not_needed
-               |= ((~ needed[(regno + n) / REGSET_ELT_BITS]) & n_bit);
+             SET_REGNO_REG_SET (dead, regno_n);
+             some_needed |= needed_regno;
+             some_not_needed |= ! needed_regno;
            }
        }
       /* Additional data to record if this is the final pass.  */
@@ -2106,9 +2037,7 @@ mark_set_1 (needed, dead, x, insn, significant)
 
              for (i = HARD_REGNO_NREGS (regno, GET_MODE (reg)) - 1;
                   i >= 0; i--)
-               if ((needed[(regno + i) / REGSET_ELT_BITS]
-                    & ((REGSET_ELT_TYPE) 1
-                       << ((regno + i) % REGSET_ELT_BITS))) == 0)
+               if (!REGNO_REG_SET_P (needed, regno + i))
                  REG_NOTES (insn)
                    = gen_rtx (EXPR_LIST, REG_UNUSED,
                               gen_rtx (REG, reg_raw_mode[regno + i],
@@ -2271,8 +2200,7 @@ find_auto_inc (needed, x, insn)
                 it previously wasn't live here.  If we don't mark
                 it as needed, we'll put a REG_DEAD note for it
                 on this insn, which is incorrect.  */
-             needed[regno / REGSET_ELT_BITS]
-               |= (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
+             SET_REGNO_REG_SET (needed, regno);
 
              /* If there are any calls between INSN and INCR, show
                 that REGNO now crosses them.  */
@@ -2407,13 +2335,10 @@ mark_used_regs (needed, live, x, final, insn)
 
       regno = REGNO (x);
       {
-       register int offset = regno / REGSET_ELT_BITS;
-       register REGSET_ELT_TYPE bit
-         = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
-       REGSET_ELT_TYPE some_needed = needed[offset] & bit;
-       REGSET_ELT_TYPE some_not_needed = (~ needed[offset]) & bit;
+       REGSET_ELT_TYPE some_needed = REGNO_REG_SET_P (needed, regno);
+       REGSET_ELT_TYPE some_not_needed = ! some_needed;
 
-       live[offset] |= bit;
+       SET_REGNO_REG_SET (live, regno);
 
        /* A hard reg in a wide mode may really be multiple registers.
           If so, mark all of them just like the first.  */
@@ -2455,13 +2380,12 @@ mark_used_regs (needed, live, x, final, insn)
            n = HARD_REGNO_NREGS (regno, GET_MODE (x));
            while (--n > 0)
              {
-               REGSET_ELT_TYPE n_bit
-                 = (REGSET_ELT_TYPE) 1 << ((regno + n) % REGSET_ELT_BITS);
+               int regno_n = regno + n;
+               int needed_regno = REGNO_REG_SET_P (needed, regno_n);
 
-               live[(regno + n) / REGSET_ELT_BITS] |= n_bit;
-               some_needed |= (needed[(regno + n) / REGSET_ELT_BITS] & n_bit);
-               some_not_needed
-                 |= ((~ needed[(regno + n) / REGSET_ELT_BITS]) & n_bit);
+               SET_REGNO_REG_SET (live, regno_n);
+               some_needed |= needed_regno;
+               some_not_needed != ! needed_regno;
              }
          }
        if (final)
@@ -2539,9 +2463,7 @@ mark_used_regs (needed, live, x, final, insn)
 
                    for (i = HARD_REGNO_NREGS (regno, GET_MODE (x)) - 1;
                         i >= 0; i--)
-                     if ((needed[(regno + i) / REGSET_ELT_BITS]
-                          & ((REGSET_ELT_TYPE) 1
-                             << ((regno + i) % REGSET_ELT_BITS))) == 0
+                     if (!REGNO_REG_SET_P (needed, regno + i)
                          && ! dead_or_set_regno_p (insn, regno + i))
                        REG_NOTES (insn)
                          = gen_rtx (EXPR_LIST, REG_DEAD,
@@ -2635,8 +2557,7 @@ mark_used_regs (needed, live, x, final, insn)
       if (! EXIT_IGNORE_STACK
          || (! FRAME_POINTER_REQUIRED && flag_omit_frame_pointer))
 #endif
-       live[STACK_POINTER_REGNUM / REGSET_ELT_BITS]
-         |= (REGSET_ELT_TYPE) 1 << (STACK_POINTER_REGNUM % REGSET_ELT_BITS);
+       SET_REGNO_REG_SET (live, STACK_POINTER_REGNUM);
 
       for (i = 0; i < FIRST_PSEUDO_REGISTER; i++)
        if (global_regs[i]
@@ -2644,8 +2565,7 @@ mark_used_regs (needed, live, x, final, insn)
            || EPILOGUE_USES (i)
 #endif
            )
-         live[i / REGSET_ELT_BITS]
-           |= (REGSET_ELT_TYPE) 1 << (i % REGSET_ELT_BITS);
+         SET_REGNO_REG_SET (live, i);
       break;
     }
 
@@ -2945,13 +2865,8 @@ dump_flow_info (file)
        }
       fprintf (file, "\nRegisters live at start:");
       for (regno = 0; regno < max_regno; regno++)
-       {
-         register int offset = regno / REGSET_ELT_BITS;
-         register REGSET_ELT_TYPE bit
-           = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
-         if (basic_block_live_at_start[i][offset] & bit)
-             fprintf (file, " %d", regno);
-       }
+       if (REGNO_REG_SET_P (basic_block_live_at_start[i], regno))
+         fprintf (file, " %d", regno);
       fprintf (file, "\n");
     }
   fprintf (file, "\n");
index ed2f9ea..9ebd5a7 100644 (file)
@@ -642,36 +642,21 @@ global_conflicts ()
         are explicitly marked in basic_block_live_at_start.  */
 
       {
-       register int offset;
-       REGSET_ELT_TYPE bit;
        register regset old = basic_block_live_at_start[b];
        int ax = 0;
 
-#ifdef HARD_REG_SET
-       hard_regs_live = old[0];
-#else
-       COPY_HARD_REG_SET (hard_regs_live, old);
-#endif
-       for (offset = 0, i = 0; offset < regset_size; offset++)
-         if (old[offset] == 0)
-           i += REGSET_ELT_BITS;
-         else
-           for (bit = 1; bit; bit <<= 1, i++)
-             {
-               if (i >= max_regno)
-                 break;
-               if (old[offset] & bit)
-                 {
-                   register int a = reg_allocno[i];
-                   if (a >= 0)
-                     {
-                       SET_ALLOCNO_LIVE (a);
-                       block_start_allocnos[ax++] = a;
-                     }
-                   else if ((a = reg_renumber[i]) >= 0)
-                     mark_reg_live_nc (a, PSEUDO_REGNO_MODE (i));
-                 }
-             }
+       REG_SET_TO_HARD_REG_SET (hard_regs_live, old);
+       EXECUTE_IF_SET_IN_REG_SET (old, 0, i,
+                                  {
+                                    register int a = reg_allocno[i];
+                                    if (a >= 0)
+                                      {
+                                        SET_ALLOCNO_LIVE (a);
+                                        block_start_allocnos[ax++] = a;
+                                      }
+                                    else if ((a = reg_renumber[i]) >= 0)
+                                      mark_reg_live_nc (a, PSEUDO_REGNO_MODE (i));
+                                  });
 
        /* Record that each allocno now live conflicts with each other
           allocno now live, and with each hard reg now live.  */
@@ -1640,13 +1625,10 @@ mark_elimination (from, to)
   int i;
 
   for (i = 0; i < n_basic_blocks; i++)
-    if ((basic_block_live_at_start[i][from / REGSET_ELT_BITS]
-        & ((REGSET_ELT_TYPE) 1 << (from % REGSET_ELT_BITS))) != 0)
+    if (REGNO_REG_SET_P (basic_block_live_at_start[i], from))
       {
-       basic_block_live_at_start[i][from / REGSET_ELT_BITS]
-         &= ~ ((REGSET_ELT_TYPE) 1 << (from % REGSET_ELT_BITS));
-       basic_block_live_at_start[i][to / REGSET_ELT_BITS]
-         |= ((REGSET_ELT_TYPE) 1 << (to % REGSET_ELT_BITS));
+       CLEAR_REGNO_REG_SET (basic_block_live_at_start[i], from);
+       SET_REGNO_REG_SET (basic_block_live_at_start[i], to);
       }
 }
 \f
index 8cd4473..5abf1bb 100644 (file)
@@ -2762,25 +2762,17 @@ mark_target_live_regs (target, res)
         marked live, plus live pseudo regs that have been renumbered to
         hard regs.  */
 
-#ifdef HARD_REG_SET
-      current_live_regs = *regs_live;
-#else
-      COPY_HARD_REG_SET (current_live_regs, regs_live);
-#endif
-
-      for (offset = 0, i = 0; offset < regset_size; offset++)
-       {
-         if (regs_live[offset] == 0)
-           i += REGSET_ELT_BITS;
-         else
-           for (bit = 1; bit && i < max_regno; bit <<= 1, i++)
-             if ((regs_live[offset] & bit)
-                 && (regno = reg_renumber[i]) >= 0)
-               for (j = regno;
-                    j < regno + HARD_REGNO_NREGS (regno,
-                                                  PSEUDO_REGNO_MODE (i));
-                    j++)
-                 SET_HARD_REG_BIT (current_live_regs, j);
+      REG_SET_TO_HARD_REG_SET (current_live_regs, regs_live);
+
+      EXECUTE_IF_SET_IN_REG_SET (regs_live, 0, i,
+                                {
+                                  if ((regno = reg_renumber[i]) >= 0)
+                                    for (j = regno;
+                                         j < regno + HARD_REGNO_NREGS (regno,
+                                                                       PSEUDO_REGNO_MODE (i));
+                                         j++)
+                                      SET_HARD_REG_BIT (current_live_regs, j);
+                                });
        }
 
       /* Get starting and ending insn, handling the case where each might
index 2627968..1fa338f 100644 (file)
@@ -289,8 +289,7 @@ static int *insn_tick;
 
 struct sometimes
 {
-  int offset;
-  int bit;
+  int regno;
   int live_length;
   int calls_crossed;
 };
@@ -333,8 +332,7 @@ static void create_reg_dead_note    PROTO((rtx, rtx));
 static void attach_deaths              PROTO((rtx, rtx, int));
 static void attach_deaths_insn         PROTO((rtx));
 static rtx unlink_notes                        PROTO((rtx, rtx));
-static int new_sometimes_live          PROTO((struct sometimes *, int, int,
-                                              int));
+static int new_sometimes_live          PROTO((struct sometimes *, int, int));
 static void finish_sometimes_live      PROTO((struct sometimes *, int));
 static rtx reemit_notes                        PROTO((rtx, rtx));
 static void schedule_block             PROTO((int, FILE *));
@@ -1733,8 +1731,7 @@ sched_analyze_1 (x, insn)
              if (reg_last_sets[regno + i])
                add_dependence (insn, reg_last_sets[regno + i],
                                REG_DEP_OUTPUT);
-             reg_pending_sets[(regno + i) / REGSET_ELT_BITS]
-               |= (REGSET_ELT_TYPE) 1 << ((regno + i) % REGSET_ELT_BITS);
+             SET_REGNO_REG_SET (reg_pending_sets, regno + i);
              if ((call_used_regs[i] || global_regs[i])
                  && last_function_call)
                /* Function calls clobber all call_used regs.  */
@@ -1750,8 +1747,7 @@ sched_analyze_1 (x, insn)
          reg_last_uses[regno] = 0;
          if (reg_last_sets[regno])
            add_dependence (insn, reg_last_sets[regno], REG_DEP_OUTPUT);
-         reg_pending_sets[regno / REGSET_ELT_BITS]
-           |= (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
+         SET_REGNO_REG_SET (reg_pending_sets, regno);
 
          /* Pseudos that are REG_EQUIV to something may be replaced
             by that during reloading.  We need only add dependencies for
@@ -2132,18 +2128,11 @@ sched_analyze_insn (x, insn, loop_notes)
          sched_analyze_2 (XEXP (note, 0), insn);
     }
 
-  for (i = 0; i < regset_size; i++)
-    {
-      REGSET_ELT_TYPE sets = reg_pending_sets[i];
-      if (sets)
-       {
-         register int bit;
-         for (bit = 0; bit < REGSET_ELT_BITS; bit++)
-           if (sets & ((REGSET_ELT_TYPE) 1 << bit))
-             reg_last_sets[i * REGSET_ELT_BITS + bit] = insn;
-         reg_pending_sets[i] = 0;
-       }
-    }
+  EXECUTE_IF_SET_AND_RESET_IN_REG_SET (reg_pending_sets, 0, i,
+                                      {
+                                        reg_last_sets[i] = insn;
+                                      });
+
   if (reg_pending_sets_all)
     {
       for (i = 0; i < maxreg; i++)
@@ -2264,8 +2253,7 @@ sched_analyze (head, tail)
                    reg_last_uses[i] = 0;
                    if (reg_last_sets[i])
                      add_dependence (insn, reg_last_sets[i], REG_DEP_ANTI);
-                   reg_pending_sets[i / REGSET_ELT_BITS]
-                     |= (REGSET_ELT_TYPE) 1 << (i % REGSET_ELT_BITS);
+                   SET_REGNO_REG_SET (reg_pending_sets, i);
                  }
            }
 
@@ -2358,10 +2346,6 @@ sched_note_set (b, x, death)
   regno = REGNO (reg);
   if (regno >= FIRST_PSEUDO_REGISTER || ! global_regs[regno])
     {
-      register int offset = regno / REGSET_ELT_BITS;
-      register REGSET_ELT_TYPE bit
-       = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
-
       if (death)
        {
          /* If we only set part of the register, then this set does not
@@ -2375,17 +2359,14 @@ sched_note_set (b, x, death)
              int j = HARD_REGNO_NREGS (regno, GET_MODE (reg));
              while (--j >= 0)
                {
-                 offset = (regno + j) / REGSET_ELT_BITS;
-                 bit = (REGSET_ELT_TYPE) 1 << ((regno + j) % REGSET_ELT_BITS);
-                 
-                 bb_live_regs[offset] &= ~bit;
-                 bb_dead_regs[offset] |= bit;
+                 CLEAR_REGNO_REG_SET (bb_live_regs, regno + j);
+                 SET_REGNO_REG_SET (bb_dead_regs, regno + j);
                }
            }
          else
            {
-             bb_live_regs[offset] &= ~bit;
-             bb_dead_regs[offset] |= bit;
+             CLEAR_REGNO_REG_SET (bb_live_regs, regno);
+             SET_REGNO_REG_SET (bb_dead_regs, regno);
            }
        }
       else
@@ -2396,17 +2377,14 @@ sched_note_set (b, x, death)
              int j = HARD_REGNO_NREGS (regno, GET_MODE (reg));
              while (--j >= 0)
                {
-                 offset = (regno + j) / REGSET_ELT_BITS;
-                 bit = (REGSET_ELT_TYPE) 1 << ((regno + j) % REGSET_ELT_BITS);
-                 
-                 bb_live_regs[offset] |= bit;
-                 bb_dead_regs[offset] &= ~bit;
+                 SET_REGNO_REG_SET (bb_live_regs, regno + j);
+                 CLEAR_REGNO_REG_SET (bb_dead_regs, regno + j);
                }
            }
          else
            {
-             bb_live_regs[offset] |= bit;
-             bb_dead_regs[offset] &= ~bit;
+             SET_REGNO_REG_SET (bb_live_regs, regno);
+             CLEAR_REGNO_REG_SET (bb_dead_regs, regno);
            }
        }
     }
@@ -2524,14 +2502,12 @@ birthing_insn_p (pat)
     {
       rtx dest = SET_DEST (pat);
       int i = REGNO (dest);
-      int offset = i / REGSET_ELT_BITS;
-      REGSET_ELT_TYPE bit = (REGSET_ELT_TYPE) 1 << (i % REGSET_ELT_BITS);
 
       /* It would be more accurate to use refers_to_regno_p or
         reg_mentioned_p to determine when the dest is not live before this
         insn.  */
 
-      if (bb_live_regs[offset] & bit)
+      if (REGNO_REG_SET_P (bb_live_regs, i))
        return (REG_N_SETS (i) == 1);
 
       return 0;
@@ -2859,16 +2835,15 @@ attach_deaths (x, insn, set_p)
        /* This code is very similar to mark_used_1 (if set_p is false)
           and mark_set_1 (if set_p is true) in flow.c.  */
 
-       register int regno = REGNO (x);
-       register int offset = regno / REGSET_ELT_BITS;
-       register REGSET_ELT_TYPE bit
-         = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
-       REGSET_ELT_TYPE all_needed = (old_live_regs[offset] & bit);
-       REGSET_ELT_TYPE some_needed = (old_live_regs[offset] & bit);
+       register int regno;
+       int some_needed;
+       int all_needed;
 
        if (set_p)
          return;
 
+       regno = REGNO (x);
+       all_needed = some_needed = REGNO_REG_SET_P (old_live_regs, regno);
        if (regno < FIRST_PSEUDO_REGISTER)
          {
            int n;
@@ -2876,12 +2851,9 @@ attach_deaths (x, insn, set_p)
            n = HARD_REGNO_NREGS (regno, GET_MODE (x));
            while (--n > 0)
              {
-               some_needed |= (old_live_regs[(regno + n) / REGSET_ELT_BITS]
-                               & ((REGSET_ELT_TYPE) 1
-                                  << ((regno + n) % REGSET_ELT_BITS)));
-               all_needed &= (old_live_regs[(regno + n) / REGSET_ELT_BITS]
-                              & ((REGSET_ELT_TYPE) 1
-                                 << ((regno + n) % REGSET_ELT_BITS)));
+               int needed = (REGNO_REG_SET_P (old_live_regs, regno + n));
+               some_needed |= needed;
+               all_needed &= needed;
              }
          }
 
@@ -2943,9 +2915,7 @@ attach_deaths (x, insn, set_p)
                           register that is set in the insn.  */
                        for (i = HARD_REGNO_NREGS (regno, GET_MODE (x)) - 1;
                             i >= 0; i--)
-                         if ((old_live_regs[(regno + i) / REGSET_ELT_BITS]
-                              & ((REGSET_ELT_TYPE) 1
-                                 << ((regno +i) % REGSET_ELT_BITS))) == 0
+                         if (REGNO_REG_SET_P (old_live_regs, regno + i)
                              && ! dead_or_set_regno_p (insn, regno + i))
                            create_reg_dead_note (gen_rtx (REG,
                                                           reg_raw_mode[regno + i],
@@ -2960,18 +2930,14 @@ attach_deaths (x, insn, set_p)
                int j = HARD_REGNO_NREGS (regno, GET_MODE (x));
                while (--j >= 0)
                  {
-                   offset = (regno + j) / REGSET_ELT_BITS;
-                   bit
-                     = (REGSET_ELT_TYPE) 1 << ((regno + j) % REGSET_ELT_BITS);
-
-                   bb_dead_regs[offset] &= ~bit;
-                   bb_live_regs[offset] |= bit;
+                   CLEAR_REGNO_REG_SET (bb_dead_regs, regno + j);
+                   SET_REGNO_REG_SET (bb_live_regs, regno + j);
                  }
              }
            else
              {
-               bb_dead_regs[offset] &= ~bit;
-               bb_live_regs[offset] |= bit;
+               CLEAR_REGNO_REG_SET (bb_dead_regs, regno);
+               SET_REGNO_REG_SET (bb_live_regs, regno);
              }
          }
        return;
@@ -3113,13 +3079,12 @@ unlink_notes (insn, tail)
 /* Constructor for `sometimes' data structure.  */
 
 static int
-new_sometimes_live (regs_sometimes_live, offset, bit, sometimes_max)
+new_sometimes_live (regs_sometimes_live, regno, sometimes_max)
      struct sometimes *regs_sometimes_live;
-     int offset, bit;
+     int regno;
      int sometimes_max;
 {
   register struct sometimes *p;
-  register int regno = offset * REGSET_ELT_BITS + bit;
 
   /* There should never be a register greater than max_regno here.  If there
      is, it means that a define_split has created a new pseudo reg.  This
@@ -3129,8 +3094,7 @@ new_sometimes_live (regs_sometimes_live, offset, bit, sometimes_max)
     abort ();
 
   p = &regs_sometimes_live[sometimes_max];
-  p->offset = offset;
-  p->bit = bit;
+  p->regno = regno;
   p->live_length = 0;
   p->calls_crossed = 0;
   sometimes_max++;
@@ -3150,9 +3114,7 @@ finish_sometimes_live (regs_sometimes_live, sometimes_max)
   for (i = 0; i < sometimes_max; i++)
     {
       register struct sometimes *p = &regs_sometimes_live[i];
-      int regno;
-
-      regno = p->offset * REGSET_ELT_BITS + p->bit;
+      int regno = p->regno;
 
       sched_reg_live_length[regno] += p->live_length;
       sched_reg_n_calls_crossed[regno] += p->calls_crossed;
@@ -3240,8 +3202,8 @@ schedule_block (b, file)
   bzero ((char *) reg_last_uses, i * sizeof (rtx));
   reg_last_sets = (rtx *) alloca (i * sizeof (rtx));
   bzero ((char *) reg_last_sets, i * sizeof (rtx));
-  reg_pending_sets = (regset) alloca (regset_bytes);
-  bzero ((char *) reg_pending_sets, regset_bytes);
+  reg_pending_sets = ALLOCA_REG_SET ();
+  CLEAR_REG_SET (reg_pending_sets);
   reg_pending_sets_all = 0;
   clear_units ();
 
@@ -3526,12 +3488,8 @@ schedule_block (b, file)
                      if (call_used_regs[j] && ! global_regs[j]
                          && ! fixed_regs[j])
                        {
-                         register int offset = j / REGSET_ELT_BITS;
-                         register REGSET_ELT_TYPE bit
-                           = (REGSET_ELT_TYPE) 1 << (j % REGSET_ELT_BITS);
-
-                         bb_live_regs[offset] |= bit;
-                         bb_dead_regs[offset] &= ~bit;
+                         SET_REGNO_REG_SET (bb_live_regs, j);
+                         CLEAR_REGNO_REG_SET (bb_dead_regs, j);
                        }
                  }
 
@@ -3543,9 +3501,6 @@ schedule_block (b, file)
                        && GET_CODE (XEXP (link, 0)) == REG)
                      {
                        register int regno = REGNO (XEXP (link, 0));
-                       register int offset = regno / REGSET_ELT_BITS;
-                       register REGSET_ELT_TYPE bit
-                         = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
 
                        if (regno < FIRST_PSEUDO_REGISTER)
                          {
@@ -3553,18 +3508,14 @@ schedule_block (b, file)
                                                      GET_MODE (XEXP (link, 0)));
                            while (--j >= 0)
                              {
-                               offset = (regno + j) / REGSET_ELT_BITS;
-                               bit = ((REGSET_ELT_TYPE) 1
-                                      << ((regno + j) % REGSET_ELT_BITS));
-
-                               bb_live_regs[offset] &= ~bit;
-                               bb_dead_regs[offset] |= bit;
+                               CLEAR_REGNO_REG_SET (bb_live_regs, regno + j);
+                               SET_REGNO_REG_SET (bb_dead_regs, regno + j);
                              }
                          }
                        else
                          {
-                           bb_live_regs[offset] &= ~bit;
-                           bb_dead_regs[offset] |= bit;
+                           CLEAR_REGNO_REG_SET (bb_live_regs, regno);
+                           SET_REGNO_REG_SET (bb_dead_regs, regno);
                          }
                      }
                  }
@@ -3647,12 +3598,8 @@ schedule_block (b, file)
                if (call_used_regs[j] && ! global_regs[j]
                    && ! fixed_regs[j])
                  {
-                   register int offset = j / REGSET_ELT_BITS;
-                   register REGSET_ELT_TYPE bit
-                     = (REGSET_ELT_TYPE) 1 << (j % REGSET_ELT_BITS);
-
-                   bb_live_regs[offset] |= bit;
-                   bb_dead_regs[offset] &= ~bit;
+                   SET_REGNO_REG_SET (bb_live_regs, j);
+                   CLEAR_REGNO_REG_SET (bb_dead_regs, j);
                  }
            }
 
@@ -3666,9 +3613,6 @@ schedule_block (b, file)
                  && GET_CODE (XEXP (link, 0)) == REG)
                {
                  register int regno = REGNO (XEXP (link, 0));
-                 register int offset = regno / REGSET_ELT_BITS;
-                 register REGSET_ELT_TYPE bit
-                   = (REGSET_ELT_TYPE) 1 << (regno % REGSET_ELT_BITS);
 
                  /* Only unlink REG_DEAD notes; leave REG_UNUSED notes
                     alone.  */
@@ -3690,18 +3634,14 @@ schedule_block (b, file)
                                                GET_MODE (XEXP (link, 0)));
                      while (--j >= 0)
                        {
-                         offset = (regno + j) / REGSET_ELT_BITS;
-                         bit = ((REGSET_ELT_TYPE) 1
-                                << ((regno + j) % REGSET_ELT_BITS));
-
-                         bb_live_regs[offset] &= ~bit;
-                         bb_dead_regs[offset] |= bit;
+                         CLEAR_REGNO_REG_SET (bb_live_regs, regno + j);
+                         SET_REGNO_REG_SET (bb_dead_regs, regno + j);
                        }
                    }
                  else
                    {
-                     bb_live_regs[offset] &= ~bit;
-                     bb_dead_regs[offset] |= bit;
+                     CLEAR_REGNO_REG_SET (bb_live_regs, regno);
+                     SET_REGNO_REG_SET (bb_dead_regs, regno);
                    }
                }
              else
@@ -3713,25 +3653,19 @@ schedule_block (b, file)
   if (reload_completed == 0)
     {
       /* Keep track of register lives.  */
-      old_live_regs = (regset) alloca (regset_bytes);
+      old_live_regs = ALLOCA_REG_SET ();
       regs_sometimes_live
        = (struct sometimes *) alloca (max_regno * sizeof (struct sometimes));
       sometimes_max = 0;
 
       /* Start with registers live at end.  */
-      for (j = 0; j < regset_size; j++)
-       {
-         REGSET_ELT_TYPE live = bb_live_regs[j];
-         old_live_regs[j] = live;
-         if (live)
-           {
-             register int bit;
-             for (bit = 0; bit < REGSET_ELT_BITS; bit++)
-               if (live & ((REGSET_ELT_TYPE) 1 << bit))
-                 sometimes_max = new_sometimes_live (regs_sometimes_live, j,
-                                                     bit, sometimes_max);
-           }
-       }
+      COPY_REG_SET (old_live_regs, bb_live_regs);
+      EXECUTE_IF_SET_IN_REG_SET (bb_live_regs, 0, j,
+                                {
+                                  sometimes_max
+                                    = new_sometimes_live (regs_sometimes_live,
+                                                          j, sometimes_max);
+                                });
     }
 
   SCHED_SORT (ready, n_ready, 1);
@@ -3902,12 +3836,8 @@ schedule_block (b, file)
                    if (call_used_regs[i] && ! global_regs[i]
                        && ! fixed_regs[i])
                      {
-                       register int offset = i / REGSET_ELT_BITS;
-                       register REGSET_ELT_TYPE bit
-                         = (REGSET_ELT_TYPE) 1 << (i % REGSET_ELT_BITS);
-
-                       bb_live_regs[offset] &= ~bit;
-                       bb_dead_regs[offset] |= bit;
+                       CLEAR_REGNO_REG_SET (bb_live_regs, i);
+                       SET_REGNO_REG_SET (bb_dead_regs, i);
                      }
 
                  /* Regs live at the time of a call instruction must not
@@ -3918,8 +3848,7 @@ schedule_block (b, file)
                     (below).  */
                  p = regs_sometimes_live;
                  for (i = 0; i < sometimes_max; i++, p++)
-                   if (bb_live_regs[p->offset]
-                       & ((REGSET_ELT_TYPE) 1 << p->bit))
+                   if (REGNO_REG_SET_P (bb_live_regs, p->regno))
                      p->calls_crossed += 1;
                }
 
@@ -3928,20 +3857,12 @@ schedule_block (b, file)
              attach_deaths_insn (insn);
 
              /* Find registers now made live by that instruction.  */
-             for (i = 0; i < regset_size; i++)
-               {
-                 REGSET_ELT_TYPE diff = bb_live_regs[i] & ~old_live_regs[i];
-                 if (diff)
-                   {
-                     register int bit;
-                     old_live_regs[i] |= diff;
-                     for (bit = 0; bit < REGSET_ELT_BITS; bit++)
-                       if (diff & ((REGSET_ELT_TYPE) 1 << bit))
-                         sometimes_max
-                           = new_sometimes_live (regs_sometimes_live, i, bit,
-                                                 sometimes_max);
-                   }
-               }
+             EXECUTE_IF_SET_IN_REG_SET (bb_live_regs, 0, i,
+                                        {
+                                          sometimes_max
+                                            = new_sometimes_live (regs_sometimes_live,
+                                                                  i, sometimes_max);
+                                        });
 
              /* Count lengths of all regs we are worrying about now,
                 and handle registers no longer live.  */
@@ -3949,20 +3870,18 @@ schedule_block (b, file)
              for (i = 0; i < sometimes_max; i++)
                {
                  register struct sometimes *p = &regs_sometimes_live[i];
-                 int regno = p->offset*REGSET_ELT_BITS + p->bit;
+                 int regno = p->regno;
 
                  p->live_length += 1;
 
-                 if ((bb_live_regs[p->offset]
-                      & ((REGSET_ELT_TYPE) 1 << p->bit)) == 0)
+                 if (REGNO_REG_SET_P (bb_live_regs, p->regno))
                    {
                      /* This is the end of one of this register's lifetime
                         segments.  Save the lifetime info collected so far,
                         and clear its bit in the old_live_regs entry.  */
                      sched_reg_live_length[regno] += p->live_length;
                      sched_reg_n_calls_crossed[regno] += p->calls_crossed;
-                     old_live_regs[p->offset]
-                       &= ~((REGSET_ELT_TYPE) 1 << p->bit);
+                     CLEAR_REGNO_REG_SET (old_live_regs, p->regno);
 
                      /* Delete the reg_sometimes_live entry for this reg by
                         copying the last entry over top of it.  */
@@ -4875,8 +4794,8 @@ schedule_insns (dump_file)
     {
       sched_reg_n_calls_crossed = (int *) alloca (max_regno * sizeof (int));
       sched_reg_live_length = (int *) alloca (max_regno * sizeof (int));
-      bb_dead_regs = (regset) alloca (regset_bytes);
-      bb_live_regs = (regset) alloca (regset_bytes);
+      bb_dead_regs = ALLOCA_REG_SET ();
+      bb_live_regs = ALLOCA_REG_SET ();
       bzero ((char *) sched_reg_n_calls_crossed, max_regno * sizeof (int));
       bzero ((char *) sched_reg_live_length, max_regno * sizeof (int));
       init_alias_analysis ();