Skip to content

Commit 45b3ddc

Browse files
committed
[MachineCopyPropagation] Refactor copy tracking into a class. NFC
This is a bit easier to follow than handling the copy and src maps directly in the pass, and will make upcoming changes to how this is done easier to follow. llvm-svn: 342703
1 parent 7b1c816 commit 45b3ddc

File tree

1 file changed

+133
-99
lines changed

1 file changed

+133
-99
lines changed

llvm/lib/CodeGen/MachineCopyPropagation.cpp

Lines changed: 133 additions & 99 deletions
Original file line numberDiff line numberDiff line change
@@ -74,9 +74,115 @@ DEBUG_COUNTER(FwdCounter, "machine-cp-fwd",
7474

7575
namespace {
7676

77-
using RegList = SmallVector<unsigned, 4>;
78-
using SourceMap = DenseMap<unsigned, RegList>;
79-
using Reg2MIMap = DenseMap<unsigned, MachineInstr *>;
77+
class CopyTracker {
78+
using RegList = SmallVector<unsigned, 4>;
79+
using SourceMap = DenseMap<unsigned, RegList>;
80+
using Reg2MIMap = DenseMap<unsigned, MachineInstr *>;
81+
82+
/// Def -> available copies map.
83+
Reg2MIMap AvailCopyMap;
84+
85+
/// Def -> copies map.
86+
Reg2MIMap CopyMap;
87+
88+
/// Src -> Def map
89+
SourceMap SrcMap;
90+
91+
public:
92+
/// Mark all of the given registers and their subregisters as unavailable for
93+
/// copying.
94+
void markRegsUnavailable(const RegList &Regs, const TargetRegisterInfo &TRI) {
95+
for (unsigned Reg : Regs) {
96+
// Source of copy is no longer available for propagation.
97+
for (MCSubRegIterator SR(Reg, &TRI, true); SR.isValid(); ++SR)
98+
AvailCopyMap.erase(*SR);
99+
}
100+
}
101+
102+
/// Remove any entry in the tracker's copy maps that is marked clobbered in \p
103+
/// RegMask. The map will typically have a lot fewer entries than the regmask
104+
/// clobbers, so this is more efficient than iterating the clobbered registers
105+
/// and calling ClobberRegister() on them.
106+
void removeClobberedRegs(const MachineOperand &RegMask,
107+
const TargetRegisterInfo &TRI) {
108+
auto RemoveFromMap = [&RegMask](Reg2MIMap &Map) {
109+
for (Reg2MIMap::iterator I = Map.begin(), E = Map.end(), Next; I != E;
110+
I = Next) {
111+
Next = std::next(I);
112+
if (RegMask.clobbersPhysReg(I->first))
113+
Map.erase(I);
114+
}
115+
};
116+
RemoveFromMap(AvailCopyMap);
117+
RemoveFromMap(CopyMap);
118+
119+
for (SourceMap::iterator I = SrcMap.begin(), E = SrcMap.end(), Next; I != E;
120+
I = Next) {
121+
Next = std::next(I);
122+
if (RegMask.clobbersPhysReg(I->first)) {
123+
markRegsUnavailable(I->second, TRI);
124+
SrcMap.erase(I);
125+
}
126+
}
127+
}
128+
129+
/// Clobber a single register, removing it from the tracker's copy maps.
130+
void clobberRegister(unsigned Reg, const TargetRegisterInfo &TRI) {
131+
for (MCRegAliasIterator AI(Reg, &TRI, true); AI.isValid(); ++AI) {
132+
CopyMap.erase(*AI);
133+
AvailCopyMap.erase(*AI);
134+
135+
SourceMap::iterator SI = SrcMap.find(*AI);
136+
if (SI != SrcMap.end()) {
137+
markRegsUnavailable(SI->second, TRI);
138+
SrcMap.erase(SI);
139+
}
140+
}
141+
}
142+
143+
/// Add this copy's registers into the tracker's copy maps.
144+
void trackCopy(MachineInstr *Copy, const TargetRegisterInfo &TRI) {
145+
assert(Copy->isCopy() && "Tracking non-copy?");
146+
147+
unsigned Def = Copy->getOperand(0).getReg();
148+
unsigned Src = Copy->getOperand(1).getReg();
149+
150+
// Remember Def is defined by the copy.
151+
for (MCSubRegIterator SR(Def, &TRI, /*IncludeSelf=*/true); SR.isValid();
152+
++SR) {
153+
CopyMap[*SR] = Copy;
154+
AvailCopyMap[*SR] = Copy;
155+
}
156+
157+
// Remember source that's copied to Def. Once it's clobbered, then
158+
// it's no longer available for copy propagation.
159+
RegList &DestList = SrcMap[Src];
160+
if (!is_contained(DestList, Def))
161+
DestList.push_back(Def);
162+
}
163+
164+
bool hasAvailableCopies() { return !AvailCopyMap.empty(); }
165+
166+
MachineInstr *findAvailCopy(unsigned Reg) {
167+
auto CI = AvailCopyMap.find(Reg);
168+
if (CI != AvailCopyMap.end())
169+
return CI->second;
170+
return nullptr;
171+
}
172+
173+
MachineInstr *findCopy(unsigned Reg) {
174+
auto CI = CopyMap.find(Reg);
175+
if (CI != CopyMap.end())
176+
return CI->second;
177+
return nullptr;
178+
}
179+
180+
void clear() {
181+
AvailCopyMap.clear();
182+
CopyMap.clear();
183+
SrcMap.clear();
184+
}
185+
};
80186

81187
class MachineCopyPropagation : public MachineFunctionPass {
82188
const TargetRegisterInfo *TRI;
@@ -115,14 +221,7 @@ class MachineCopyPropagation : public MachineFunctionPass {
115221
/// Candidates for deletion.
116222
SmallSetVector<MachineInstr *, 8> MaybeDeadCopies;
117223

118-
/// Def -> available copies map.
119-
Reg2MIMap AvailCopyMap;
120-
121-
/// Def -> copies map.
122-
Reg2MIMap CopyMap;
123-
124-
/// Src -> Def map
125-
SourceMap SrcMap;
224+
CopyTracker Tracker;
126225

127226
bool Changed;
128227
};
@@ -136,54 +235,13 @@ char &llvm::MachineCopyPropagationID = MachineCopyPropagation::ID;
136235
INITIALIZE_PASS(MachineCopyPropagation, DEBUG_TYPE,
137236
"Machine Copy Propagation Pass", false, false)
138237

139-
/// Remove any entry in \p Map where the register is a subregister or equal to
140-
/// a register contained in \p Regs.
141-
static void removeRegsFromMap(Reg2MIMap &Map, const RegList &Regs,
142-
const TargetRegisterInfo &TRI) {
143-
for (unsigned Reg : Regs) {
144-
// Source of copy is no longer available for propagation.
145-
for (MCSubRegIterator SR(Reg, &TRI, true); SR.isValid(); ++SR)
146-
Map.erase(*SR);
147-
}
148-
}
149-
150-
/// Remove any entry in \p Map that is marked clobbered in \p RegMask.
151-
/// The map will typically have a lot fewer entries than the regmask clobbers,
152-
/// so this is more efficient than iterating the clobbered registers and calling
153-
/// ClobberRegister() on them.
154-
static void removeClobberedRegsFromMap(Reg2MIMap &Map,
155-
const MachineOperand &RegMask) {
156-
for (Reg2MIMap::iterator I = Map.begin(), E = Map.end(), Next; I != E;
157-
I = Next) {
158-
Next = std::next(I);
159-
unsigned Reg = I->first;
160-
if (RegMask.clobbersPhysReg(Reg))
161-
Map.erase(I);
162-
}
163-
}
164-
165-
void MachineCopyPropagation::ClobberRegister(unsigned Reg) {
166-
for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
167-
CopyMap.erase(*AI);
168-
AvailCopyMap.erase(*AI);
169-
170-
SourceMap::iterator SI = SrcMap.find(*AI);
171-
if (SI != SrcMap.end()) {
172-
removeRegsFromMap(AvailCopyMap, SI->second, *TRI);
173-
SrcMap.erase(SI);
174-
}
175-
}
176-
}
177-
178238
void MachineCopyPropagation::ReadRegister(unsigned Reg) {
179239
// If 'Reg' is defined by a copy, the copy is no longer a candidate
180240
// for elimination.
181241
for (MCRegAliasIterator AI(Reg, TRI, true); AI.isValid(); ++AI) {
182-
Reg2MIMap::iterator CI = CopyMap.find(*AI);
183-
if (CI != CopyMap.end()) {
184-
LLVM_DEBUG(dbgs() << "MCP: Copy is used - not dead: ";
185-
CI->second->dump());
186-
MaybeDeadCopies.remove(CI->second);
242+
if (MachineInstr *Copy = Tracker.findCopy(*AI)) {
243+
LLVM_DEBUG(dbgs() << "MCP: Copy is used - not dead: "; Copy->dump());
244+
MaybeDeadCopies.remove(Copy);
187245
}
188246
}
189247
}
@@ -219,15 +277,14 @@ bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, unsigned Src,
219277
return false;
220278

221279
// Search for an existing copy.
222-
Reg2MIMap::iterator CI = AvailCopyMap.find(Def);
223-
if (CI == AvailCopyMap.end())
280+
MachineInstr *PrevCopy = Tracker.findAvailCopy(Def);
281+
if (!PrevCopy)
224282
return false;
225283

226284
// Check that the existing copy uses the correct sub registers.
227-
MachineInstr &PrevCopy = *CI->second;
228-
if (PrevCopy.getOperand(0).isDead())
285+
if (PrevCopy->getOperand(0).isDead())
229286
return false;
230-
if (!isNopCopy(PrevCopy, Src, Def, TRI))
287+
if (!isNopCopy(*PrevCopy, Src, Def, TRI))
231288
return false;
232289

233290
LLVM_DEBUG(dbgs() << "MCP: copy is a NOP, removing: "; Copy.dump());
@@ -238,7 +295,7 @@ bool MachineCopyPropagation::eraseIfRedundant(MachineInstr &Copy, unsigned Src,
238295
unsigned CopyDef = Copy.getOperand(0).getReg();
239296
assert(CopyDef == Src || CopyDef == Def);
240297
for (MachineInstr &MI :
241-
make_range(PrevCopy.getIterator(), Copy.getIterator()))
298+
make_range(PrevCopy->getIterator(), Copy.getIterator()))
242299
MI.clearRegisterKills(CopyDef, TRI);
243300

244301
Copy.eraseFromParent();
@@ -314,7 +371,7 @@ bool MachineCopyPropagation::hasImplicitOverlap(const MachineInstr &MI,
314371
/// Look for available copies whose destination register is used by \p MI and
315372
/// replace the use in \p MI with the copy's source register.
316373
void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
317-
if (AvailCopyMap.empty())
374+
if (!Tracker.hasAvailableCopies())
318375
return;
319376

320377
// Look for non-tied explicit vreg uses that have an active COPY
@@ -341,13 +398,12 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
341398
if (!MOUse.isRenamable())
342399
continue;
343400

344-
auto CI = AvailCopyMap.find(MOUse.getReg());
345-
if (CI == AvailCopyMap.end())
401+
MachineInstr *Copy = Tracker.findAvailCopy(MOUse.getReg());
402+
if (!Copy)
346403
continue;
347404

348-
MachineInstr &Copy = *CI->second;
349-
unsigned CopyDstReg = Copy.getOperand(0).getReg();
350-
const MachineOperand &CopySrc = Copy.getOperand(1);
405+
unsigned CopyDstReg = Copy->getOperand(0).getReg();
406+
const MachineOperand &CopySrc = Copy->getOperand(1);
351407
unsigned CopySrcReg = CopySrc.getReg();
352408

353409
// FIXME: Don't handle partial uses of wider COPYs yet.
@@ -362,7 +418,7 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
362418
if (MRI->isReserved(CopySrcReg) && !MRI->isConstantPhysReg(CopySrcReg))
363419
continue;
364420

365-
if (!isForwardableRegClassCopy(Copy, MI, OpIdx))
421+
if (!isForwardableRegClassCopy(*Copy, MI, OpIdx))
366422
continue;
367423

368424
if (hasImplicitOverlap(MI, MOUse))
@@ -376,7 +432,7 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
376432

377433
LLVM_DEBUG(dbgs() << "MCP: Replacing " << printReg(MOUse.getReg(), TRI)
378434
<< "\n with " << printReg(CopySrcReg, TRI)
379-
<< "\n in " << MI << " from " << Copy);
435+
<< "\n in " << MI << " from " << *Copy);
380436

381437
MOUse.setReg(CopySrcReg);
382438
if (!CopySrc.isRenamable())
@@ -386,7 +442,7 @@ void MachineCopyPropagation::forwardUses(MachineInstr &MI) {
386442

387443
// Clear kill markers that may have been invalidated.
388444
for (MachineInstr &KMI :
389-
make_range(Copy.getIterator(), std::next(MI.getIterator())))
445+
make_range(Copy->getIterator(), std::next(MI.getIterator())))
390446
KMI.clearRegisterKills(CopySrcReg, TRI);
391447

392448
++NumCopyForwards;
@@ -459,28 +515,17 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) {
459515
// %xmm2 = copy %xmm0
460516
// ...
461517
// %xmm2 = copy %xmm9
462-
ClobberRegister(Def);
518+
Tracker.clobberRegister(Def, *TRI);
463519
for (const MachineOperand &MO : MI->implicit_operands()) {
464520
if (!MO.isReg() || !MO.isDef())
465521
continue;
466522
unsigned Reg = MO.getReg();
467523
if (!Reg)
468524
continue;
469-
ClobberRegister(Reg);
470-
}
471-
472-
// Remember Def is defined by the copy.
473-
for (MCSubRegIterator SR(Def, TRI, /*IncludeSelf=*/true); SR.isValid();
474-
++SR) {
475-
CopyMap[*SR] = MI;
476-
AvailCopyMap[*SR] = MI;
525+
Tracker.clobberRegister(Reg, *TRI);
477526
}
478527

479-
// Remember source that's copied to Def. Once it's clobbered, then
480-
// it's no longer available for copy propagation.
481-
RegList &DestList = SrcMap[Src];
482-
if (!is_contained(DestList, Def))
483-
DestList.push_back(Def);
528+
Tracker.trackCopy(MI, *TRI);
484529

485530
continue;
486531
}
@@ -494,7 +539,7 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) {
494539
// later.
495540
if (MO.isTied())
496541
ReadRegister(Reg);
497-
ClobberRegister(Reg);
542+
Tracker.clobberRegister(Reg, *TRI);
498543
}
499544

500545
forwardUses(*MI);
@@ -549,21 +594,12 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) {
549594
++NumDeletes;
550595
}
551596

552-
removeClobberedRegsFromMap(AvailCopyMap, *RegMask);
553-
removeClobberedRegsFromMap(CopyMap, *RegMask);
554-
for (SourceMap::iterator I = SrcMap.begin(), E = SrcMap.end(), Next;
555-
I != E; I = Next) {
556-
Next = std::next(I);
557-
if (RegMask->clobbersPhysReg(I->first)) {
558-
removeRegsFromMap(AvailCopyMap, I->second, *TRI);
559-
SrcMap.erase(I);
560-
}
561-
}
597+
Tracker.removeClobberedRegs(*RegMask, *TRI);
562598
}
563599

564600
// Any previous copy definition or reading the Defs is no longer available.
565601
for (unsigned Reg : Defs)
566-
ClobberRegister(Reg);
602+
Tracker.clobberRegister(Reg, *TRI);
567603
}
568604

569605
// If MBB doesn't have successors, delete the copies whose defs are not used.
@@ -581,9 +617,7 @@ void MachineCopyPropagation::CopyPropagateBlock(MachineBasicBlock &MBB) {
581617
}
582618

583619
MaybeDeadCopies.clear();
584-
AvailCopyMap.clear();
585-
CopyMap.clear();
586-
SrcMap.clear();
620+
Tracker.clear();
587621
}
588622

589623
bool MachineCopyPropagation::runOnMachineFunction(MachineFunction &MF) {

0 commit comments

Comments
 (0)