https://gcc.gnu.org/g:b222ee10045db06655d2a9f0d87e25c5083d98c8
commit r15-5475-gb222ee10045db06655d2a9f0d87e25c5083d98c8 Author: Georg-Johann Lay <a...@gjlay.de> Date: Tue Nov 19 18:18:20 2024 +0100 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: --- gcc/config/avr/avr.cc | 144 +++++++++++++++++++++++++++----------------------- 1 file changed, 77 insertions(+), 67 deletions(-) diff --git a/gcc/config/avr/avr.cc b/gcc/config/avr/avr.cc index 4ad07acd789b..508e2d147bff 100644 --- a/gcc/config/avr/avr.cc +++ b/gcc/config/avr/avr.cc @@ -11773,6 +11773,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. @@ -11783,8 +11801,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) { @@ -11799,7 +11820,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: @@ -11813,7 +11834,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: @@ -11837,19 +11858,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); @@ -11889,13 +11910,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; } @@ -11904,8 +11925,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; } @@ -11994,7 +12015,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> @@ -12002,8 +12023,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; } @@ -12066,17 +12087,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; @@ -12190,12 +12211,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; @@ -12204,20 +12225,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: @@ -12257,11 +12276,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); } @@ -12293,7 +12311,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; @@ -12326,9 +12344,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; @@ -12338,7 +12355,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; @@ -12352,7 +12369,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; @@ -12365,7 +12382,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; @@ -12385,9 +12402,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; @@ -12409,13 +12425,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); } @@ -12438,7 +12453,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; @@ -12470,9 +12485,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; @@ -12482,7 +12496,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; @@ -12498,7 +12512,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; @@ -12511,7 +12525,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; @@ -12531,9 +12545,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; @@ -12561,11 +12574,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); } @@ -12579,7 +12591,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; @@ -12614,9 +12626,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; @@ -12626,7 +12637,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; @@ -12640,7 +12651,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; @@ -12653,7 +12664,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; @@ -12673,9 +12684,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;