Also use rs6000_cost only for speed. * config/rs6000/rs6000.c (rs6000_rtx_costs): Reduce cost for SETs when insn operation cost handled on recursive call. Only use rs6000_cost for speed. Tidy break/return. Tidy AND costing.
diff --git a/gcc/config/rs6000/rs6000.c b/gcc/config/rs6000/rs6000.c index fb5fe7969a3..86c90c4d756 100644 --- a/gcc/config/rs6000/rs6000.c +++ b/gcc/config/rs6000/rs6000.c @@ -21277,15 +21277,19 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, case PLUS: case MINUS: - if (FLOAT_MODE_P (mode)) + if (speed && FLOAT_MODE_P (mode)) *total = rs6000_cost->fp; else *total = COSTS_N_INSNS (1); return false; case MULT: - if (CONST_INT_P (XEXP (x, 1)) - && satisfies_constraint_I (XEXP (x, 1))) + if (!speed) + /* A little more than one insn so that nothing is tempted to + turn a shift left into a multiply. */ + *total = COSTS_N_INSNS (1) + 1; + else if (CONST_INT_P (XEXP (x, 1)) + && satisfies_constraint_I (XEXP (x, 1))) { if (INTVAL (XEXP (x, 1)) >= -256 && INTVAL (XEXP (x, 1)) <= 255) @@ -21304,18 +21308,22 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, return false; case FMA: - if (mode == SFmode) + if (!speed) + *total = COSTS_N_INSNS (1) + 1; + else if (mode == SFmode) *total = rs6000_cost->fp; else *total = rs6000_cost->dmul; - break; + return false; case DIV: case MOD: if (FLOAT_MODE_P (mode)) { - *total = mode == DFmode ? rs6000_cost->ddiv - : rs6000_cost->sdiv; + if (!speed) + *total = COSTS_N_INSNS (1) + 2; + else + *total = mode == DFmode ? rs6000_cost->ddiv : rs6000_cost->sdiv; return false; } /* FALLTHRU */ @@ -21334,7 +21342,9 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, } else { - if (GET_MODE (XEXP (x, 1)) == DImode) + if (!speed) + *total = COSTS_N_INSNS (1) + 2; + else if (GET_MODE (XEXP (x, 1)) == DImode) *total = rs6000_cost->divdi; else *total = rs6000_cost->divsi; @@ -21368,6 +21378,7 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, return false; case AND: + *total = COSTS_N_INSNS (1); right = XEXP (x, 1); if (CONST_INT_P (right)) { @@ -21380,15 +21391,15 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, || left_code == LSHIFTRT) && rs6000_is_valid_shift_mask (right, left, mode)) { - *total = rtx_cost (XEXP (left, 0), mode, left_code, 0, speed); - if (!CONST_INT_P (XEXP (left, 1))) - *total += rtx_cost (XEXP (left, 1), SImode, left_code, 1, speed); - *total += COSTS_N_INSNS (1); + rtx reg_op = XEXP (left, 0); + if (!REG_P (reg_op)) + *total += rtx_cost (reg_op, mode, left_code, 0, speed); + reg_op = XEXP (left, 1); + if (!REG_P (reg_op) && !CONST_INT_P (reg_op)) + *total += rtx_cost (reg_op, mode, left_code, 1, speed); return true; } } - - *total = COSTS_N_INSNS (1); return false; case IOR: @@ -21519,7 +21530,9 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, if (outer_code == TRUNCATE && GET_CODE (XEXP (x, 0)) == MULT) { - if (mode == DImode) + if (!speed) + *total = COSTS_N_INSNS (1) + 1; + else if (mode == DImode) *total = rs6000_cost->muldi; else *total = rs6000_cost->mulsi; @@ -21554,11 +21567,16 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, case FIX: case UNSIGNED_FIX: case FLOAT_TRUNCATE: - *total = rs6000_cost->fp; + if (!speed) + *total = COSTS_N_INSNS (1); + else + *total = rs6000_cost->fp; return false; case FLOAT_EXTEND: - if (mode == DFmode) + if (!speed) + *total = COSTS_N_INSNS (1); + else if (mode == DFmode) *total = rs6000_cost->sfdf_convert; else *total = rs6000_cost->fp; @@ -21576,7 +21594,7 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, *total = rs6000_cost->fp; return false; } - break; + return false; case NE: case EQ: @@ -21614,13 +21632,32 @@ rs6000_rtx_costs (rtx x, machine_mode mode, int outer_code, *total = 0; return true; } - break; + return false; + + case SET: + /* The default cost of a SET is the number of general purpose + regs being set multiplied by COSTS_N_INSNS (1). That only + works where the incremental cost of the operation and + operands is zero, when the operation performed can be done in + one instruction. For other cases where we add COSTS_N_INSNS + for some operation (see point 5 above), COSTS_N_INSNS (1) + should be subtracted from the total cost. */ + { + rtx_code src_code = GET_CODE (SET_SRC (x)); + if (src_code == CONST_INT + || src_code == CONST_DOUBLE + || src_code == CONST_WIDE_INT) + return false; + int set_cost = (rtx_cost (SET_SRC (x), mode, SET, 1, speed) + + rtx_cost (SET_DEST (x), mode, SET, 0, speed)); + if (set_cost >= COSTS_N_INSNS (1)) + *total += set_cost - COSTS_N_INSNS (1); + return true; + } default: - break; + return false; } - - return false; } /* Debug form of r6000_rtx_costs that is selected if -mdebug=cost. */