parent
2217c9f0e8
commit
916b1701c2
|
@ -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;
|
||||
|
|
|
@ -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
|
||||
|
|
347
gcc/flow.c
347
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 int regno;
|
||||
register int *p;
|
||||
|
||||
EXECUTE_IF_AND_COMPL_IN_REG_SET (live, maxlive, 0, regno,
|
||||
{
|
||||
regs_sometimes_live[sometimes_max++] = regno;
|
||||
SET_REGNO_REG_SET (maxlive, regno);
|
||||
});
|
||||
|
||||
p = regs_sometimes_live;
|
||||
for (i = 0; i < sometimes_max; i++)
|
||||
{
|
||||
register REGSET_ELT_TYPE diff = live[i] & ~maxlive[i];
|
||||
|
||||
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++;
|
||||
}
|
||||
}
|
||||
regno = *p++;
|
||||
if (REGNO_REG_SET_P (old, regno))
|
||||
REG_LIVE_LENGTH (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)++;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
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");
|
||||
|
|
48
gcc/global.c
48
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);
|
||||
}
|
||||
}
|
||||
|
||||
|
|
28
gcc/reorg.c
28
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
|
||||
REG_SET_TO_HARD_REG_SET (current_live_regs, regs_live);
|
||||
|
||||
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);
|
||||
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
|
||||
|
|
225
gcc/sched.c
225
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 ();
|
||||
|
|
Loading…
Reference in New Issue