OSDN Git Service

* gcse.c (want_to_gcse_p): On STACK_REGS targets, look through
authorsayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 19 Feb 2006 22:01:17 +0000 (22:01 +0000)
committersayle <sayle@138bc75d-0d04-0410-961f-82ee72b054a4>
Sun, 19 Feb 2006 22:01:17 +0000 (22:01 +0000)
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

gcc/ChangeLog
gcc/gcse.c
gcc/loop-invariant.c
gcc/loop.c
gcc/rtl.h
gcc/rtlanal.c

index f855ed0..988eed4 100644 (file)
@@ -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.
index 93c366b..4270737 100644 (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:
index 04531a0..3f8f6e3 100644 (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);
index 1beb4dc..dc9d3a0 100644 (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)
index 45fe6a0..e35c805 100644 (file)
--- 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
index 1390ad9..7c7731b 100644 (file)
@@ -4800,3 +4800,12 @@ init_rtlanal (void)
       non_rtx_starting_operands[i] = first ? first - format : -1;
     }
 }
+\f
+/* 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;
+}
+