@@ -223,6 +223,8 @@ flagsNeedToBePreservedBeforeTheTerminators(const MachineBasicBlock &MBB) {
223
223
return false ;
224
224
}
225
225
226
+ constexpr int64_t MaxSPChunk = (1LL << 31 ) - 1 ;
227
+
226
228
// / emitSPUpdate - Emit a series of instructions to increment / decrement the
227
229
// / stack pointer by a constant value.
228
230
void X86FrameLowering::emitSPUpdate (MachineBasicBlock &MBB,
@@ -242,7 +244,7 @@ void X86FrameLowering::emitSPUpdate(MachineBasicBlock &MBB,
242
244
return ;
243
245
}
244
246
245
- uint64_t Chunk = ( 1LL << 31 ) - 1 ;
247
+ uint64_t Chunk = MaxSPChunk ;
246
248
247
249
MachineFunction &MF = *MBB.getParent ();
248
250
const X86Subtarget &STI = MF.getSubtarget <X86Subtarget>();
@@ -391,12 +393,14 @@ MachineInstrBuilder X86FrameLowering::BuildStackAdjustment(
391
393
return MI;
392
394
}
393
395
394
- int X86FrameLowering::mergeSPUpdates (MachineBasicBlock &MBB,
395
- MachineBasicBlock::iterator &MBBI,
396
- bool doMergeWithPrevious) const {
396
+ template <typename T>
397
+ int64_t X86FrameLowering::mergeSPUpdates (MachineBasicBlock &MBB,
398
+ MachineBasicBlock::iterator &MBBI,
399
+ T CalcNewOffset,
400
+ bool doMergeWithPrevious) const {
397
401
if ((doMergeWithPrevious && MBBI == MBB.begin ()) ||
398
402
(!doMergeWithPrevious && MBBI == MBB.end ()))
399
- return 0 ;
403
+ return CalcNewOffset ( 0 ) ;
400
404
401
405
MachineBasicBlock::iterator PI = doMergeWithPrevious ? std::prev (MBBI) : MBBI;
402
406
@@ -415,27 +419,37 @@ int X86FrameLowering::mergeSPUpdates(MachineBasicBlock &MBB,
415
419
if (doMergeWithPrevious && PI != MBB.begin () && PI->isCFIInstruction ())
416
420
PI = std::prev (PI);
417
421
418
- unsigned Opc = PI->getOpcode ();
419
- int Offset = 0 ;
420
-
421
- if ((Opc == X86::ADD64ri32 || Opc == X86::ADD32ri) &&
422
- PI->getOperand (0 ).getReg () == StackPtr) {
423
- assert (PI->getOperand (1 ).getReg () == StackPtr);
424
- Offset = PI->getOperand (2 ).getImm ();
425
- } else if ((Opc == X86::LEA32r || Opc == X86::LEA64_32r) &&
426
- PI->getOperand (0 ).getReg () == StackPtr &&
427
- PI->getOperand (1 ).getReg () == StackPtr &&
428
- PI->getOperand (2 ).getImm () == 1 &&
429
- PI->getOperand (3 ).getReg () == X86::NoRegister &&
430
- PI->getOperand (5 ).getReg () == X86::NoRegister) {
431
- // For LEAs we have: def = lea SP, FI, noreg, Offset, noreg.
432
- Offset = PI->getOperand (4 ).getImm ();
433
- } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB32ri) &&
434
- PI->getOperand (0 ).getReg () == StackPtr) {
435
- assert (PI->getOperand (1 ).getReg () == StackPtr);
436
- Offset = -PI->getOperand (2 ).getImm ();
437
- } else
438
- return 0 ;
422
+ int64_t Offset = 0 ;
423
+ for (;;) {
424
+ unsigned Opc = PI->getOpcode ();
425
+
426
+ if ((Opc == X86::ADD64ri32 || Opc == X86::ADD32ri) &&
427
+ PI->getOperand (0 ).getReg () == StackPtr) {
428
+ assert (PI->getOperand (1 ).getReg () == StackPtr);
429
+ Offset = PI->getOperand (2 ).getImm ();
430
+ } else if ((Opc == X86::LEA32r || Opc == X86::LEA64_32r) &&
431
+ PI->getOperand (0 ).getReg () == StackPtr &&
432
+ PI->getOperand (1 ).getReg () == StackPtr &&
433
+ PI->getOperand (2 ).getImm () == 1 &&
434
+ PI->getOperand (3 ).getReg () == X86::NoRegister &&
435
+ PI->getOperand (5 ).getReg () == X86::NoRegister) {
436
+ // For LEAs we have: def = lea SP, FI, noreg, Offset, noreg.
437
+ Offset = PI->getOperand (4 ).getImm ();
438
+ } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB32ri) &&
439
+ PI->getOperand (0 ).getReg () == StackPtr) {
440
+ assert (PI->getOperand (1 ).getReg () == StackPtr);
441
+ Offset = -PI->getOperand (2 ).getImm ();
442
+ } else
443
+ return CalcNewOffset (0 );
444
+
445
+ if (std::abs ((int64_t )CalcNewOffset (Offset)) < MaxSPChunk)
446
+ break ;
447
+
448
+ if (doMergeWithPrevious ? (PI == MBB.begin ()) : (PI == MBB.end ()))
449
+ return CalcNewOffset (0 );
450
+
451
+ PI = doMergeWithPrevious ? std::prev (PI) : std::next (PI);
452
+ }
439
453
440
454
PI = MBB.erase (PI);
441
455
if (PI != MBB.end () && PI->isCFIInstruction ()) {
@@ -448,7 +462,16 @@ int X86FrameLowering::mergeSPUpdates(MachineBasicBlock &MBB,
448
462
if (!doMergeWithPrevious)
449
463
MBBI = skipDebugInstructionsForward (PI, MBB.end ());
450
464
451
- return Offset;
465
+ return CalcNewOffset (Offset);
466
+ }
467
+
468
+ int64_t X86FrameLowering::mergeSPAdd (MachineBasicBlock &MBB,
469
+ MachineBasicBlock::iterator &MBBI,
470
+ int64_t AddOffset,
471
+ bool doMergeWithPrevious) const {
472
+ return mergeSPUpdates (
473
+ MBB, MBBI, [AddOffset](int64_t Offset) { return AddOffset + Offset; },
474
+ doMergeWithPrevious);
452
475
}
453
476
454
477
void X86FrameLowering::BuildCFI (MachineBasicBlock &MBB,
@@ -1975,8 +1998,10 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
1975
1998
1976
1999
// If there is an SUB32ri of ESP immediately before this instruction, merge
1977
2000
// the two. This can be the case when tail call elimination is enabled and
1978
- // the callee has more arguments then the caller.
1979
- NumBytes -= mergeSPUpdates (MBB, MBBI, true );
2001
+ // the callee has more arguments than the caller.
2002
+ NumBytes = mergeSPUpdates (
2003
+ MBB, MBBI, [NumBytes](int64_t Offset) { return NumBytes - Offset; },
2004
+ true );
1980
2005
1981
2006
// Adjust stack pointer: ESP -= numbytes.
1982
2007
@@ -2457,7 +2482,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
2457
2482
if (HasFP) {
2458
2483
if (X86FI->hasSwiftAsyncContext ()) {
2459
2484
// Discard the context.
2460
- int Offset = 16 + mergeSPUpdates (MBB, MBBI, true );
2485
+ int64_t Offset = mergeSPAdd (MBB, MBBI, 16 , true );
2461
2486
emitSPUpdate (MBB, MBBI, DL, Offset, /* InEpilogue*/ true );
2462
2487
}
2463
2488
// Pop EBP.
@@ -2531,7 +2556,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
2531
2556
// If there is an ADD32ri or SUB32ri of ESP immediately before this
2532
2557
// instruction, merge the two instructions.
2533
2558
if (NumBytes || MFI.hasVarSizedObjects ())
2534
- NumBytes += mergeSPUpdates (MBB, MBBI, true );
2559
+ NumBytes = mergeSPAdd (MBB, MBBI, NumBytes , true );
2535
2560
2536
2561
// If dynamic alloca is used, then reset esp to point to the last callee-saved
2537
2562
// slot before popping them off! Same applies for the case, when stack was
@@ -2618,11 +2643,11 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
2618
2643
2619
2644
if (Terminator == MBB.end () || !isTailCallOpcode (Terminator->getOpcode ())) {
2620
2645
// Add the return addr area delta back since we are not tail calling.
2621
- int Offset = -1 * X86FI->getTCReturnAddrDelta ();
2646
+ int64_t Offset = -1 * X86FI->getTCReturnAddrDelta ();
2622
2647
assert (Offset >= 0 && " TCDelta should never be positive" );
2623
2648
if (Offset) {
2624
2649
// Check for possible merge with preceding ADD instruction.
2625
- Offset += mergeSPUpdates (MBB, Terminator, true );
2650
+ Offset = mergeSPAdd (MBB, Terminator, Offset , true );
2626
2651
emitSPUpdate (MBB, Terminator, DL, Offset, /* InEpilogue=*/ true );
2627
2652
}
2628
2653
}
@@ -3822,8 +3847,8 @@ MachineBasicBlock::iterator X86FrameLowering::eliminateCallFramePseudoInstr(
3822
3847
// Merge with any previous or following adjustment instruction. Note: the
3823
3848
// instructions merged with here do not have CFI, so their stack
3824
3849
// adjustments do not feed into CfaAdjustment.
3825
- StackAdjustment += mergeSPUpdates (MBB, InsertPos, true );
3826
- StackAdjustment += mergeSPUpdates (MBB, InsertPos, false );
3850
+ StackAdjustment = mergeSPAdd (MBB, InsertPos, StackAdjustment , true );
3851
+ StackAdjustment = mergeSPAdd (MBB, InsertPos, StackAdjustment , false );
3827
3852
3828
3853
if (StackAdjustment) {
3829
3854
if (!(F.hasMinSize () &&
0 commit comments