Skip to content

Commit 9451233

Browse files
committed
[PEI][ARM] Switch to backwards frame index elimination
This adds better support for call frame pseudos that adjust SP in PEI::replaceFrameIndicesBackward. Running frame index elimination backwards is preferred because it can do backwards register scavenging (on targets that require scavenging) which does not rely on accurate kill flags. Differential Revision: https://reviews.llvm.org/D156434
1 parent 17aaa65 commit 9451233

File tree

3 files changed

+54
-26
lines changed

3 files changed

+54
-26
lines changed

llvm/lib/CodeGen/PrologEpilogInserter.cpp

Lines changed: 44 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -133,8 +133,8 @@ class PEI : public MachineFunctionPass {
133133
bool replaceFrameIndexDebugInstr(MachineFunction &MF, MachineInstr &MI,
134134
unsigned OpIdx, int SPAdj = 0);
135135
// Does same as replaceFrameIndices but using the backward MIR walk and
136-
// backward register scavenger walk. Does not yet support call sequence
137-
// processing.
136+
// backward register scavenger walk.
137+
void replaceFrameIndicesBackward(MachineFunction &MF);
138138
void replaceFrameIndicesBackward(MachineBasicBlock *BB, MachineFunction &MF,
139139
int &SPAdj);
140140

@@ -271,8 +271,17 @@ bool PEI::runOnMachineFunction(MachineFunction &MF) {
271271

272272
// Replace all MO_FrameIndex operands with physical register references
273273
// and actual offsets.
274-
//
275-
replaceFrameIndices(MF);
274+
if (TFI->needsFrameIndexResolution(MF)) {
275+
// Allow the target to determine this after knowing the frame size.
276+
FrameIndexEliminationScavenging =
277+
(RS && !FrameIndexVirtualScavenging) ||
278+
TRI->requiresFrameIndexReplacementScavenging(MF);
279+
280+
if (TRI->supportsBackwardScavenger())
281+
replaceFrameIndicesBackward(MF);
282+
else
283+
replaceFrameIndices(MF);
284+
}
276285

277286
// If register scavenging is needed, as we've enabled doing it as a
278287
// post-pass, scavenge the virtual registers that frame index elimination
@@ -1331,19 +1340,38 @@ void PEI::insertZeroCallUsedRegs(MachineFunction &MF) {
13311340
TFI.emitZeroCallUsedRegs(RegsToZero, MBB);
13321341
}
13331342

1343+
/// Replace all FrameIndex operands with physical register references and actual
1344+
/// offsets.
1345+
void PEI::replaceFrameIndicesBackward(MachineFunction &MF) {
1346+
const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
1347+
1348+
for (auto &MBB : MF) {
1349+
int SPAdj = 0;
1350+
if (!MBB.succ_empty()) {
1351+
// Get the SP adjustment for the end of MBB from the start of any of its
1352+
// successors. They should all be the same.
1353+
assert(all_of(MBB.successors(), [&MBB](const MachineBasicBlock *Succ) {
1354+
return Succ->getCallFrameSize() ==
1355+
(*MBB.succ_begin())->getCallFrameSize();
1356+
}));
1357+
const MachineBasicBlock &FirstSucc = **MBB.succ_begin();
1358+
SPAdj = TFI.alignSPAdjust(FirstSucc.getCallFrameSize());
1359+
if (TFI.getStackGrowthDirection() == TargetFrameLowering::StackGrowsUp)
1360+
SPAdj = -SPAdj;
1361+
}
1362+
1363+
replaceFrameIndicesBackward(&MBB, MF, SPAdj);
1364+
1365+
// We can't track the call frame size after call frame pseudos have been
1366+
// eliminated. Set it to zero everywhere to keep MachineVerifier happy.
1367+
MBB.setCallFrameSize(0);
1368+
}
1369+
}
1370+
13341371
/// replaceFrameIndices - Replace all MO_FrameIndex operands with physical
13351372
/// register references and actual offsets.
13361373
void PEI::replaceFrameIndices(MachineFunction &MF) {
1337-
const auto &ST = MF.getSubtarget();
1338-
const TargetFrameLowering &TFI = *ST.getFrameLowering();
1339-
if (!TFI.needsFrameIndexResolution(MF))
1340-
return;
1341-
1342-
const TargetRegisterInfo *TRI = ST.getRegisterInfo();
1343-
1344-
// Allow the target to determine this after knowing the frame size.
1345-
FrameIndexEliminationScavenging = (RS && !FrameIndexVirtualScavenging) ||
1346-
TRI->requiresFrameIndexReplacementScavenging(MF);
1374+
const TargetFrameLowering &TFI = *MF.getSubtarget().getFrameLowering();
13471375

13481376
for (auto &MBB : MF) {
13491377
int SPAdj = TFI.alignSPAdjust(MBB.getCallFrameSize());
@@ -1455,6 +1483,7 @@ void PEI::replaceFrameIndicesBackward(MachineBasicBlock *BB,
14551483

14561484
for (MachineInstr &MI : make_early_inc_range(reverse(*BB))) {
14571485
if (TII.isFrameInstr(MI)) {
1486+
SPAdj -= TII.getSPAdjust(MI);
14581487
TFI.eliminateCallFramePseudoInstr(MF, *BB, &MI);
14591488
continue;
14601489
}
@@ -1477,7 +1506,7 @@ void PEI::replaceFrameIndicesBackward(MachineBasicBlock *BB,
14771506
MachineBasicBlock::iterator Save;
14781507
if (LocalRS)
14791508
Save = std::next(LocalRS->getCurrentPosition());
1480-
bool Removed = TRI.eliminateFrameIndex(MI, SPAdj, i, RS);
1509+
bool Removed = TRI.eliminateFrameIndex(MI, SPAdj, i, LocalRS);
14811510
if (LocalRS)
14821511
LocalRS->skipTo(std::prev(Save));
14831512

@@ -1495,9 +1524,6 @@ void PEI::replaceFrameIndices(MachineBasicBlock *BB, MachineFunction &MF,
14951524
const TargetRegisterInfo &TRI = *MF.getSubtarget().getRegisterInfo();
14961525
const TargetFrameLowering *TFI = MF.getSubtarget().getFrameLowering();
14971526

1498-
if (TRI.supportsBackwardScavenger())
1499-
return replaceFrameIndicesBackward(BB, MF, SPAdj);
1500-
15011527
if (RS && FrameIndexEliminationScavenging)
15021528
RS->enterBasicBlock(*BB);
15031529

llvm/lib/Target/ARM/ARMBaseRegisterInfo.h

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -219,6 +219,8 @@ class ARMBaseRegisterInfo : public ARMGenRegisterInfo {
219219

220220
bool requiresFrameIndexScavenging(const MachineFunction &MF) const override;
221221

222+
bool supportsBackwardScavenger() const override { return true; }
223+
222224
bool requiresVirtualBaseRegisters(const MachineFunction &MF) const override;
223225

224226
bool eliminateFrameIndex(MachineBasicBlock::iterator II,

llvm/test/CodeGen/Thumb/emergency-spill-slot.ll

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -64,12 +64,12 @@ define void @simple_emergency_spill(i32 %n) {
6464
; CHECK-NEXT: .pad #8196
6565
; CHECK-NEXT: add sp, r7
6666
; CHECK-NEXT: add r0, sp, #4
67-
; CHECK-NEXT: ldr r1, .LCPI1_2
67+
; CHECK-NEXT: ldr r1, .LCPI1_3
6868
; CHECK-NEXT: add r1, sp
6969
; CHECK-NEXT: @APP
7070
; CHECK-NEXT: @NO_APP
7171
; CHECK-NEXT: str r0, [sp]
72-
; CHECK-NEXT: ldr r0, .LCPI1_3
72+
; CHECK-NEXT: ldr r0, .LCPI1_2
7373
; CHECK-NEXT: add r0, sp
7474
; CHECK-NEXT: str r5, [r0]
7575
; CHECK-NEXT: ldr r0, [sp]
@@ -85,9 +85,9 @@ define void @simple_emergency_spill(i32 %n) {
8585
; CHECK-NEXT: .LCPI1_1:
8686
; CHECK-NEXT: .long 8196 @ 0x2004
8787
; CHECK-NEXT: .LCPI1_2:
88-
; CHECK-NEXT: .long 4100 @ 0x1004
89-
; CHECK-NEXT: .LCPI1_3:
9088
; CHECK-NEXT: .long 5120 @ 0x1400
89+
; CHECK-NEXT: .LCPI1_3:
90+
; CHECK-NEXT: .long 4100 @ 0x1004
9191
entry:
9292
%x = alloca [1024 x i32], align 4
9393
%y = alloca [1024 x i32], align 4
@@ -124,12 +124,12 @@ define void @simple_emergency_spill_nor7(i32 %n) {
124124
; CHECK-NEXT: .pad #8196
125125
; CHECK-NEXT: add sp, r6
126126
; CHECK-NEXT: add r0, sp, #4
127-
; CHECK-NEXT: ldr r1, .LCPI2_2
127+
; CHECK-NEXT: ldr r1, .LCPI2_3
128128
; CHECK-NEXT: add r1, sp
129129
; CHECK-NEXT: @APP
130130
; CHECK-NEXT: @NO_APP
131131
; CHECK-NEXT: str r7, [sp]
132-
; CHECK-NEXT: ldr r7, .LCPI2_3
132+
; CHECK-NEXT: ldr r7, .LCPI2_2
133133
; CHECK-NEXT: add r7, sp
134134
; CHECK-NEXT: str r5, [r7]
135135
; CHECK-NEXT: ldr r7, [sp]
@@ -145,9 +145,9 @@ define void @simple_emergency_spill_nor7(i32 %n) {
145145
; CHECK-NEXT: .LCPI2_1:
146146
; CHECK-NEXT: .long 8196 @ 0x2004
147147
; CHECK-NEXT: .LCPI2_2:
148-
; CHECK-NEXT: .long 4100 @ 0x1004
149-
; CHECK-NEXT: .LCPI2_3:
150148
; CHECK-NEXT: .long 5120 @ 0x1400
149+
; CHECK-NEXT: .LCPI2_3:
150+
; CHECK-NEXT: .long 4100 @ 0x1004
151151
entry:
152152
%x = alloca [1024 x i32], align 4
153153
%y = alloca [1024 x i32], align 4

0 commit comments

Comments
 (0)