diff options
author | David Edelsohn <edelsohn@gnu.org> | 2004-08-03 15:31:38 +0000 |
---|---|---|
committer | David Edelsohn <dje@gcc.gnu.org> | 2004-08-03 11:31:38 -0400 |
commit | 066cd96767670cf235869528e8c8fc963b35cc1d (patch) | |
tree | 3b0bf6b11fb046e48534253a14dcb690c105425b | |
parent | 315cd6b5a6352f32134e60b28e3bb98cd32c80c7 (diff) | |
download | gcc-066cd96767670cf235869528e8c8fc963b35cc1d.zip gcc-066cd96767670cf235869528e8c8fc963b35cc1d.tar.gz gcc-066cd96767670cf235869528e8c8fc963b35cc1d.tar.bz2 |
rs6000.c (rs6000_rtx_costs): Calculate cost of constants more accurately.
* config/rs6000/rs6000.c (rs6000_rtx_costs): Calculate cost of
constants more accurately. Adjust costs for FMA instructions.
Add cases for most logical and float operations. Recurse into
most operands.
Co-Authored-By: Dale Johannesen <dalej@apple.com>
Co-Authored-By: Roger Sayle <roger@eyesopen.com>
From-SVN: r85488
-rw-r--r-- | gcc/ChangeLog | 9 | ||||
-rw-r--r-- | gcc/config/rs6000/rs6000.c | 220 |
2 files changed, 179 insertions, 50 deletions
diff --git a/gcc/ChangeLog b/gcc/ChangeLog index 9475062..8828ae1 100644 --- a/gcc/ChangeLog +++ b/gcc/ChangeLog @@ -1,3 +1,12 @@ +2004-08-03 David Edelsohn <edelsohn@gnu.org> + Dale Johannesen <dalej@apple.com> + Roger Sayle <roger@eyesopen.com> + + * config/rs6000/rs6000.c (rs6000_rtx_costs): Calculate cost of + constants more accurately. Adjust costs for FMA instructions. + Add cases for most logical and float operations. Recurse into + most operands. + 2004-08-03 Richard Earnshaw <rearnsha@arm.com> * config.gcc (strongarm-*, xscale-*): Add t-arm to tmake_files. diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index 773ca9e..1a9cf8d 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -16517,21 +16517,105 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, /* On the RS/6000, if it is valid in the insn, it is free. So this always returns 0. */ case CONST_INT: + if (((outer_code == SET + || outer_code == PLUS + || outer_code == MINUS) + && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I') + || CONST_OK_FOR_LETTER_P (INTVAL (x), 'L'))) + || ((outer_code == IOR || outer_code == XOR) + && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K') + || CONST_OK_FOR_LETTER_P (INTVAL (x), 'L'))) + || (outer_code == AND + && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K') + || CONST_OK_FOR_LETTER_P (INTVAL (x), 'L') + || CONST_OK_FOR_LETTER_P (INTVAL (x), 'T'))) + || outer_code == ASHIFT + || outer_code == ASHIFTRT + || outer_code == LSHIFTRT + || outer_code == ROTATE + || outer_code == ROTATERT + || (outer_code == MULT + && CONST_OK_FOR_LETTER_P (INTVAL (x), 'I')) + || (outer_code == COMPARE + && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'I') + || CONST_OK_FOR_LETTER_P (INTVAL (x), 'K')))) + { + *total = 0; + return true; + } + else if ((outer_code == PLUS + && reg_or_add_cint64_operand (x, VOIDmode)) + || (outer_code == MINUS + && reg_or_sub_cint64_operand (x, VOIDmode)) + || ((outer_code == SET + || outer_code == IOR + || outer_code == XOR) + && (INTVAL (x) + & ~ (unsigned HOST_WIDE_INT) 0xffffffff) == 0)) + { + *total = COSTS_N_INSNS (1); + return true; + } + /* FALLTHRU */ + + case CONST_DOUBLE: + if (mode == DImode + && ((outer_code == AND + && (CONST_OK_FOR_LETTER_P (INTVAL (x), 'K') + || CONST_OK_FOR_LETTER_P (INTVAL (x), 'L') + || CONST_OK_FOR_LETTER_P (INTVAL (x), 'S'))) + || ((outer_code == IOR || outer_code == XOR) + && CONST_DOUBLE_HIGH (x) == 0 + && (CONST_DOUBLE_LOW (x) + & ~ (unsigned HOST_WIDE_INT) 0xffff) == 0))) + { + *total = 0; + return true; + } + else if (mode == DImode + && (outer_code == SET + || outer_code == IOR + || outer_code == XOR) + && CONST_DOUBLE_HIGH (x) == 0) + { + *total = COSTS_N_INSNS (1); + return true; + } + /* FALLTHRU */ + case CONST: + case HIGH: case LABEL_REF: case SYMBOL_REF: - case CONST_DOUBLE: - case HIGH: - *total = 0; + case MEM: + /* When optimizing for size, MEM should be slightly more expensive + than generating address, e.g., (plus (reg) (const)). + L1 cache latecy is about two instructions. */ + *total = optimize_size ? COSTS_N_INSNS (1) + 1 : COSTS_N_INSNS (2); return true; case PLUS: if (mode == DFmode) - *total = GET_CODE (XEXP (x, 0)) == MULT - ? rs6000_cost->dmul - : rs6000_cost->fp; + { + if (GET_CODE (XEXP (x, 0)) == MULT) + { + /* FNMA accounted in outer NEG. */ + if (outer_code == NEG) + *total = rs6000_cost->dmul - rs6000_cost->fp; + else + *total = rs6000_cost->dmul; + } + else + *total = rs6000_cost->fp; + } else if (mode == SFmode) - *total = rs6000_cost->fp; + { + /* FNMA accounted in outer NEG. */ + if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT) + *total = 0; + else + *total = rs6000_cost->fp; + } else if (GET_CODE (XEXP (x, 0)) == MULT) { /* The rs6000 doesn't have shift-and-add instructions. */ @@ -16539,21 +16623,31 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, *total += COSTS_N_INSNS (1); } else - *total = ((GET_CODE (XEXP (x, 1)) == CONST_INT - && ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) - + 0x8000) >= 0x10000) - && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0)) - ? COSTS_N_INSNS (2) - : COSTS_N_INSNS (1)); - return true; + *total = COSTS_N_INSNS (1); + return false; case MINUS: if (mode == DFmode) - *total = GET_CODE (XEXP (x, 0)) == MULT - ? rs6000_cost->dmul - : rs6000_cost->fp; + { + if (GET_CODE (XEXP (x, 0)) == MULT) + { + /* FNMA accounted in outer NEG. */ + if (outer_code == NEG) + *total = 0; + else + *total = rs6000_cost->dmul; + } + else + *total = rs6000_cost->fp; + } else if (mode == SFmode) - *total = rs6000_cost->fp; + { + /* FNMA accounted in outer NEG. */ + if (outer_code == NEG && GET_CODE (XEXP (x, 0)) == MULT) + *total = 0; + else + *total = rs6000_cost->fp; + } else if (GET_CODE (XEXP (x, 0)) == MULT) { /* The rs6000 doesn't have shift-and-sub instructions. */ @@ -16562,17 +16656,7 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, } else *total = COSTS_N_INSNS (1); - return true; - - case AND: - case IOR: - case XOR: - *total = ((GET_CODE (XEXP (x, 1)) == CONST_INT - && (INTVAL (XEXP (x, 1)) & (~ (HOST_WIDE_INT) 0xffff)) != 0 - && ((INTVAL (XEXP (x, 1)) & 0xffff) != 0)) - ? COSTS_N_INSNS (2) - : COSTS_N_INSNS (1)); - return true; + return false; case MULT: if (GET_CODE (XEXP (x, 1)) == CONST_INT) @@ -16583,6 +16667,10 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, else *total = rs6000_cost->mulsi_const; } + /* FMA accounted in outer PLUS/MINUS. */ + else if ((mode == DFmode || mode == SFmode) + && (outer_code == PLUS || outer_code == MINUS)) + *total = 0; else if (mode == DFmode) *total = rs6000_cost->dmul; else if (mode == SFmode) @@ -16591,7 +16679,7 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, *total = rs6000_cost->muldi; else *total = rs6000_cost->mulsi; - return true; + return false; case DIV: case MOD: @@ -16599,13 +16687,13 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, { *total = mode == DFmode ? rs6000_cost->ddiv : rs6000_cost->sdiv; - return true; + return false; } if (GET_CODE (XEXP (x, 1)) == CONST_INT && exact_log2 (INTVAL (XEXP (x, 1))) >= 0) { *total = COSTS_N_INSNS (2); - return true; + return false; } /* FALLTHRU */ @@ -16615,35 +16703,60 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, *total = rs6000_cost->divdi; else *total = rs6000_cost->divsi; - return true; + return false; case FFS: *total = COSTS_N_INSNS (4); - return true; - - case NEG: - case ABS: - if (FLOAT_MODE_P (mode)) - *total = rs6000_cost->fp; - else - *total = COSTS_N_INSNS (1); - return true; - - case MEM: - /* MEM should be slightly more expensive than (plus (reg) (const)). */ - *total = COSTS_N_INSNS (1) + 1; - return true; + return false; case NOT: + if (outer_code == AND || outer_code == IOR || outer_code == XOR) + { + *total = 0; + return false; + } + /* FALLTHRU */ + + case AND: + case IOR: + case XOR: + case ASHIFT: + case ASHIFTRT: + case LSHIFTRT: + case ROTATE: + case ROTATERT: case SIGN_EXTEND: case ZERO_EXTEND: - case COMPARE: + if (outer_code == TRUNCATE + && GET_CODE (XEXP (x, 0)) == MULT) + { + if (mode == DImode) + *total = rs6000_cost->muldi; + else + *total = rs6000_cost->mulsi; + return true; + } *total = COSTS_N_INSNS (1); - break; + return false; + case COMPARE: + case NEG: + case ABS: + if (!FLOAT_MODE_P (mode)) + { + *total = COSTS_N_INSNS (1); + return false; + } + /* FALLTHRU */ + + case FLOAT: + case UNSIGNED_FLOAT: + case FIX: + case UNSIGNED_FIX: + case FLOAT_EXTEND: case FLOAT_TRUNCATE: *total = rs6000_cost->fp; - return true; + return false; case UNSPEC: switch (XINT (x, 1)) @@ -16664,6 +16777,13 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, *total = COSTS_N_INSNS (1); return true; } + else if (FLOAT_MODE_P (mode) + && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS) + { + *total = rs6000_cost->fp; + return false; + } + break; default: |