@@ -216,6 +216,24 @@ AArch64FrameLowering::getStackIDForScalableVectors() const {
216216 return TargetStackID::SVEVector;
217217}
218218
219+ // / Returns the size of the fixed object area (allocated next to sp on entry)
220+ // / On Win64 this may include a var args area and an UnwindHelp object for EH.
221+ static unsigned getFixedObjectSize (const MachineFunction &MF,
222+ const AArch64FunctionInfo *AFI, bool IsWin64,
223+ bool IsFunclet) {
224+ if (!IsWin64 || IsFunclet) {
225+ // Only Win64 uses fixed objects, and then only for the function (not
226+ // funclets)
227+ return 0 ;
228+ } else {
229+ // Var args are stored here in the primary function.
230+ const unsigned VarArgsArea = AFI->getVarArgsGPRSize ();
231+ // To support EH funclets we allocate an UnwindHelp object
232+ const unsigned UnwindHelpObject = (MF.hasEHFunclets () ? 8 : 0 );
233+ return alignTo (VarArgsArea + UnwindHelpObject, 16 );
234+ }
235+ }
236+
219237// / Returns the size of the entire SVE stackframe (calleesaves + spills).
220238static StackOffset getSVEStackSize (const MachineFunction &MF) {
221239 const AArch64FunctionInfo *AFI = MF.getInfo <AArch64FunctionInfo>();
@@ -995,10 +1013,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
9951013
9961014 bool IsWin64 =
9971015 Subtarget.isCallingConvWin64 (MF.getFunction ().getCallingConv ());
998- // Var args are accounted for in the containing function, so don't
999- // include them for funclets.
1000- unsigned FixedObject = (IsWin64 && !IsFunclet) ?
1001- alignTo (AFI->getVarArgsGPRSize (), 16 ) : 0 ;
1016+ unsigned FixedObject = getFixedObjectSize (MF, AFI, IsWin64, IsFunclet);
10021017
10031018 auto PrologueSaveSize = AFI->getCalleeSavedStackSize () + FixedObject;
10041019 // All of the remaining stack allocations are for locals.
@@ -1477,10 +1492,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
14771492
14781493 bool IsWin64 =
14791494 Subtarget.isCallingConvWin64 (MF.getFunction ().getCallingConv ());
1480- // Var args are accounted for in the containing function, so don't
1481- // include them for funclets.
1482- unsigned FixedObject =
1483- (IsWin64 && !IsFunclet) ? alignTo (AFI->getVarArgsGPRSize (), 16 ) : 0 ;
1495+ unsigned FixedObject = getFixedObjectSize (MF, AFI, IsWin64, IsFunclet);
14841496
14851497 uint64_t AfterCSRPopSize = ArgumentPopSize;
14861498 auto PrologueSaveSize = AFI->getCalleeSavedStackSize () + FixedObject;
@@ -1706,7 +1718,9 @@ static StackOffset getFPOffset(const MachineFunction &MF, int64_t ObjectOffset)
17061718 const auto &Subtarget = MF.getSubtarget <AArch64Subtarget>();
17071719 bool IsWin64 =
17081720 Subtarget.isCallingConvWin64 (MF.getFunction ().getCallingConv ());
1709- unsigned FixedObject = IsWin64 ? alignTo (AFI->getVarArgsGPRSize (), 16 ) : 0 ;
1721+
1722+ unsigned FixedObject =
1723+ getFixedObjectSize (MF, AFI, IsWin64, /* IsFunclet=*/ false );
17101724 unsigned FPAdjust = isTargetDarwin (MF)
17111725 ? 16 : AFI->getCalleeSavedStackSize (MF.getFrameInfo ());
17121726 return {ObjectOffset + FixedObject + FPAdjust, MVT::i8 };
@@ -2659,9 +2673,14 @@ void AArch64FrameLowering::processFunctionBeforeFrameFinalized(
26592673 ++MBBI;
26602674
26612675 // Create an UnwindHelp object.
2662- int UnwindHelpFI =
2663- MFI.CreateStackObject (/* size*/ 8 , /* alignment*/ 16 , false );
2676+ // The UnwindHelp object is allocated at the start of the fixed object area
2677+ int64_t FixedObject =
2678+ getFixedObjectSize (MF, AFI, /* IsWin64*/ true , /* IsFunclet*/ false );
2679+ int UnwindHelpFI = MFI.CreateFixedObject (/* Size*/ 8 ,
2680+ /* SPOffset*/ -FixedObject,
2681+ /* IsImmutable=*/ false );
26642682 EHInfo.UnwindHelpFrameIdx = UnwindHelpFI;
2683+
26652684 // We need to store -2 into the UnwindHelp object at the start of the
26662685 // function.
26672686 DebugLoc DL;
@@ -3073,10 +3092,14 @@ int AArch64FrameLowering::getFrameIndexReferencePreferSP(
30733092 const MachineFunction &MF, int FI, unsigned &FrameReg,
30743093 bool IgnoreSPUpdates) const {
30753094 const MachineFrameInfo &MFI = MF.getFrameInfo ();
3076- LLVM_DEBUG (dbgs () << " Offset from the SP for " << FI << " is "
3077- << MFI.getObjectOffset (FI) << " \n " );
3078- FrameReg = AArch64::SP;
3079- return MFI.getObjectOffset (FI);
3095+ if (IgnoreSPUpdates) {
3096+ LLVM_DEBUG (dbgs () << " Offset from the SP for " << FI << " is "
3097+ << MFI.getObjectOffset (FI) << " \n " );
3098+ FrameReg = AArch64::SP;
3099+ return MFI.getObjectOffset (FI);
3100+ }
3101+
3102+ return getFrameIndexReference (MF, FI, FrameReg);
30803103}
30813104
30823105// / The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve
0 commit comments