gcse.c (want_to_gcse_p): On STACK_REGS targets...
* gcse.c (want_to_gcse_p): On STACK_REGS targets, look through constant pool references to identify stack mode constants. * rtlanal.c (constant_pool_constant_p): New predicate to check whether operand is a floating point constant in the pool. * rtl.h (constant_pool_constant_p): Prototype here. * loop.c (scan_loop): Avoid hoisting constants from the constant pool on STACK_REGS targets. (load_mems): Likewise. * loop-invariant.c (get_inv_cost): Make hoisting constant pool loads into x87 registers expensive in terms of register pressure. Co-Authored-By: Steven Bosscher <stevenb.gcc@gmail.com> From-SVN: r111283
This commit is contained in:
parent
c2a8530e21
commit
3d8504ac32
|
@ -1,3 +1,17 @@
|
|||
2006-02-19 Roger Sayle <roger@eyesopen.com>
|
||||
Steven Bosscher <stevenb.gcc@gmail.com>
|
||||
|
||||
* gcse.c (want_to_gcse_p): On STACK_REGS targets, look through
|
||||
constant pool references to identify stack mode constants.
|
||||
* rtlanal.c (constant_pool_constant_p): New predicate to check
|
||||
whether operand is a floating point constant in the pool.
|
||||
* rtl.h (constant_pool_constant_p): Prototype here.
|
||||
* loop.c (scan_loop): Avoid hoisting constants from the constant
|
||||
pool on STACK_REGS targets.
|
||||
(load_mems): Likewise.
|
||||
* loop-invariant.c (get_inv_cost): Make hoisting constant pool
|
||||
loads into x87 registers expensive in terms of register pressure.
|
||||
|
||||
2006-02-19 Roger Sayle <roger@eyesopen.com>
|
||||
|
||||
* gthr-posix.h: On Tru64, map __gthr_foo as a weak reference to
|
||||
|
|
|
@ -1170,6 +1170,14 @@ static basic_block current_bb;
|
|||
static int
|
||||
want_to_gcse_p (rtx x)
|
||||
{
|
||||
#ifdef STACK_REGS
|
||||
/* On register stack architectures, don't GCSE constants from the
|
||||
constant pool, as the benefits are often swamped by the overhead
|
||||
of shuffling the register stack between basic blocks. */
|
||||
if (IS_STACK_MODE (GET_MODE (x)))
|
||||
x = avoid_constant_pool_reference (x);
|
||||
#endif
|
||||
|
||||
switch (GET_CODE (x))
|
||||
{
|
||||
case REG:
|
||||
|
|
|
@ -932,6 +932,32 @@ get_inv_cost (struct invariant *inv, int *comp_cost, unsigned *regs_needed)
|
|||
(*regs_needed)++;
|
||||
(*comp_cost) += inv->cost;
|
||||
|
||||
#ifdef STACK_REGS
|
||||
{
|
||||
/* Hoisting constant pool constants into stack regs may cost more than
|
||||
just single register. On x87, the balance is affected both by the
|
||||
small number of FP registers, and by its register stack organisation,
|
||||
that forces us to add compensation code in and around the loop to
|
||||
shuffle the operands to the top of stack before use, and pop them
|
||||
from the stack after the loop finishes.
|
||||
|
||||
To model this effect, we increase the number of registers needed for
|
||||
stack registers by two: one register push, and one register pop.
|
||||
This usually has the effect that FP constant loads from the constant
|
||||
pool are not moved out of the loop.
|
||||
|
||||
Note that this also means that dependent invariants can not be moved.
|
||||
However, the primary purpose of this pass is to move loop invariant
|
||||
address arithmetic out of loops, and address arithmetic that depends
|
||||
on floating point constants is unlikely to ever occur. */
|
||||
rtx set = single_set (inv->insn);
|
||||
if (set
|
||||
&& IS_STACK_MODE (GET_MODE (SET_SRC (set)))
|
||||
&& constant_pool_constant_p (SET_SRC (set)))
|
||||
(*regs_needed) += 2;
|
||||
}
|
||||
#endif
|
||||
|
||||
EXECUTE_IF_SET_IN_BITMAP (inv->depends_on, 0, depno, bi)
|
||||
{
|
||||
dep = VEC_index (invariant_p, invariants, depno);
|
||||
|
|
13
gcc/loop.c
13
gcc/loop.c
|
@ -1222,6 +1222,12 @@ scan_loop (struct loop *loop, int flags)
|
|||
if (GET_MODE_CLASS (GET_MODE (SET_DEST (set))) == MODE_CC
|
||||
&& CONSTANT_P (src))
|
||||
;
|
||||
#ifdef STACK_REGS
|
||||
/* Don't hoist constant pool constants into stack regs. */
|
||||
else if (IS_STACK_MODE (GET_MODE (SET_SRC (set)))
|
||||
&& constant_pool_constant_p (SET_SRC (set)))
|
||||
;
|
||||
#endif
|
||||
/* Don't try to optimize a register that was made
|
||||
by loop-optimization for an inner loop.
|
||||
We don't know its life-span, so we can't compute
|
||||
|
@ -10823,6 +10829,13 @@ load_mems (const struct loop *loop)
|
|||
&& SCALAR_FLOAT_MODE_P (GET_MODE (mem)))
|
||||
loop_info->mems[i].optimize = 0;
|
||||
|
||||
#ifdef STACK_REGS
|
||||
/* Don't hoist constant pool constants into stack registers. */
|
||||
if (IS_STACK_MODE (GET_MODE (mem))
|
||||
&& constant_pool_constant_p (mem))
|
||||
loop_info->mems[i].optimize = 0;
|
||||
#endif
|
||||
|
||||
/* If this MEM is written to, we must be sure that there
|
||||
are no reads from another MEM that aliases this one. */
|
||||
if (loop_info->mems[i].optimize && written)
|
||||
|
|
|
@ -1046,6 +1046,7 @@ extern bool subreg_offset_representable_p (unsigned int, enum machine_mode,
|
|||
extern unsigned int subreg_regno (rtx);
|
||||
extern unsigned HOST_WIDE_INT nonzero_bits (rtx, enum machine_mode);
|
||||
extern unsigned int num_sign_bit_copies (rtx, enum machine_mode);
|
||||
extern bool constant_pool_constant_p (rtx);
|
||||
|
||||
|
||||
/* 1 if RTX is a subreg containing a reg that is already known to be
|
||||
|
|
|
@ -4800,3 +4800,12 @@ init_rtlanal (void)
|
|||
non_rtx_starting_operands[i] = first ? first - format : -1;
|
||||
}
|
||||
}
|
||||
|
||||
/* Check whether this is a constant pool constant. */
|
||||
bool
|
||||
constant_pool_constant_p (rtx x)
|
||||
{
|
||||
x = avoid_constant_pool_reference (x);
|
||||
return GET_CODE (x) == CONST_DOUBLE;
|
||||
}
|
||||
|
||||
|
|
Loading…
Reference in New Issue