https://gcc.gnu.org/g:3e26dca1bd94ca26b21c661a471e929ab58642fd
commit r13-9728-g3e26dca1bd94ca26b21c661a471e929ab58642fd Author: Vladimir N. Makarov <vmaka...@redhat.com> Date: Fri May 30 08:28:59 2025 -0400 Revert "[LRA]: Backporting solutions for PR112918 and PR113354 to solve PR99015" This reverts commit af73c8bf5168848275bf909ee44fbb8f4973438f. Diff: --- gcc/lra-constraints.cc | 124 +++++++++++++++++++------------------------------ 1 file changed, 49 insertions(+), 75 deletions(-) diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index 2d31fcc9b4f2..21f05df0d618 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -233,41 +233,6 @@ get_reg_class (int regno) return NO_REGS; } -/* Return true if REG_CLASS has enough allocatable hard regs to keep value of - REG_MODE. */ -static bool -enough_allocatable_hard_regs_p (enum reg_class reg_class, - enum machine_mode reg_mode) -{ - int i, j, hard_regno, class_size, nregs; - - if (hard_reg_set_subset_p (reg_class_contents[reg_class], lra_no_alloc_regs)) - return false; - class_size = ira_class_hard_regs_num[reg_class]; - for (i = 0; i < class_size; i++) - { - hard_regno = ira_class_hard_regs[reg_class][i]; - nregs = hard_regno_nregs (hard_regno, reg_mode); - if (nregs == 1) - return true; - for (j = 0; j < nregs; j++) - if (TEST_HARD_REG_BIT (lra_no_alloc_regs, hard_regno + j) - || ! TEST_HARD_REG_BIT (reg_class_contents[reg_class], - hard_regno + j)) - break; - if (j >= nregs) - return true; - } - return false; -} - -/* True if C is a non-empty register class that has too few registers - to be safely used as a reload target class. */ -#define SMALL_REGISTER_CLASS_P(C) \ - (ira_class_hard_regs_num [(C)] == 1 \ - || (ira_class_hard_regs_num [(C)] >= 1 \ - && targetm.class_likely_spilled_p (C))) - /* Return true if REG satisfies (or will satisfy) reg class constraint CL. Use elimination first if REG is a hard register. If REG is a reload pseudo created by this constraints pass, assume that it will @@ -287,6 +252,7 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class, enum reg_class rclass, common_class; machine_mode reg_mode; rtx src; + int class_size, hard_regno, nregs, i, j; int regno = REGNO (reg); if (new_class != NULL) @@ -325,11 +291,26 @@ in_class_p (rtx reg, enum reg_class cl, enum reg_class *new_class, common_class = ira_reg_class_subset[rclass][cl]; if (new_class != NULL) *new_class = common_class; - return (enough_allocatable_hard_regs_p (common_class, reg_mode) - /* Do not permit reload insn operand matching (new_class == NULL - case) if the new class is too small. */ - && (new_class != NULL || common_class == rclass - || !SMALL_REGISTER_CLASS_P (common_class))); + if (hard_reg_set_subset_p (reg_class_contents[common_class], + lra_no_alloc_regs)) + return false; + /* Check that there are enough allocatable regs. */ + class_size = ira_class_hard_regs_num[common_class]; + for (i = 0; i < class_size; i++) + { + hard_regno = ira_class_hard_regs[common_class][i]; + nregs = hard_regno_nregs (hard_regno, reg_mode); + if (nregs == 1) + return true; + for (j = 0; j < nregs; j++) + if (TEST_HARD_REG_BIT (lra_no_alloc_regs, hard_regno + j) + || ! TEST_HARD_REG_BIT (reg_class_contents[common_class], + hard_regno + j)) + break; + if (j >= nregs) + return true; + } + return false; } } @@ -933,6 +914,13 @@ operands_match_p (rtx x, rtx y, int y_hard_regno) && GET_MODE_SIZE (MODE).is_constant () \ && !targetm.cannot_force_const_mem (MODE, X)) +/* True if C is a non-empty register class that has too few registers + to be safely used as a reload target class. */ +#define SMALL_REGISTER_CLASS_P(C) \ + (ira_class_hard_regs_num [(C)] == 1 \ + || (ira_class_hard_regs_num [(C)] >= 1 \ + && targetm.class_likely_spilled_p (C))) + /* If REG is a reload pseudo, try to make its class satisfying CL. */ static void narrow_reload_pseudo_class (rtx reg, enum reg_class cl) @@ -2070,7 +2058,6 @@ process_alt_operands (int only_alternative) int curr_alt_dont_inherit_ops_num; /* Numbers of operands whose reload pseudos should not be inherited. */ int curr_alt_dont_inherit_ops[MAX_RECOG_OPERANDS]; - bool curr_alt_class_change_p; rtx op; /* The register when the operand is a subreg of register, otherwise the operand itself. */ @@ -2146,7 +2133,6 @@ process_alt_operands (int only_alternative) } reject += static_reject; early_clobbered_regs_num = 0; - curr_alt_class_change_p = false; for (nop = 0; nop < n_operands; nop++) { @@ -2171,7 +2157,6 @@ process_alt_operands (int only_alternative) bool scratch_p; machine_mode mode; enum constraint_num cn; - bool class_change_p = false; opalt_num = nalt * n_operands + nop; if (curr_static_id->operand_alternative[opalt_num].anything_ok) @@ -2539,16 +2524,9 @@ process_alt_operands (int only_alternative) (this_alternative_exclude_start_hard_regs, hard_regno[nop])) win = true; - else if (hard_regno[nop] < 0) - { - if (in_class_p (op, this_alternative, NULL)) - win = true; - else if (in_class_p (op, this_alternative, NULL, true)) - { - class_change_p = true; - win = true; - } - } + else if (hard_regno[nop] < 0 + && in_class_p (op, this_alternative, NULL)) + win = true; } break; } @@ -2563,15 +2541,6 @@ process_alt_operands (int only_alternative) if (win) { this_alternative_win = true; - if (class_change_p) - { - curr_alt_class_change_p = true; - if (lra_dump_file != NULL) - fprintf (lra_dump_file, - " %d Narrowing class: reject+=3\n", - nop); - reject += 3; - } if (operand_reg[nop] != NULL_RTX) { if (hard_regno[nop] >= 0) @@ -2600,7 +2569,7 @@ process_alt_operands (int only_alternative) reject++; } if (in_class_p (operand_reg[nop], - this_costly_alternative, NULL, true)) + this_costly_alternative, NULL)) { if (lra_dump_file != NULL) fprintf @@ -3281,7 +3250,7 @@ process_alt_operands (int only_alternative) best_reload_sum = reload_sum; goal_alt_number = nalt; } - if (losers == 0 && !curr_alt_class_change_p) + if (losers == 0) /* Everything is satisfied. Do not process alternatives anymore. */ break; @@ -4386,7 +4355,7 @@ curr_insn_transform (bool check_only_p) if (REG_P (reg) && (regno = REGNO (reg)) >= FIRST_PSEUDO_REGISTER) { - bool ok_p = in_class_p (reg, goal_alt[i], &new_class, true); + bool ok_p = in_class_p (reg, goal_alt[i], &new_class); if (new_class != NO_REGS && get_reg_class (regno) != new_class) { @@ -4466,18 +4435,23 @@ curr_insn_transform (bool check_only_p) { if (goal_alt[i] == NO_REGS && REG_P (op) - && (regno = REGNO (op)) >= FIRST_PSEUDO_REGISTER - /* We assigned a hard register to the pseudo in the past but now - decided to spill it for the insn. If the pseudo is used only - in this insn, it is better to spill it here as we free hard - registers for other pseudos referenced in the insn. The most - common case of this is a scratch register which will be - transformed to scratch back at the end of LRA. */ - && lra_get_regno_hard_regno (regno) >= 0 - && bitmap_single_bit_set_p (&lra_reg_info[regno].insn_bitmap)) + /* When we assign NO_REGS it means that we will not + assign a hard register to the scratch pseudo by + assigment pass and the scratch pseudo will be + spilled. Spilled scratch pseudos are transformed + back to scratches at the LRA end. */ + && ira_former_scratch_operand_p (curr_insn, i) + && ira_former_scratch_p (REGNO (op))) { + int regno = REGNO (op); lra_change_class (regno, NO_REGS, " Change to", true); - reg_renumber[regno] = -1; + if (lra_get_regno_hard_regno (regno) >= 0) + /* We don't have to mark all insn affected by the + spilled pseudo as there is only one such insn, the + current one. */ + reg_renumber[regno] = -1; + lra_assert (bitmap_single_bit_set_p + (&lra_reg_info[REGNO (op)].insn_bitmap)); } /* We can do an optional reload. If the pseudo got a hard reg, we might improve the code through inheritance. If