@@ -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+
373388struct 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)
0 commit comments