mirror of
git://gcc.gnu.org/git/gcc.git
synced 2025-04-09 17:01:06 +08:00
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
This commit is contained in:
parent
315cd6b5a6
commit
066cd96767
@ -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.
|
||||
|
@ -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:
|
||||
|
Loading…
x
Reference in New Issue
Block a user