@@ -211,6 +211,24 @@ AArch64FrameLowering::getStackIDForScalableVectors() const {
211211 return TargetStackID::SVEVector;
212212}
213213
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+
214232// / Returns the size of the entire SVE stackframe (calleesaves + spills).
215233static StackOffset getSVEStackSize (const MachineFunction &MF) {
216234 const AArch64FunctionInfo *AFI = MF.getInfo <AArch64FunctionInfo>();
@@ -959,10 +977,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
959977
960978 bool IsWin64 =
961979 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);
966981
967982 auto PrologueSaveSize = AFI->getCalleeSavedStackSize () + FixedObject;
968983 // All of the remaining stack allocations are for locals.
@@ -1442,10 +1457,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
14421457
14431458 bool IsWin64 =
14441459 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);
14491461
14501462 uint64_t AfterCSRPopSize = ArgumentPopSize;
14511463 auto PrologueSaveSize = AFI->getCalleeSavedStackSize () + FixedObject;
@@ -1671,7 +1683,9 @@ static StackOffset getFPOffset(const MachineFunction &MF, int64_t ObjectOffset)
16711683 const auto &Subtarget = MF.getSubtarget <AArch64Subtarget>();
16721684 bool IsWin64 =
16731685 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 );
16751689 unsigned FPAdjust = isTargetDarwin (MF)
16761690 ? 16 : AFI->getCalleeSavedStackSize (MF.getFrameInfo ());
16771691 return {ObjectOffset + FixedObject + FPAdjust, MVT::i8 };
@@ -2624,9 +2638,14 @@ void AArch64FrameLowering::processFunctionBeforeFrameFinalized(
26242638 ++MBBI;
26252639
26262640 // 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 );
26292647 EHInfo.UnwindHelpFrameIdx = UnwindHelpFI;
2648+
26302649 // We need to store -2 into the UnwindHelp object at the start of the
26312650 // function.
26322651 DebugLoc DL;
@@ -2648,10 +2667,14 @@ int AArch64FrameLowering::getFrameIndexReferencePreferSP(
26482667 const MachineFunction &MF, int FI, unsigned &FrameReg,
26492668 bool IgnoreSPUpdates) const {
26502669 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);
26552678}
26562679
26572680// / The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve
0 commit comments