Skip to content

Commit 0e1152e

Browse files
authored
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).
1 parent e06fabc commit 0e1152e

File tree

2 files changed

+85
-108
lines changed

2 files changed

+85
-108
lines changed

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 85 additions & 107 deletions
Original file line numberDiff line numberDiff line change
@@ -71,148 +71,126 @@ bool AArch64RegisterInfo::regNeedsCFI(MCRegister Reg,
7171
const MCPhysReg *
7272
AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
7373
assert(MF && "Invalid MachineFunction pointer.");
74+
7475
auto &AFI = *MF->getInfo<AArch64FunctionInfo>();
76+
const auto &F = MF->getFunction();
77+
const auto *TLI = MF->getSubtarget<AArch64Subtarget>().getTargetLowering();
78+
const bool Darwin = MF->getSubtarget<AArch64Subtarget>().isTargetDarwin();
79+
const bool Windows = MF->getSubtarget<AArch64Subtarget>().isTargetWindows();
80+
81+
if (TLI->supportSwiftError() &&
82+
F.getAttributes().hasAttrSomewhere(Attribute::SwiftError)) {
83+
if (Darwin)
84+
return CSR_Darwin_AArch64_AAPCS_SwiftError_SaveList;
85+
if (Windows)
86+
return CSR_Win_AArch64_AAPCS_SwiftError_SaveList;
87+
return CSR_AArch64_AAPCS_SwiftError_SaveList;
88+
}
7589

76-
if (MF->getFunction().getCallingConv() == CallingConv::GHC)
90+
switch (F.getCallingConv()) {
91+
case CallingConv::GHC:
7792
// GHC set of callee saved regs is empty as all those regs are
7893
// used for passing STG regs around
7994
return CSR_AArch64_NoRegs_SaveList;
80-
if (MF->getFunction().getCallingConv() == CallingConv::PreserveNone)
95+
96+
case CallingConv::PreserveNone:
97+
// FIXME: Windows likely need this to be altered for properly unwinding.
8198
return CSR_AArch64_NoneRegs_SaveList;
82-
if (MF->getFunction().getCallingConv() == CallingConv::AnyReg)
99+
100+
case CallingConv::AnyReg:
83101
return CSR_AArch64_AllRegs_SaveList;
84102

85-
if (MF->getFunction().getCallingConv() == CallingConv::ARM64EC_Thunk_X64)
103+
case CallingConv::ARM64EC_Thunk_X64:
86104
return CSR_Win_AArch64_Arm64EC_Thunk_SaveList;
87105

88-
// Darwin has its own CSR_AArch64_AAPCS_SaveList, which means most CSR save
89-
// lists depending on that will need to have their Darwin variant as well.
90-
if (MF->getSubtarget<AArch64Subtarget>().isTargetDarwin())
91-
return getDarwinCalleeSavedRegs(MF);
92-
93-
if (MF->getFunction().getCallingConv() == CallingConv::PreserveMost)
94-
return MF->getSubtarget<AArch64Subtarget>().isTargetWindows()
95-
? CSR_Win_AArch64_RT_MostRegs_SaveList
96-
: CSR_AArch64_RT_MostRegs_SaveList;
106+
case CallingConv::PreserveMost:
107+
if (Darwin)
108+
return CSR_Darwin_AArch64_RT_MostRegs_SaveList;
109+
if (Windows)
110+
return CSR_Win_AArch64_RT_MostRegs_SaveList;
111+
return CSR_AArch64_RT_MostRegs_SaveList;
97112

98-
if (MF->getFunction().getCallingConv() == CallingConv::PreserveAll)
99-
return MF->getSubtarget<AArch64Subtarget>().isTargetWindows()
100-
? CSR_Win_AArch64_RT_AllRegs_SaveList
101-
: CSR_AArch64_RT_AllRegs_SaveList;
113+
case CallingConv::PreserveAll:
114+
if (Darwin)
115+
return CSR_Darwin_AArch64_RT_AllRegs_SaveList;
116+
if (Windows)
117+
return CSR_Win_AArch64_RT_AllRegs_SaveList;
118+
return CSR_AArch64_RT_AllRegs_SaveList;
102119

103-
if (MF->getFunction().getCallingConv() == CallingConv::CFGuard_Check)
120+
case CallingConv::CFGuard_Check:
121+
if (Darwin)
122+
report_fatal_error(
123+
"Calling convention CFGuard_Check is unsupported on Darwin.");
104124
return CSR_Win_AArch64_CFGuard_Check_SaveList;
105-
if (MF->getSubtarget<AArch64Subtarget>().isTargetWindows()) {
106-
if (MF->getSubtarget<AArch64Subtarget>().getTargetLowering()
107-
->supportSwiftError() &&
108-
MF->getFunction().getAttributes().hasAttrSomewhere(
109-
Attribute::SwiftError))
110-
return CSR_Win_AArch64_AAPCS_SwiftError_SaveList;
111-
if (MF->getFunction().getCallingConv() == CallingConv::SwiftTail)
125+
126+
case CallingConv::SwiftTail:
127+
if (Darwin)
128+
return CSR_Darwin_AArch64_AAPCS_SwiftTail_SaveList;
129+
if (Windows)
112130
return CSR_Win_AArch64_AAPCS_SwiftTail_SaveList;
113-
if (MF->getFunction().getCallingConv() == CallingConv::AArch64_VectorCall)
131+
return CSR_AArch64_AAPCS_SwiftTail_SaveList;
132+
133+
case CallingConv::AArch64_VectorCall:
134+
if (Darwin)
135+
return CSR_Darwin_AArch64_AAVPCS_SaveList;
136+
if (Windows)
114137
return CSR_Win_AArch64_AAVPCS_SaveList;
115-
if (AFI.hasSVE_AAPCS(*MF))
116-
return CSR_Win_AArch64_SVE_AAPCS_SaveList;
117-
return CSR_Win_AArch64_AAPCS_SaveList;
118-
}
119-
if (MF->getFunction().getCallingConv() == CallingConv::AArch64_VectorCall)
120138
return CSR_AArch64_AAVPCS_SaveList;
121-
if (MF->getFunction().getCallingConv() == CallingConv::AArch64_SVE_VectorCall)
139+
140+
case CallingConv::AArch64_SVE_VectorCall:
141+
if (Darwin)
142+
report_fatal_error(
143+
"Calling convention SVE_VectorCall is unsupported on Darwin.");
144+
if (Windows)
145+
return CSR_Win_AArch64_SVE_AAPCS_SaveList;
122146
return CSR_AArch64_SVE_AAPCS_SaveList;
123-
if (MF->getFunction().getCallingConv() ==
124-
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0)
147+
148+
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0:
125149
report_fatal_error(
126150
"Calling convention "
127151
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is only "
128152
"supported to improve calls to SME ACLE save/restore/disable-za "
129153
"functions, and is not intended to be used beyond that scope.");
130-
if (MF->getFunction().getCallingConv() ==
131-
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1)
154+
155+
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1:
132156
report_fatal_error(
133157
"Calling convention "
134158
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1 is "
135159
"only supported to improve calls to SME ACLE __arm_get_current_vg "
136160
"function, and is not intended to be used beyond that scope.");
137-
if (MF->getFunction().getCallingConv() ==
138-
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
161+
162+
case CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2:
139163
report_fatal_error(
140164
"Calling convention "
141165
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 is "
142166
"only supported to improve calls to SME ACLE __arm_sme_state "
143167
"and is not intended to be used beyond that scope.");
144-
if (MF->getSubtarget<AArch64Subtarget>().getTargetLowering()
145-
->supportSwiftError() &&
146-
MF->getFunction().getAttributes().hasAttrSomewhere(
147-
Attribute::SwiftError))
148-
return CSR_AArch64_AAPCS_SwiftError_SaveList;
149-
if (MF->getFunction().getCallingConv() == CallingConv::SwiftTail)
150-
return CSR_AArch64_AAPCS_SwiftTail_SaveList;
151-
if (MF->getFunction().getCallingConv() == CallingConv::Win64)
152-
// This is for OSes other than Windows; Windows is a separate case further
153-
// above.
168+
169+
case CallingConv::Win64:
170+
if (Darwin)
171+
return CSR_Darwin_AArch64_AAPCS_Win64_SaveList;
172+
if (Windows)
173+
return CSR_Win_AArch64_AAPCS_SaveList;
154174
return CSR_AArch64_AAPCS_X18_SaveList;
155-
if (AFI.hasSVE_AAPCS(*MF))
156-
return CSR_AArch64_SVE_AAPCS_SaveList;
157-
return CSR_AArch64_AAPCS_SaveList;
158-
}
159175

160-
const MCPhysReg *
161-
AArch64RegisterInfo::getDarwinCalleeSavedRegs(const MachineFunction *MF) const {
162-
assert(MF && "Invalid MachineFunction pointer.");
163-
assert(MF->getSubtarget<AArch64Subtarget>().isTargetDarwin() &&
164-
"Invalid subtarget for getDarwinCalleeSavedRegs");
165-
auto &AFI = *MF->getInfo<AArch64FunctionInfo>();
176+
case CallingConv::CXX_FAST_TLS:
177+
if (Darwin)
178+
return AFI.isSplitCSR() ? CSR_Darwin_AArch64_CXX_TLS_PE_SaveList
179+
: CSR_Darwin_AArch64_CXX_TLS_SaveList;
180+
// FIXME: this likely should be a `report_fatal_error` condition, however,
181+
// that would be a departure from the previously implemented behaviour.
182+
LLVM_FALLTHROUGH;
166183

167-
if (MF->getFunction().getCallingConv() == CallingConv::CFGuard_Check)
168-
report_fatal_error(
169-
"Calling convention CFGuard_Check is unsupported on Darwin.");
170-
if (MF->getFunction().getCallingConv() == CallingConv::AArch64_VectorCall)
171-
return CSR_Darwin_AArch64_AAVPCS_SaveList;
172-
if (MF->getFunction().getCallingConv() == CallingConv::AArch64_SVE_VectorCall)
173-
report_fatal_error(
174-
"Calling convention SVE_VectorCall is unsupported on Darwin.");
175-
if (MF->getFunction().getCallingConv() ==
176-
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0)
177-
report_fatal_error(
178-
"Calling convention "
179-
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X0 is "
180-
"only supported to improve calls to SME ACLE save/restore/disable-za "
181-
"functions, and is not intended to be used beyond that scope.");
182-
if (MF->getFunction().getCallingConv() ==
183-
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1)
184-
report_fatal_error(
185-
"Calling convention "
186-
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X1 is "
187-
"only supported to improve calls to SME ACLE __arm_get_current_vg "
188-
"function, and is not intended to be used beyond that scope.");
189-
if (MF->getFunction().getCallingConv() ==
190-
CallingConv::AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2)
191-
report_fatal_error(
192-
"Calling convention "
193-
"AArch64_SME_ABI_Support_Routines_PreserveMost_From_X2 is "
194-
"only supported to improve calls to SME ACLE __arm_sme_state "
195-
"and is not intended to be used beyond that scope.");
196-
if (MF->getFunction().getCallingConv() == CallingConv::CXX_FAST_TLS)
197-
return MF->getInfo<AArch64FunctionInfo>()->isSplitCSR()
198-
? CSR_Darwin_AArch64_CXX_TLS_PE_SaveList
199-
: CSR_Darwin_AArch64_CXX_TLS_SaveList;
200-
if (MF->getSubtarget<AArch64Subtarget>().getTargetLowering()
201-
->supportSwiftError() &&
202-
MF->getFunction().getAttributes().hasAttrSomewhere(
203-
Attribute::SwiftError))
204-
return CSR_Darwin_AArch64_AAPCS_SwiftError_SaveList;
205-
if (MF->getFunction().getCallingConv() == CallingConv::SwiftTail)
206-
return CSR_Darwin_AArch64_AAPCS_SwiftTail_SaveList;
207-
if (MF->getFunction().getCallingConv() == CallingConv::PreserveMost)
208-
return CSR_Darwin_AArch64_RT_MostRegs_SaveList;
209-
if (MF->getFunction().getCallingConv() == CallingConv::PreserveAll)
210-
return CSR_Darwin_AArch64_RT_AllRegs_SaveList;
211-
if (MF->getFunction().getCallingConv() == CallingConv::Win64)
212-
return CSR_Darwin_AArch64_AAPCS_Win64_SaveList;
213-
if (AFI.hasSVE_AAPCS(*MF))
214-
return CSR_Darwin_AArch64_SVE_AAPCS_SaveList;
215-
return CSR_Darwin_AArch64_AAPCS_SaveList;
184+
default:
185+
if (Darwin)
186+
return AFI.hasSVE_AAPCS(*MF) ? CSR_Darwin_AArch64_SVE_AAPCS_SaveList
187+
: CSR_Darwin_AArch64_AAPCS_SaveList;
188+
if (Windows)
189+
return AFI.hasSVE_AAPCS(*MF) ? CSR_Win_AArch64_SVE_AAPCS_SaveList
190+
: CSR_Win_AArch64_AAPCS_SaveList;
191+
return AFI.hasSVE_AAPCS(*MF) ? CSR_AArch64_SVE_AAPCS_SaveList
192+
: CSR_AArch64_AAPCS_SaveList;
193+
}
216194
}
217195

218196
const MCPhysReg *AArch64RegisterInfo::getCalleeSavedRegsViaCopy(

llvm/lib/Target/AArch64/AArch64RegisterInfo.h

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -46,7 +46,6 @@ class AArch64RegisterInfo final : public AArch64GenRegisterInfo {
4646

4747
/// Code Generation virtual methods...
4848
const MCPhysReg *getCalleeSavedRegs(const MachineFunction *MF) const override;
49-
const MCPhysReg *getDarwinCalleeSavedRegs(const MachineFunction *MF) const;
5049
const MCPhysReg *
5150
getCalleeSavedRegsViaCopy(const MachineFunction *MF) const;
5251
const uint32_t *getCallPreservedMask(const MachineFunction &MF,

0 commit comments

Comments
 (0)