summaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorMichael Meissner <meissner@gcc.gnu.org>1997-06-05 10:24:03 +0000
committerMichael Meissner <meissner@gcc.gnu.org>1997-06-05 10:24:03 +0000
commit916b1701c2f14c41c71a8dc6816e49a24e9609e4 (patch)
tree619a5e6cc2340785ce05f2bf95307154e057626d /gcc
parent2217c9f0e87acd69fb5e2675cee25bc97c32f4ef (diff)
downloadgcc-916b1701c2f14c41c71a8dc6816e49a24e9609e4.tar.gz
abstract regset stuff into macros
From-SVN: r14147
Diffstat (limited to 'gcc')
-rw-r--r--gcc/basic-block.h221
-rw-r--r--gcc/caller-save.c31
-rw-r--r--gcc/flow.c347
-rw-r--r--gcc/global.c48
-rw-r--r--gcc/reorg.c30
-rw-r--r--gcc/sched.c225
6 files changed, 458 insertions, 444 deletions
diff --git a/gcc/basic-block.h b/gcc/basic-block.h
index 3d1f3a9f30b..a6b8cf9dc52 100644
--- a/gcc/basic-block.h
+++ b/gcc/basic-block.h
@@ -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;
diff --git a/gcc/caller-save.c b/gcc/caller-save.c
index f05f3271d96..51b9d5a8f62 100644
--- a/gcc/caller-save.c
+++ b/gcc/caller-save.c
@@ -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
diff --git a/gcc/flow.c b/gcc/flow.c
index 355a35e90d6..d39b784c6a4 100644
--- a/gcc/flow.c
+++ b/gcc/flow.c
@@ -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));
}
/* 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");
diff --git a/gcc/global.c b/gcc/global.c
index ed2f9eaa561..9ebd5a7d294 100644
--- a/gcc/global.c
+++ b/gcc/global.c
@@ -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);
}
}
diff --git a/gcc/reorg.c b/gcc/reorg.c
index 8cd44731a5e..5abf1bb1899 100644
--- a/gcc/reorg.c
+++ b/gcc/reorg.c
@@ -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
diff --git a/gcc/sched.c b/gcc/sched.c
index 262796851b0..1fa338f2e25 100644
--- a/gcc/sched.c
+++ b/gcc/sched.c
@@ -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 ();