aboutsummaryrefslogtreecommitdiff
path: root/gcc
diff options
context:
space:
mode:
authorRoger Sayle <roger@eyesopen.com>2006-02-19 22:01:17 +0000
committerRoger Sayle <sayle@gcc.gnu.org>2006-02-19 22:01:17 +0000
commit3d8504ac3262976d2c63d547a07aef0874f530b6 (patch)
tree548133d8c92115bf18fa7c2d6f3e7800dbd456bb /gcc
parentc2a8530e21c7a3bc4824d00e0bb8ff39009da43a (diff)
downloadgcc-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/ChangeLog14
-rw-r--r--gcc/gcse.c8
-rw-r--r--gcc/loop-invariant.c26
-rw-r--r--gcc/loop.c13
-rw-r--r--gcc/rtl.h1
-rw-r--r--gcc/rtlanal.c9
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.
diff --git a/gcc/gcse.c b/gcc/gcse.c
index 93c366b..4270737 100644
--- a/gcc/gcse.c
+++ b/gcc/gcse.c
@@ -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);
diff --git a/gcc/loop.c b/gcc/loop.c
index 1beb4dc..dc9d3a0 100644
--- a/gcc/loop.c
+++ b/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)
diff --git a/gcc/rtl.h b/gcc/rtl.h
index 45fe6a0..e35c805 100644
--- a/gcc/rtl.h
+++ b/gcc/rtl.h
@@ -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;
+}
+