@@ -330,13 +330,36 @@ static int64_t getArgumentStackToRestore(MachineFunction &MF,
330
330
331
331
static bool produceCompactUnwindFrame (MachineFunction &MF);
332
332
static 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);
336
333
static Register findScratchNonCalleeSaveRegister (MachineBasicBlock *MBB,
337
334
bool HasCall = false );
338
335
static 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
+ }
340
363
341
364
// Conservatively, returns true if the function is likely to have SVE vectors
342
365
// on the stack. This function is safe to be called before callee-saves or
@@ -496,38 +519,6 @@ static unsigned getFixedObjectSize(const MachineFunction &MF,
496
519
}
497
520
}
498
521
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
-
531
522
bool AArch64FrameLowering::canUseRedZone (const MachineFunction &MF) const {
532
523
if (!EnableRedZone)
533
524
return false ;
@@ -553,7 +544,7 @@ bool AArch64FrameLowering::canUseRedZone(const MachineFunction &MF) const {
553
544
!Subtarget.hasSVE ();
554
545
555
546
return !(MFI.hasCalls () || hasFP (MF) || NumBytes > RedZoneSize ||
556
- hasSVEStackSize (MF ) || LowerQRegCopyThroughMem);
547
+ AFI-> hasSVEStackSize () || LowerQRegCopyThroughMem);
557
548
}
558
549
559
550
// / hasFPImpl - Return true if the specified function should have a dedicated
@@ -1253,7 +1244,7 @@ bool AArch64FrameLowering::shouldCombineCSRLocalStackBump(
1253
1244
1254
1245
// When there is an SVE area on the stack, always allocate the
1255
1246
// callee-saves and spills/locals separately.
1256
- if (hasSVEStackSize (MF ))
1247
+ if (AFI-> hasSVEStackSize ())
1257
1248
return false ;
1258
1249
1259
1250
return true ;
@@ -1697,8 +1688,8 @@ static bool isTargetWindows(const MachineFunction &MF) {
1697
1688
return MF.getSubtarget <AArch64Subtarget>().isTargetWindows ();
1698
1689
}
1699
1690
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) {
1702
1693
switch (I->getOpcode ()) {
1703
1694
default :
1704
1695
return false ;
@@ -1718,8 +1709,8 @@ static bool IsZPRCalleeSave(MachineBasicBlock::iterator I) {
1718
1709
}
1719
1710
}
1720
1711
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) {
1723
1714
switch (I->getOpcode ()) {
1724
1715
default :
1725
1716
return false ;
@@ -1730,8 +1721,9 @@ static bool IsPPRCalleeSave(MachineBasicBlock::iterator I) {
1730
1721
}
1731
1722
}
1732
1723
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);
1735
1727
}
1736
1728
1737
1729
static void emitShadowCallStackPrologue (const TargetInstrInfo &TII,
@@ -1975,7 +1967,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
1975
1967
IsFunclet ? getWinEHFuncletFrameSize (MF) : MFI.getStackSize ();
1976
1968
if (!AFI->hasStackFrame () && !windowsRequiresStackProbe (MF, NumBytes)) {
1977
1969
assert (!HasFP && " unexpected function without stack frame but with FP" );
1978
- assert (!hasSVEStackSize (MF ) &&
1970
+ assert (!AFI-> hasSVEStackSize () &&
1979
1971
" unexpected function without stack frame but with SVE objects" );
1980
1972
// All of the stack allocation is for locals.
1981
1973
AFI->setLocalStackSize (NumBytes);
@@ -2049,14 +2041,14 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
2049
2041
NumBytes -= FixedObject;
2050
2042
2051
2043
// Now allocate space for the GPR callee saves.
2052
- while (MBBI != End && IsSVECalleeSave (MBBI))
2044
+ while (MBBI != End && isPartOfSVECalleeSaves (MBBI))
2053
2045
++MBBI;
2054
2046
MBBI = convertCalleeSaveRestoreToSPPrePostIncDec (
2055
2047
MBB, MBBI, DL, TII, -AFI->getCalleeSavedStackSize (), NeedsWinCFI,
2056
2048
&HasWinCFI, EmitAsyncCFI);
2057
2049
NumBytes -= AFI->getCalleeSavedStackSize ();
2058
2050
} else if (CombineSPBump) {
2059
- assert (!hasSVEStackSize (MF ) && " Cannot combine SP bump with SVE" );
2051
+ assert (!AFI-> hasSVEStackSize () && " Cannot combine SP bump with SVE" );
2060
2052
emitFrameOffset (MBB, MBBI, DL, AArch64::SP, AArch64::SP,
2061
2053
StackOffset::getFixed (-NumBytes), TII,
2062
2054
MachineInstr::FrameSetup, false , NeedsWinCFI, &HasWinCFI,
@@ -2077,7 +2069,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
2077
2069
// and pre-inc if we decided to combine the callee-save and local stack
2078
2070
// pointer bump above.
2079
2071
while (MBBI != End && MBBI->getFlag (MachineInstr::FrameSetup) &&
2080
- !IsSVECalleeSave (MBBI)) {
2072
+ !isPartOfSVECalleeSaves (MBBI)) {
2081
2073
if (CombineSPBump &&
2082
2074
// Only fix-up frame-setup load/store instructions.
2083
2075
(!requiresSaveVG (MF) || !isVGInstruction (MBBI)))
@@ -2341,8 +2333,9 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
2341
2333
<< PPRCalleeSavesSize.getScalable () << " \n " );
2342
2334
2343
2335
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 ())
2346
2339
++MBBI;
2347
2340
PPRCalleeSavesEnd = MBBI;
2348
2341
}
@@ -2351,8 +2344,9 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
2351
2344
LLVM_DEBUG (dbgs () << " ZPRCalleeSavedStackSize = "
2352
2345
<< ZPRCalleeSavesSize.getScalable () << " \n " );
2353
2346
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 ())
2356
2350
++MBBI;
2357
2351
ZPRCalleeSavesEnd = MBBI;
2358
2352
}
@@ -2586,7 +2580,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
2586
2580
while (LastPopI != Begin) {
2587
2581
--LastPopI;
2588
2582
if (!LastPopI->getFlag (MachineInstr::FrameDestroy) ||
2589
- (!FPAfterSVECalleeSaves && IsSVECalleeSave (LastPopI))) {
2583
+ (!FPAfterSVECalleeSaves && isPartOfSVECalleeSaves (LastPopI))) {
2590
2584
++LastPopI;
2591
2585
break ;
2592
2586
} else if (CombineSPBump)
@@ -2671,11 +2665,12 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
2671
2665
2672
2666
RestoreBegin = std::prev (RestoreEnd);
2673
2667
while (RestoreBegin != MBB.begin () &&
2674
- IsSVECalleeSave (std::prev (RestoreBegin)))
2668
+ isPartOfSVECalleeSaves (std::prev (RestoreBegin)))
2675
2669
--RestoreBegin;
2676
2670
2677
- assert (IsSVECalleeSave (RestoreBegin) &&
2678
- IsSVECalleeSave (std::prev (RestoreEnd)) && " Unexpected instruction" );
2671
+ assert (isPartOfSVECalleeSaves (RestoreBegin) &&
2672
+ isPartOfSVECalleeSaves (std::prev (RestoreEnd)) &&
2673
+ " Unexpected instruction" );
2679
2674
2680
2675
StackOffset CalleeSavedSizeAsOffset =
2681
2676
StackOffset::getScalable (SVECalleeSavedSize);
@@ -4384,14 +4379,14 @@ determineSVEStackObjectOffsets(MachineFunction &MF, bool AssignOffsets,
4384
4379
bool SplitSVEObjects = false ) {
4385
4380
MachineFrameInfo &MFI = MF.getFrameInfo ();
4386
4381
4387
- int64_t ZPRStack = 0 ;
4388
- int64_t PPRStack = 0 ;
4382
+ SVEStackSizes SVEStack{};
4389
4383
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 ;
4395
4390
4396
4391
#ifndef NDEBUG
4397
4392
// First process all fixed stack objects.
@@ -4473,14 +4468,7 @@ determineSVEStackObjectOffsets(MachineFunction &MF, bool AssignOffsets,
4473
4468
4474
4469
PPROffset = alignTo (PPROffset, Align (16U ));
4475
4470
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;
4484
4472
}
4485
4473
4486
4474
SVEStackSizes
@@ -4805,8 +4793,7 @@ void AArch64FrameLowering::processFunctionBeforeFrameFinalized(
4805
4793
" Upwards growing stack unsupported" );
4806
4794
4807
4795
auto [ZPRStackSize, PPRStackSize] = assignSVEStackObjectOffsets (MF);
4808
- AFI->setStackSizeZPR (ZPRStackSize);
4809
- AFI->setStackSizePPR (PPRStackSize);
4796
+ AFI->setStackSizeSVE (ZPRStackSize, PPRStackSize);
4810
4797
4811
4798
// If this function isn't doing Win64-style C++ EH, we don't need to do
4812
4799
// anything.
@@ -5355,7 +5342,8 @@ StackOffset AArch64FrameLowering::getFrameIndexReferencePreferSP(
5355
5342
}
5356
5343
5357
5344
// 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 () ||
5359
5347
MF.getSubtarget ().getRegisterInfo ()->hasStackRealignment (MF))
5360
5348
return getFrameIndexReference (MF, FI, FrameReg);
5361
5349
0 commit comments