This patch calculates more accurate shift costs, but makes the costs for larger offsets no more expensive than the costs for an unrolled shift.
Ok for trunk? Johann -- AVR: target/54378 - Reconsider the default shift costs. This patch calculates more accurate shift costs, but makes the costs for larger offsets no more expensive than the costs for an unrolled shift. gcc/ PR target/54378 * config/avr/avr.cc (avr_default_shift_costs): New static function. (avr_rtx_costs_1) [ASHIFT, LSHIFTRT, ASHIFTRT]: Use it to determine the default shift costs for shifts with a constant shift offset.
AVR: target/54378 - Reconsider the default shift costs. This patch calculates more accurate shift costs, but makes the costs for larger offsets no more expensive than the costs for an unrolled shift. gcc/ PR target/54378 * config/avr/avr.cc (avr_default_shift_costs): New static function. (avr_rtx_costs_1) [ASHIFT, LSHIFTRT, ASHIFTRT]: Use it to determine the default shift costs for shifts with a constant shift offset. diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index 8fab896b70f..245c579a075 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -12028,6 +12028,24 @@ avr_operand_rtx_cost (rtx x, machine_mode mode, rtx_code outer, return total; } + +/* Return the default shift costs for an n-byte shift with a constant + bit offset in terms of cycles (speed) or in terms of words (!speed). */ + +static int +avr_default_shift_costs (int n_bytes, int offset, bool speed) +{ + int c_space = 3 + n_bytes; + int c_speed = offset <= 4 + ? (3 + n_bytes) * offset + // For larger offsets, don't make the speed costs more costly than + // an unrolled shift, because we cannot rollback from an unrolled shift. + : n_bytes * offset; + + return COSTS_N_INSNS (speed ? c_speed : c_space); +} + + /* Worker function for AVR backend's rtx_cost function. X is rtx expression whose cost is to be calculated. Return true if the complete cost has been computed. @@ -12038,8 +12056,11 @@ static bool avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, int /*opno*/, int *total, bool speed) { - rtx_code code = GET_CODE (x); - HOST_WIDE_INT val; + const rtx_code code = GET_CODE (x); + const int n_bytes = GET_MODE_SIZE (mode); + const HOST_WIDE_INT val1 = BINARY_P (x) && CONST_INT_P (XEXP (x, 1)) + ? INTVAL (XEXP (x, 1)) + : -1; switch (code) { @@ -12054,7 +12075,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, return true; case MEM: - *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); + *total = COSTS_N_INSNS (n_bytes); return true; case NEG: @@ -12068,7 +12089,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, case E_HImode: case E_PSImode: case E_SImode: - *total = COSTS_N_INSNS (2 * GET_MODE_SIZE (mode) - 1); + *total = COSTS_N_INSNS (2 * n_bytes - 1); break; default: @@ -12092,19 +12113,19 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, return true; case NOT: - *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); + *total = COSTS_N_INSNS (n_bytes); *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); return true; case ZERO_EXTEND: - *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + *total = COSTS_N_INSNS (n_bytes - GET_MODE_SIZE (GET_MODE (XEXP (x, 0)))); *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)), code, 0, speed); return true; case SIGN_EXTEND: - *total = COSTS_N_INSNS (GET_MODE_SIZE (mode) + 2 + *total = COSTS_N_INSNS (n_bytes + 2 - GET_MODE_SIZE (GET_MODE (XEXP (x, 0)))); *total += avr_operand_rtx_cost (XEXP (x, 0), GET_MODE (XEXP (x, 0)), code, 0, speed); @@ -12144,13 +12165,13 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, if (GET_CODE (XEXP (x, 0)) == ZERO_EXTEND && REG_P (XEXP (x, 1))) { - *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); + *total = COSTS_N_INSNS (n_bytes); return true; } if (REG_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND) { - *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); + *total = COSTS_N_INSNS (n_bytes); return true; } @@ -12159,8 +12180,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, && REG_P (XEXP (x, 1))) { int size2 = GET_MODE_SIZE (GET_MODE (XEXP (XEXP (x, 0), 0))); - *total = COSTS_N_INSNS (2 + GET_MODE_SIZE (mode) - + (GET_MODE_SIZE (mode) > 1 + size2)); + *total = COSTS_N_INSNS (2 + n_bytes + + (n_bytes > 1 + size2)); return true; } @@ -12249,7 +12270,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, if (REG_P (XEXP (x, 0)) && GET_CODE (XEXP (x, 1)) == ZERO_EXTEND) { - *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); + *total = COSTS_N_INSNS (n_bytes); return true; } // *sub<HISI:mode>3.sign_extend.<QIPSI:mode> @@ -12257,8 +12278,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, && GET_CODE (XEXP (x, 1)) == SIGN_EXTEND) { int size2 = GET_MODE_SIZE (GET_MODE (XEXP (XEXP (x, 1), 0))); - *total = COSTS_N_INSNS (2 + GET_MODE_SIZE (mode) - + (GET_MODE_SIZE (mode) > 1 + size2)); + *total = COSTS_N_INSNS (2 + n_bytes + + (n_bytes > 1 + size2)); return true; } @@ -12321,17 +12342,17 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, || LSHIFTRT == GET_CODE (XEXP (x, 0)))) { // "*insv.any_shift.<mode> - *total = COSTS_N_INSNS (1 + GET_MODE_SIZE (mode)); + *total = COSTS_N_INSNS (1 + n_bytes); return true; } - *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); + *total = COSTS_N_INSNS (n_bytes); *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); if (!CONST_INT_P (XEXP (x, 1))) *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed); return true; case XOR: - *total = COSTS_N_INSNS (GET_MODE_SIZE (mode)); + *total = COSTS_N_INSNS (n_bytes); *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, speed); return true; @@ -12445,12 +12466,12 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, if (!speed) *total = COSTS_N_INSNS (AVR_HAVE_JMP_CALL ? 2 : 1); else - *total = COSTS_N_INSNS (15 * GET_MODE_SIZE (mode)); + *total = COSTS_N_INSNS (15 * n_bytes); *total += avr_operand_rtx_cost (XEXP (x, 0), mode, code, 0, speed); /* For div/mod with const-int divisor we have at least the cost of loading the divisor. */ if (CONST_INT_P (XEXP (x, 1))) - *total += COSTS_N_INSNS (GET_MODE_SIZE (mode)); + *total += COSTS_N_INSNS (n_bytes); /* Add some overall penaly for clobbering and moving around registers */ *total += COSTS_N_INSNS (2); return true; @@ -12459,20 +12480,18 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, switch (mode) { case E_QImode: - if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 4) + if (val1 == 4) *total = COSTS_N_INSNS (1); - break; case E_HImode: - if (CONST_INT_P (XEXP (x, 1)) && INTVAL (XEXP (x, 1)) == 8) + if (val1 == 8) *total = COSTS_N_INSNS (3); - break; case E_SImode: if (CONST_INT_P (XEXP (x, 1))) - switch (INTVAL (XEXP (x, 1))) + switch (val1) { case 8: case 24: @@ -12512,11 +12531,10 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, } else { - val = INTVAL (XEXP (x, 1)); - if (val == 7) + if (val1 == 7) *total = COSTS_N_INSNS (3); - else if (val >= 0 && val <= 7) - *total = COSTS_N_INSNS (val); + else if (val1 >= 0 && val1 <= 7) + *total = COSTS_N_INSNS (val1); else *total = COSTS_N_INSNS (1); } @@ -12548,7 +12566,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, speed); } else - switch (INTVAL (XEXP (x, 1))) + switch (val1) { case 0: *total = 0; @@ -12581,9 +12599,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (!speed ? 5 : 10); break; default: - *total = COSTS_N_INSNS (!speed ? 5 : 41); - *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, - speed); + *total = avr_default_shift_costs (n_bytes, val1, speed); + break; } break; @@ -12593,7 +12610,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (!speed ? 6 : 73); } else - switch (INTVAL (XEXP (x, 1))) + switch (val1) { case 0: *total = 0; @@ -12607,7 +12624,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (5); break; default: - *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1))); + *total = avr_default_shift_costs (n_bytes, val1, speed); break; } break; @@ -12620,7 +12637,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, speed); } else - switch (INTVAL (XEXP (x, 1))) + switch (val1) { case 0: *total = 0; @@ -12640,9 +12657,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (!speed ? 7 : 8); break; default: - *total = COSTS_N_INSNS (!speed ? 7 : 113); - *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, - speed); + *total = avr_default_shift_costs (n_bytes, val1, speed); + break; } break; @@ -12664,13 +12680,12 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, } else { - val = INTVAL (XEXP (x, 1)); - if (val == 6) + if (val1 == 6) *total = COSTS_N_INSNS (4); - else if (val == 7) + else if (val1 == 7) *total = COSTS_N_INSNS (2); - else if (val >= 0 && val <= 7) - *total = COSTS_N_INSNS (val); + else if (val1 >= 0 && val1 <= 7) + *total = COSTS_N_INSNS (val1); else *total = COSTS_N_INSNS (1); } @@ -12693,7 +12708,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, speed); } else - switch (INTVAL (XEXP (x, 1))) + switch (val1) { case 0: *total = 0; @@ -12725,9 +12740,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (!speed ? 5 : 8); break; default: - *total = COSTS_N_INSNS (!speed ? 5 : 41); - *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, - speed); + *total = avr_default_shift_costs (n_bytes, val1, speed); + break; } break; @@ -12737,7 +12751,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (!speed ? 6 : 73); } else - switch (INTVAL (XEXP (x, 1))) + switch (val1) { case 0: *total = 0; @@ -12753,7 +12767,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (4); break; default: - *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1))); + *total = avr_default_shift_costs (n_bytes, val1, speed); break; } break; @@ -12766,7 +12780,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, speed); } else - switch (INTVAL (XEXP (x, 1))) + switch (val1) { case 0: *total = 0; @@ -12786,9 +12800,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (AVR_HAVE_MOVW ? 4 : 5); break; default: - *total = COSTS_N_INSNS (!speed ? 7 : 113); - *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, - speed); + *total = avr_default_shift_costs (n_bytes, val1, speed); + break; } break; @@ -12816,11 +12829,10 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, } else { - val = INTVAL (XEXP (x, 1)); - if (val == 7) + if (val1 == 7) *total = COSTS_N_INSNS (3); - else if (val >= 0 && val <= 7) - *total = COSTS_N_INSNS (val); + else if (val1 >= 0 && val1 <= 7) + *total = COSTS_N_INSNS (val1); else *total = COSTS_N_INSNS (1); } @@ -12834,7 +12846,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, speed); } else - switch (INTVAL (XEXP (x, 1))) + switch (val1) { case 0: *total = 0; @@ -12869,9 +12881,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (!speed ? 5 : 9); break; default: - *total = COSTS_N_INSNS (!speed ? 5 : 41); - *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, - speed); + *total = avr_default_shift_costs (n_bytes, val1, speed); + break; } break; @@ -12881,7 +12892,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (!speed ? 6 : 73); } else - switch (INTVAL (XEXP (x, 1))) + switch (val1) { case 0: *total = 0; @@ -12895,7 +12906,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (5); break; default: - *total = COSTS_N_INSNS (!speed ? 5 : 3 * INTVAL (XEXP (x, 1))); + *total = avr_default_shift_costs (n_bytes, val1, speed); break; } break; @@ -12908,7 +12919,7 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, speed); } else - switch (INTVAL (XEXP (x, 1))) + switch (val1) { case 0: *total = 0; @@ -12928,9 +12939,8 @@ avr_rtx_costs_1 (rtx x, machine_mode mode, int outer_code, *total = COSTS_N_INSNS (6); break; default: - *total = COSTS_N_INSNS (!speed ? 7 : 113); - *total += avr_operand_rtx_cost (XEXP (x, 1), mode, code, 1, - speed); + *total = avr_default_shift_costs (n_bytes, val1, speed); + break; } break;