diff options
author | Vladimir N. Makarov <vmakarov@redhat.com> | 2025-02-25 15:01:15 -0500 |
---|---|---|
committer | Vladimir N. Makarov <vmakarov@redhat.com> | 2025-02-25 15:04:50 -0500 |
commit | 2341f675edadd6370147d2bc55ca7761a7ecfaa1 (patch) | |
tree | 4b96fc958ea2f747355e8a314a69cd103d80a397 /gcc/lra-assigns.cc | |
parent | 0bb431d0a77cf8dc790b9c61539b3eb6ab1710f0 (diff) | |
download | gcc-2341f675edadd6370147d2bc55ca7761a7ecfaa1.zip gcc-2341f675edadd6370147d2bc55ca7761a7ecfaa1.tar.gz gcc-2341f675edadd6370147d2bc55ca7761a7ecfaa1.tar.bz2 |
[PR115458][LRA]: Run split sub-pass more times
In this PR case LRA needs to provide too many hard regs for insn
reloads, where some reload pseudos require 8 aligned regs for
themselves. As the last attempt, LRA tries to split live ranges of
hard regs for insn reload pseudos. It is a very rare case. An
inheritance pseudo involving a reload pseudo of the insn can be
spilled in the assignment sub-pass run right after splitting and we need
to run split sub-pass for the inheritance pseudo now.
gcc/ChangeLog:
PR target/115458
* lra-int.h (LRA_MAX_FAILED_SPLITS): Define and check its value.
(lra_split_hard_reg_for): Change prototype.
* lra.cc (lra): Try to split hard reg range several times after a
failure.
* lra-assigns.cc (lra_split_hard_reg_for): Add an arg, a flag of
giving up. Report asm error and nullify the asm insn depending on
the arg value.
gcc/testsuite/ChangeLog:
PR target/115458
* g++.target/riscv/pr115458.C: New.
Diffstat (limited to 'gcc/lra-assigns.cc')
-rw-r--r-- | gcc/lra-assigns.cc | 50 |
1 files changed, 29 insertions, 21 deletions
diff --git a/gcc/lra-assigns.cc b/gcc/lra-assigns.cc index f9e3dfc..480925a 100644 --- a/gcc/lra-assigns.cc +++ b/gcc/lra-assigns.cc @@ -1763,12 +1763,13 @@ find_reload_regno_insns (int regno, rtx_insn * &start, rtx_insn * &finish) return true; } -/* Process reload pseudos which did not get a hard reg, split a hard - reg live range in live range of a reload pseudo, and then return - TRUE. If we did not split a hard reg live range, report an error, - and return FALSE. */ +/* Process reload pseudos which did not get a hard reg, split a hard reg live + range in live range of a reload pseudo, and then return TRUE. Otherwise, + return FALSE. When FAIL_P is TRUE and if we did not split a hard reg live + range for failed reload pseudos, report an error and modify related asm + insns. */ bool -lra_split_hard_reg_for (void) +lra_split_hard_reg_for (bool fail_p) { int i, regno; rtx_insn *insn, *first, *last; @@ -1843,23 +1844,30 @@ lra_split_hard_reg_for (void) regno = u; bitmap_ior_into (&failed_reload_insns, &lra_reg_info[regno].insn_bitmap); - lra_setup_reg_renumber - (regno, ira_class_hard_regs[lra_get_allocno_class (regno)][0], false); - } - EXECUTE_IF_SET_IN_BITMAP (&failed_reload_insns, 0, u, bi) - { - insn = lra_insn_recog_data[u]->insn; - if (asm_noperands (PATTERN (insn)) >= 0) - { - asm_p = true; - lra_asm_insn_error (insn); - } - else if (!asm_p) - { - error ("unable to find a register to spill"); - fatal_insn ("this is the insn:", insn); - } + if (fail_p) + lra_setup_reg_renumber + (regno, ira_class_hard_regs[lra_get_allocno_class (regno)][0], false); } + if (fail_p) + EXECUTE_IF_SET_IN_BITMAP (&failed_reload_insns, 0, u, bi) + { + insn = lra_insn_recog_data[u]->insn; + if (asm_noperands (PATTERN (insn)) >= 0) + { + asm_p = true; + lra_asm_insn_error (insn); + if (JUMP_P (insn)) + ira_nullify_asm_goto (insn); + else + PATTERN (insn) = gen_rtx_USE (VOIDmode, const0_rtx); + lra_invalidate_insn_data (insn); + } + else if (!asm_p) + { + error ("unable to find a register to spill"); + fatal_insn ("this is the insn:", insn); + } + } bitmap_clear (&failed_reload_pseudos); bitmap_clear (&failed_reload_insns); return false; |