invoke.texi (avoid-indexed-addresses): Document new option.
authorPat Haugen <pthaugen@us.ibm.com>
Wed, 28 Jan 2009 18:51:53 +0000 (18:51 +0000)
committerPat Haugen <pthaugen@gcc.gnu.org>
Wed, 28 Jan 2009 18:51:53 +0000 (18:51 +0000)
* doc/invoke.texi (avoid-indexed-addresses): Document new option.
* config/rs6000/rs6000-protos.h (avoiding_indexed_address_p): Declare.
* config/rs6000/rs6000.opt (avoid-indexed-addresses): New option.
* config/rs6000/rs6000.c (rs6000_override_options): Default
avoid-indexed-addresses on for Power6, off for everything else.
(avoiding_indexed_address_p): New function.
(rs6000_legitimize_address): Use it.
(rs6000_legitimate_address): Likewise.
* config/rs6000/rs6000.md (movXX_updateX): Likewise
* gcc.target/powerpc/avoid-indexed-addresses.c: New test.

From-SVN: r143742

gcc/ChangeLog
gcc/config/rs6000/rs6000-protos.h
gcc/config/rs6000/rs6000.c
gcc/config/rs6000/rs6000.md
gcc/config/rs6000/rs6000.opt
gcc/doc/invoke.texi
gcc/testsuite/ChangeLog
gcc/testsuite/gcc.target/powerpc/avoid-indexed-addresses.c [new file with mode: 0644]

index da53b53358b3337942b8809f0d7e39b74a03c2c8..5f99aab0337783da7b6edba467269bbaa6df5d11 100644 (file)
@@ -1,3 +1,15 @@
+2009-01-28  Pat Haugen  <pthaugen@us.ibm.com>
+
+       * doc/invoke.texi (avoid-indexed-addresses): Document new option.
+       * config/rs6000/rs6000-protos.h (avoiding_indexed_address_p): Declare.
+       * config/rs6000/rs6000.opt (avoid-indexed-addresses): New option.
+       * config/rs6000/rs6000.c (rs6000_override_options): Default
+       avoid-indexed-addresses on for Power6, off for everything else.
+       (avoiding_indexed_address_p): New function.
+       (rs6000_legitimize_address): Use it.
+       (rs6000_legitimate_address): Likewise.
+       * config/rs6000/rs6000.md (movXX_updateX): Likewise
+
 2009-01-28  Kazu Hirata  <kazu@codesourcery.com>
 
        PR tree-optimization/38997
index 2f1b04c4f386983543e0ad0aec122208bdec165e..4e2ecd3ec4a542bd0c570d8254ceb61e0ce9ae42 100644 (file)
@@ -42,6 +42,7 @@ extern void validate_condition_mode (enum rtx_code, enum machine_mode);
 extern bool legitimate_constant_pool_address_p (rtx);
 extern bool legitimate_indirect_address_p (rtx, int);
 extern bool legitimate_indexed_address_p (rtx, int);
+extern bool avoiding_indexed_address_p (enum machine_mode);
 
 extern rtx rs6000_got_register (rtx);
 extern rtx find_addr_reg (rtx);
index 6d7327b5ea4dd5cb3ec1d9ae2602bdd2e80473a3..d2ebf628f5730c29e01b6d0362e96529bf5ee190 100644 (file)
@@ -1987,6 +1987,13 @@ rs6000_override_options (const char *default_cpu)
       rs6000_single_float = rs6000_double_float = 1;
   }
 
+  /* If not explicitly specified via option, decide whether to generate indexed
+     load/store instructions.  */
+  if (TARGET_AVOID_XFORM == -1)
+    /* Avoid indexed addressing when targeting Power6 in order to avoid
+     the DERAT mispredict penalty.  */
+    TARGET_AVOID_XFORM = (rs6000_cpu == PROCESSOR_POWER6 && TARGET_CMPB);
+
   rs6000_init_hard_regno_mode_ok ();
 }
 
@@ -3704,6 +3711,14 @@ legitimate_indexed_address_p (rtx x, int strict)
                  && INT_REG_OK_FOR_INDEX_P (op0, strict))));
 }
 
+bool
+avoiding_indexed_address_p (enum machine_mode mode)
+{
+  /* Avoid indexed addressing for modes that have non-indexed
+     load/store instruction forms.  */
+  return TARGET_AVOID_XFORM && !ALTIVEC_VECTOR_MODE (mode);
+}
+
 inline bool
 legitimate_indirect_address_p (rtx x, int strict)
 {
@@ -3830,6 +3845,7 @@ rs6000_legitimize_address (rtx x, rtx oldx ATTRIBUTE_UNUSED,
               || ((mode != DImode && mode != DFmode && mode != DDmode)
                   || (TARGET_E500_DOUBLE && mode != DDmode)))
           && (TARGET_POWERPC64 || mode != DImode)
+          && !avoiding_indexed_address_p (mode)
           && mode != TImode
           && mode != TFmode
           && mode != TDmode)
@@ -4441,6 +4457,7 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
          || (mode != DFmode && mode != DDmode)
          || (TARGET_E500_DOUBLE && mode != DDmode))
       && (TARGET_POWERPC64 || mode != DImode)
+      && !avoiding_indexed_address_p (mode)
       && legitimate_indexed_address_p (x, reg_ok_strict))
     return 1;
   if (GET_CODE (x) == PRE_MODIFY
@@ -4459,7 +4476,8 @@ rs6000_legitimate_address (enum machine_mode mode, rtx x, int reg_ok_strict)
       && TARGET_UPDATE
       && legitimate_indirect_address_p (XEXP (x, 0), reg_ok_strict)
       && (rs6000_legitimate_offset_address_p (mode, XEXP (x, 1), reg_ok_strict)
-         || legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict))
+         || (!avoiding_indexed_address_p (mode)
+             && legitimate_indexed_address_p (XEXP (x, 1), reg_ok_strict)))
       && rtx_equal_p (XEXP (XEXP (x, 1), 0), XEXP (x, 0)))
     return 1;
   if (legitimate_lo_sum_address_p (mode, x, reg_ok_strict))
index a5a6ec17b269f4e193c9720aeffa444ecad0914f..b6f41814ebac4d42361bb38ff1cbd3a717fcf8a1 100644 (file)
                         (match_operand:DI 2 "reg_or_aligned_short_operand" "r,I"))))
    (set (match_operand:DI 0 "gpc_reg_operand" "=b,b")
        (plus:DI (match_dup 1) (match_dup 2)))]
-  "TARGET_POWERPC64 && TARGET_UPDATE"
+  "TARGET_POWERPC64 && TARGET_UPDATE
+   && (!avoiding_indexed_address_p (DImode)
+       || !gpc_reg_operand (operands[2], DImode))"
   "@
    ldux %3,%0,%2
    ldu %3,%2(%0)"
        (match_operand:DI 3 "gpc_reg_operand" "r,r"))
    (set (match_operand:P 0 "gpc_reg_operand" "=b,b")
        (plus:P (match_dup 1) (match_dup 2)))]
-  "TARGET_POWERPC64 && TARGET_UPDATE"
+  "TARGET_POWERPC64 && TARGET_UPDATE
+   && (!avoiding_indexed_address_p (Pmode)
+       || !gpc_reg_operand (operands[2], Pmode)
+       || (REG_P (operands[0])
+          && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
   "@
    stdux %3,%0,%2
    stdu %3,%2(%0)"
                         (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_UPDATE"
+  "TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    {lux|lwzux} %3,%0,%2
    {lu|lwzu} %3,%2(%0)"
                          (match_operand:DI 2 "gpc_reg_operand" "r")))))
    (set (match_operand:DI 0 "gpc_reg_operand" "=b")
        (plus:DI (match_dup 1) (match_dup 2)))]
-  "TARGET_POWERPC64 && rs6000_gen_cell_microcode"
+  "TARGET_POWERPC64 && rs6000_gen_cell_microcode
+   && !avoiding_indexed_address_p (DImode)"
   "lwaux %3,%0,%2"
   [(set_attr "type" "load_ext_ux")])
 
        (match_operand:SI 3 "gpc_reg_operand" "r,r"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_UPDATE"
+  "TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode)
+       || (REG_P (operands[0])
+          && REGNO (operands[0]) == STACK_POINTER_REGNUM))"
   "@
    {stux|stwux} %3,%0,%2
    {stu|stwu} %3,%2(%0)"
                         (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_UPDATE"
+  "TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    lhzux %3,%0,%2
    lhzu %3,%2(%0)"
                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_UPDATE"
+  "TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    lhzux %3,%0,%2
    lhzu %3,%2(%0)"
                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_UPDATE && rs6000_gen_cell_microcode"
+  "TARGET_UPDATE && rs6000_gen_cell_microcode
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    lhaux %3,%0,%2
    lhau %3,%2(%0)"
        (match_operand:HI 3 "gpc_reg_operand" "r,r"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_UPDATE"
+  "TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    sthux %3,%0,%2
    sthu %3,%2(%0)"
                         (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_UPDATE"
+  "TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    lbzux %3,%0,%2
    lbzu %3,%2(%0)"
                          (match_operand:SI 2 "reg_or_short_operand" "r,I")))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_UPDATE"
+  "TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    lbzux %3,%0,%2
    lbzu %3,%2(%0)"
        (match_operand:QI 3 "gpc_reg_operand" "r,r"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_UPDATE"
+  "TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    stbux %3,%0,%2
    stbu %3,%2(%0)"
                         (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    lfsux %3,%0,%2
    lfsu %3,%2(%0)"
        (match_operand:SF 3 "gpc_reg_operand" "f,f"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_SINGLE_FLOAT && TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    stfsux %3,%0,%2
    stfsu %3,%2(%0)"
                         (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE"
+  "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    {lux|lwzux} %3,%0,%2
    {lu|lwzu} %3,%2(%0)"
        (match_operand:SF 3 "gpc_reg_operand" "r,r"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE"
+  "(TARGET_SOFT_FLOAT || !TARGET_FPRS) && TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    {stux|stwux} %3,%0,%2
    {stu|stwu} %3,%2(%0)"
                         (match_operand:SI 2 "reg_or_short_operand" "r,I"))))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    lfdux %3,%0,%2
    lfdu %3,%2(%0)"
        (match_operand:DF 3 "gpc_reg_operand" "f,f"))
    (set (match_operand:SI 0 "gpc_reg_operand" "=b,b")
        (plus:SI (match_dup 1) (match_dup 2)))]
-  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE"
+  "TARGET_HARD_FLOAT && TARGET_FPRS && TARGET_DOUBLE_FLOAT && TARGET_UPDATE
+   && (!avoiding_indexed_address_p (SImode)
+       || !gpc_reg_operand (operands[2], SImode))"
   "@
    stfdux %3,%0,%2
    stfdu %3,%2(%0)"
index 8a40fc3539b611e3f462d78c6b329ccedbcd909d..ec5373eb877e17ef0639011b67c6fe139e8e079a 100644 (file)
@@ -119,6 +119,10 @@ mupdate
 Target Report RejectNegative InverseMask(NO_UPDATE, UPDATE)
 Generate load/store with update instructions
 
+mavoid-indexed-addresses
+Target Report Var(TARGET_AVOID_XFORM) Init(-1)
+Avoid generation of indexed load/store instructions when possible
+
 mno-fused-madd
 Target Report RejectNegative Mask(NO_FUSED_MADD)
 Do not generate fused multiply/add instructions
index 247782a5769d4a20e9a0409bbfa13a1c07bae5d2..7e991c89f995c6eabe93a86ee5f8adc7f0dc874c 100644 (file)
@@ -721,6 +721,7 @@ See RS/6000 and PowerPC Options.
 -msoft-float  -mhard-float  -mmultiple  -mno-multiple @gol
 -msingle-float -mdouble-float -msimple-fpu @gol
 -mstring  -mno-string  -mupdate  -mno-update @gol
+-mavoid-indexed-addresses  -mno-avoid-indexed-addresses @gol
 -mfused-madd  -mno-fused-madd  -mbit-align  -mno-bit-align @gol
 -mstrict-align  -mno-strict-align  -mrelocatable @gol
 -mno-relocatable  -mrelocatable-lib  -mno-relocatable-lib @gol
@@ -13814,6 +13815,16 @@ stack pointer is updated and the address of the previous frame is
 stored, which means code that walks the stack frame across interrupts or
 signals may get corrupted data.
 
+@item -mavoid-indexed-addresses
+@item -mno-avoid-indexed-addresses
+@opindex mavoid-indexed-addresses
+@opindex mno-avoid-indexed-addresses
+Generate code that tries to avoid (not avoid) the use of indexed load
+or store instructions. These instructions can incur a performance
+penalty on Power6 processors in certain situations, such as when
+stepping through large arrays that cross a 16M boundary.  This option
+is enabled by default when targetting Power6 and disabled otherwise.
+
 @item -mfused-madd
 @itemx -mno-fused-madd
 @opindex mfused-madd
index d6038a1ef282b8ec6bcce8a269ba6a832bc686b7..44e685b51bfb82fa517b44e3d0672560e824d9c3 100644 (file)
@@ -1,3 +1,7 @@
+2009-01-28  Pat Haugen  <pthaugen@us.ibm.com>
+
+       * gcc.target/powerpc/avoid-indexed-addresses.c: New test.
+
 2009-01-28  Kazu Hirata  <kazu@codesourcery.com>
 
        PR tree-optimization/38997
diff --git a/gcc/testsuite/gcc.target/powerpc/avoid-indexed-addresses.c b/gcc/testsuite/gcc.target/powerpc/avoid-indexed-addresses.c
new file mode 100644 (file)
index 0000000..b1b0672
--- /dev/null
@@ -0,0 +1,14 @@
+/* { dg-do compile { target { powerpc*-*-* } } } */
+/* { dg-options "-O2 -mavoid-indexed-addresses" } */
+
+/* { dg-final { scan-assembler-not "lbzx" } }
+
+/* Ensure that an indexed load is not generated with
+   -mavoid-indexed-addresses. */
+
+char
+do_one (char *base, unsigned long offset)
+{
+  return base[offset];
+}
+