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:
Roger Sayle 2006-02-19 22:01:17 +00:00 committed by Roger Sayle
parent c2a8530e21
commit 3d8504ac32
6 changed files with 71 additions and 0 deletions

View File

@ -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

View File

@ -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:

View File

@ -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);

View File

@ -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)

View File

@ -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

View File

@ -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;
}