Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
192 changes: 85 additions & 107 deletions llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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(
Expand Down
1 change: 0 additions & 1 deletion llvm/lib/Target/AArch64/AArch64RegisterInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -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,
Expand Down
Loading