Commit 066cd967 by David Edelsohn Committed by David Edelsohn

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
parent 315cd6b5
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> 2004-08-03 Richard Earnshaw <rearnsha@arm.com>
* config.gcc (strongarm-*, xscale-*): Add t-arm to tmake_files. * config.gcc (strongarm-*, xscale-*): Add t-arm to tmake_files.
......
...@@ -16517,21 +16517,105 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, ...@@ -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. /* On the RS/6000, if it is valid in the insn, it is free.
So this always returns 0. */ So this always returns 0. */
case CONST_INT: 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 CONST:
case HIGH:
case LABEL_REF: case LABEL_REF:
case SYMBOL_REF: case SYMBOL_REF:
case CONST_DOUBLE: case MEM:
case HIGH: /* When optimizing for size, MEM should be slightly more expensive
*total = 0; 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; return true;
case PLUS: case PLUS:
if (mode == DFmode) if (mode == DFmode)
*total = GET_CODE (XEXP (x, 0)) == MULT {
? rs6000_cost->dmul if (GET_CODE (XEXP (x, 0)) == MULT)
: rs6000_cost->fp; {
/* 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) 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) else if (GET_CODE (XEXP (x, 0)) == MULT)
{ {
/* The rs6000 doesn't have shift-and-add instructions. */ /* 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, ...@@ -16539,21 +16623,31 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
*total += COSTS_N_INSNS (1); *total += COSTS_N_INSNS (1);
} }
else else
*total = ((GET_CODE (XEXP (x, 1)) == CONST_INT *total = COSTS_N_INSNS (1);
&& ((unsigned HOST_WIDE_INT) (INTVAL (XEXP (x, 1)) return false;
+ 0x8000) >= 0x10000)
&& ((INTVAL (XEXP (x, 1)) & 0xffff) != 0))
? COSTS_N_INSNS (2)
: COSTS_N_INSNS (1));
return true;
case MINUS: case MINUS:
if (mode == DFmode) if (mode == DFmode)
*total = GET_CODE (XEXP (x, 0)) == MULT {
? rs6000_cost->dmul if (GET_CODE (XEXP (x, 0)) == MULT)
: rs6000_cost->fp; {
/* 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) 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) else if (GET_CODE (XEXP (x, 0)) == MULT)
{ {
/* The rs6000 doesn't have shift-and-sub instructions. */ /* 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, ...@@ -16562,17 +16656,7 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
} }
else else
*total = COSTS_N_INSNS (1); *total = COSTS_N_INSNS (1);
return true; return false;
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;
case MULT: case MULT:
if (GET_CODE (XEXP (x, 1)) == CONST_INT) if (GET_CODE (XEXP (x, 1)) == CONST_INT)
...@@ -16583,6 +16667,10 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, ...@@ -16583,6 +16667,10 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
else else
*total = rs6000_cost->mulsi_const; *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) else if (mode == DFmode)
*total = rs6000_cost->dmul; *total = rs6000_cost->dmul;
else if (mode == SFmode) else if (mode == SFmode)
...@@ -16591,7 +16679,7 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, ...@@ -16591,7 +16679,7 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
*total = rs6000_cost->muldi; *total = rs6000_cost->muldi;
else else
*total = rs6000_cost->mulsi; *total = rs6000_cost->mulsi;
return true; return false;
case DIV: case DIV:
case MOD: case MOD:
...@@ -16599,13 +16687,13 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, ...@@ -16599,13 +16687,13 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
{ {
*total = mode == DFmode ? rs6000_cost->ddiv *total = mode == DFmode ? rs6000_cost->ddiv
: rs6000_cost->sdiv; : rs6000_cost->sdiv;
return true; return false;
} }
if (GET_CODE (XEXP (x, 1)) == CONST_INT if (GET_CODE (XEXP (x, 1)) == CONST_INT
&& exact_log2 (INTVAL (XEXP (x, 1))) >= 0) && exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
{ {
*total = COSTS_N_INSNS (2); *total = COSTS_N_INSNS (2);
return true; return false;
} }
/* FALLTHRU */ /* FALLTHRU */
...@@ -16615,35 +16703,60 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, ...@@ -16615,35 +16703,60 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
*total = rs6000_cost->divdi; *total = rs6000_cost->divdi;
else else
*total = rs6000_cost->divsi; *total = rs6000_cost->divsi;
return true; return false;
case FFS: case FFS:
*total = COSTS_N_INSNS (4); *total = COSTS_N_INSNS (4);
return true; return false;
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;
case NOT: 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 SIGN_EXTEND:
case ZERO_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); *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: case FLOAT_TRUNCATE:
*total = rs6000_cost->fp; *total = rs6000_cost->fp;
return true; return false;
case UNSPEC: case UNSPEC:
switch (XINT (x, 1)) switch (XINT (x, 1))
...@@ -16664,6 +16777,13 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED, ...@@ -16664,6 +16777,13 @@ rs6000_rtx_costs (rtx x, int code, int outer_code ATTRIBUTE_UNUSED,
*total = COSTS_N_INSNS (1); *total = COSTS_N_INSNS (1);
return true; return true;
} }
else if (FLOAT_MODE_P (mode)
&& TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
{
*total = rs6000_cost->fp;
return false;
}
break; break;
default: default:
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment