From 001b9eb6b19df30cceb3e9bddeb7fbec526ff958 Mon Sep 17 00:00:00 2001 From: Pat Haugen Date: Wed, 28 Jan 2009 18:51:53 +0000 Subject: invoke.texi (avoid-indexed-addresses): Document new option. * 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 | 12 ++++ gcc/config/rs6000/rs6000-protos.h | 1 + gcc/config/rs6000/rs6000.c | 20 +++++- gcc/config/rs6000/rs6000.md | 75 ++++++++++++++++------ gcc/config/rs6000/rs6000.opt | 4 ++ gcc/doc/invoke.texi | 11 ++++ gcc/testsuite/ChangeLog | 4 ++ .../gcc.target/powerpc/avoid-indexed-addresses.c | 14 ++++ 8 files changed, 122 insertions(+), 19 deletions(-) create mode 100644 gcc/testsuite/gcc.target/powerpc/avoid-indexed-addresses.c diff --git a/gcc/ChangeLog b/gcc/ChangeLog index da53b53..5f99aab 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,15 @@ +2009-01-28 Pat Haugen + + * 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 PR tree-optimization/38997 diff --git a/gcc/config/rs6000/rs6000-protos.h b/gcc/config/rs6000/rs6000-protos.h index 2f1b04c..4e2ecd3 100644 --- a/gcc/config/rs6000/rs6000-protos.h +++ b/gcc/config/rs6000/rs6000-protos.h @@ -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); diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 6d7327b..d2ebf62 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -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)) diff --git a/gcc/config/rs6000/rs6000.md b/gcc/config/rs6000/rs6000.md index a5a6ec1..b6f4181 100644 --- a/gcc/config/rs6000/rs6000.md +++ b/gcc/config/rs6000/rs6000.md @@ -10055,7 +10055,9 @@ (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)" @@ -10067,7 +10069,11 @@ (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)" @@ -10079,7 +10085,9 @@ (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)" @@ -10092,7 +10100,8 @@ (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")]) @@ -10102,7 +10111,11 @@ (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)" @@ -10114,7 +10127,9 @@ (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)" @@ -10127,7 +10142,9 @@ (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)" @@ -10140,7 +10157,9 @@ (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)" @@ -10152,7 +10171,9 @@ (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)" @@ -10164,7 +10185,9 @@ (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)" @@ -10177,7 +10200,9 @@ (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)" @@ -10189,7 +10214,9 @@ (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)" @@ -10201,7 +10228,9 @@ (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)" @@ -10213,7 +10242,9 @@ (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)" @@ -10225,7 +10256,9 @@ (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)" @@ -10237,7 +10270,9 @@ (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)" @@ -10249,7 +10284,9 @@ (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)" @@ -10261,7 +10298,9 @@ (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)" diff --git a/gcc/config/rs6000/rs6000.opt b/gcc/config/rs6000/rs6000.opt index 8a40fc3..ec5373e 100644 --- a/gcc/config/rs6000/rs6000.opt +++ b/gcc/config/rs6000/rs6000.opt @@ -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 diff --git a/gcc/doc/invoke.texi b/gcc/doc/invoke.texi index 247782a..7e991c8 100644 --- a/gcc/doc/invoke.texi +++ b/gcc/doc/invoke.texi @@ -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 diff --git a/gcc/testsuite/ChangeLog b/gcc/testsuite/ChangeLog index d6038a1..44e685b 100644 --- a/gcc/testsuite/ChangeLog +++ b/gcc/testsuite/ChangeLog @@ -1,3 +1,7 @@ +2009-01-28 Pat Haugen + + * gcc.target/powerpc/avoid-indexed-addresses.c: New test. + 2009-01-28 Kazu Hirata 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 index 0000000..b1b0672 --- /dev/null +++ b/gcc/testsuite/gcc.target/powerpc/avoid-indexed-addresses.c @@ -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]; +} + -- cgit v1.1