https://gcc.gnu.org/g:44e61bd7124c762e81d8c6e615fbe7c88f773637
commit r15-6432-g44e61bd7124c762e81d8c6e615fbe7c88f773637 Author: Jiahao Xu <xujia...@loongson.cn> Date: Tue Dec 17 10:41:48 2024 +0800 LoongArch: Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS hook The hook changes the allocno class to either FP_REGS or GR_REGS depending on the mode of the register. This results in better register allocation overall, fewer spills and reduced codesize - particularly in SPEC2017 lbm. gcc/ChangeLog: * config/loongarch/loongarch.cc (loongarch_ira_change_pseudo_allocno_class): New function. (TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS): Define macro. Diff: --- gcc/config/loongarch/loongarch.cc | 38 ++++++++++++++++++++++++++++++++++++++ 1 file changed, 38 insertions(+) diff --git a/gcc/config/loongarch/loongarch.cc b/gcc/config/loongarch/loongarch.cc index 861558f07bcc..125ecc26c9cd 100644 --- a/gcc/config/loongarch/loongarch.cc +++ b/gcc/config/loongarch/loongarch.cc @@ -6989,6 +6989,40 @@ loongarch_secondary_reload (bool in_p ATTRIBUTE_UNUSED, rtx x, return NO_REGS; } +/* Implement TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS. + + The register allocator chooses ALL_REGS if FP_REGS and GR_REGS have the + same cost - even if ALL_REGS has a much higher cost. ALL_REGS is also used + if the cost of both FP_REGS and GR_REGS is lower than the memory cost (in + this case the best class is the lowest cost one). Using ALL_REGS + irrespectively of itself cost results in bad allocations with many redundant + int<->FP moves which are expensive on various cores. + + To avoid this we don't allow ALL_REGS as the allocno class, but force a + decision between FP_REGS and GR_REGS. We use the allocno class if it isn't + ALL_REGS. Similarly, use the best class if it isn't ALL_REGS. Otherwise Set + the allocno class depending on the mode. + + This change has a similar effect to increasing the cost of FPR->GPR register + moves for integer modes so that they are higher than the cost of memory but + changing the allocno class is more reliable. */ + +static reg_class_t +loongarch_ira_change_pseudo_allocno_class (int regno, reg_class_t allocno_class, + reg_class_t best_class) +{ + enum machine_mode mode; + + if (allocno_class != ALL_REGS) + return allocno_class; + + if (best_class != ALL_REGS) + return best_class; + + mode = PSEUDO_REGNO_MODE (regno); + return FLOAT_MODE_P (mode) || VECTOR_MODE_P (mode) ? FP_REGS : GR_REGS; +} + /* Implement TARGET_VALID_POINTER_MODE. */ static bool @@ -11148,6 +11182,10 @@ loongarch_asm_code_end (void) #undef TARGET_SECONDARY_RELOAD #define TARGET_SECONDARY_RELOAD loongarch_secondary_reload +#undef TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS +#define TARGET_IRA_CHANGE_PSEUDO_ALLOCNO_CLASS \ + loongarch_ira_change_pseudo_allocno_class + #undef TARGET_HAVE_SPECULATION_SAFE_VALUE #define TARGET_HAVE_SPECULATION_SAFE_VALUE speculation_safe_value_not_needed