@@ -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,15 @@ 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 FoundT, typename CalcT>
397
+ int64_t X86FrameLowering::mergeSPUpdates (MachineBasicBlock &MBB,
398
+ MachineBasicBlock::iterator &MBBI,
399
+ FoundT FoundStackAdjust,
400
+ CalcT CalcNewOffset,
401
+ bool doMergeWithPrevious) const {
397
402
if ((doMergeWithPrevious && MBBI == MBB.begin ()) ||
398
403
(!doMergeWithPrevious && MBBI == MBB.end ()))
399
- return 0 ;
404
+ return CalcNewOffset ( 0 ) ;
400
405
401
406
MachineBasicBlock::iterator PI = doMergeWithPrevious ? std::prev (MBBI) : MBBI;
402
407
@@ -415,27 +420,38 @@ int X86FrameLowering::mergeSPUpdates(MachineBasicBlock &MBB,
415
420
if (doMergeWithPrevious && PI != MBB.begin () && PI->isCFIInstruction ())
416
421
PI = std::prev (PI);
417
422
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 ;
423
+ int64_t Offset = 0 ;
424
+ for (;;) {
425
+ unsigned Opc = PI->getOpcode ();
426
+
427
+ if ((Opc == X86::ADD64ri32 || Opc == X86::ADD32ri) &&
428
+ PI->getOperand (0 ).getReg () == StackPtr) {
429
+ assert (PI->getOperand (1 ).getReg () == StackPtr);
430
+ Offset = PI->getOperand (2 ).getImm ();
431
+ } else if ((Opc == X86::LEA32r || Opc == X86::LEA64_32r) &&
432
+ PI->getOperand (0 ).getReg () == StackPtr &&
433
+ PI->getOperand (1 ).getReg () == StackPtr &&
434
+ PI->getOperand (2 ).getImm () == 1 &&
435
+ PI->getOperand (3 ).getReg () == X86::NoRegister &&
436
+ PI->getOperand (5 ).getReg () == X86::NoRegister) {
437
+ // For LEAs we have: def = lea SP, FI, noreg, Offset, noreg.
438
+ Offset = PI->getOperand (4 ).getImm ();
439
+ } else if ((Opc == X86::SUB64ri32 || Opc == X86::SUB32ri) &&
440
+ PI->getOperand (0 ).getReg () == StackPtr) {
441
+ assert (PI->getOperand (1 ).getReg () == StackPtr);
442
+ Offset = -PI->getOperand (2 ).getImm ();
443
+ } else
444
+ return CalcNewOffset (0 );
445
+
446
+ FoundStackAdjust (PI, Offset);
447
+ if (std::abs ((int64_t )CalcNewOffset (Offset)) < MaxSPChunk)
448
+ break ;
449
+
450
+ if (doMergeWithPrevious ? (PI == MBB.begin ()) : (PI == MBB.end ()))
451
+ return CalcNewOffset (0 );
452
+
453
+ PI = doMergeWithPrevious ? std::prev (PI) : std::next (PI);
454
+ }
439
455
440
456
PI = MBB.erase (PI);
441
457
if (PI != MBB.end () && PI->isCFIInstruction ()) {
@@ -448,7 +464,16 @@ int X86FrameLowering::mergeSPUpdates(MachineBasicBlock &MBB,
448
464
if (!doMergeWithPrevious)
449
465
MBBI = skipDebugInstructionsForward (PI, MBB.end ());
450
466
451
- return Offset;
467
+ return CalcNewOffset (Offset);
468
+ }
469
+
470
+ int64_t X86FrameLowering::mergeSPAdd (MachineBasicBlock &MBB,
471
+ MachineBasicBlock::iterator &MBBI,
472
+ int64_t AddOffset,
473
+ bool doMergeWithPrevious) const {
474
+ return mergeSPUpdates (
475
+ MBB, MBBI, [AddOffset](int64_t Offset) { return AddOffset + Offset; },
476
+ doMergeWithPrevious);
452
477
}
453
478
454
479
void X86FrameLowering::BuildCFI (MachineBasicBlock &MBB,
@@ -1975,8 +2000,10 @@ void X86FrameLowering::emitPrologue(MachineFunction &MF,
1975
2000
1976
2001
// If there is an SUB32ri of ESP immediately before this instruction, merge
1977
2002
// 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 );
2003
+ // the callee has more arguments than the caller.
2004
+ NumBytes = mergeSPUpdates (
2005
+ MBB, MBBI, [NumBytes](int64_t Offset) { return NumBytes - Offset; },
2006
+ true );
1980
2007
1981
2008
// Adjust stack pointer: ESP -= numbytes.
1982
2009
@@ -2457,7 +2484,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
2457
2484
if (HasFP) {
2458
2485
if (X86FI->hasSwiftAsyncContext ()) {
2459
2486
// Discard the context.
2460
- int Offset = 16 + mergeSPUpdates (MBB, MBBI, true );
2487
+ int64_t Offset = mergeSPAdd (MBB, MBBI, 16 , true );
2461
2488
emitSPUpdate (MBB, MBBI, DL, Offset, /* InEpilogue*/ true );
2462
2489
}
2463
2490
// Pop EBP.
@@ -2531,7 +2558,7 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
2531
2558
// If there is an ADD32ri or SUB32ri of ESP immediately before this
2532
2559
// instruction, merge the two instructions.
2533
2560
if (NumBytes || MFI.hasVarSizedObjects ())
2534
- NumBytes += mergeSPUpdates (MBB, MBBI, true );
2561
+ NumBytes = mergeSPAdd (MBB, MBBI, NumBytes , true );
2535
2562
2536
2563
// If dynamic alloca is used, then reset esp to point to the last callee-saved
2537
2564
// slot before popping them off! Same applies for the case, when stack was
@@ -2612,11 +2639,11 @@ void X86FrameLowering::emitEpilogue(MachineFunction &MF,
2612
2639
2613
2640
if (Terminator == MBB.end () || !isTailCallOpcode (Terminator->getOpcode ())) {
2614
2641
// Add the return addr area delta back since we are not tail calling.
2615
- int Offset = -1 * X86FI->getTCReturnAddrDelta ();
2642
+ int64_t Offset = -1 * X86FI->getTCReturnAddrDelta ();
2616
2643
assert (Offset >= 0 && " TCDelta should never be positive" );
2617
2644
if (Offset) {
2618
2645
// Check for possible merge with preceding ADD instruction.
2619
- Offset += mergeSPUpdates (MBB, Terminator, true );
2646
+ Offset = mergeSPAdd (MBB, Terminator, Offset , true );
2620
2647
emitSPUpdate (MBB, Terminator, DL, Offset, /* InEpilogue=*/ true );
2621
2648
}
2622
2649
}
@@ -3814,13 +3841,24 @@ MachineBasicBlock::iterator X86FrameLowering::eliminateCallFramePseudoInstr(
3814
3841
3815
3842
// Add Amount to SP to destroy a frame, or subtract to setup.
3816
3843
int64_t StackAdjustment = isDestroy ? Amount : -Amount;
3844
+ int64_t CfaAdjustment = StackAdjustment;
3817
3845
3818
3846
if (StackAdjustment) {
3819
3847
// Merge with any previous or following adjustment instruction. Note: the
3820
3848
// instructions merged with here do not have CFI, so their stack
3821
- // adjustments do not feed into CfaAdjustment.
3822
- StackAdjustment += mergeSPUpdates (MBB, InsertPos, true );
3823
- StackAdjustment += mergeSPUpdates (MBB, InsertPos, false );
3849
+ // adjustments do not feed into CfaAdjustment
3850
+
3851
+ auto CalcCfaAdjust = [&CfaAdjustment](MachineBasicBlock::iterator PI,
3852
+ int64_t Offset) {
3853
+ CfaAdjustment += Offset;
3854
+ };
3855
+ auto CalcNewOffset = [&StackAdjustment](int64_t Offset) {
3856
+ return StackAdjustment + Offset;
3857
+ };
3858
+ StackAdjustment =
3859
+ mergeSPUpdates (MBB, InsertPos, CalcCfaAdjust, CalcNewOffset, true );
3860
+ StackAdjustment =
3861
+ mergeSPUpdates (MBB, InsertPos, CalcCfaAdjust, CalcNewOffset, false );
3824
3862
3825
3863
if (StackAdjustment) {
3826
3864
if (!(F.hasMinSize () &&
@@ -3830,22 +3868,19 @@ MachineBasicBlock::iterator X86FrameLowering::eliminateCallFramePseudoInstr(
3830
3868
}
3831
3869
}
3832
3870
3833
- if (DwarfCFI && !hasFP (MF)) {
3871
+ if (DwarfCFI && !hasFP (MF) && CfaAdjustment ) {
3834
3872
// If we don't have FP, but need to generate unwind information,
3835
3873
// we need to set the correct CFA offset after the stack adjustment.
3836
3874
// How much we adjust the CFA offset depends on whether we're emitting
3837
3875
// CFI only for EH purposes or for debugging. EH only requires the CFA
3838
3876
// offset to be correct at each call site, while for debugging we want
3839
3877
// it to be more precise.
3840
3878
3841
- int64_t CfaAdjustment = -StackAdjustment;
3842
3879
// TODO: When not using precise CFA, we also need to adjust for the
3843
3880
// InternalAmt here.
3844
- if (CfaAdjustment) {
3845
- BuildCFI (
3846
- MBB, InsertPos, DL,
3847
- MCCFIInstruction::createAdjustCfaOffset (nullptr , CfaAdjustment));
3848
- }
3881
+ BuildCFI (
3882
+ MBB, InsertPos, DL,
3883
+ MCCFIInstruction::createAdjustCfaOffset (nullptr , -CfaAdjustment));
3849
3884
}
3850
3885
3851
3886
return I;
0 commit comments