diff options
author | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-02-19 22:01:17 +0000 |
---|---|---|
committer | sayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4> | 2006-02-19 22:01:17 +0000 |
commit | e207fd7ae6bbf4146f40cc68e841a2576695d7ca (patch) | |
tree | 548133d8c92115bf18fa7c2d6f3e7800dbd456bb /gcc/loop-invariant.c | |
parent | 3b19d3be1ae915879fa5f404b2cb88242058d980 (diff) | |
download | gcc-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.c | 26 |
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); |