@@ -715,8 +715,6 @@ void AArch64PrologueEmitter::emitPrologue() {
715715 if (AFL.windowsRequiresStackProbe (MF, NumBytes + RealignmentPadding))
716716 emitWindowsStackProbe (AfterGPRSavesI, DL, NumBytes, RealignmentPadding);
717717
718- MachineBasicBlock::iterator CalleeSavesEnd = AfterGPRSavesI;
719-
720718 StackOffset PPRCalleeSavesSize =
721719 StackOffset::getScalable (AFI->getPPRCalleeSavedStackSize ());
722720 StackOffset ZPRCalleeSavesSize =
@@ -728,72 +726,59 @@ void AArch64PrologueEmitter::emitPrologue() {
728726 StackOffset CFAOffset =
729727 StackOffset::getFixed ((int64_t )MFI.getStackSize () - NumBytes);
730728 MachineBasicBlock::iterator AfterSVESavesI = AfterGPRSavesI;
731-
732729 if (!FPAfterSVECalleeSaves) {
733- MachineBasicBlock::iterator ZPRCalleeSavesBegin = AfterGPRSavesI,
734- ZPRCalleeSavesEnd = AfterGPRSavesI;
735- MachineBasicBlock::iterator PPRCalleeSavesBegin = AfterGPRSavesI,
736- PPRCalleeSavesEnd = AfterGPRSavesI;
737-
738- // Process the SVE callee-saves to determine what space needs to be
739- // allocated.
740-
730+ // Process the SVE callee-saves to find the starts/ends of the ZPR and PPR
731+ // areas.
741732 if (PPRCalleeSavesSize) {
742733 LLVM_DEBUG (dbgs () << " PPRCalleeSavedStackSize = "
743734 << PPRCalleeSavesSize.getScalable () << " \n " );
744735
745- PPRCalleeSavesBegin = AfterSVESavesI;
746- assert (isPartOfPPRCalleeSaves (PPRCalleeSavesBegin) &&
736+ assert (isPartOfPPRCalleeSaves (AfterSVESavesI) &&
747737 " Unexpected instruction" );
748738 while (isPartOfPPRCalleeSaves (AfterSVESavesI) &&
749739 AfterSVESavesI != MBB.getFirstTerminator ())
750740 ++AfterSVESavesI;
751- PPRCalleeSavesEnd = AfterSVESavesI;
752741 }
753-
754742 if (ZPRCalleeSavesSize) {
755743 LLVM_DEBUG (dbgs () << " ZPRCalleeSavedStackSize = "
756744 << ZPRCalleeSavesSize.getScalable () << " \n " );
757- ZPRCalleeSavesBegin = AfterSVESavesI;
758- assert (isPartOfZPRCalleeSaves (ZPRCalleeSavesBegin) &&
745+ assert (isPartOfZPRCalleeSaves (AfterSVESavesI) &&
759746 " Unexpected instruction" );
760747 while (isPartOfZPRCalleeSaves (AfterSVESavesI) &&
761748 AfterSVESavesI != MBB.getFirstTerminator ())
762749 ++AfterSVESavesI;
763- ZPRCalleeSavesEnd = AfterSVESavesI;
764750 }
751+ }
752+
753+ if (EmitAsyncCFI)
754+ emitCalleeSavedSVELocations (AfterSVESavesI);
765755
756+ if (AFI->hasSplitSVEObjects ()) {
757+ reportFatalInternalError (" not implemented yet" );
758+ } else {
766759 // Allocate space for the callee saves (if any).
767760 StackOffset LocalsSize =
768761 PPRLocalsSize + ZPRLocalsSize + StackOffset::getFixed (NumBytes);
769- MachineBasicBlock::iterator CalleeSavesBegin =
770- AFI->getPPRCalleeSavedStackSize () ? PPRCalleeSavesBegin
771- : ZPRCalleeSavesBegin;
772- allocateStackSpace (CalleeSavesBegin, 0 , SVECalleeSavesSize,
773- EmitAsyncCFI && !HasFP, CFAOffset,
774- MFI.hasVarSizedObjects () || LocalsSize);
775-
776- CalleeSavesEnd = AFI->getZPRCalleeSavedStackSize () ? ZPRCalleeSavesEnd
777- : PPRCalleeSavesEnd;
778- }
779- CFAOffset += SVECalleeSavesSize;
780-
781- if (EmitAsyncCFI)
782- emitCalleeSavedSVELocations (CalleeSavesEnd);
783-
784- // Allocate space for the rest of the frame including SVE locals. Align the
785- // stack as necessary.
786- assert (!(AFL.canUseRedZone (MF) && NeedsRealignment) &&
787- " Cannot use redzone with stack realignment" );
788- if (!AFL.canUseRedZone (MF)) {
789- // FIXME: in the case of dynamic re-alignment, NumBytes doesn't have
790- // the correct value here, as NumBytes also includes padding bytes,
791- // which shouldn't be counted here.
792- StackOffset SVELocalsSize = PPRLocalsSize + ZPRLocalsSize;
793- allocateStackSpace (CalleeSavesEnd, RealignmentPadding,
794- SVELocalsSize + StackOffset::getFixed (NumBytes),
795- EmitAsyncCFI && !HasFP, CFAOffset,
796- MFI.hasVarSizedObjects ());
762+ if (!FPAfterSVECalleeSaves)
763+ allocateStackSpace (AfterGPRSavesI, 0 , SVECalleeSavesSize,
764+ EmitAsyncCFI && !HasFP, CFAOffset,
765+ MFI.hasVarSizedObjects () || LocalsSize);
766+ CFAOffset += SVECalleeSavesSize;
767+
768+ // Allocate space for the rest of the frame including SVE locals. Align the
769+ // stack as necessary.
770+ assert (!(AFL.canUseRedZone (MF) && NeedsRealignment) &&
771+ " Cannot use redzone with stack realignment" );
772+ if (!AFL.canUseRedZone (MF)) {
773+ // FIXME: in the case of dynamic re-alignment, NumBytes doesn't have
774+ // the correct value here, as NumBytes also includes padding bytes,
775+ // which shouldn't be counted here.
776+ StackOffset SVELocalsSize = PPRLocalsSize + ZPRLocalsSize;
777+ allocateStackSpace (AfterSVESavesI, RealignmentPadding,
778+ SVELocalsSize + StackOffset::getFixed (NumBytes),
779+ EmitAsyncCFI && !HasFP, CFAOffset,
780+ MFI.hasVarSizedObjects ());
781+ }
797782 }
798783
799784 // If we need a base pointer, set it up here. It's whatever the value of the
@@ -1391,7 +1376,9 @@ void AArch64EpilogueEmitter::emitEpilogue() {
13911376 if (HasFP && AFI->hasSwiftAsyncContext ())
13921377 emitSwiftAsyncContextFramePointer (EpilogueEndI, DL);
13931378
1394- StackOffset SVEStackSize = AFL.getSVEStackSize (MF);
1379+ StackOffset ZPRStackSize = AFL.getZPRStackSize (MF);
1380+ StackOffset PPRStackSize = AFL.getPPRStackSize (MF);
1381+ StackOffset SVEStackSize = ZPRStackSize + PPRStackSize;
13951382
13961383 // If there is a single SP update, insert it before the ret and we're done.
13971384 if (CombineSPBump) {
@@ -1412,111 +1399,120 @@ void AArch64EpilogueEmitter::emitEpilogue() {
14121399 NumBytes -= PrologueSaveSize;
14131400 assert (NumBytes >= 0 && " Negative stack allocation size!?" );
14141401
1415- // Process the SVE callee-saves to determine what space needs to be
1416- // deallocated.
1417- StackOffset DeallocateBefore = {}, DeallocateAfter = SVEStackSize;
1418- MachineBasicBlock::iterator RestoreBegin = FirstGPRRestoreI,
1419- RestoreEnd = FirstGPRRestoreI;
1420- int64_t ZPRCalleeSavedSize = AFI->getZPRCalleeSavedStackSize ();
1421- int64_t PPRCalleeSavedSize = AFI->getPPRCalleeSavedStackSize ();
1422- int64_t SVECalleeSavedSize = ZPRCalleeSavedSize + PPRCalleeSavedSize;
1423-
1424- if (SVECalleeSavedSize) {
1425- if (FPAfterSVECalleeSaves)
1426- RestoreEnd = MBB.getFirstTerminator ();
1427-
1428- RestoreBegin = std::prev (RestoreEnd);
1429- while (RestoreBegin != MBB.begin () &&
1430- isPartOfSVECalleeSaves (std::prev (RestoreBegin)))
1431- --RestoreBegin;
1432-
1433- assert (isPartOfSVECalleeSaves (RestoreBegin) &&
1434- isPartOfSVECalleeSaves (std::prev (RestoreEnd)) &&
1435- " Unexpected instruction" );
1436-
1437- StackOffset CalleeSavedSizeAsOffset =
1438- StackOffset::getScalable (SVECalleeSavedSize);
1439- DeallocateBefore = SVEStackSize - CalleeSavedSizeAsOffset;
1440- DeallocateAfter = CalleeSavedSizeAsOffset;
1441- }
1402+ if (!AFI->hasSplitSVEObjects ()) {
1403+ // Process the SVE callee-saves to determine what space needs to be
1404+ // deallocated.
1405+ StackOffset DeallocateBefore = {}, DeallocateAfter = SVEStackSize;
1406+ MachineBasicBlock::iterator RestoreBegin = FirstGPRRestoreI,
1407+ RestoreEnd = FirstGPRRestoreI;
1408+ int64_t ZPRCalleeSavedSize = AFI->getZPRCalleeSavedStackSize ();
1409+ int64_t PPRCalleeSavedSize = AFI->getPPRCalleeSavedStackSize ();
1410+ int64_t SVECalleeSavedSize = ZPRCalleeSavedSize + PPRCalleeSavedSize;
1411+
1412+ if (SVECalleeSavedSize) {
1413+ if (FPAfterSVECalleeSaves)
1414+ RestoreEnd = MBB.getFirstTerminator ();
1415+
1416+ RestoreBegin = std::prev (RestoreEnd);
1417+ while (RestoreBegin != MBB.begin () &&
1418+ isPartOfSVECalleeSaves (std::prev (RestoreBegin)))
1419+ --RestoreBegin;
1420+
1421+ assert (isPartOfSVECalleeSaves (RestoreBegin) &&
1422+ isPartOfSVECalleeSaves (std::prev (RestoreEnd)) &&
1423+ " Unexpected instruction" );
14421424
1443- // Deallocate the SVE area.
1444- if (FPAfterSVECalleeSaves) {
1445- // If the callee-save area is before FP, restoring the FP implicitly
1446- // deallocates non-callee-save SVE allocations. Otherwise, deallocate
1447- // them explicitly.
1448- if (!AFI->isStackRealigned () && !MFI.hasVarSizedObjects ()) {
1449- emitFrameOffset (MBB, FirstGPRRestoreI, DL, AArch64::SP, AArch64::SP,
1450- DeallocateBefore, TII, MachineInstr::FrameDestroy, false ,
1451- NeedsWinCFI, &HasWinCFI);
1425+ StackOffset CalleeSavedSizeAsOffset =
1426+ StackOffset::getScalable (SVECalleeSavedSize);
1427+ DeallocateBefore = SVEStackSize - CalleeSavedSizeAsOffset;
1428+ DeallocateAfter = CalleeSavedSizeAsOffset;
14521429 }
14531430
1454- // Deallocate callee-save non-SVE registers.
1455- emitFrameOffset (MBB, RestoreBegin, DL, AArch64::SP, AArch64::SP,
1456- StackOffset::getFixed (AFI->getCalleeSavedStackSize ()), TII,
1457- MachineInstr::FrameDestroy, false , NeedsWinCFI, &HasWinCFI);
1458-
1459- // Deallocate fixed objects.
1460- emitFrameOffset (MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
1461- StackOffset::getFixed (FixedObject), TII,
1462- MachineInstr::FrameDestroy, false , NeedsWinCFI, &HasWinCFI);
1463-
1464- // Deallocate callee-save SVE registers.
1465- emitFrameOffset (MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
1466- DeallocateAfter, TII, MachineInstr::FrameDestroy, false ,
1467- NeedsWinCFI, &HasWinCFI);
1468- } else if (SVEStackSize) {
1469- int64_t SVECalleeSavedSize = AFI->getSVECalleeSavedStackSize ();
1470- // If we have stack realignment or variable-sized objects we must use the
1471- // FP to restore SVE callee saves (as there is an unknown amount of
1472- // data/padding between the SP and SVE CS area).
1473- Register BaseForSVEDealloc =
1474- (AFI->isStackRealigned () || MFI.hasVarSizedObjects ()) ? AArch64::FP
1475- : AArch64::SP;
1476- if (SVECalleeSavedSize && BaseForSVEDealloc == AArch64::FP) {
1477- Register CalleeSaveBase = AArch64::FP;
1478- if (int64_t CalleeSaveBaseOffset =
1479- AFI->getCalleeSaveBaseToFrameRecordOffset ()) {
1480- // If we have have an non-zero offset to the non-SVE CS base we need to
1481- // compute the base address by subtracting the offest in a temporary
1482- // register first (to avoid briefly deallocating the SVE CS).
1483- CalleeSaveBase =
1484- MF.getRegInfo ().createVirtualRegister (&AArch64::GPR64RegClass);
1485- emitFrameOffset (MBB, RestoreBegin, DL, CalleeSaveBase, AArch64::FP,
1486- StackOffset::getFixed (-CalleeSaveBaseOffset), TII,
1487- MachineInstr::FrameDestroy);
1488- }
1489- // The code below will deallocate the stack space space by moving the
1490- // SP to the start of the SVE callee-save area.
1491- emitFrameOffset (MBB, RestoreBegin, DL, AArch64::SP, CalleeSaveBase,
1492- StackOffset::getScalable (-SVECalleeSavedSize), TII,
1493- MachineInstr::FrameDestroy);
1494- } else if (BaseForSVEDealloc == AArch64::SP) {
1495- if (SVECalleeSavedSize) {
1496- // Deallocate the non-SVE locals first before we can deallocate (and
1497- // restore callee saves) from the SVE area.
1498- emitFrameOffset (
1499- MBB, RestoreBegin, DL, AArch64::SP, AArch64::SP,
1500- StackOffset::getFixed (NumBytes), TII, MachineInstr::FrameDestroy,
1501- false , NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP,
1502- SVEStackSize + StackOffset::getFixed (NumBytes + PrologueSaveSize));
1503- NumBytes = 0 ;
1431+ // Deallocate the SVE area.
1432+ if (FPAfterSVECalleeSaves) {
1433+ // If the callee-save area is before FP, restoring the FP implicitly
1434+ // deallocates non-callee-save SVE allocations. Otherwise, deallocate
1435+ // them explicitly.
1436+ if (!AFI->isStackRealigned () && !MFI.hasVarSizedObjects ()) {
1437+ emitFrameOffset (MBB, FirstGPRRestoreI, DL, AArch64::SP, AArch64::SP,
1438+ DeallocateBefore, TII, MachineInstr::FrameDestroy,
1439+ false , NeedsWinCFI, &HasWinCFI);
15041440 }
15051441
1442+ // Deallocate callee-save non-SVE registers.
15061443 emitFrameOffset (MBB, RestoreBegin, DL, AArch64::SP, AArch64::SP,
1507- DeallocateBefore, TII, MachineInstr::FrameDestroy, false ,
1508- NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP,
1509- SVEStackSize +
1510- StackOffset::getFixed (NumBytes + PrologueSaveSize));
1444+ StackOffset::getFixed (AFI->getCalleeSavedStackSize ()),
1445+ TII, MachineInstr::FrameDestroy, false , NeedsWinCFI,
1446+ &HasWinCFI);
1447+
1448+ // Deallocate fixed objects.
1449+ emitFrameOffset (MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
1450+ StackOffset::getFixed (FixedObject), TII,
1451+ MachineInstr::FrameDestroy, false , NeedsWinCFI,
1452+ &HasWinCFI);
15111453
1454+ // Deallocate callee-save SVE registers.
15121455 emitFrameOffset (MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
15131456 DeallocateAfter, TII, MachineInstr::FrameDestroy, false ,
1514- NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP,
1515- DeallocateAfter +
1516- StackOffset::getFixed (NumBytes + PrologueSaveSize));
1457+ NeedsWinCFI, &HasWinCFI);
1458+ } else if (SVEStackSize) {
1459+ int64_t SVECalleeSavedSize = AFI->getSVECalleeSavedStackSize ();
1460+ // If we have stack realignment or variable-sized objects we must use the
1461+ // FP to restore SVE callee saves (as there is an unknown amount of
1462+ // data/padding between the SP and SVE CS area).
1463+ Register BaseForSVEDealloc =
1464+ (AFI->isStackRealigned () || MFI.hasVarSizedObjects ()) ? AArch64::FP
1465+ : AArch64::SP;
1466+ if (SVECalleeSavedSize && BaseForSVEDealloc == AArch64::FP) {
1467+ Register CalleeSaveBase = AArch64::FP;
1468+ if (int64_t CalleeSaveBaseOffset =
1469+ AFI->getCalleeSaveBaseToFrameRecordOffset ()) {
1470+ // If we have have an non-zero offset to the non-SVE CS base we need
1471+ // to compute the base address by subtracting the offest in a
1472+ // temporary register first (to avoid briefly deallocating the SVE
1473+ // CS).
1474+ CalleeSaveBase = MBB.getParent ()->getRegInfo ().createVirtualRegister (
1475+ &AArch64::GPR64RegClass);
1476+ emitFrameOffset (MBB, RestoreBegin, DL, CalleeSaveBase, AArch64::FP,
1477+ StackOffset::getFixed (-CalleeSaveBaseOffset), TII,
1478+ MachineInstr::FrameDestroy);
1479+ }
1480+ // The code below will deallocate the stack space space by moving the
1481+ // SP to the start of the SVE callee-save area.
1482+ emitFrameOffset (MBB, RestoreBegin, DL, AArch64::SP, CalleeSaveBase,
1483+ StackOffset::getScalable (-SVECalleeSavedSize), TII,
1484+ MachineInstr::FrameDestroy);
1485+ } else if (BaseForSVEDealloc == AArch64::SP) {
1486+ if (SVECalleeSavedSize) {
1487+ // Deallocate the non-SVE locals first before we can deallocate (and
1488+ // restore callee saves) from the SVE area.
1489+ emitFrameOffset (MBB, RestoreBegin, DL, AArch64::SP, AArch64::SP,
1490+ StackOffset::getFixed (NumBytes), TII,
1491+ MachineInstr::FrameDestroy, false , NeedsWinCFI,
1492+ &HasWinCFI, EmitCFI && !HasFP,
1493+ SVEStackSize + StackOffset::getFixed (
1494+ NumBytes + PrologueSaveSize));
1495+ NumBytes = 0 ;
1496+ }
1497+
1498+ emitFrameOffset (MBB, RestoreBegin, DL, AArch64::SP, AArch64::SP,
1499+ DeallocateBefore, TII, MachineInstr::FrameDestroy,
1500+ false , NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP,
1501+ SVEStackSize +
1502+ StackOffset::getFixed (NumBytes + PrologueSaveSize));
1503+
1504+ emitFrameOffset (MBB, RestoreEnd, DL, AArch64::SP, AArch64::SP,
1505+ DeallocateAfter, TII, MachineInstr::FrameDestroy, false ,
1506+ NeedsWinCFI, &HasWinCFI, EmitCFI && !HasFP,
1507+ DeallocateAfter +
1508+ StackOffset::getFixed (NumBytes + PrologueSaveSize));
1509+ }
1510+
1511+ if (EmitCFI)
1512+ emitCalleeSavedSVERestores (RestoreEnd);
15171513 }
1518- if (EmitCFI)
1519- emitCalleeSavedSVERestores (RestoreEnd );
1514+ } else if (AFI-> hasSplitSVEObjects () && SVEStackSize) {
1515+ reportFatalInternalError ( " not implemented yet " );
15201516 }
15211517
15221518 if (!HasFP) {
0 commit comments