aboutsummaryrefslogtreecommitdiff
path: root/gcc/lra-assigns.cc
diff options
context:
space:
mode:
authorVladimir N. Makarov <vmakarov@redhat.com>2025-02-25 15:01:15 -0500
committerVladimir N. Makarov <vmakarov@redhat.com>2025-02-25 15:04:50 -0500
commit2341f675edadd6370147d2bc55ca7761a7ecfaa1 (patch)
tree4b96fc958ea2f747355e8a314a69cd103d80a397 /gcc/lra-assigns.cc
parent0bb431d0a77cf8dc790b9c61539b3eb6ab1710f0 (diff)
downloadgcc-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.cc50
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;