diff --git a/llvm/lib/CodeGen/PrologEpilogInserter.cpp b/llvm/lib/CodeGen/PrologEpilogInserter.cpp --- a/llvm/lib/CodeGen/PrologEpilogInserter.cpp +++ b/llvm/lib/CodeGen/PrologEpilogInserter.cpp @@ -133,8 +133,8 @@ bool replaceFrameIndexDebugInstr(MachineFunction &MF, MachineInstr &MI, unsigned OpIdx, int SPAdj = 0); // Does same as replaceFrameIndices but using the backward MIR walk and - // backward register scavenger walk. Does not yet support call sequence - // processing. + // backward register scavenger walk. + void replaceFrameIndicesBackward(MachineFunction &MF); void replaceFrameIndicesBackward(MachineBasicBlock *BB, MachineFunction &MF, int &SPAdj); @@ -271,8 +271,17 @@ // Replace all MO_FrameIndex operands with physical register references // and actual offsets. - // - replaceFrameIndices(MF); + if (TFI->needsFrameIndexResolution(MF)) { + // Allow the target to determine this after knowing the frame size. + FrameIndexEliminationScavenging = + (RS && !FrameIndexVirtualScavenging) || + TRI->requiresFrameIndexReplacementScavenging(MF); + + if (TRI->supportsBackwardScavenger()) + replaceFrameIndicesBackward(MF); + else + replaceFrameIndices(MF); + } // If register scavenging is needed, as we've enabled doing it as a // post-pass, scavenge the virtual registers that frame index elimination @@ -1331,19 +1340,38 @@ TFI.emitZeroCallUsedRegs(RegsToZero, MBB); } +/// Replace all FrameIndex operands with physical register references and actual +/// offsets. +void PEI::replaceFrameIndicesBackward(MachineFunction &MF) { + const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering(); + + for (auto &MBB : MF) { + int SPAdj = 0; + if (!MBB.succ_empty()) { + // Get the SP adjustment for the end of MBB from the start of any of its + // successors. They should all be the same. + assert(all_of(MBB.successors(), [&MBB](const MachineBasicBlock *Succ) { + return Succ->getCallFrameSize() == + (*MBB.succ_begin())->getCallFrameSize(); + })); + const MachineBasicBlock &FirstSucc = **MBB.succ_begin(); + SPAdj = TFI.alignSPAdjust(FirstSucc.getCallFrameSize()); + if (TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsUp) + SPAdj = -SPAdj; + } + + replaceFrameIndicesBackward(&MBB, MF, SPAdj); + + // We can't track the call frame size after call frame pseudos have been + // eliminated. Set it to zero everywhere to keep MachineVerifier happy. + MBB.setCallFrameSize(0); + } +} + /// replaceFrameIndices - Replace all MO_FrameIndex operands with physical /// register references and actual offsets. void PEI::replaceFrameIndices(MachineFunction &MF) { - const auto &ST = MF.getSubtarget(); - const TargetFrameLowering &TFI = *ST.getFrameLowering(); - if (!TFI.needsFrameIndexResolution(MF)) - return; - - const TargetRegisterInfo *TRI = ST.getRegisterInfo(); - - // Allow the target to determine this after knowing the frame size. - FrameIndexEliminationScavenging = (RS && !FrameIndexVirtualScavenging) || - TRI->requiresFrameIndexReplacementScavenging(MF); + const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering(); for (auto &MBB : MF) { int SPAdj = TFI.alignSPAdjust(MBB.getCallFrameSize()); @@ -1455,6 +1483,7 @@ for (MachineInstr &MI : make_early_inc_range(reverse(*BB))) { if (TII.isFrameInstr(MI)) { + SPAdj -= TII.getSPAdjust(MI); TFI.eliminateCallFramePseudoInstr(MF, *BB, &MI); continue; } @@ -1477,7 +1506,7 @@ MachineBasicBlock::iterator Save; if (LocalRS) Save = std::next(LocalRS->getCurrentPosition()); - bool Removed = TRI.eliminateFrameIndex(MI, SPAdj, i, RS); + bool Removed = TRI.eliminateFrameIndex(MI, SPAdj, i, LocalRS); if (LocalRS) LocalRS->skipTo(std::prev(Save)); @@ -1495,9 +1524,6 @@ const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo(); const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering(); - if (TRI.supportsBackwardScavenger()) - return replaceFrameIndicesBackward(BB, MF, SPAdj); - if (RS && FrameIndexEliminationScavenging) RS->enterBasicBlock(*BB); diff --git a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h --- a/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h +++ b/llvm/lib/Target/ARM/ARMBaseRegisterInfo.h @@ -219,6 +219,8 @@ bool requiresFrameIndexScavenging(const MachineFunction &MF) const override; + bool supportsBackwardScavenger() const override { return true; } + bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override; bool eliminateFrameIndex(MachineBasicBlock::iterator II, diff --git a/llvm/test/CodeGen/Thumb/emergency-spill-slot.ll b/llvm/test/CodeGen/Thumb/emergency-spill-slot.ll --- a/llvm/test/CodeGen/Thumb/emergency-spill-slot.ll +++ b/llvm/test/CodeGen/Thumb/emergency-spill-slot.ll @@ -64,12 +64,12 @@ ; CHECK-NEXT: .pad #8196 ; CHECK-NEXT: add sp, r7 ; CHECK-NEXT: add r0, sp, #4 -; CHECK-NEXT: ldr r1, .LCPI1_2 +; CHECK-NEXT: ldr r1, .LCPI1_3 ; CHECK-NEXT: add r1, sp ; CHECK-NEXT: @APP ; CHECK-NEXT: @NO_APP ; CHECK-NEXT: str r0, [sp] -; CHECK-NEXT: ldr r0, .LCPI1_3 +; CHECK-NEXT: ldr r0, .LCPI1_2 ; CHECK-NEXT: add r0, sp ; CHECK-NEXT: str r5, [r0] ; CHECK-NEXT: ldr r0, [sp] @@ -85,9 +85,9 @@ ; CHECK-NEXT: .LCPI1_1: ; CHECK-NEXT: .long 8196 @ 0x2004 ; CHECK-NEXT: .LCPI1_2: -; CHECK-NEXT: .long 4100 @ 0x1004 -; CHECK-NEXT: .LCPI1_3: ; CHECK-NEXT: .long 5120 @ 0x1400 +; CHECK-NEXT: .LCPI1_3: +; CHECK-NEXT: .long 4100 @ 0x1004 entry: %x = alloca [1024 x i32], align 4 %y = alloca [1024 x i32], align 4 @@ -124,12 +124,12 @@ ; CHECK-NEXT: .pad #8196 ; CHECK-NEXT: add sp, r6 ; CHECK-NEXT: add r0, sp, #4 -; CHECK-NEXT: ldr r1, .LCPI2_2 +; CHECK-NEXT: ldr r1, .LCPI2_3 ; CHECK-NEXT: add r1, sp ; CHECK-NEXT: @APP ; CHECK-NEXT: @NO_APP ; CHECK-NEXT: str r7, [sp] -; CHECK-NEXT: ldr r7, .LCPI2_3 +; CHECK-NEXT: ldr r7, .LCPI2_2 ; CHECK-NEXT: add r7, sp ; CHECK-NEXT: str r5, [r7] ; CHECK-NEXT: ldr r7, [sp] @@ -145,9 +145,9 @@ ; CHECK-NEXT: .LCPI2_1: ; CHECK-NEXT: .long 8196 @ 0x2004 ; CHECK-NEXT: .LCPI2_2: -; CHECK-NEXT: .long 4100 @ 0x1004 -; CHECK-NEXT: .LCPI2_3: ; CHECK-NEXT: .long 5120 @ 0x1400 +; CHECK-NEXT: .LCPI2_3: +; CHECK-NEXT: .long 4100 @ 0x1004 entry: %x = alloca [1024 x i32], align 4 %y = alloca [1024 x i32], align 4