@@ -211,6 +211,24 @@ AArch64FrameLowering::getStackIDForScalableVectors() const {
211
211
return TargetStackID::SVEVector;
212
212
}
213
213
214
+ // / Returns the size of the fixed object area (allocated next to sp on entry)
215
+ // / On Win64 this may include a var args area and an UnwindHelp object for EH.
216
+ static unsigned getFixedObjectSize (const MachineFunction &MF,
217
+ const AArch64FunctionInfo *AFI, bool IsWin64,
218
+ bool IsFunclet) {
219
+ if (!IsWin64 || IsFunclet) {
220
+ // Only Win64 uses fixed objects, and then only for the function (not
221
+ // funclets)
222
+ return 0 ;
223
+ } else {
224
+ // Var args are stored here in the primary function.
225
+ const unsigned VarArgsArea = AFI->getVarArgsGPRSize ();
226
+ // To support EH funclets we allocate an UnwindHelp object
227
+ const unsigned UnwindHelpObject = (MF.hasEHFunclets () ? 8 : 0 );
228
+ return alignTo (VarArgsArea + UnwindHelpObject, 16 );
229
+ }
230
+ }
231
+
214
232
// / Returns the size of the entire SVE stackframe (calleesaves + spills).
215
233
static StackOffset getSVEStackSize (const MachineFunction &MF) {
216
234
const AArch64FunctionInfo *AFI = MF.getInfo <AArch64FunctionInfo>();
@@ -959,10 +977,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
959
977
960
978
bool IsWin64 =
961
979
Subtarget.isCallingConvWin64 (MF.getFunction ().getCallingConv ());
962
- // Var args are accounted for in the containing function, so don't
963
- // include them for funclets.
964
- unsigned FixedObject = (IsWin64 && !IsFunclet) ?
965
- alignTo (AFI->getVarArgsGPRSize (), 16 ) : 0 ;
980
+ unsigned FixedObject = getFixedObjectSize (MF, AFI, IsWin64, IsFunclet);
966
981
967
982
auto PrologueSaveSize = AFI->getCalleeSavedStackSize () + FixedObject;
968
983
// All of the remaining stack allocations are for locals.
@@ -1442,10 +1457,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
1442
1457
1443
1458
bool IsWin64 =
1444
1459
Subtarget.isCallingConvWin64 (MF.getFunction ().getCallingConv ());
1445
- // Var args are accounted for in the containing function, so don't
1446
- // include them for funclets.
1447
- unsigned FixedObject =
1448
- (IsWin64 && !IsFunclet) ? alignTo (AFI->getVarArgsGPRSize (), 16 ) : 0 ;
1460
+ unsigned FixedObject = getFixedObjectSize (MF, AFI, IsWin64, IsFunclet);
1449
1461
1450
1462
uint64_t AfterCSRPopSize = ArgumentPopSize;
1451
1463
auto PrologueSaveSize = AFI->getCalleeSavedStackSize () + FixedObject;
@@ -1671,7 +1683,9 @@ static StackOffset getFPOffset(const MachineFunction &MF, int64_t ObjectOffset)
1671
1683
const auto &Subtarget = MF.getSubtarget <AArch64Subtarget>();
1672
1684
bool IsWin64 =
1673
1685
Subtarget.isCallingConvWin64 (MF.getFunction ().getCallingConv ());
1674
- unsigned FixedObject = IsWin64 ? alignTo (AFI->getVarArgsGPRSize (), 16 ) : 0 ;
1686
+
1687
+ unsigned FixedObject =
1688
+ getFixedObjectSize (MF, AFI, IsWin64, /* IsFunclet=*/ false );
1675
1689
unsigned FPAdjust = isTargetDarwin (MF)
1676
1690
? 16 : AFI->getCalleeSavedStackSize (MF.getFrameInfo ());
1677
1691
return {ObjectOffset + FixedObject + FPAdjust, MVT::i8 };
@@ -2624,9 +2638,14 @@ void AArch64FrameLowering::processFunctionBeforeFrameFinalized(
2624
2638
++MBBI;
2625
2639
2626
2640
// Create an UnwindHelp object.
2627
- int UnwindHelpFI =
2628
- MFI.CreateStackObject (/* size*/ 8 , /* alignment*/ 16 , false );
2641
+ // The UnwindHelp object is allocated at the start of the fixed object area
2642
+ int64_t FixedObject =
2643
+ getFixedObjectSize (MF, AFI, /* IsWin64*/ true , /* IsFunclet*/ false );
2644
+ int UnwindHelpFI = MFI.CreateFixedObject (/* Size*/ 8 ,
2645
+ /* SPOffset*/ -FixedObject,
2646
+ /* IsImmutable=*/ false );
2629
2647
EHInfo.UnwindHelpFrameIdx = UnwindHelpFI;
2648
+
2630
2649
// We need to store -2 into the UnwindHelp object at the start of the
2631
2650
// function.
2632
2651
DebugLoc DL;
@@ -2648,10 +2667,14 @@ int AArch64FrameLowering::getFrameIndexReferencePreferSP(
2648
2667
const MachineFunction &MF, int FI, unsigned &FrameReg,
2649
2668
bool IgnoreSPUpdates) const {
2650
2669
const MachineFrameInfo &MFI = MF.getFrameInfo ();
2651
- LLVM_DEBUG (dbgs () << " Offset from the SP for " << FI << " is "
2652
- << MFI.getObjectOffset (FI) << " \n " );
2653
- FrameReg = AArch64::SP;
2654
- return MFI.getObjectOffset (FI);
2670
+ if (IgnoreSPUpdates) {
2671
+ LLVM_DEBUG (dbgs () << " Offset from the SP for " << FI << " is "
2672
+ << MFI.getObjectOffset (FI) << " \n " );
2673
+ FrameReg = AArch64::SP;
2674
+ return MFI.getObjectOffset (FI);
2675
+ }
2676
+
2677
+ return getFrameIndexReference (MF, FI, FrameReg);
2655
2678
}
2656
2679
2657
2680
// / The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve
0 commit comments