@@ -237,6 +237,41 @@ ARMFrameLowering::canSimplifyCallFramePseudos(const MachineFunction &MF) const {
237
237
return hasReservedCallFrame (MF) || MF.getFrameInfo ().hasVarSizedObjects ();
238
238
}
239
239
240
+ // Returns how much of the incoming argument stack area we should clean up in an
241
+ // epilogue. For the C calling convention this will be 0, for guaranteed tail
242
+ // call conventions it can be positive (a normal return or a tail call to a
243
+ // function that uses less stack space for arguments) or negative (for a tail
244
+ // call to a function that needs more stack space than us for arguments).
245
+ static int getArgumentStackToRestore (MachineFunction &MF,
246
+ MachineBasicBlock &MBB) {
247
+ MachineBasicBlock::iterator MBBI = MBB.getLastNonDebugInstr ();
248
+ bool IsTailCallReturn = false ;
249
+ if (MBB.end () != MBBI) {
250
+ unsigned RetOpcode = MBBI->getOpcode ();
251
+ IsTailCallReturn = RetOpcode == ARM::TCRETURNdi ||
252
+ RetOpcode == ARM::TCRETURNri;
253
+ }
254
+ ARMFunctionInfo *AFI = MF.getInfo <ARMFunctionInfo>();
255
+
256
+ int ArgumentPopSize = 0 ;
257
+ if (IsTailCallReturn) {
258
+ MachineOperand &StackAdjust = MBBI->getOperand (1 );
259
+
260
+ // For a tail-call in a callee-pops-arguments environment, some or all of
261
+ // the stack may actually be in use for the call's arguments, this is
262
+ // calculated during LowerCall and consumed here...
263
+ ArgumentPopSize = StackAdjust.getImm ();
264
+ } else {
265
+ // ... otherwise the amount to pop is *all* of the argument space,
266
+ // conveniently stored in the MachineFunctionInfo by
267
+ // LowerFormalArguments. This will, of course, be zero for the C calling
268
+ // convention.
269
+ ArgumentPopSize = AFI->getArgumentStackToRestore ();
270
+ }
271
+
272
+ return ArgumentPopSize;
273
+ }
274
+
240
275
static void emitRegPlusImmediate (
241
276
bool isARM, MachineBasicBlock &MBB, MachineBasicBlock::iterator &MBBI,
242
277
const DebugLoc &dl, const ARMBaseInstrInfo &TII, unsigned DestReg,
@@ -868,7 +903,13 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
868
903
" This emitEpilogue does not support Thumb1!" );
869
904
bool isARM = !AFI->isThumbFunction ();
870
905
871
- unsigned ArgRegsSaveSize = AFI->getArgRegsSaveSize ();
906
+ // Amount of stack space we reserved next to incoming args for either
907
+ // varargs registers or stack arguments in tail calls made by this function.
908
+ unsigned ReservedArgStack = AFI->getArgRegsSaveSize ();
909
+
910
+ // How much of the stack used by incoming arguments this function is expected
911
+ // to restore in this particular epilogue.
912
+ int IncomingArgStackToRestore = getArgumentStackToRestore (MF, MBB);
872
913
int NumBytes = (int )MFI.getStackSize ();
873
914
Register FramePtr = RegInfo->getFrameRegister (MF);
874
915
@@ -882,8 +923,8 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
882
923
DebugLoc dl = MBBI != MBB.end () ? MBBI->getDebugLoc () : DebugLoc ();
883
924
884
925
if (!AFI->hasStackFrame ()) {
885
- if (NumBytes - ArgRegsSaveSize != 0 )
886
- emitSPUpdate (isARM, MBB, MBBI, dl, TII, NumBytes - ArgRegsSaveSize ,
926
+ if (NumBytes - ReservedArgStack != 0 )
927
+ emitSPUpdate (isARM, MBB, MBBI, dl, TII, NumBytes - ReservedArgStack ,
887
928
MachineInstr::FrameDestroy);
888
929
} else {
889
930
// Unwind MBBI to point to first LDR / VLDRD.
@@ -897,7 +938,7 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
897
938
}
898
939
899
940
// Move SP to start of FP callee save spill area.
900
- NumBytes -= (ArgRegsSaveSize +
941
+ NumBytes -= (ReservedArgStack +
901
942
AFI->getFPCXTSaveAreaSize () +
902
943
AFI->getGPRCalleeSavedArea1Size () +
903
944
AFI->getGPRCalleeSavedArea2Size () +
@@ -969,9 +1010,13 @@ void ARMFrameLowering::emitEpilogue(MachineFunction &MF,
969
1010
if (AFI->getFPCXTSaveAreaSize ()) MBBI++;
970
1011
}
971
1012
972
- if (ArgRegsSaveSize)
973
- emitSPUpdate (isARM, MBB, MBBI, dl, TII, ArgRegsSaveSize,
1013
+ if (ReservedArgStack || IncomingArgStackToRestore) {
1014
+ assert (ReservedArgStack + IncomingArgStackToRestore >= 0 &&
1015
+ " attempting to restore negative stack amount" );
1016
+ emitSPUpdate (isARM, MBB, MBBI, dl, TII,
1017
+ ReservedArgStack + IncomingArgStackToRestore,
974
1018
MachineInstr::FrameDestroy);
1019
+ }
975
1020
}
976
1021
977
1022
// / getFrameIndexReference - Provide a base+offset reference to an FI slot for
@@ -2288,31 +2333,37 @@ MachineBasicBlock::iterator ARMFrameLowering::eliminateCallFramePseudoInstr(
2288
2333
MachineBasicBlock::iterator I) const {
2289
2334
const ARMBaseInstrInfo &TII =
2290
2335
*static_cast <const ARMBaseInstrInfo *>(MF.getSubtarget ().getInstrInfo ());
2336
+ ARMFunctionInfo *AFI = MF.getInfo <ARMFunctionInfo>();
2337
+ bool isARM = !AFI->isThumbFunction ();
2338
+ DebugLoc dl = I->getDebugLoc ();
2339
+ unsigned Opc = I->getOpcode ();
2340
+ bool IsDestroy = Opc == TII.getCallFrameDestroyOpcode ();
2341
+ unsigned CalleePopAmount = IsDestroy ? I->getOperand (1 ).getImm () : 0 ;
2342
+
2343
+ assert (!AFI->isThumb1OnlyFunction () &&
2344
+ " This eliminateCallFramePseudoInstr does not support Thumb1!" );
2345
+
2346
+ int PIdx = I->findFirstPredOperandIdx ();
2347
+ ARMCC::CondCodes Pred = (PIdx == -1 )
2348
+ ? ARMCC::AL
2349
+ : (ARMCC::CondCodes)I->getOperand (PIdx).getImm ();
2350
+ unsigned PredReg = TII.getFramePred (*I);
2351
+
2291
2352
if (!hasReservedCallFrame (MF)) {
2353
+ // Bail early if the callee is expected to do the adjustment.
2354
+ if (IsDestroy && CalleePopAmount != -1U )
2355
+ return MBB.erase (I);
2356
+
2292
2357
// If we have alloca, convert as follows:
2293
2358
// ADJCALLSTACKDOWN -> sub, sp, sp, amount
2294
2359
// ADJCALLSTACKUP -> add, sp, sp, amount
2295
- MachineInstr &Old = *I;
2296
- DebugLoc dl = Old.getDebugLoc ();
2297
- unsigned Amount = TII.getFrameSize (Old);
2360
+ unsigned Amount = TII.getFrameSize (*I);
2298
2361
if (Amount != 0 ) {
2299
2362
// We need to keep the stack aligned properly. To do this, we round the
2300
2363
// amount of space needed for the outgoing arguments up to the next
2301
2364
// alignment boundary.
2302
2365
Amount = alignSPAdjust (Amount);
2303
2366
2304
- ARMFunctionInfo *AFI = MF.getInfo <ARMFunctionInfo>();
2305
- assert (!AFI->isThumb1OnlyFunction () &&
2306
- " This eliminateCallFramePseudoInstr does not support Thumb1!" );
2307
- bool isARM = !AFI->isThumbFunction ();
2308
-
2309
- // Replace the pseudo instruction with a new instruction...
2310
- unsigned Opc = Old.getOpcode ();
2311
- int PIdx = Old.findFirstPredOperandIdx ();
2312
- ARMCC::CondCodes Pred =
2313
- (PIdx == -1 ) ? ARMCC::AL
2314
- : (ARMCC::CondCodes)Old.getOperand (PIdx).getImm ();
2315
- unsigned PredReg = TII.getFramePred (Old);
2316
2367
if (Opc == ARM::ADJCALLSTACKDOWN || Opc == ARM::tADJCALLSTACKDOWN) {
2317
2368
emitSPUpdate (isARM, MBB, I, dl, TII, -Amount, MachineInstr::NoFlags,
2318
2369
Pred, PredReg);
@@ -2322,6 +2373,11 @@ MachineBasicBlock::iterator ARMFrameLowering::eliminateCallFramePseudoInstr(
2322
2373
Pred, PredReg);
2323
2374
}
2324
2375
}
2376
+ } else if (CalleePopAmount != -1U ) {
2377
+ // If the calling convention demands that the callee pops arguments from the
2378
+ // stack, we want to add it back if we have a reserved call frame.
2379
+ emitSPUpdate (isARM, MBB, I, dl, TII, -CalleePopAmount,
2380
+ MachineInstr::NoFlags, Pred, PredReg);
2325
2381
}
2326
2382
return MBB.erase (I);
2327
2383
}
0 commit comments