@@ -330,13 +330,36 @@ static int64_t getArgumentStackToRestore(MachineFunction &MF,
330330
331331static bool produceCompactUnwindFrame (MachineFunction &MF);
332332static bool needsWinCFI (const MachineFunction &MF);
333- static StackOffset getZPRStackSize (const MachineFunction &MF);
334- static StackOffset getPPRStackSize (const MachineFunction &MF);
335- static StackOffset getSVEStackSize (const MachineFunction &MF);
336333static Register findScratchNonCalleeSaveRegister (MachineBasicBlock *MBB,
337334 bool HasCall = false );
338335static bool requiresSaveVG (const MachineFunction &MF);
339- static bool hasSVEStackSize (const MachineFunction &MF);
336+
337+ static unsigned getStackHazardSize (const MachineFunction &MF) {
338+ return MF.getSubtarget <AArch64Subtarget>().getStreamingHazardSize ();
339+ }
340+
341+ // / Returns the size of the entire ZPR stackframe (calleesaves + spills).
342+ static StackOffset getZPRStackSize (const MachineFunction &MF) {
343+ const AArch64FunctionInfo *AFI = MF.getInfo <AArch64FunctionInfo>();
344+ return StackOffset::getScalable (AFI->getStackSizeZPR ());
345+ }
346+
347+ // / Returns the size of the entire PPR stackframe (calleesaves + spills).
348+ static StackOffset getPPRStackSize (const MachineFunction &MF) {
349+ const AArch64FunctionInfo *AFI = MF.getInfo <AArch64FunctionInfo>();
350+ return StackOffset::getScalable (AFI->getStackSizePPR ());
351+ }
352+
353+ // / Returns the size of the entire SVE stackframe (PPRs + ZPRs).
354+ static StackOffset getSVEStackSize (const MachineFunction &MF) {
355+ return getZPRStackSize (MF) + getPPRStackSize (MF);
356+ }
357+
358+ // / Returns true if PPRs are spilled as ZPRs.
359+ static bool arePPRsSpilledAsZPR (const MachineFunction &MF) {
360+ return MF.getSubtarget ().getRegisterInfo ()->getSpillSize (
361+ AArch64::PPRRegClass) == 16 ;
362+ }
340363
341364// Conservatively, returns true if the function is likely to have SVE vectors
342365// on the stack. This function is safe to be called before callee-saves or
@@ -496,38 +519,6 @@ static unsigned getFixedObjectSize(const MachineFunction &MF,
496519 }
497520}
498521
499- static unsigned getStackHazardSize (const MachineFunction &MF) {
500- return MF.getSubtarget <AArch64Subtarget>().getStreamingHazardSize ();
501- }
502-
503- // / Returns the size of the entire ZPR stackframe (calleesaves + spills).
504- static StackOffset getZPRStackSize (const MachineFunction &MF) {
505- const AArch64FunctionInfo *AFI = MF.getInfo <AArch64FunctionInfo>();
506- return StackOffset::getScalable (AFI->getStackSizeZPR ());
507- }
508-
509- // / Returns the size of the entire PPR stackframe (calleesaves + spills).
510- static StackOffset getPPRStackSize (const MachineFunction &MF) {
511- const AArch64FunctionInfo *AFI = MF.getInfo <AArch64FunctionInfo>();
512- return StackOffset::getScalable (AFI->getStackSizePPR ());
513- }
514-
515- // / Returns the size of the entire SVE stackframe (PPRs + ZPRs).
516- static StackOffset getSVEStackSize (const MachineFunction &MF) {
517- return getZPRStackSize (MF) + getPPRStackSize (MF);
518- }
519-
520- static bool hasSVEStackSize (const MachineFunction &MF) {
521- const AArch64FunctionInfo *AFI = MF.getInfo <AArch64FunctionInfo>();
522- return AFI->getStackSizeZPR () > 0 || AFI->getStackSizePPR () > 0 ;
523- }
524-
525- // / Returns true if PPRs are spilled as ZPRs.
526- static bool arePPRsSpilledAsZPR (const MachineFunction &MF) {
527- return MF.getSubtarget ().getRegisterInfo ()->getSpillSize (
528- AArch64::PPRRegClass) == 16 ;
529- }
530-
531522bool AArch64FrameLowering::canUseRedZone (const MachineFunction &MF) const {
532523 if (!EnableRedZone)
533524 return false ;
@@ -553,7 +544,7 @@ bool AArch64FrameLowering::canUseRedZone(const MachineFunction &MF) const {
553544 !Subtarget.hasSVE ();
554545
555546 return !(MFI.hasCalls () || hasFP (MF) || NumBytes > RedZoneSize ||
556- hasSVEStackSize (MF ) || LowerQRegCopyThroughMem);
547+ AFI-> hasSVEStackSize () || LowerQRegCopyThroughMem);
557548}
558549
559550// / hasFPImpl - Return true if the specified function should have a dedicated
@@ -1253,7 +1244,7 @@ bool AArch64FrameLowering::shouldCombineCSRLocalStackBump(
12531244
12541245 // When there is an SVE area on the stack, always allocate the
12551246 // callee-saves and spills/locals separately.
1256- if (hasSVEStackSize (MF ))
1247+ if (AFI-> hasSVEStackSize ())
12571248 return false ;
12581249
12591250 return true ;
@@ -1697,8 +1688,8 @@ static bool isTargetWindows(const MachineFunction &MF) {
16971688 return MF.getSubtarget <AArch64Subtarget>().isTargetWindows ();
16981689}
16991690
1700- // Convenience function to determine whether I is an SVE callee save .
1701- static bool IsZPRCalleeSave (MachineBasicBlock::iterator I) {
1691+ // Convenience function to determine whether I is part of the ZPR callee saves .
1692+ static bool isPartOfZPRCalleeSaves (MachineBasicBlock::iterator I) {
17021693 switch (I->getOpcode ()) {
17031694 default :
17041695 return false ;
@@ -1718,8 +1709,8 @@ static bool IsZPRCalleeSave(MachineBasicBlock::iterator I) {
17181709 }
17191710}
17201711
1721- // Convenience function to determine whether I is an SVE predicate callee save .
1722- static bool IsPPRCalleeSave (MachineBasicBlock::iterator I) {
1712+ // Convenience function to determine whether I is part of the PPR callee saves .
1713+ static bool isPartOfPPRCalleeSaves (MachineBasicBlock::iterator I) {
17231714 switch (I->getOpcode ()) {
17241715 default :
17251716 return false ;
@@ -1730,8 +1721,9 @@ static bool IsPPRCalleeSave(MachineBasicBlock::iterator I) {
17301721 }
17311722}
17321723
1733- static bool IsSVECalleeSave (MachineBasicBlock::iterator I) {
1734- return IsZPRCalleeSave (I) || IsPPRCalleeSave (I);
1724+ // Convenience function to determine whether I is part of the SVE callee saves.
1725+ static bool isPartOfSVECalleeSaves (MachineBasicBlock::iterator I) {
1726+ return isPartOfZPRCalleeSaves (I) || isPartOfPPRCalleeSaves (I);
17351727}
17361728
17371729static void emitShadowCallStackPrologue (const TargetInstrInfo &TII,
@@ -1975,7 +1967,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
19751967 IsFunclet ? getWinEHFuncletFrameSize (MF) : MFI.getStackSize ();
19761968 if (!AFI->hasStackFrame () && !windowsRequiresStackProbe (MF, NumBytes)) {
19771969 assert (!HasFP && " unexpected function without stack frame but with FP" );
1978- assert (!hasSVEStackSize (MF ) &&
1970+ assert (!AFI-> hasSVEStackSize () &&
19791971 " unexpected function without stack frame but with SVE objects" );
19801972 // All of the stack allocation is for locals.
19811973 AFI->setLocalStackSize (NumBytes);
@@ -2049,14 +2041,14 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
20492041 NumBytes -= FixedObject;
20502042
20512043 // Now allocate space for the GPR callee saves.
2052- while (MBBI != End && IsSVECalleeSave (MBBI))
2044+ while (MBBI != End && isPartOfSVECalleeSaves (MBBI))
20532045 ++MBBI;
20542046 MBBI = convertCalleeSaveRestoreToSPPrePostIncDec (
20552047 MBB, MBBI, DL, TII, -AFI->getCalleeSavedStackSize (), NeedsWinCFI,
20562048 &HasWinCFI, EmitAsyncCFI);
20572049 NumBytes -= AFI->getCalleeSavedStackSize ();
20582050 } else if (CombineSPBump) {
2059- assert (!hasSVEStackSize (MF ) && " Cannot combine SP bump with SVE" );
2051+ assert (!AFI-> hasSVEStackSize () && " Cannot combine SP bump with SVE" );
20602052 emitFrameOffset (MBB, MBBI, DL, AArch64::SP, AArch64::SP,
20612053 StackOffset::getFixed (-NumBytes), TII,
20622054 MachineInstr::FrameSetup, false , NeedsWinCFI, &HasWinCFI,
@@ -2077,7 +2069,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
20772069 // and pre-inc if we decided to combine the callee-save and local stack
20782070 // pointer bump above.
20792071 while (MBBI != End && MBBI->getFlag (MachineInstr::FrameSetup) &&
2080- !IsSVECalleeSave (MBBI)) {
2072+ !isPartOfSVECalleeSaves (MBBI)) {
20812073 if (CombineSPBump &&
20822074 // Only fix-up frame-setup load/store instructions.
20832075 (!requiresSaveVG (MF) || !isVGInstruction (MBBI)))
@@ -2341,8 +2333,9 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
23412333 << PPRCalleeSavesSize.getScalable () << " \n " );
23422334
23432335 PPRCalleeSavesBegin = MBBI;
2344- assert (IsPPRCalleeSave (PPRCalleeSavesBegin) && " Unexpected instruction" );
2345- while (IsPPRCalleeSave (MBBI) && MBBI != MBB.getFirstTerminator ())
2336+ assert (isPartOfPPRCalleeSaves (PPRCalleeSavesBegin) &&
2337+ " Unexpected instruction" );
2338+ while (isPartOfPPRCalleeSaves (MBBI) && MBBI != MBB.getFirstTerminator ())
23462339 ++MBBI;
23472340 PPRCalleeSavesEnd = MBBI;
23482341 }
@@ -2351,8 +2344,9 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
23512344 LLVM_DEBUG (dbgs () << " ZPRCalleeSavedStackSize = "
23522345 << ZPRCalleeSavesSize.getScalable () << " \n " );
23532346 ZPRCalleeSavesBegin = MBBI;
2354- assert (IsZPRCalleeSave (ZPRCalleeSavesBegin) && " Unexpected instruction" );
2355- while (IsZPRCalleeSave (MBBI) && MBBI != MBB.getFirstTerminator ())
2347+ assert (isPartOfZPRCalleeSaves (ZPRCalleeSavesBegin) &&
2348+ " Unexpected instruction" );
2349+ while (isPartOfZPRCalleeSaves (MBBI) && MBBI != MBB.getFirstTerminator ())
23562350 ++MBBI;
23572351 ZPRCalleeSavesEnd = MBBI;
23582352 }
@@ -2586,7 +2580,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
25862580 while (LastPopI != Begin) {
25872581 --LastPopI;
25882582 if (!LastPopI->getFlag (MachineInstr::FrameDestroy) ||
2589- (!FPAfterSVECalleeSaves && IsSVECalleeSave (LastPopI))) {
2583+ (!FPAfterSVECalleeSaves && isPartOfSVECalleeSaves (LastPopI))) {
25902584 ++LastPopI;
25912585 break ;
25922586 } else if (CombineSPBump)
@@ -2671,11 +2665,12 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
26712665
26722666 RestoreBegin = std::prev (RestoreEnd);
26732667 while (RestoreBegin != MBB.begin () &&
2674- IsSVECalleeSave (std::prev (RestoreBegin)))
2668+ isPartOfSVECalleeSaves (std::prev (RestoreBegin)))
26752669 --RestoreBegin;
26762670
2677- assert (IsSVECalleeSave (RestoreBegin) &&
2678- IsSVECalleeSave (std::prev (RestoreEnd)) && " Unexpected instruction" );
2671+ assert (isPartOfSVECalleeSaves (RestoreBegin) &&
2672+ isPartOfSVECalleeSaves (std::prev (RestoreEnd)) &&
2673+ " Unexpected instruction" );
26792674
26802675 StackOffset CalleeSavedSizeAsOffset =
26812676 StackOffset::getScalable (SVECalleeSavedSize);
@@ -4384,14 +4379,14 @@ determineSVEStackObjectOffsets(MachineFunction &MF, bool AssignOffsets,
43844379 bool SplitSVEObjects = false ) {
43854380 MachineFrameInfo &MFI = MF.getFrameInfo ();
43864381
4387- int64_t ZPRStack = 0 ;
4388- int64_t PPRStack = 0 ;
4382+ SVEStackSizes SVEStack{};
43894383
4390- auto [ZPROffset, PPROffset] = [&] {
4391- if (SplitSVEObjects)
4392- return std::tie (ZPRStack, PPRStack);
4393- return std::tie (ZPRStack, ZPRStack);
4394- }();
4384+ // With SplitSVEObjects we maintain separate stack offsets for predicates
4385+ // (PPRs) and SVE vectors (ZPRs). When SplitSVEObjects is disabled predicates
4386+ // are included in the SVE vector area.
4387+ int64_t &ZPROffset = SVEStack.ZPRStackSize ;
4388+ int64_t &PPROffset =
4389+ SplitSVEObjects ? SVEStack.PPRStackSize : SVEStack.ZPRStackSize ;
43954390
43964391#ifndef NDEBUG
43974392 // First process all fixed stack objects.
@@ -4473,14 +4468,7 @@ determineSVEStackObjectOffsets(MachineFunction &MF, bool AssignOffsets,
44734468
44744469 PPROffset = alignTo (PPROffset, Align (16U ));
44754470 ZPROffset = alignTo (ZPROffset, Align (16U ));
4476-
4477- if (&ZPROffset != &PPROffset) {
4478- // SplitSVEObjects (PPRs and ZPRs allocated to separate areas).
4479- return SVEStackSizes{ZPROffset, PPROffset};
4480- }
4481- // When SplitSVEObjects is disabled just attribute all the stack to ZPRs.
4482- // Determining the split is not necessary.
4483- return SVEStackSizes{ZPROffset, 0 };
4471+ return SVEStack;
44844472}
44854473
44864474SVEStackSizes
@@ -4805,8 +4793,7 @@ void AArch64FrameLowering::processFunctionBeforeFrameFinalized(
48054793 " Upwards growing stack unsupported" );
48064794
48074795 auto [ZPRStackSize, PPRStackSize] = assignSVEStackObjectOffsets (MF);
4808- AFI->setStackSizeZPR (ZPRStackSize);
4809- AFI->setStackSizePPR (PPRStackSize);
4796+ AFI->setStackSizeSVE (ZPRStackSize, PPRStackSize);
48104797
48114798 // If this function isn't doing Win64-style C++ EH, we don't need to do
48124799 // anything.
@@ -5355,7 +5342,8 @@ StackOffset AArch64FrameLowering::getFrameIndexReferencePreferSP(
53555342 }
53565343
53575344 // Go to common code if we cannot provide sp + offset.
5358- if (MFI.hasVarSizedObjects () || hasSVEStackSize (MF) ||
5345+ if (MFI.hasVarSizedObjects () ||
5346+ MF.getInfo <AArch64FunctionInfo>()->hasSVEStackSize () ||
53595347 MF.getSubtarget ().getRegisterInfo ()->hasStackRealignment (MF))
53605348 return getFrameIndexReference (MF, FI, FrameReg);
53615349
0 commit comments