Skip to content

Commit 8f67cdd

Browse files
authored
[AArch64][SME] Support split ZPR and PPR area allocation (#142392)
For a while we have supported the `-aarch64-stack-hazard-size=<size>` option, which adds "hazard padding" between GPRs and FPR/ZPRs. However, there is currently a hole in this mitigation as PPR and FPR/ZPR accesses to the same area also cause streaming memory hazards (this is noted by `-pass-remarks-analysis=sme -aarch64-stack-hazard-remark-size=<val>`), and the current stack layout places PPRs and ZPRs within the same area. Which looks like: ``` ------------------------------------ Higher address | callee-saved gpr registers | |---------------------------------- | | lr,fp (a.k.a. "frame record") | |-----------------------------------| <- fp(=x29) | <hazard padding> | |-----------------------------------| | callee-saved fp/simd/SVE regs | |-----------------------------------| | SVE stack objects | |-----------------------------------| | local variables of fixed size | | <FPR> | | <hazard padding> | | <GPR> | ------------------------------------| <- sp | Lower address ``` With this patch the stack (and hazard padding) is rearranged so that hazard padding is placed between the PPRs and ZPRs rather than within the (fixed size) callee-save region. Which looks something like this: ``` ------------------------------------ Higher address | callee-saved gpr registers | |---------------------------------- | | lr,fp (a.k.a. "frame record") | |-----------------------------------| <- fp(=x29) | callee-saved PPRs | | PPR stack objects | (These are SVE predicates) |-----------------------------------| | <hazard padding> | |-----------------------------------| | callee-saved ZPR regs | (These are SVE vectors) | ZPR stack objects | Note: FPRs are promoted to ZPRs |-----------------------------------| | local variables of fixed size | | <FPR> | | <hazard padding> | | <GPR> | ------------------------------------| <- sp | Lower address ``` This layout is only enabled if: * SplitSVEObjects are enabled (`-aarch64-split-sve-objects`) - (This may be enabled by default in a later patch) * Streaming memory hazards are present - (`-aarch64-stack-hazard-size=<val>` != 0) * PPRs and FPRs/ZPRs are on the stack * There's no stack realignment or variable-sized objects - This is left as a TODO for now Additionally, any FPR callee-saves that are present will be promoted to ZPRs. This is to prevent stack hazards between FPRs and GRPs in the fixed size callee-save area (which would otherwise require more hazard padding, or moving the FPR callee-saves). This layout should resolve the hole in the hazard padding mitigation, and is not intended change codegen for non-SME code.
1 parent b86ddae commit 8f67cdd

15 files changed

+2350
-435
lines changed

llvm/include/llvm/CodeGen/MachineFrameInfo.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -501,8 +501,12 @@ class MachineFrameInfo {
501501
StackID == TargetStackID::ScalablePredicateVector;
502502
}
503503

504-
bool isScalableStackID(int ObjectIdx) const {
504+
bool hasScalableStackID(int ObjectIdx) const {
505505
uint8_t StackID = getStackID(ObjectIdx);
506+
return isScalableStackID(StackID);
507+
}
508+
509+
bool isScalableStackID(uint8_t StackID) const {
506510
return StackID == TargetStackID::ScalableVector ||
507511
StackID == TargetStackID::ScalablePredicateVector;
508512
}

llvm/lib/CodeGen/StackFrameLayoutAnalysisPass.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -72,7 +72,7 @@ struct StackFrameLayoutAnalysis {
7272
: Slot(Idx), Size(MFI.getObjectSize(Idx)),
7373
Align(MFI.getObjectAlign(Idx).value()), Offset(Offset),
7474
SlotTy(Invalid), Scalable(false) {
75-
Scalable = MFI.isScalableStackID(Idx);
75+
Scalable = MFI.hasScalableStackID(Idx);
7676
if (MFI.isSpillSlotObjectIndex(Idx))
7777
SlotTy = SlotType::Spill;
7878
else if (MFI.isFixedObjectIndex(Idx))

llvm/lib/Target/AArch64/AArch64ExpandPseudoInsts.cpp

Lines changed: 2 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1610,7 +1610,8 @@ bool AArch64ExpandPseudo::expandMI(MachineBasicBlock &MBB,
16101610
int BaseOffset = -AFI->getTaggedBasePointerOffset();
16111611
Register FrameReg;
16121612
StackOffset FrameRegOffset = TFI->resolveFrameOffsetReference(
1613-
MF, BaseOffset, false /*isFixed*/, false /*isSVE*/, FrameReg,
1613+
MF, BaseOffset, false /*isFixed*/, TargetStackID::Default /*StackID*/,
1614+
FrameReg,
16141615
/*PreferFP=*/false,
16151616
/*ForSimm=*/true);
16161617
Register SrcReg = FrameReg;

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 232 additions & 65 deletions
Large diffs are not rendered by default.

llvm/lib/Target/AArch64/AArch64FrameLowering.h

Lines changed: 5 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -69,8 +69,9 @@ class AArch64FrameLowering : public TargetFrameLowering {
6969
bool ForSimm) const;
7070
StackOffset resolveFrameOffsetReference(const MachineFunction &MF,
7171
int64_t ObjectOffset, bool isFixed,
72-
bool isSVE, Register &FrameReg,
73-
bool PreferFP, bool ForSimm) const;
72+
TargetStackID::Value StackID,
73+
Register &FrameReg, bool PreferFP,
74+
bool ForSimm) const;
7475
bool spillCalleeSavedRegisters(MachineBasicBlock &MBB,
7576
MachineBasicBlock::iterator MI,
7677
ArrayRef<CalleeSavedInfo> CSI,
@@ -155,7 +156,8 @@ class AArch64FrameLowering : public TargetFrameLowering {
155156
/// Returns the size of the entire ZPR stackframe (calleesaves + spills).
156157
StackOffset getZPRStackSize(const MachineFunction &MF) const;
157158

158-
/// Returns the size of the entire PPR stackframe (calleesaves + spills).
159+
/// Returns the size of the entire PPR stackframe (calleesaves + spills +
160+
/// hazard padding).
159161
StackOffset getPPRStackSize(const MachineFunction &MF) const;
160162

161163
/// Returns the size of the entire SVE stackframe (PPRs + ZPRs).

llvm/lib/Target/AArch64/AArch64ISelDAGToDAG.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7497,7 +7497,7 @@ bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root, SDValue N,
74977497
int FI = cast<FrameIndexSDNode>(N)->getIndex();
74987498
// We can only encode VL scaled offsets, so only fold in frame indexes
74997499
// referencing SVE objects.
7500-
if (MFI.isScalableStackID(FI)) {
7500+
if (MFI.hasScalableStackID(FI)) {
75017501
Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL));
75027502
OffImm = CurDAG->getTargetConstant(0, SDLoc(N), MVT::i64);
75037503
return true;
@@ -7543,7 +7543,7 @@ bool AArch64DAGToDAGISel::SelectAddrModeIndexedSVE(SDNode *Root, SDValue N,
75437543
int FI = cast<FrameIndexSDNode>(Base)->getIndex();
75447544
// We can only encode VL scaled offsets, so only fold in frame indexes
75457545
// referencing SVE objects.
7546-
if (MFI.isScalableStackID(FI))
7546+
if (MFI.hasScalableStackID(FI))
75477547
Base = CurDAG->getTargetFrameIndex(FI, TLI->getPointerTy(DL));
75487548
}
75497549

llvm/lib/Target/AArch64/AArch64ISelLowering.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -9256,7 +9256,7 @@ void AArch64TargetLowering::AdjustInstrPostInstrSelection(MachineInstr &MI,
92569256
(MI.getOpcode() == AArch64::ADDXri ||
92579257
MI.getOpcode() == AArch64::SUBXri)) {
92589258
const MachineOperand &MO = MI.getOperand(1);
9259-
if (MO.isFI() && MF.getFrameInfo().isScalableStackID(MO.getIndex()))
9259+
if (MO.isFI() && MF.getFrameInfo().hasScalableStackID(MO.getIndex()))
92609260
MI.addOperand(MachineOperand::CreateReg(AArch64::VG, /*IsDef=*/false,
92619261
/*IsImplicit=*/true));
92629262
}
@@ -29608,7 +29608,7 @@ void AArch64TargetLowering::finalizeLowering(MachineFunction &MF) const {
2960829608
// than doing it here in finalizeLowering.
2960929609
if (MFI.hasStackProtectorIndex()) {
2961029610
for (unsigned int i = 0, e = MFI.getObjectIndexEnd(); i != e; ++i) {
29611-
if (MFI.isScalableStackID(i) &&
29611+
if (MFI.hasScalableStackID(i) &&
2961229612
MFI.getObjectSSPLayout(i) != MachineFrameInfo::SSPLK_None) {
2961329613
MFI.setStackID(MFI.getStackProtectorIndex(),
2961429614
TargetStackID::ScalableVector);

llvm/lib/Target/AArch64/AArch64MachineFunctionInfo.h

Lines changed: 18 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -137,6 +137,10 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
137137
uint64_t StackSizeZPR = 0;
138138
uint64_t StackSizePPR = 0;
139139

140+
/// Are SVE objects (vectors and predicates) split into separate regions on
141+
/// the stack.
142+
bool SplitSVEObjects = false;
143+
140144
/// HasCalculatedStackSizeSVE indicates whether StackSizeZPR/PPR is valid.
141145
bool HasCalculatedStackSizeSVE = false;
142146

@@ -336,7 +340,6 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
336340

337341
bool isStackRealigned() const { return StackRealigned; }
338342
void setStackRealigned(bool s) { StackRealigned = s; }
339-
340343
bool hasCalleeSaveStackFreeSpace() const {
341344
return CalleeSaveStackHasFreeSpace;
342345
}
@@ -438,6 +441,8 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
438441
}
439442

440443
unsigned getSVECalleeSavedStackSize() const {
444+
assert(!hasSplitSVEObjects() &&
445+
"ZPRs and PPRs are split. Use get[ZPR|PPR]CalleeSavedStackSize()");
441446
return getZPRCalleeSavedStackSize() + getPPRCalleeSavedStackSize();
442447
}
443448

@@ -446,6 +451,10 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
446451
return NumLocalDynamicTLSAccesses;
447452
}
448453

454+
bool isStackHazardIncludedInCalleeSaveArea() const {
455+
return hasStackHazardSlotIndex() && !hasSplitSVEObjects();
456+
}
457+
449458
std::optional<bool> hasRedZone() const { return HasRedZone; }
450459
void setHasRedZone(bool s) { HasRedZone = s; }
451460

@@ -481,7 +490,14 @@ class AArch64FunctionInfo final : public MachineFunctionInfo {
481490
StackHazardCSRSlotIndex = Index;
482491
}
483492

484-
bool hasSplitSVEObjects() const { return false; }
493+
bool hasSplitSVEObjects() const { return SplitSVEObjects; }
494+
void setSplitSVEObjects(bool s) { SplitSVEObjects = s; }
495+
496+
bool hasSVE_AAPCS(const MachineFunction &MF) const {
497+
return hasSplitSVEObjects() || isSVECC() ||
498+
MF.getFunction().getCallingConv() ==
499+
CallingConv::AArch64_SVE_VectorCall;
500+
}
485501

486502
SMEAttrs getSMEFnAttrs() const { return SMEFnAttrs; }
487503

llvm/lib/Target/AArch64/AArch64PrologueEpilogue.cpp

Lines changed: 117 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -723,38 +723,73 @@ void AArch64PrologueEmitter::emitPrologue() {
723723
StackOffset PPRLocalsSize = AFL.getPPRStackSize(MF) - PPRCalleeSavesSize;
724724
StackOffset ZPRLocalsSize = AFL.getZPRStackSize(MF) - ZPRCalleeSavesSize;
725725

726+
std::optional<MachineBasicBlock::iterator> ZPRCalleeSavesBegin,
727+
ZPRCalleeSavesEnd, PPRCalleeSavesBegin, PPRCalleeSavesEnd;
728+
726729
StackOffset CFAOffset =
727730
StackOffset::getFixed((int64_t)MFI.getStackSize() - NumBytes);
728731
MachineBasicBlock::iterator AfterSVESavesI = AfterGPRSavesI;
729732
if (!FPAfterSVECalleeSaves) {
730733
// Process the SVE callee-saves to find the starts/ends of the ZPR and PPR
731734
// areas.
735+
PPRCalleeSavesBegin = AfterGPRSavesI;
732736
if (PPRCalleeSavesSize) {
733737
LLVM_DEBUG(dbgs() << "PPRCalleeSavedStackSize = "
734738
<< PPRCalleeSavesSize.getScalable() << "\n");
735739

736-
assert(isPartOfPPRCalleeSaves(AfterSVESavesI) &&
740+
assert(isPartOfPPRCalleeSaves(*PPRCalleeSavesBegin) &&
737741
"Unexpected instruction");
738742
while (isPartOfPPRCalleeSaves(AfterSVESavesI) &&
739743
AfterSVESavesI != MBB.getFirstTerminator())
740744
++AfterSVESavesI;
741745
}
746+
PPRCalleeSavesEnd = ZPRCalleeSavesBegin = AfterSVESavesI;
742747
if (ZPRCalleeSavesSize) {
743748
LLVM_DEBUG(dbgs() << "ZPRCalleeSavedStackSize = "
744749
<< ZPRCalleeSavesSize.getScalable() << "\n");
745-
assert(isPartOfZPRCalleeSaves(AfterSVESavesI) &&
750+
assert(isPartOfZPRCalleeSaves(*ZPRCalleeSavesBegin) &&
746751
"Unexpected instruction");
747752
while (isPartOfZPRCalleeSaves(AfterSVESavesI) &&
748753
AfterSVESavesI != MBB.getFirstTerminator())
749754
++AfterSVESavesI;
750755
}
756+
ZPRCalleeSavesEnd = AfterSVESavesI;
751757
}
752758

753759
if (EmitAsyncCFI)
754760
emitCalleeSavedSVELocations(AfterSVESavesI);
755761

756762
if (AFI->hasSplitSVEObjects()) {
757-
reportFatalInternalError("not implemented yet");
763+
assert(!FPAfterSVECalleeSaves &&
764+
"Cannot use FPAfterSVECalleeSaves with aarch64-split-sve-objects");
765+
assert(!AFL.canUseRedZone(MF) &&
766+
"Cannot use redzone with aarch64-split-sve-objects");
767+
// TODO: Handle HasWinCFI/NeedsWinCFI?
768+
assert(!NeedsWinCFI &&
769+
"WinCFI with aarch64-split-sve-objects is not supported");
770+
771+
// Split ZPR and PPR allocation.
772+
// Allocate PPR callee saves
773+
allocateStackSpace(*PPRCalleeSavesBegin, 0, PPRCalleeSavesSize,
774+
EmitAsyncCFI && !HasFP, CFAOffset,
775+
MFI.hasVarSizedObjects() || ZPRCalleeSavesSize ||
776+
ZPRLocalsSize || PPRLocalsSize);
777+
CFAOffset += PPRCalleeSavesSize;
778+
779+
// Allocate PPR locals + ZPR callee saves
780+
assert(PPRCalleeSavesEnd == ZPRCalleeSavesBegin &&
781+
"Expected ZPR callee saves after PPR locals");
782+
allocateStackSpace(*PPRCalleeSavesEnd, RealignmentPadding,
783+
PPRLocalsSize + ZPRCalleeSavesSize,
784+
EmitAsyncCFI && !HasFP, CFAOffset,
785+
MFI.hasVarSizedObjects() || ZPRLocalsSize);
786+
CFAOffset += PPRLocalsSize + ZPRCalleeSavesSize;
787+
788+
// Allocate ZPR locals
789+
allocateStackSpace(*ZPRCalleeSavesEnd, RealignmentPadding,
790+
ZPRLocalsSize + StackOffset::getFixed(NumBytes),
791+
EmitAsyncCFI && !HasFP, CFAOffset,
792+
MFI.hasVarSizedObjects());
758793
} else {
759794
// Allocate space for the callee saves (if any).
760795
StackOffset LocalsSize =
@@ -1195,7 +1230,7 @@ void AArch64PrologueEmitter::emitCalleeSavedGPRLocations(
11951230
CFIInstBuilder CFIBuilder(MBB, MBBI, MachineInstr::FrameSetup);
11961231
for (const auto &Info : CSI) {
11971232
unsigned FrameIdx = Info.getFrameIdx();
1198-
if (MFI.isScalableStackID(FrameIdx))
1233+
if (MFI.hasScalableStackID(FrameIdx))
11991234
continue;
12001235

12011236
assert(!Info.isSpilledToReg() && "Spilling to registers not implemented");
@@ -1221,8 +1256,10 @@ void AArch64PrologueEmitter::emitCalleeSavedSVELocations(
12211256
AFL.getOffsetOfLocalArea();
12221257
}
12231258

1259+
StackOffset PPRStackSize = AFL.getPPRStackSize(MF);
12241260
for (const auto &Info : CSI) {
1225-
if (!MFI.isScalableStackID(Info.getFrameIdx()))
1261+
int FI = Info.getFrameIdx();
1262+
if (!MFI.hasScalableStackID(FI))
12261263
continue;
12271264

12281265
// Not all unwinders may know about SVE registers, so assume the lowest
@@ -1233,9 +1270,13 @@ void AArch64PrologueEmitter::emitCalleeSavedSVELocations(
12331270
continue;
12341271

12351272
StackOffset Offset =
1236-
StackOffset::getScalable(MFI.getObjectOffset(Info.getFrameIdx())) -
1273+
StackOffset::getScalable(MFI.getObjectOffset(FI)) -
12371274
StackOffset::getFixed(AFI->getCalleeSavedStackSize(MFI));
12381275

1276+
if (AFI->hasSplitSVEObjects() &&
1277+
MFI.getStackID(FI) == TargetStackID::ScalableVector)
1278+
Offset -= PPRStackSize;
1279+
12391280
CFIBuilder.insertCFIInst(
12401281
createCFAOffset(RegInfo, Reg, Offset, IncomingVGOffsetFromDefCFA));
12411282
}
@@ -1512,7 +1553,75 @@ void AArch64EpilogueEmitter::emitEpilogue() {
15121553
emitCalleeSavedSVERestores(RestoreEnd);
15131554
}
15141555
} else if (AFI->hasSplitSVEObjects() && SVEStackSize) {
1515-
reportFatalInternalError("not implemented yet");
1556+
// TODO: Support stack realigment and variable-sized objects.
1557+
assert(!AFI->isStackRealigned() && !MFI.hasVarSizedObjects() &&
1558+
"unexpected stack realignment or variable sized objects with split "
1559+
"SVE stack objects");
1560+
// SplitSVEObjects. Determine the sizes and starts/ends of the ZPR and PPR
1561+
// areas.
1562+
auto ZPRCalleeSavedSize =
1563+
StackOffset::getScalable(AFI->getZPRCalleeSavedStackSize());
1564+
auto PPRCalleeSavedSize =
1565+
StackOffset::getScalable(AFI->getPPRCalleeSavedStackSize());
1566+
StackOffset PPRLocalsSize = PPRStackSize - PPRCalleeSavedSize;
1567+
StackOffset ZPRLocalsSize = ZPRStackSize - ZPRCalleeSavedSize;
1568+
1569+
MachineBasicBlock::iterator PPRRestoreBegin = FirstGPRRestoreI,
1570+
PPRRestoreEnd = FirstGPRRestoreI;
1571+
if (PPRCalleeSavedSize) {
1572+
PPRRestoreBegin = std::prev(PPRRestoreEnd);
1573+
while (PPRRestoreBegin != MBB.begin() &&
1574+
isPartOfPPRCalleeSaves(std::prev(PPRRestoreBegin)))
1575+
--PPRRestoreBegin;
1576+
}
1577+
1578+
MachineBasicBlock::iterator ZPRRestoreBegin = PPRRestoreBegin,
1579+
ZPRRestoreEnd = PPRRestoreBegin;
1580+
if (ZPRCalleeSavedSize) {
1581+
ZPRRestoreBegin = std::prev(ZPRRestoreEnd);
1582+
while (ZPRRestoreBegin != MBB.begin() &&
1583+
isPartOfZPRCalleeSaves(std::prev(ZPRRestoreBegin)))
1584+
--ZPRRestoreBegin;
1585+
}
1586+
1587+
auto CFAOffset =
1588+
SVEStackSize + StackOffset::getFixed(NumBytes + PrologueSaveSize);
1589+
if (PPRCalleeSavedSize || ZPRCalleeSavedSize) {
1590+
// Deallocate the non-SVE locals first before we can deallocate (and
1591+
// restore callee saves) from the SVE area.
1592+
auto NonSVELocals = StackOffset::getFixed(NumBytes);
1593+
emitFrameOffset(MBB, ZPRRestoreBegin, DL, AArch64::SP, AArch64::SP,
1594+
NonSVELocals, TII, MachineInstr::FrameDestroy, false,
1595+
false, nullptr, EmitCFI && !HasFP, CFAOffset);
1596+
NumBytes = 0;
1597+
CFAOffset -= NonSVELocals;
1598+
}
1599+
1600+
if (ZPRLocalsSize) {
1601+
emitFrameOffset(MBB, ZPRRestoreBegin, DL, AArch64::SP, AArch64::SP,
1602+
ZPRLocalsSize, TII, MachineInstr::FrameDestroy, false,
1603+
false, nullptr, EmitCFI && !HasFP, CFAOffset);
1604+
CFAOffset -= ZPRLocalsSize;
1605+
}
1606+
1607+
if (PPRLocalsSize || ZPRCalleeSavedSize) {
1608+
assert(PPRRestoreBegin == ZPRRestoreEnd &&
1609+
"Expected PPR restores after ZPR");
1610+
emitFrameOffset(MBB, PPRRestoreBegin, DL, AArch64::SP, AArch64::SP,
1611+
PPRLocalsSize + ZPRCalleeSavedSize, TII,
1612+
MachineInstr::FrameDestroy, false, false, nullptr,
1613+
EmitCFI && !HasFP, CFAOffset);
1614+
CFAOffset -= PPRLocalsSize + ZPRCalleeSavedSize;
1615+
}
1616+
if (PPRCalleeSavedSize) {
1617+
emitFrameOffset(MBB, PPRRestoreEnd, DL, AArch64::SP, AArch64::SP,
1618+
PPRCalleeSavedSize, TII, MachineInstr::FrameDestroy,
1619+
false, false, nullptr, EmitCFI && !HasFP, CFAOffset);
1620+
}
1621+
1622+
// We only emit CFI information for ZPRs so emit CFI after the ZPR restores.
1623+
if (EmitCFI)
1624+
emitCalleeSavedSVERestores(ZPRRestoreEnd);
15161625
}
15171626

15181627
if (!HasFP) {
@@ -1670,7 +1779,7 @@ void AArch64EpilogueEmitter::emitCalleeSavedRestores(
16701779
CFIInstBuilder CFIBuilder(MBB, MBBI, MachineInstr::FrameDestroy);
16711780

16721781
for (const auto &Info : CSI) {
1673-
if (SVE != MFI.isScalableStackID(Info.getFrameIdx()))
1782+
if (SVE != MFI.hasScalableStackID(Info.getFrameIdx()))
16741783
continue;
16751784

16761785
MCRegister Reg = Info.getReg();

llvm/lib/Target/AArch64/AArch64RegisterInfo.cpp

Lines changed: 5 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -71,6 +71,7 @@ bool AArch64RegisterInfo::regNeedsCFI(MCRegister Reg,
7171
const MCPhysReg *
7272
AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
7373
assert(MF && "Invalid MachineFunction pointer.");
74+
auto &AFI = *MF->getInfo<AArch64FunctionInfo>();
7475

7576
if (MF->getFunction().getCallingConv() == CallingConv::GHC)
7677
// GHC set of callee saved regs is empty as all those regs are
@@ -101,10 +102,7 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
101102
return CSR_Win_AArch64_AAPCS_SwiftTail_SaveList;
102103
if (MF->getFunction().getCallingConv() == CallingConv::AArch64_VectorCall)
103104
return CSR_Win_AArch64_AAVPCS_SaveList;
104-
if (MF->getFunction().getCallingConv() ==
105-
CallingConv::AArch64_SVE_VectorCall)
106-
return CSR_Win_AArch64_SVE_AAPCS_SaveList;
107-
if (MF->getInfo<AArch64FunctionInfo>()->isSVECC())
105+
if (AFI.hasSVE_AAPCS(*MF))
108106
return CSR_Win_AArch64_SVE_AAPCS_SaveList;
109107
return CSR_Win_AArch64_AAPCS_SaveList;
110108
}
@@ -148,7 +146,7 @@ AArch64RegisterInfo::getCalleeSavedRegs(const MachineFunction *MF) const {
148146
// This is for OSes other than Windows; Windows is a separate case further
149147
// above.
150148
return CSR_AArch64_AAPCS_X18_SaveList;
151-
if (MF->getInfo<AArch64FunctionInfo>()->isSVECC())
149+
if (AFI.hasSVE_AAPCS(*MF))
152150
return CSR_AArch64_SVE_AAPCS_SaveList;
153151
return CSR_AArch64_AAPCS_SaveList;
154152
}
@@ -158,6 +156,7 @@ AArch64RegisterInfo::getDarwinCalleeSavedRegs(const MachineFunction *MF) const {
158156
assert(MF && "Invalid MachineFunction pointer.");
159157
assert(MF->getSubtarget<AArch64Subtarget>().isTargetDarwin() &&
160158
"Invalid subtarget for getDarwinCalleeSavedRegs");
159+
auto &AFI = *MF->getInfo<AArch64FunctionInfo>();
161160

162161
if (MF->getFunction().getCallingConv() == CallingConv::CFGuard_Check)
163162
report_fatal_error(
@@ -205,7 +204,7 @@ AArch64RegisterInfo::getDarwinCalleeSavedRegs(const MachineFunction *MF) const {
205204
return CSR_Darwin_AArch64_RT_AllRegs_SaveList;
206205
if (MF->getFunction().getCallingConv() == CallingConv::Win64)
207206
return CSR_Darwin_AArch64_AAPCS_Win64_SaveList;
208-
if (MF->getInfo<AArch64FunctionInfo>()->isSVECC())
207+
if (AFI.hasSVE_AAPCS(*MF))
209208
return CSR_Darwin_AArch64_SVE_AAPCS_SaveList;
210209
return CSR_Darwin_AArch64_AAPCS_SaveList;
211210
}

0 commit comments

Comments
 (0)