@@ -216,6 +216,24 @@ AArch64FrameLowering::getStackIDForScalableVectors() const {
216
216
return TargetStackID::SVEVector;
217
217
}
218
218
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
+
219
237
// / Returns the size of the entire SVE stackframe (calleesaves + spills).
220
238
static StackOffset getSVEStackSize (const MachineFunction &MF) {
221
239
const AArch64FunctionInfo *AFI = MF.getInfo <AArch64FunctionInfo>();
@@ -995,10 +1013,7 @@ void AArch64FrameLowering::emitPrologue(MachineFunction &MF,
995
1013
996
1014
bool IsWin64 =
997
1015
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);
1002
1017
1003
1018
auto PrologueSaveSize = AFI->getCalleeSavedStackSize () + FixedObject;
1004
1019
// All of the remaining stack allocations are for locals.
@@ -1477,10 +1492,7 @@ void AArch64FrameLowering::emitEpilogue(MachineFunction &MF,
1477
1492
1478
1493
bool IsWin64 =
1479
1494
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);
1484
1496
1485
1497
uint64_t AfterCSRPopSize = ArgumentPopSize;
1486
1498
auto PrologueSaveSize = AFI->getCalleeSavedStackSize () + FixedObject;
@@ -1706,7 +1718,9 @@ static StackOffset getFPOffset(const MachineFunction &MF, int64_t ObjectOffset)
1706
1718
const auto &Subtarget = MF.getSubtarget <AArch64Subtarget>();
1707
1719
bool IsWin64 =
1708
1720
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 );
1710
1724
unsigned FPAdjust = isTargetDarwin (MF)
1711
1725
? 16 : AFI->getCalleeSavedStackSize (MF.getFrameInfo ());
1712
1726
return {ObjectOffset + FixedObject + FPAdjust, MVT::i8};
@@ -2659,9 +2673,14 @@ void AArch64FrameLowering::processFunctionBeforeFrameFinalized(
2659
2673
++MBBI;
2660
2674
2661
2675
// 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 );
2664
2682
EHInfo.UnwindHelpFrameIdx = UnwindHelpFI;
2683
+
2665
2684
// We need to store -2 into the UnwindHelp object at the start of the
2666
2685
// function.
2667
2686
DebugLoc DL;
@@ -3073,10 +3092,14 @@ int AArch64FrameLowering::getFrameIndexReferencePreferSP(
3073
3092
const MachineFunction &MF, int FI, unsigned &FrameReg,
3074
3093
bool IgnoreSPUpdates) const {
3075
3094
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);
3080
3103
}
3081
3104
3082
3105
// / The parent frame offset (aka dispFrame) is only used on X86_64 to retrieve
0 commit comments