diff options
author | Roger Sayle <roger@eyesopen.com> | 2006-02-19 22:01:17 +0000 |
---|---|---|
committer | Roger Sayle <sayle@gcc.gnu.org> | 2006-02-19 22:01:17 +0000 |
commit | 3d8504ac3262976d2c63d547a07aef0874f530b6 (patch) | |
tree | 548133d8c92115bf18fa7c2d6f3e7800dbd456bb /gcc | |
parent | c2a8530e21c7a3bc4824d00e0bb8ff39009da43a (diff) | |
download | gcc-3d8504ac3262976d2c63d547a07aef0874f530b6.zip gcc-3d8504ac3262976d2c63d547a07aef0874f530b6.tar.gz gcc-3d8504ac3262976d2c63d547a07aef0874f530b6.tar.bz2 |
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
Diffstat (limited to 'gcc')
-rw-r--r-- | gcc/ChangeLog | 14 | ||||
-rw-r--r-- | gcc/gcse.c | 8 | ||||
-rw-r--r-- | gcc/loop-invariant.c | 26 | ||||
-rw-r--r-- | gcc/loop.c | 13 | ||||
-rw-r--r-- | gcc/rtl.h | 1 | ||||
-rw-r--r-- | gcc/rtlanal.c | 9 |
6 files changed, 71 insertions, 0 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index f855ed0..988eed4 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,4 +1,18 @@ 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 __foo and not foo when _PTHREAD_USE_MANGLED_NAMES_ is defined. @@ -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: diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c index 04531a0..3f8f6e3 100644 --- a/gcc/loop-invariant.c +++ b/gcc/loop-invariant.c @@ -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); @@ -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 diff --git a/gcc/rtlanal.c b/gcc/rtlanal.c index 1390ad9..7c7731b 100644 --- a/gcc/rtlanal.c +++ b/gcc/rtlanal.c @@ -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; +} + |