From 916b1701c2f14c41c71a8dc6816e49a24e9609e4 Mon Sep 17 00:00:00 2001 From: Michael Meissner Date: Thu, 5 Jun 1997 10:24:03 +0000 Subject: [PATCH] abstract regset stuff into macros From-SVN: r14147 --- gcc/basic-block.h | 221 +++++++++++++++++++++++++++++++++- gcc/caller-save.c | 31 ++--- gcc/flow.c | 347 +++++++++++++++++++++--------------------------------- gcc/global.c | 48 +++----- gcc/reorg.c | 30 ++--- gcc/sched.c | 225 +++++++++++------------------------ 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 = ®s_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 = ®s_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 = ®s_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 (); -- 2.11.4.GIT