Skip to content

Commit d5f3b3b

Browse files
authored
[RegScavenger] Simplify state tracking for backwards scavenging (#71202)
Track the live register state immediately before, instead of after, MBBI. This makes it simple to track the state at the start or end of a basic block without a separate (and poorly named) Tracking flag. This changes the API of the backward(MachineBasicBlock::iterator I) method, which now recedes to the state just before, instead of just after, *I. Some clients are simplified by this change. There is one small functional change shown in the lit tests where multiple spilled registers all need to be reloaded before the same instruction. The reloads will now be inserted in the opposite order. This should not affect correctness.
1 parent e6a94dc commit d5f3b3b

File tree

11 files changed

+19
-52
lines changed

11 files changed

+19
-52
lines changed

llvm/include/llvm/CodeGen/RegisterScavenging.h

Lines changed: 1 addition & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -38,9 +38,6 @@ class RegScavenger {
3838
MachineBasicBlock *MBB = nullptr;
3939
MachineBasicBlock::iterator MBBI;
4040

41-
/// True if RegScavenger is currently tracking the liveness of registers.
42-
bool Tracking = false;
43-
4441
/// Information on scavenged registers (held in a spill slot).
4542
struct ScavengedInfo {
4643
ScavengedInfo(int FI = -1) : FrameIndex(FI) {}
@@ -95,21 +92,12 @@ class RegScavenger {
9592
/// method gives precise results even in the absence of kill flags.
9693
void backward();
9794

98-
/// Call backward() as long as the internal iterator does not point to \p I.
95+
/// Call backward() to update internal register state to just before \p *I.
9996
void backward(MachineBasicBlock::iterator I) {
10097
while (MBBI != I)
10198
backward();
10299
}
103100

104-
/// Move the internal MBB iterator but do not update register states.
105-
void skipTo(MachineBasicBlock::iterator I) {
106-
if (I == MachineBasicBlock::iterator(nullptr))
107-
Tracking = false;
108-
MBBI = I;
109-
}
110-
111-
MachineBasicBlock::iterator getCurrentPosition() const { return MBBI; }
112-
113101
/// Return if a specific register is currently used.
114102
bool isRegUsed(Register Reg, bool includeReserved = true) const;
115103

llvm/lib/CodeGen/PrologEpilogInserter.cpp

Lines changed: 1 addition & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -1499,7 +1499,7 @@ void PEI::replaceFrameIndicesBackward(MachineBasicBlock *BB,
14991499

15001500
// Step backwards to get the liveness state at (immedately after) MI.
15011501
if (LocalRS)
1502-
LocalRS->backward(MI);
1502+
LocalRS->backward(I);
15031503

15041504
bool RemovedMI = false;
15051505
for (const auto &[Idx, Op] : enumerate(MI.operands())) {
@@ -1515,11 +1515,6 @@ void PEI::replaceFrameIndicesBackward(MachineBasicBlock *BB,
15151515
break;
15161516
}
15171517

1518-
// Refresh the scavenger's internal iterator in case MI was removed or more
1519-
// instructions were inserted after it.
1520-
if (LocalRS)
1521-
LocalRS->skipTo(std::prev(I));
1522-
15231518
if (!RemovedMI)
15241519
--I;
15251520
}

llvm/lib/CodeGen/RegisterScavenging.cpp

Lines changed: 9 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -65,30 +65,22 @@ void RegScavenger::init(MachineBasicBlock &MBB) {
6565
SI.Reg = 0;
6666
SI.Restore = nullptr;
6767
}
68-
69-
Tracking = false;
7068
}
7169

7270
void RegScavenger::enterBasicBlock(MachineBasicBlock &MBB) {
7371
init(MBB);
7472
LiveUnits.addLiveIns(MBB);
73+
MBBI = MBB.begin();
7574
}
7675

7776
void RegScavenger::enterBasicBlockEnd(MachineBasicBlock &MBB) {
7877
init(MBB);
7978
LiveUnits.addLiveOuts(MBB);
80-
81-
// Move internal iterator at the last instruction of the block.
82-
if (!MBB.empty()) {
83-
MBBI = std::prev(MBB.end());
84-
Tracking = true;
85-
}
79+
MBBI = MBB.end();
8680
}
8781

8882
void RegScavenger::backward() {
89-
assert(Tracking && "Must be tracking to determine kills and defs");
90-
91-
const MachineInstr &MI = *MBBI;
83+
const MachineInstr &MI = *--MBBI;
9284
LiveUnits.stepBackward(MI);
9385

9486
// Expire scavenge spill frameindex uses.
@@ -98,12 +90,6 @@ void RegScavenger::backward() {
9890
I.Restore = nullptr;
9991
}
10092
}
101-
102-
if (MBBI == MBB->begin()) {
103-
MBBI = MachineBasicBlock::iterator(nullptr);
104-
Tracking = false;
105-
} else
106-
--MBBI;
10793
}
10894

10995
bool RegScavenger::isRegUsed(Register Reg, bool includeReserved) const {
@@ -317,9 +303,8 @@ Register RegScavenger::scavengeRegisterBackwards(const TargetRegisterClass &RC,
317303
// Find the register whose use is furthest away.
318304
MachineBasicBlock::iterator UseMI;
319305
ArrayRef<MCPhysReg> AllocationOrder = RC.getRawAllocationOrder(MF);
320-
std::pair<MCPhysReg, MachineBasicBlock::iterator> P =
321-
findSurvivorBackwards(*MRI, MBBI, To, LiveUnits, AllocationOrder,
322-
RestoreAfter);
306+
std::pair<MCPhysReg, MachineBasicBlock::iterator> P = findSurvivorBackwards(
307+
*MRI, std::prev(MBBI), To, LiveUnits, AllocationOrder, RestoreAfter);
323308
MCPhysReg Reg = P.first;
324309
MachineBasicBlock::iterator SpillBefore = P.second;
325310
// Found an available register?
@@ -334,9 +319,8 @@ Register RegScavenger::scavengeRegisterBackwards(const TargetRegisterClass &RC,
334319

335320
assert(Reg != 0 && "No register left to scavenge!");
336321

337-
MachineBasicBlock::iterator ReloadAfter =
338-
RestoreAfter ? std::next(MBBI) : MBBI;
339-
MachineBasicBlock::iterator ReloadBefore = std::next(ReloadAfter);
322+
MachineBasicBlock::iterator ReloadBefore =
323+
RestoreAfter ? std::next(MBBI) : MBBI;
340324
if (ReloadBefore != MBB.end())
341325
LLVM_DEBUG(dbgs() << "Reload before: " << *ReloadBefore << '\n');
342326
ScavengedInfo &Scavenged = spill(Reg, RC, SPAdj, SpillBefore, ReloadBefore);
@@ -414,9 +398,9 @@ static bool scavengeFrameVirtualRegsInBlock(MachineRegisterInfo &MRI,
414398
unsigned InitialNumVirtRegs = MRI.getNumVirtRegs();
415399
bool NextInstructionReadsVReg = false;
416400
for (MachineBasicBlock::iterator I = MBB.end(); I != MBB.begin(); ) {
417-
--I;
418-
// Move RegScavenger to the position between *I and *std::next(I).
401+
// Move RegScavenger to the position between *std::prev(I) and *I.
419402
RS.backward(I);
403+
--I;
420404

421405
// Look for unassigned vregs in the uses of *std::next(I).
422406
if (NextInstructionReadsVReg) {

llvm/lib/Target/AArch64/AArch64FrameLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -3426,7 +3426,7 @@ void AArch64FrameLowering::processFunctionBeforeFrameFinalized(
34263426
// function.
34273427
DebugLoc DL;
34283428
RS->enterBasicBlockEnd(MBB);
3429-
RS->backward(std::prev(MBBI));
3429+
RS->backward(MBBI);
34303430
Register DstReg = RS->FindUnusedReg(&AArch64::GPR64commonRegClass);
34313431
assert(DstReg && "There must be a free register after frame setup");
34323432
BuildMI(MBB, MBBI, DL, TII.get(AArch64::MOVi64imm), DstReg).addImm(-2);

llvm/lib/Target/AArch64/AArch64SpeculationHardening.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -299,7 +299,7 @@ bool AArch64SpeculationHardening::instrumentControlFlow(
299299
if (I == MBB.begin())
300300
RS.enterBasicBlock(MBB);
301301
else
302-
RS.backward(std::prev(I));
302+
RS.backward(I);
303303
// FIXME: The below just finds *a* unused register. Maybe code could be
304304
// optimized more if this looks for the register that isn't used for the
305305
// longest time around this place, to enable more scheduling freedom. Not

llvm/lib/Target/AMDGPU/SIFrameLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1376,7 +1376,7 @@ void SIFrameLowering::processFunctionBeforeFrameFinalized(
13761376
TRI->isAGPR(MRI, VReg))) {
13771377
assert(RS != nullptr);
13781378
RS->enterBasicBlockEnd(MBB);
1379-
RS->backward(MI);
1379+
RS->backward(std::next(MI.getIterator()));
13801380
TRI->eliminateFrameIndex(MI, 0, FIOp, RS);
13811381
SpillFIs.set(FI);
13821382
continue;

llvm/lib/Target/AMDGPU/SIInstrInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -681,7 +681,7 @@ static void indirectCopyToAGPR(const SIInstrInfo &TII,
681681
}
682682

683683
RS.enterBasicBlockEnd(MBB);
684-
RS.backward(MI);
684+
RS.backward(std::next(MI));
685685

686686
// Ideally we want to have three registers for a long reg_sequence copy
687687
// to hide 2 waitstates between v_mov_b32 and accvgpr_write.

llvm/lib/Target/Mips/Mips16InstrInfo.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -341,7 +341,7 @@ unsigned Mips16InstrInfo::loadImmediate(unsigned FrameReg, int64_t Imm,
341341
int SpReg = 0;
342342

343343
rs.enterBasicBlockEnd(MBB);
344-
rs.backward(II);
344+
rs.backward(std::next(II));
345345
//
346346
// We need to know which registers can be used, in the case where there
347347
// are not enough free registers. We exclude all registers that

llvm/lib/Target/PowerPC/PPCFrameLowering.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -466,7 +466,7 @@ PPCFrameLowering::findScratchRegister(MachineBasicBlock *MBB,
466466
RS.enterBasicBlock(*MBB);
467467
} else {
468468
RS.enterBasicBlockEnd(*MBB);
469-
RS.backward(std::prev(MBBI));
469+
RS.backward(MBBI);
470470
}
471471
} else {
472472
// The scratch register will be used at the start of the block.

llvm/lib/Target/RISCV/RISCVMakeCompressible.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -271,7 +271,7 @@ static Register analyzeCompressibleUses(MachineInstr &FirstMI,
271271

272272
RegScavenger RS;
273273
RS.enterBasicBlockEnd(MBB);
274-
RS.backward(MIs.back()->getIterator());
274+
RS.backward(std::next(MIs.back()->getIterator()));
275275
return RS.scavengeRegisterBackwards(*RCToScavenge, FirstMI.getIterator(),
276276
/*RestoreAfter=*/false, /*SPAdj=*/0,
277277
/*AllowSpill=*/false);

llvm/test/CodeGen/XCore/scavenging.ll

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -87,8 +87,8 @@ declare void @g(ptr, ptr)
8787
; CHECK: ldw r2, cp[[[INDEX4]]]
8888
; r4 & r5 used by InsertSPConstInst() to emit STW_l3r instruction.
8989
; CHECK: stw r0, r1[r2]
90-
; CHECK: ldw r2, sp[0]
9190
; CHECK: ldw r1, sp[1]
91+
; CHECK: ldw r2, sp[0]
9292
; CHECK: ldaw r0, sp[0]
9393
; scavenge r2 using SR spill slot
9494
; CHECK: stw r2, sp[1]

0 commit comments

Comments
 (0)