aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDavid Edelsohn <edelsohn@gnu.org>2004-08-03 15:31:38 +0000
committerDavid Edelsohn <dje@gcc.gnu.org>2004-08-03 11:31:38 -0400
commit066cd96767670cf235869528e8c8fc963b35cc1d (patch)
tree3b0bf6b11fb046e48534253a14dcb690c105425b
parent315cd6b5a6352f32134e60b28e3bb98cd32c80c7 (diff)
downloadgcc-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/ChangeLog9
-rw-r--r--gcc/config/rs6000/rs6000.c220
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: