summaryrefslogtreecommitdiff
path: root/gcc/loop-invariant.c
diff options
context:
space:
mode:
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-19 22:01:17 +0000
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>2006-02-19 22:01:17 +0000
commite207fd7ae6bbf4146f40cc68e841a2576695d7ca (patch)
tree548133d8c92115bf18fa7c2d6f3e7800dbd456bb /gcc/loop-invariant.c
parent3b19d3be1ae915879fa5f404b2cb88242058d980 (diff)
downloadgcc-e207fd7ae6bbf4146f40cc68e841a2576695d7ca.tar.gz
* 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. git-svn-id: svn+ssh://gcc.gnu.org/svn/gcc/trunk@111283 138bc75d-0d04-0410-961f-82ee72b054a4
Diffstat (limited to 'gcc/loop-invariant.c')
-rw-r--r--gcc/loop-invariant.c26
1 files changed, 26 insertions, 0 deletions
diff --git a/gcc/loop-invariant.c b/gcc/loop-invariant.c
index 04531a0e05f..3f8f6e34848 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);