-
Notifications
You must be signed in to change notification settings - Fork 15.2k
AArch64: rewrite the CSR compuation #167967
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Conversation
|
@llvm/pr-subscribers-backend-aarch64 Author: Saleem Abdulrasool (compnerd) ChangesRather 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). Full diff: https://github.com/llvm/llvm-project/pull/167967.diff 2 Files Affected:
diff --git a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
index ef5941c42f687..e327c081578ec 100644
--- a/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
+++ b/llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
@@ -71,148 +71,123 @@ 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:
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;
+ 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,
|
efriedma-quic
left a comment
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
LGTM with a couple minor comments.
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).
c3e5f11 to
faf48fa
Compare
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).