https://gcc.gnu.org/g:bb77ebb8b6a4ae850fd74c7969909dba72d5360c
commit r17-5746-gbb77ebb8b6a4ae850fd74c7969909dba72d5360c Author: Vladimir N. Makarov <[email protected]> Date: Thu Oct 29 14:36:37 2026 -0400 [PR 128174][LRA]: Propagate invariants (equivalence) for inherited pseudos In the PR test case we have too many insns using invariants (sfp + constant) and for all of them after sfp elimination the offset is out of immediate range. So all the insns are reloaded. Invariant inheritance creates a lot of inheritance pseudos, some of them should be spilled (thumb1 has few hard regs) and this results in increase of stack frame making insns containing sfp to be reloaded again and results in additional inheritance. This process is extremely slow and requires generation of many reload insns. To fix this, we record that the inheritance pseudos have equivalence and use the equivalence instead of inheritance pseudo spilling. Spilling would be a pessimization anyway (reloading from the slot is no cheaper than rematerialization). Also the extra slot would change the frame size and therefore the elimination offsets, which would invalidate every insn mentioning an eliminable register. With many invariant occurrences that feedback would keep LRA iterating for a very long time. gcc/ChangeLog: PR middle-end/128174 * lra-constraints.cc (add_invariant): New function. (process_invariant_for_inheritance): Call add_invariant. Diff: --- gcc/lra-constraints.cc | 16 ++++++++++++++++ 1 file changed, 16 insertions(+) diff --git a/gcc/lra-constraints.cc b/gcc/lra-constraints.cc index 2aa3b296f49d..40bdd26b3763 100644 --- a/gcc/lra-constraints.cc +++ b/gcc/lra-constraints.cc @@ -608,6 +608,21 @@ get_equiv_with_elimination (rtx x, rtx_insn *insn) return res; } +/* Record invariant INVARIANT_RTX as an equivalence of REG. */ +static void +add_invariant (rtx reg, rtx invariant_rtx) +{ + int regno = REGNO (reg); + + ira_expand_reg_equiv (); + ira_reg_equiv[regno].defined_p = true; + ira_reg_equiv[regno].profitable_p = true; + if (CONSTANT_P (invariant_rtx)) + ira_reg_equiv[regno].constant = copy_rtx (invariant_rtx); + else + ira_reg_equiv[regno].invariant = copy_rtx (invariant_rtx); +} + /* Set up curr_operand_mode. */ static void init_curr_operand_mode (void) @@ -7272,6 +7287,7 @@ process_invariant_for_inheritance (rtx dst_reg, rtx invariant_rtx) "invariant inheritance"); bitmap_set_bit (&lra_inheritance_pseudos, REGNO (new_reg)); bitmap_set_bit (&check_only_regs, REGNO (new_reg)); + add_invariant (new_reg, invariant_rtx); lra_reg_info[REGNO (new_reg)].restore_rtx = PATTERN (insn); start_sequence (); lra_emit_move (new_reg, dst_reg);
