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>
* 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:
......
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