[llvm] 0e1152e - AArch64: rewrite the CSR compuation (#167967)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Nov 14 08:25:53 PST 2025
Author: Saleem Abdulrasool
Date: 2025-11-14T08:25:49-08:00
New Revision: 0e1152e3eb34275ac1874761ee7931931a5815d4
URL: https://github.com/llvm/llvm-project/commit/0e1152e3eb34275ac1874761ee7931931a5815d4
DIFF: https://github.com/llvm/llvm-project/commit/0e1152e3eb34275ac1874761ee7931931a5815d4.diff
LOG: AArch64: rewrite the CSR compuation (#167967)
Rather than having a separate path for Darwin, and then a partial
handling for Windows, and then the remainder using its own path, unify
the three paths. Use a switch over the calling convention to avoid
having to check and handle the calling convention in a variety of
places. This simplifies the logic and avoids accidnetally missing a
calling convention (such as we had done with PreserveMost, PreserveAll
on Windows).
Added:
Modified:
llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
llvm/lib/Target/AArch64/AArch64RegisterInfo.h
Removed:
################################################################################
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
index ef5941c42f687..2c004e00aa00d 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -71,148 +71,126 @@ bool AArch64RegisterInfo::regNeedsCFI(MCRegister Reg,
const MCPhysReg *
AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
assert(MF && "Invalid MachineFunction pointer.");
+
auto &AFI = *MF->getInfo<AArch64FunctionInfo>();
+ const auto &F = MF->getFunction();
+ const auto *TLI = MF->getSubtarget<AArch64Subtarget>().getTargetLowering();
+ const bool Darwin = MF->getSubtarget<AArch64Subtarget>().isTargetDarwin();
+ const bool Windows = MF->getSubtarget<AArch64Subtarget>().isTargetWindows();
+
+ if (TLI->supportSwiftError() &&
+ F.getAttributes().hasAttrSomewhere(Attribute::SwiftError)) {
+ if (Darwin)
+ return CSR_Darwin_AArch64_AAPCS_SwiftError_SaveList;
+ if (Windows)
+ return CSR_Win_AArch64_AAPCS_SwiftError_SaveList;
+ return CSR_AArch64_AAPCS_SwiftError_SaveList;
+ }
- if (MF->getFunction().getCallingConv() == CallingConv::GHC)
+ switch (F.getCallingConv()) {
+ case CallingConv::GHC:
// GHC set of callee saved regs is empty as all those regs are
// used for passing STG regs around
return CSR_AArch64_NoRegs_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::PreserveNone)
+
+ case CallingConv::PreserveNone:
+ // FIXME: Windows likely need this to be altered for properly unwinding.
return CSR_AArch64_NoneRegs_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::AnyReg)
+
+ case CallingConv::AnyReg:
return CSR_AArch64_AllRegs_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::ARM64EC_Thunk_X64)
+ case CallingConv::ARM64EC_Thunk_X64:
return CSR_Win_AArch64_Arm64EC_Thunk_SaveList;
- // Darwin has its own CSR_AArch64_AAPCS_SaveList, which means most CSR save
- // lists depending on that will need to have their Darwin variant as well.
- if (MF->getSubtarget<AArch64Subtarget>().isTargetDarwin())
- return getDarwinCalleeSavedRegs(MF);
-
- if (MF->getFunction().getCallingConv() == CallingConv::PreserveMost)
- return MF->getSubtarget<AArch64Subtarget>().isTargetWindows()
- ? CSR_Win_AArch64_RT_MostRegs_SaveList
- : CSR_AArch64_RT_MostRegs_SaveList;
+ case CallingConv::PreserveMost:
+ if (Darwin)
+ return CSR_Darwin_AArch64_RT_MostRegs_SaveList;
+ if (Windows)
+ return CSR_Win_AArch64_RT_MostRegs_SaveList;
+ return CSR_AArch64_RT_MostRegs_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::PreserveAll)
- return MF->getSubtarget<AArch64Subtarget>().isTargetWindows()
- ? CSR_Win_AArch64_RT_AllRegs_SaveList
- : CSR_AArch64_RT_AllRegs_SaveList;
+ case CallingConv::PreserveAll:
+ if (Darwin)
+ return CSR_Darwin_AArch64_RT_AllRegs_SaveList;
+ if (Windows)
+ return CSR_Win_AArch64_RT_AllRegs_SaveList;
+ return CSR_AArch64_RT_AllRegs_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::CFGuard_Check)
+ case CallingConv::CFGuard_Check:
+ if (Darwin)
+ report_fatal_error(
+ "Calling convention CFGuard_Check is unsupported on Darwin.");
return CSR_Win_AArch64_CFGuard_Check_SaveList;
- if (MF->getSubtarget<AArch64Subtarget>().isTargetWindows()) {
- if (MF->getSubtarget<AArch64Subtarget>().getTargetLowering()
- ->supportSwiftError() &&
- MF->getFunction().getAttributes().hasAttrSomewhere(
- Attribute::SwiftError))
- return CSR_Win_AArch64_AAPCS_SwiftError_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::SwiftTail)
+
+ case CallingConv::SwiftTail:
+ if (Darwin)
+ return CSR_Darwin_AArch64_AAPCS_SwiftTail_SaveList;
+ if (Windows)
return CSR_Win_AArch64_AAPCS_SwiftTail_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::AArch64_VectorCall)
+ return CSR_AArch64_AAPCS_SwiftTail_SaveList;
+
+ case CallingConv::AArch64_VectorCall:
+ if (Darwin)
+ return CSR_Darwin_AArch64_AAVPCS_SaveList;
+ if (Windows)
return CSR_Win_AArch64_AAVPCS_SaveList;
- if (AFI.hasSVE_AAPCS(*MF))
- return CSR_Win_AArch64_SVE_AAPCS_SaveList;
- return CSR_Win_AArch64_AAPCS_SaveList;
- }
- if (MF->getFunction().getCallingConv() == CallingConv::AArch64_VectorCall)
return CSR_AArch64_AAVPCS_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::AArch64_SVE_VectorCall)
+
+ case CallingConv::AArch64_SVE_VectorCall:
+ if (Darwin)
+ report_fatal_error(
+ "Calling convention SVE_VectorCall is unsupported on Darwin.");
+ if (Windows)
+ return CSR_Win_AArch64_SVE_AAPCS_SaveList;
return CSR_AArch64_SVE_AAPCS_SaveList;
- if (MF->getFunction().getCallingConv() ==
- CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0)
+
+ case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0:
report_fatal_error(
"Calling convention "
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is only "
"supported to improve calls to SME ACLE save/restore/disable-za "
"functions, and is not intended to be used beyond that scope.");
- if (MF->getFunction().getCallingConv() ==
- CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1)
+
+ case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1:
report_fatal_error(
"Calling convention "
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1 is "
"only supported to improve calls to SME ACLE __arm_get_current_vg "
"function, and is not intended to be used beyond that scope.");
- if (MF->getFunction().getCallingConv() ==
- CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
+
+ case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2:
report_fatal_error(
"Calling convention "
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 is "
"only supported to improve calls to SME ACLE __arm_sme_state "
"and is not intended to be used beyond that scope.");
- if (MF->getSubtarget<AArch64Subtarget>().getTargetLowering()
- ->supportSwiftError() &&
- MF->getFunction().getAttributes().hasAttrSomewhere(
- Attribute::SwiftError))
- return CSR_AArch64_AAPCS_SwiftError_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::SwiftTail)
- return CSR_AArch64_AAPCS_SwiftTail_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::Win64)
- // This is for OSes other than Windows; Windows is a separate case further
- // above.
+
+ case CallingConv::Win64:
+ if (Darwin)
+ return CSR_Darwin_AArch64_AAPCS_Win64_SaveList;
+ if (Windows)
+ return CSR_Win_AArch64_AAPCS_SaveList;
return CSR_AArch64_AAPCS_X18_SaveList;
- if (AFI.hasSVE_AAPCS(*MF))
- return CSR_AArch64_SVE_AAPCS_SaveList;
- return CSR_AArch64_AAPCS_SaveList;
-}
-const MCPhysReg *
-AArch64RegisterInfo::getDarwinCalleeSavedRegs(const MachineFunction *MF) const {
- assert(MF && "Invalid MachineFunction pointer.");
- assert(MF->getSubtarget<AArch64Subtarget>().isTargetDarwin() &&
- "Invalid subtarget for getDarwinCalleeSavedRegs");
- auto &AFI = *MF->getInfo<AArch64FunctionInfo>();
+ case CallingConv::CXX_FAST_TLS:
+ if (Darwin)
+ return AFI.isSplitCSR() ? CSR_Darwin_AArch64_CXX_TLS_PE_SaveList
+ : CSR_Darwin_AArch64_CXX_TLS_SaveList;
+ // FIXME: this likely should be a `report_fatal_error` condition, however,
+ // that would be a departure from the previously implemented behaviour.
+ LLVM_FALLTHROUGH;
- if (MF->getFunction().getCallingConv() == CallingConv::CFGuard_Check)
- report_fatal_error(
- "Calling convention CFGuard_Check is unsupported on Darwin.");
- if (MF->getFunction().getCallingConv() == CallingConv::AArch64_VectorCall)
- return CSR_Darwin_AArch64_AAVPCS_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::AArch64_SVE_VectorCall)
- report_fatal_error(
- "Calling convention SVE_VectorCall is unsupported on Darwin.");
- if (MF->getFunction().getCallingConv() ==
- CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0)
- report_fatal_error(
- "Calling convention "
- "AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is "
- "only supported to improve calls to SME ACLE save/restore/disable-za "
- "functions, and is not intended to be used beyond that scope.");
- if (MF->getFunction().getCallingConv() ==
- CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1)
- report_fatal_error(
- "Calling convention "
- "AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1 is "
- "only supported to improve calls to SME ACLE __arm_get_current_vg "
- "function, and is not intended to be used beyond that scope.");
- if (MF->getFunction().getCallingConv() ==
- CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
- report_fatal_error(
- "Calling convention "
- "AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 is "
- "only supported to improve calls to SME ACLE __arm_sme_state "
- "and is not intended to be used beyond that scope.");
- if (MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS)
- return MF->getInfo<AArch64FunctionInfo>()->isSplitCSR()
- ? CSR_Darwin_AArch64_CXX_TLS_PE_SaveList
- : CSR_Darwin_AArch64_CXX_TLS_SaveList;
- if (MF->getSubtarget<AArch64Subtarget>().getTargetLowering()
- ->supportSwiftError() &&
- MF->getFunction().getAttributes().hasAttrSomewhere(
- Attribute::SwiftError))
- return CSR_Darwin_AArch64_AAPCS_SwiftError_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::SwiftTail)
- return CSR_Darwin_AArch64_AAPCS_SwiftTail_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::PreserveMost)
- return CSR_Darwin_AArch64_RT_MostRegs_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::PreserveAll)
- return CSR_Darwin_AArch64_RT_AllRegs_SaveList;
- if (MF->getFunction().getCallingConv() == CallingConv::Win64)
- return CSR_Darwin_AArch64_AAPCS_Win64_SaveList;
- if (AFI.hasSVE_AAPCS(*MF))
- return CSR_Darwin_AArch64_SVE_AAPCS_SaveList;
- return CSR_Darwin_AArch64_AAPCS_SaveList;
+ default:
+ if (Darwin)
+ return AFI.hasSVE_AAPCS(*MF) ? CSR_Darwin_AArch64_SVE_AAPCS_SaveList
+ : CSR_Darwin_AArch64_AAPCS_SaveList;
+ if (Windows)
+ return AFI.hasSVE_AAPCS(*MF) ? CSR_Win_AArch64_SVE_AAPCS_SaveList
+ : CSR_Win_AArch64_AAPCS_SaveList;
+ return AFI.hasSVE_AAPCS(*MF) ? CSR_AArch64_SVE_AAPCS_SaveList
+ : CSR_AArch64_AAPCS_SaveList;
+ }
}
const MCPhysReg *AArch64RegisterInfo::getCalleeSavedRegsViaCopy(
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
index 3b0f4f668b05d..89d1802ab98d5 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.h
@@ -46,7 +46,6 @@ class AArch64RegisterInfo final : public AArch64GenRegisterInfo {
/// Code Generation virtual methods...
const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
- const MCPhysReg *getDarwinCalleeSavedRegs(const MachineFunction *MF) const;
const MCPhysReg *
getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
const uint32_t *getCallPreservedMask(const MachineFunction &MF,
More information about the llvm-commits
mailing list