[RFC] rs6000 rtx_costs (take 3)
David Edelsohn
dje@watson.ibm.com
Wed Jul 28 08:54:00 GMT 2004
The main difference here is treating the cost of FP CONST_DOULE as
MEM.
David
Index: rs6000.c
===================================================================
RCS file: /cvs/gcc/gcc/gcc/config/rs6000/rs6000.c,v
retrieving revision 1.670
diff -c -p -r1.670 rs6000.c
*** rs6000.c 20 Jul 2004 07:27:13 -0000 1.670
--- rs6000.c 27 Jul 2004 19:24:32 -0000
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16506,16526 ****
/* On the RS/6000, if it is valid in the insn, it is free.
So this always returns 0. */
case CONST_INT:
case CONST:
case LABEL_REF:
case SYMBOL_REF:
! case CONST_DOUBLE:
! case HIGH:
! *total = 0;
return true;
case PLUS:
if (mode == DFmode)
! *total = GET_CODE (XEXP (x, 0)) == MULT
! ? rs6000_cost->dmul
! : rs6000_cost->fp;
else if (mode == SFmode)
! *total = rs6000_cost->fp;
else if (GET_CODE (XEXP (x, 0)) == MULT)
{
/* The rs6000 doesn't have shift-and-add instructions. */
--- 16511,16592 ----
/* 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 == PLUS && add_operand (x, VOIDmode))
+ || (outer_code == MINUS && add_operand (x, VOIDmode))
+ || (outer_code == AND
+ && (logical_operand (x, VOIDmode) || mask_operand (x, VOIDmode)))
+ || (outer_code == IOR && logical_operand (x, VOIDmode))
+ || (outer_code == XOR && logical_operand (x, VOIDmode)))
+ {
+ *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 == IOR
+ && reg_or_logical_cint_operand (x, VOIDmode))
+ || (outer_code == XOR
+ && reg_or_logical_cint_operand (x, VOIDmode)))
+ {
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
+ /* FALLTHRU */
+
+ case CONST_DOUBLE:
+ if ((outer_code == AND
+ && (logical_operand (x, VOIDmode)) || mask_operand (x, VOIDmode))
+ || (outer_code == IOR && logical_operand (x, VOIDmode))
+ || (outer_code == XOR && logical_operand (x, VOIDmode)))
+ {
+ *total = 0;
+ return true;
+ }
+ else if ((outer_code == IOR
+ && reg_or_logical_cint_operand (x, VOIDmode))
+ || (outer_code == XOR
+ && reg_or_logical_cint_operand (x, VOIDmode)))
+ {
+ *total = COSTS_N_INSNS (1);
+ return true;
+ }
+ /* FALLTHRU */
+
case CONST:
+ case HIGH:
case LABEL_REF:
case SYMBOL_REF:
! 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)
! {
! 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)
! {
! /* 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. */
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16528,16548 ****
*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;
case MINUS:
if (mode == DFmode)
! *total = GET_CODE (XEXP (x, 0)) == MULT
! ? rs6000_cost->dmul
! : rs6000_cost->fp;
else if (mode == SFmode)
! *total = rs6000_cost->fp;
else if (GET_CODE (XEXP (x, 0)) == MULT)
{
/* The rs6000 doesn't have shift-and-sub instructions. */
--- 16594,16624 ----
*total += COSTS_N_INSNS (1);
}
else
! *total = COSTS_N_INSNS (1);
! return false;
case MINUS:
if (mode == DFmode)
! {
! 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)
! {
! /* 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. */
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16551,16567 ****
}
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;
case MULT:
if (GET_CODE (XEXP (x, 1)) == CONST_INT)
--- 16627,16633 ----
}
else
*total = COSTS_N_INSNS (1);
! return false;
case MULT:
if (GET_CODE (XEXP (x, 1)) == CONST_INT)
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16572,16577 ****
--- 16638,16647 ----
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)
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16580,16586 ****
*total = rs6000_cost->muldi;
else
*total = rs6000_cost->mulsi;
! return true;
case DIV:
case MOD:
--- 16650,16656 ----
*total = rs6000_cost->muldi;
else
*total = rs6000_cost->mulsi;
! return false;
case DIV:
case MOD:
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16588,16600 ****
{
*total = mode == DFmode ? rs6000_cost->ddiv
: rs6000_cost->sdiv;
! return true;
}
if (GET_CODE (XEXP (x, 1)) == CONST_INT
&& exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
{
*total = COSTS_N_INSNS (2);
! return true;
}
/* FALLTHRU */
--- 16658,16670 ----
{
*total = mode == DFmode ? rs6000_cost->ddiv
: rs6000_cost->sdiv;
! return false;
}
if (GET_CODE (XEXP (x, 1)) == CONST_INT
&& exact_log2 (INTVAL (XEXP (x, 1))) >= 0)
{
*total = COSTS_N_INSNS (2);
! return false;
}
/* FALLTHRU */
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16604,16638 ****
*total = rs6000_cost->divdi;
else
*total = rs6000_cost->divsi;
! return true;
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;
case NOT:
case SIGN_EXTEND:
case ZERO_EXTEND:
- case COMPARE:
*total = COSTS_N_INSNS (1);
! break;
case FLOAT_TRUNCATE:
*total = rs6000_cost->fp;
! return true;
case UNSPEC:
switch (XINT (x, 1))
--- 16674,16724 ----
*total = rs6000_cost->divdi;
else
*total = rs6000_cost->divsi;
! return false;
case FFS:
*total = COSTS_N_INSNS (4);
! 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:
*total = COSTS_N_INSNS (1);
! 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 false;
case UNSPEC:
switch (XINT (x, 1))
*************** rs6000_rtx_costs (rtx x, int code, int o
*** 16653,16658 ****
--- 16739,16751 ----
*total = COSTS_N_INSNS (1);
return true;
}
+ else if (FLOAT_MODE_P (x)
+ && TARGET_PPC_GFXOPT && TARGET_HARD_FLOAT && TARGET_FPRS)
+ {
+ *total = rs6000_cost->fp;
+ return false;
+ }
+
break;
default:
More information about the Gcc-patches
mailing list