Skip to content

Commit 08c90e0

Browse files
committed
Add getSVEStackAllocations helper (NFC)
1 parent d719e81 commit 08c90e0

File tree

2 files changed

+58
-59
lines changed

2 files changed

+58
-59
lines changed

llvm/lib/Target/AArch64/AArch64PrologueEpilogue.cpp

Lines changed: 52 additions & 59 deletions
Original file line numberDiff line numberDiff line change
@@ -370,6 +370,21 @@ SVEFrameSizes AArch64PrologueEpilogueCommon::getSVEStackFrameSizes() const {
370370
{ZPRCalleeSavesSize, PPRLocalsSize + ZPRLocalsSize}};
371371
}
372372

373+
SVEStackAllocations AArch64PrologueEpilogueCommon::getSVEStackAllocations(
374+
SVEFrameSizes const &SVE) {
375+
StackOffset AfterZPRs = SVE.ZPR.LocalsSize;
376+
StackOffset BeforePPRs = SVE.ZPR.CalleeSavesSize + SVE.PPR.CalleeSavesSize;
377+
StackOffset AfterPPRs = {};
378+
if (SVELayout == SVEStackLayout::Split) {
379+
BeforePPRs = SVE.PPR.CalleeSavesSize;
380+
if (SVE.ZPR.CalleeSavesSize)
381+
AfterPPRs += SVE.PPR.LocalsSize + SVE.ZPR.CalleeSavesSize;
382+
else
383+
AfterZPRs += SVE.PPR.LocalsSize; // Group allocation of locals.
384+
}
385+
return {BeforePPRs, AfterPPRs, AfterZPRs};
386+
}
387+
373388
struct SVEPartitions {
374389
struct {
375390
MachineBasicBlock::iterator Begin, End;
@@ -687,16 +702,17 @@ void AArch64PrologueEmitter::emitPrologue() {
687702
// All of the remaining stack allocations are for locals.
688703
determineLocalsStackSize(NumBytes, PrologueSaveSize);
689704

705+
auto [PPR, ZPR] = getSVEStackFrameSizes();
706+
SVEStackAllocations SVEAllocs = getSVEStackAllocations({PPR, ZPR});
707+
690708
MachineBasicBlock::iterator FirstGPRSaveI = PrologueBeginI;
691709
if (SVELayout == SVEStackLayout::CalleeSavesAboveFrameRecord) {
692710
// If we're doing SVE saves first, we need to immediately allocate space
693711
// for fixed objects, then space for the SVE callee saves.
694712
//
695713
// Windows unwind requires that the scalable size is a multiple of 16;
696714
// that's handled when the callee-saved size is computed.
697-
auto SaveSize =
698-
StackOffset::getScalable(AFI->getSVECalleeSavedStackSize()) +
699-
StackOffset::getFixed(FixedObject);
715+
auto SaveSize = SVEAllocs.BeforePPRs + StackOffset::getFixed(FixedObject);
700716
allocateStackSpace(PrologueBeginI, 0, SaveSize, false, StackOffset{},
701717
/*FollowupAllocs=*/true);
702718
NumBytes -= FixedObject;
@@ -764,13 +780,11 @@ void AArch64PrologueEmitter::emitPrologue() {
764780
if (AFL.windowsRequiresStackProbe(MF, NumBytes + RealignmentPadding))
765781
emitWindowsStackProbe(AfterGPRSavesI, DL, NumBytes, RealignmentPadding);
766782

767-
auto [PPR, ZPR] = getSVEStackFrameSizes();
768-
StackOffset SVECalleeSavesSize = ZPR.CalleeSavesSize + PPR.CalleeSavesSize;
769783
StackOffset NonSVELocalsSize = StackOffset::getFixed(NumBytes);
770-
StackOffset AllocateAfterZPRs = ZPR.LocalsSize + NonSVELocalsSize;
784+
SVEAllocs.AfterZPRs += NonSVELocalsSize;
785+
771786
StackOffset CFAOffset =
772787
StackOffset::getFixed(MFI.getStackSize()) - NonSVELocalsSize;
773-
774788
MachineBasicBlock::iterator AfterSVESavesI = AfterGPRSavesI;
775789
// Allocate space for the callee saves and PPR locals (if any).
776790
if (SVELayout != SVEStackLayout::CalleeSavesAboveFrameRecord) {
@@ -781,34 +795,24 @@ void AArch64PrologueEmitter::emitPrologue() {
781795
if (EmitAsyncCFI)
782796
emitCalleeSavedSVELocations(AfterSVESavesI);
783797

784-
StackOffset AllocateBeforePPRs = SVECalleeSavesSize;
785-
StackOffset AllocateAfterPPRs = {};
786-
787-
if (SVELayout == SVEStackLayout::Split) {
788-
AllocateBeforePPRs = PPR.CalleeSavesSize;
789-
if (ZPR.CalleeSavesSize)
790-
AllocateAfterPPRs += PPR.LocalsSize + ZPR.CalleeSavesSize;
791-
else
792-
AllocateAfterZPRs += PPR.LocalsSize; // Group allocation of locals.
793-
}
794-
allocateStackSpace(PPRRange.Begin, 0, AllocateBeforePPRs,
798+
allocateStackSpace(PPRRange.Begin, 0, SVEAllocs.BeforePPRs,
795799
EmitAsyncCFI && !HasFP, CFAOffset,
796-
MFI.hasVarSizedObjects() || AllocateAfterPPRs ||
797-
AllocateAfterZPRs);
798-
CFAOffset += AllocateBeforePPRs;
800+
MFI.hasVarSizedObjects() || SVEAllocs.AfterPPRs ||
801+
SVEAllocs.AfterZPRs);
802+
CFAOffset += SVEAllocs.BeforePPRs;
799803
assert(PPRRange.End == ZPRRange.Begin &&
800804
"Expected ZPR callee saves after PPR locals");
801-
allocateStackSpace(PPRRange.End, RealignmentPadding, AllocateAfterPPRs,
805+
allocateStackSpace(PPRRange.End, RealignmentPadding, SVEAllocs.AfterPPRs,
802806
EmitAsyncCFI && !HasFP, CFAOffset,
803-
MFI.hasVarSizedObjects() || AllocateAfterZPRs);
804-
CFAOffset += AllocateAfterPPRs;
807+
MFI.hasVarSizedObjects() || SVEAllocs.AfterZPRs);
808+
CFAOffset += SVEAllocs.AfterPPRs;
805809
} else {
806810
assert(SVELayout == SVEStackLayout::CalleeSavesAboveFrameRecord);
807811
// Note: With CalleeSavesAboveFrameRecord, the SVE CS have already been
808812
// allocated (and separate PPR locals are not supported, all SVE locals,
809813
// both PPR and ZPR, are within the ZPR locals area).
810814
assert(!PPR.LocalsSize && "Unexpected PPR locals!");
811-
CFAOffset += SVECalleeSavesSize;
815+
CFAOffset += ZPR.CalleeSavesSize + PPR.CalleeSavesSize;
812816
}
813817

814818
// Allocate space for the rest of the frame including ZPR locals. Align the
@@ -819,7 +823,7 @@ void AArch64PrologueEmitter::emitPrologue() {
819823
// FIXME: in the case of dynamic re-alignment, NumBytes doesn't have the
820824
// correct value here, as NumBytes also includes padding bytes, which
821825
// shouldn't be counted here.
822-
allocateStackSpace(AfterSVESavesI, RealignmentPadding, AllocateAfterZPRs,
826+
allocateStackSpace(AfterSVESavesI, RealignmentPadding, SVEAllocs.AfterZPRs,
823827
EmitAsyncCFI && !HasFP, CFAOffset,
824828
MFI.hasVarSizedObjects());
825829
}
@@ -1476,27 +1480,24 @@ void AArch64EpilogueEmitter::emitEpilogue() {
14761480
assert(NumBytes >= 0 && "Negative stack allocation size!?");
14771481

14781482
StackOffset SVECalleeSavesSize = ZPR.CalleeSavesSize + PPR.CalleeSavesSize;
1479-
StackOffset SVEStackSize =
1480-
SVECalleeSavesSize + PPR.LocalsSize + ZPR.LocalsSize;
1483+
SVEStackAllocations SVEAllocs = getSVEStackAllocations({PPR, ZPR});
14811484
MachineBasicBlock::iterator RestoreBegin = ZPRRange.Begin;
1482-
MachineBasicBlock::iterator RestoreEnd = PPRRange.End;
14831485

14841486
// Deallocate the SVE area.
14851487
if (SVELayout == SVEStackLayout::CalleeSavesAboveFrameRecord) {
1486-
StackOffset SVELocalsSize = ZPR.LocalsSize + PPR.LocalsSize;
14871488
// If the callee-save area is before FP, restoring the FP implicitly
1488-
// deallocates non-callee-save SVE allocations. Otherwise, deallocate them
1489+
// deallocates non-callee-save SVE allocations. Otherwise, deallocate them
14891490
// explicitly.
14901491
if (!AFI->isStackRealigned() && !MFI.hasVarSizedObjects()) {
14911492
emitFrameOffset(MBB, FirstGPRRestoreI, DL, AArch64::SP, AArch64::SP,
1492-
SVELocalsSize, TII, MachineInstr::FrameDestroy, false,
1493-
NeedsWinCFI, &HasWinCFI);
1493+
SVEAllocs.AfterZPRs, TII, MachineInstr::FrameDestroy,
1494+
false, NeedsWinCFI, &HasWinCFI);
14941495
}
14951496

14961497
// Deallocate callee-save SVE registers.
1497-
emitFrameOffset(MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
1498-
SVECalleeSavesSize, TII, MachineInstr::FrameDestroy, false,
1499-
NeedsWinCFI, &HasWinCFI);
1498+
emitFrameOffset(MBB, PPRRange.End, DL, AArch64::SP, AArch64::SP,
1499+
SVEAllocs.BeforePPRs, TII, MachineInstr::FrameDestroy,
1500+
false, NeedsWinCFI, &HasWinCFI);
15001501
} else if (AFI->hasSVEStackSize()) {
15011502
// If we have stack realignment or variable-sized objects we must use the FP
15021503
// to restore SVE callee saves (as there is an unknown amount of
@@ -1529,40 +1530,32 @@ void AArch64EpilogueEmitter::emitEpilogue() {
15291530
-SVECalleeSavesSize, TII, MachineInstr::FrameDestroy);
15301531
} else if (BaseForSVEDealloc == AArch64::SP) {
15311532
auto NonSVELocals = StackOffset::getFixed(NumBytes);
1532-
auto CFAOffset =
1533-
SVEStackSize + NonSVELocals + StackOffset::getFixed(PrologueSaveSize);
1534-
1535-
StackOffset DeallocBeforePPRs = {};
1536-
StackOffset DeallocBeforeZPRs = ZPR.LocalsSize;
1537-
StackOffset DeallocAfterPPRs = SVECalleeSavesSize;
1533+
auto CFAOffset = NonSVELocals + StackOffset::getFixed(PrologueSaveSize) +
1534+
SVEAllocs.totalSize();
15381535

15391536
if (SVECalleeSavesSize || SVELayout == SVEStackLayout::Split) {
15401537
// Deallocate non-SVE locals now. This is needed to reach the SVE callee
15411538
// saves, but may also allow combining stack hazard bumps for split SVE.
1542-
DeallocBeforeZPRs += NonSVELocals;
1539+
SVEAllocs.AfterZPRs += NonSVELocals;
15431540
NumBytes -= NonSVELocals.getFixed();
15441541
}
1545-
1546-
if (SVELayout == SVEStackLayout::Split) {
1547-
DeallocAfterPPRs = PPR.CalleeSavesSize;
1548-
if (ZPR.CalleeSavesSize)
1549-
DeallocBeforePPRs += PPR.LocalsSize + ZPR.CalleeSavesSize;
1550-
else
1551-
DeallocBeforeZPRs += PPR.LocalsSize; // Group deallocation of locals.
1552-
}
1542+
// To deallocate the SVE stack adjust by the allocations in reverse.
15531543
emitFrameOffset(MBB, ZPRRange.Begin, DL, AArch64::SP, AArch64::SP,
1554-
DeallocBeforeZPRs, TII, MachineInstr::FrameDestroy, false,
1555-
NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP, CFAOffset);
1556-
CFAOffset -= DeallocBeforeZPRs;
1544+
SVEAllocs.AfterZPRs, TII, MachineInstr::FrameDestroy,
1545+
false, NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP,
1546+
CFAOffset);
1547+
CFAOffset -= SVEAllocs.AfterZPRs;
15571548
assert(PPRRange.Begin == ZPRRange.End &&
15581549
"Expected PPR restores after ZPR");
15591550
emitFrameOffset(MBB, PPRRange.Begin, DL, AArch64::SP, AArch64::SP,
1560-
DeallocBeforePPRs, TII, MachineInstr::FrameDestroy, false,
1561-
NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP, CFAOffset);
1562-
CFAOffset -= DeallocBeforePPRs;
1551+
SVEAllocs.AfterPPRs, TII, MachineInstr::FrameDestroy,
1552+
false, NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP,
1553+
CFAOffset);
1554+
CFAOffset -= SVEAllocs.AfterPPRs;
15631555
emitFrameOffset(MBB, PPRRange.End, DL, AArch64::SP, AArch64::SP,
1564-
DeallocAfterPPRs, TII, MachineInstr::FrameDestroy, false,
1565-
NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP, CFAOffset);
1556+
SVEAllocs.BeforePPRs, TII, MachineInstr::FrameDestroy,
1557+
false, NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP,
1558+
CFAOffset);
15661559
}
15671560

15681561
if (EmitCFI)

llvm/lib/Target/AArch64/AArch64PrologueEpilogue.h

Lines changed: 6 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -33,6 +33,11 @@ struct SVEFrameSizes {
3333
} PPR, ZPR;
3434
};
3535

36+
struct SVEStackAllocations {
37+
StackOffset BeforePPRs, AfterPPRs, AfterZPRs;
38+
StackOffset totalSize() const { return BeforePPRs + AfterPPRs + AfterZPRs; }
39+
};
40+
3641
class AArch64PrologueEpilogueCommon {
3742
public:
3843
AArch64PrologueEpilogueCommon(MachineFunction &MF, MachineBasicBlock &MBB,
@@ -66,6 +71,7 @@ class AArch64PrologueEpilogueCommon {
6671
bool shouldCombineCSRLocalStackBump(uint64_t StackBumpBytes) const;
6772

6873
SVEFrameSizes getSVEStackFrameSizes() const;
74+
SVEStackAllocations getSVEStackAllocations(SVEFrameSizes const &);
6975

7076
MachineFunction &MF;
7177
MachineBasicBlock &MBB;

0 commit comments

Comments
 (0)