Skip to content

Commit aa2d0fb

Browse files
committed
[MC] Add MCRegisterInfo::regunits for iteration over register units
Reviewed By: foad Differential Revision: https://reviews.llvm.org/D152098
1 parent 6edfa61 commit aa2d0fb

39 files changed

+219
-221
lines changed

llvm/include/llvm/CodeGen/LiveIntervals.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -417,8 +417,8 @@ class VirtRegMap;
417417
/// method can result in inconsistent liveness tracking if multiple phyical
418418
/// registers share a regunit, and should be used cautiously.
419419
void removeAllRegUnitsForPhysReg(MCRegister Reg) {
420-
for (MCRegUnitIterator Units(Reg, TRI); Units.isValid(); ++Units)
421-
removeRegUnit(*Units);
420+
for (MCRegUnit Unit : TRI->regunits(Reg))
421+
removeRegUnit(Unit);
422422
}
423423

424424
/// Remove value numbers and related live segments starting at position

llvm/include/llvm/CodeGen/LiveRegUnits.h

Lines changed: 6 additions & 6 deletions
Original file line numberDiff line numberDiff line change
@@ -84,8 +84,8 @@ class LiveRegUnits {
8484

8585
/// Adds register units covered by physical register \p Reg.
8686
void addReg(MCPhysReg Reg) {
87-
for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit)
88-
Units.set(*Unit);
87+
for (MCRegUnit Unit : TRI->regunits(Reg))
88+
Units.set(Unit);
8989
}
9090

9191
/// Adds register units covered by physical register \p Reg that are
@@ -100,8 +100,8 @@ class LiveRegUnits {
100100

101101
/// Removes all register units covered by physical register \p Reg.
102102
void removeReg(MCPhysReg Reg) {
103-
for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit)
104-
Units.reset(*Unit);
103+
for (MCRegUnit Unit : TRI->regunits(Reg))
104+
Units.reset(Unit);
105105
}
106106

107107
/// Removes register units not preserved by the regmask \p RegMask.
@@ -114,8 +114,8 @@ class LiveRegUnits {
114114

115115
/// Returns true if no part of physical register \p Reg is live.
116116
bool available(MCPhysReg Reg) const {
117-
for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
118-
if (Units.test(*Unit))
117+
for (MCRegUnit Unit : TRI->regunits(Reg)) {
118+
if (Units.test(Unit))
119119
return false;
120120
}
121121
return true;

llvm/include/llvm/CodeGen/TargetRegisterInfo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -428,8 +428,8 @@ class TargetRegisterInfo : public MCRegisterInfo {
428428

429429
/// Returns true if Reg contains RegUnit.
430430
bool hasRegUnit(MCRegister Reg, Register RegUnit) const {
431-
for (MCRegUnitIterator Units(Reg, this); Units.isValid(); ++Units)
432-
if (Register(*Units) == RegUnit)
431+
for (MCRegUnit Unit : regunits(Reg))
432+
if (Register(Unit) == RegUnit)
433433
return true;
434434
return false;
435435
}

llvm/include/llvm/MC/MCRegister.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,15 @@ namespace llvm {
2020
/// but not necessarily virtual registers.
2121
using MCPhysReg = uint16_t;
2222

23+
/// Register units are used to compute register aliasing. Every register has at
24+
/// least one register unit, but it can have more. Two registers overlap if and
25+
/// only if they have a common register unit.
26+
///
27+
/// A target with a complicated sub-register structure will typically have many
28+
/// fewer register units than actual registers. MCRI::getNumRegUnits() returns
29+
/// the number of register units in the target.
30+
using MCRegUnit = unsigned;
31+
2332
/// Wrapper class representing physical registers. Should be passed by value.
2433
class MCRegister {
2534
friend hash_code hash_value(const MCRegister &);

llvm/include/llvm/MC/MCRegisterInfo.h

Lines changed: 25 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -27,6 +27,7 @@
2727

2828
namespace llvm {
2929

30+
class MCRegUnitIterator;
3031
class MCSubRegIterator;
3132
class MCSuperRegIterator;
3233

@@ -253,6 +254,9 @@ class MCRegisterInfo {
253254
iterator_range<MCSuperRegIterator>>
254255
sub_and_superregs_inclusive(MCRegister Reg) const;
255256

257+
/// Returns an iterator range over all regunits for \p Reg.
258+
iterator_range<MCRegUnitIterator> regunits(MCRegister Reg) const;
259+
256260
// These iterators are allowed to sub-class DiffListIterator and access
257261
// internal list pointers.
258262
friend class MCSubRegIterator;
@@ -615,23 +619,19 @@ inline bool MCRegisterInfo::isSuperRegister(MCRegister RegA, MCRegister RegB) co
615619
// Register Units
616620
//===----------------------------------------------------------------------===//
617621

618-
// Register units are used to compute register aliasing. Every register has at
619-
// least one register unit, but it can have more. Two registers overlap if and
620-
// only if they have a common register unit.
621-
//
622-
// A target with a complicated sub-register structure will typically have many
623-
// fewer register units than actual registers. MCRI::getNumRegUnits() returns
624-
// the number of register units in the target.
625-
626622
// MCRegUnitIterator enumerates a list of register units for Reg. The list is
627623
// in ascending numerical order.
628-
class MCRegUnitIterator : public MCRegisterInfo::DiffListIterator {
624+
class MCRegUnitIterator
625+
: public iterator_adaptor_base<MCRegUnitIterator,
626+
MCRegisterInfo::DiffListIterator,
627+
std::forward_iterator_tag, const MCRegUnit> {
629628
// The value must be kept in sync with RegisterInfoEmitter.cpp.
630629
static constexpr unsigned RegUnitBits = 12;
630+
// Cache the current value, so that we can return a reference to it.
631+
MCRegUnit Val;
631632

632633
public:
633-
/// MCRegUnitIterator - Create an iterator that traverses the register units
634-
/// in Reg.
634+
/// Constructs an end iterator.
635635
MCRegUnitIterator() = default;
636636

637637
MCRegUnitIterator(MCRegister Reg, const MCRegisterInfo *MCRI) {
@@ -641,13 +641,20 @@ class MCRegUnitIterator : public MCRegisterInfo::DiffListIterator {
641641
unsigned RU = MCRI->get(Reg).RegUnits;
642642
unsigned FirstRU = RU & ((1u << RegUnitBits) - 1);
643643
unsigned Offset = RU >> RegUnitBits;
644-
init(FirstRU, MCRI->DiffLists + Offset);
644+
I.init(FirstRU, MCRI->DiffLists + Offset);
645+
Val = MCRegUnit(*I);
645646
}
646647

648+
const MCRegUnit &operator*() const { return Val; }
649+
650+
using iterator_adaptor_base::operator++;
647651
MCRegUnitIterator &operator++() {
648-
MCRegisterInfo::DiffListIterator::operator++();
652+
Val = MCRegUnit(*++I);
649653
return *this;
650654
}
655+
656+
/// Returns true if this iterator is not yet at the end.
657+
bool isValid() const { return I.isValid(); }
651658
};
652659

653660
/// MCRegUnitMaskIterator enumerates a list of register units and their
@@ -810,6 +817,11 @@ MCRegisterInfo::sub_and_superregs_inclusive(MCRegister Reg) const {
810817
return concat<const MCPhysReg>(subregs_inclusive(Reg), superregs(Reg));
811818
}
812819

820+
inline iterator_range<MCRegUnitIterator>
821+
MCRegisterInfo::regunits(MCRegister Reg) const {
822+
return make_range({Reg, this}, MCRegUnitIterator());
823+
}
824+
813825
} // end namespace llvm
814826

815827
#endif // LLVM_MC_MCREGISTERINFO_H

llvm/lib/CodeGen/AsmPrinter/DwarfDebug.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -709,8 +709,8 @@ static void interpretValues(const MachineInstr *CurMI,
709709
for (auto &FwdReg : ForwardedRegWorklist)
710710
if (TRI.regsOverlap(FwdReg.first, MO.getReg()))
711711
Defs.insert(FwdReg.first);
712-
for (MCRegUnitIterator Units(MO.getReg(), &TRI); Units.isValid(); ++Units)
713-
NewClobberedRegUnits.insert(*Units);
712+
for (MCRegUnit Unit : TRI.regunits(MO.getReg()))
713+
NewClobberedRegUnits.insert(Unit);
714714
}
715715
}
716716
};

llvm/lib/CodeGen/BreakFalseDeps.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -124,9 +124,9 @@ bool BreakFalseDeps::pickBestRegisterForUndef(MachineInstr *MI, unsigned OpIdx,
124124
MCRegister OriginalReg = MO.getReg().asMCReg();
125125

126126
// Update only undef operands that have reg units that are mapped to one root.
127-
for (MCRegUnitIterator Unit(OriginalReg, TRI); Unit.isValid(); ++Unit) {
127+
for (MCRegUnit Unit : TRI->regunits(OriginalReg)) {
128128
unsigned NumRoots = 0;
129-
for (MCRegUnitRootIterator Root(*Unit, TRI); Root.isValid(); ++Root) {
129+
for (MCRegUnitRootIterator Root(Unit, TRI); Root.isValid(); ++Root) {
130130
NumRoots++;
131131
if (NumRoots > 1)
132132
return false;

llvm/lib/CodeGen/EarlyIfConversion.cpp

Lines changed: 7 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -263,9 +263,8 @@ bool SSAIfConv::InstrDependenciesAllowIfConv(MachineInstr *I) {
263263

264264
// Remember clobbered regunits.
265265
if (MO.isDef() && Reg.isPhysical())
266-
for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
267-
++Units)
268-
ClobberedRegUnits.set(*Units);
266+
for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg()))
267+
ClobberedRegUnits.set(Unit);
269268

270269
if (!MO.readsReg() || !Reg.isVirtual())
271270
continue;
@@ -394,19 +393,17 @@ bool SSAIfConv::findInsertionPoint() {
394393
continue;
395394
// I clobbers Reg, so it isn't live before I.
396395
if (MO.isDef())
397-
for (MCRegUnitIterator Units(Reg.asMCReg(), TRI); Units.isValid();
398-
++Units)
399-
LiveRegUnits.erase(*Units);
396+
for (MCRegUnit Unit : TRI->regunits(Reg.asMCReg()))
397+
LiveRegUnits.erase(Unit);
400398
// Unless I reads Reg.
401399
if (MO.readsReg())
402400
Reads.push_back(Reg.asMCReg());
403401
}
404402
// Anything read by I is live before I.
405403
while (!Reads.empty())
406-
for (MCRegUnitIterator Units(Reads.pop_back_val(), TRI); Units.isValid();
407-
++Units)
408-
if (ClobberedRegUnits.test(*Units))
409-
LiveRegUnits.insert(*Units);
404+
for (MCRegUnit Unit : TRI->regunits(Reads.pop_back_val()))
405+
if (ClobberedRegUnits.test(Unit))
406+
LiveRegUnits.insert(Unit);
410407

411408
// We can't insert before a terminator.
412409
if (I != FirstTerm && I->isTerminator())

llvm/lib/CodeGen/InterferenceCache.cpp

Lines changed: 8 additions & 7 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ void InterferenceCache::Entry::revalidate(LiveIntervalUnion *LIUArray,
9393
// Invalidate all iterators.
9494
PrevPos = SlotIndex();
9595
unsigned i = 0;
96-
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units, ++i)
97-
RegUnits[i].VirtTag = LIUArray[*Units].getTag();
96+
for (MCRegUnit Unit : TRI->regunits(PhysReg))
97+
RegUnits[i++].VirtTag = LIUArray[Unit].getTag();
9898
}
9999

100100
void InterferenceCache::Entry::reset(MCRegister physReg,
@@ -110,20 +110,21 @@ void InterferenceCache::Entry::reset(MCRegister physReg,
110110
// Reset iterators.
111111
PrevPos = SlotIndex();
112112
RegUnits.clear();
113-
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
114-
RegUnits.push_back(LIUArray[*Units]);
115-
RegUnits.back().Fixed = &LIS->getRegUnit(*Units);
113+
for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
114+
RegUnits.push_back(LIUArray[Unit]);
115+
RegUnits.back().Fixed = &LIS->getRegUnit(Unit);
116116
}
117117
}
118118

119119
bool InterferenceCache::Entry::valid(LiveIntervalUnion *LIUArray,
120120
const TargetRegisterInfo *TRI) {
121121
unsigned i = 0, e = RegUnits.size();
122-
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units, ++i) {
122+
for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
123123
if (i == e)
124124
return false;
125-
if (LIUArray[*Units].changedSince(RegUnits[i].VirtTag))
125+
if (LIUArray[Unit].changedSince(RegUnits[i].VirtTag))
126126
return false;
127+
++i;
127128
}
128129
return i == e;
129130
}

llvm/lib/CodeGen/LiveDebugValues/InstrRefBasedImpl.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -2513,8 +2513,8 @@ void InstrRefBasedLDV::placeMLocPHIs(
25132513
Register R = MTracker->LocIdxToLocID[L];
25142514
SmallSet<Register, 8> FoundRegUnits;
25152515
bool AnyIllegal = false;
2516-
for (MCRegUnitIterator RUI(R.asMCReg(), TRI); RUI.isValid(); ++RUI) {
2517-
for (MCRegUnitRootIterator URoot(*RUI, TRI); URoot.isValid(); ++URoot){
2516+
for (MCRegUnit Unit : TRI->regunits(R.asMCReg())) {
2517+
for (MCRegUnitRootIterator URoot(Unit, TRI); URoot.isValid(); ++URoot) {
25182518
if (!MTracker->isRegisterTracked(*URoot)) {
25192519
// Not all roots were loaded into the tracking map: this register
25202520
// isn't actually def'd anywhere, we only read from it. Generate PHIs

llvm/lib/CodeGen/LiveIntervals.cpp

Lines changed: 8 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -329,8 +329,7 @@ void LiveIntervals::computeLiveInRegUnits() {
329329
SlotIndex Begin = Indexes->getMBBStartIdx(&MBB);
330330
LLVM_DEBUG(dbgs() << Begin << "\t" << printMBBReference(MBB));
331331
for (const auto &LI : MBB.liveins()) {
332-
for (MCRegUnitIterator Units(LI.PhysReg, TRI); Units.isValid(); ++Units) {
333-
unsigned Unit = *Units;
332+
for (MCRegUnit Unit : TRI->regunits(LI.PhysReg)) {
334333
LiveRange *LR = RegUnitRanges[Unit];
335334
if (!LR) {
336335
// Use segment set to speed-up initial computation of the live range.
@@ -704,9 +703,8 @@ void LiveIntervals::addKillFlags(const VirtRegMap *VRM) {
704703
// Find the regunit intervals for the assigned register. They may overlap
705704
// the virtual register live range, cancelling any kills.
706705
RU.clear();
707-
for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid();
708-
++Unit) {
709-
const LiveRange &RURange = getRegUnit(*Unit);
706+
for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
707+
const LiveRange &RURange = getRegUnit(Unit);
710708
if (RURange.empty())
711709
continue;
712710
RU.push_back(std::make_pair(&RURange, RURange.find(LI.begin()->end)));
@@ -1052,10 +1050,9 @@ class LiveIntervals::HMEditor {
10521050

10531051
// For physregs, only update the regunits that actually have a
10541052
// precomputed live range.
1055-
for (MCRegUnitIterator Units(Reg.asMCReg(), &TRI); Units.isValid();
1056-
++Units)
1057-
if (LiveRange *LR = getRegUnitLI(*Units))
1058-
updateRange(*LR, *Units, LaneBitmask::getNone());
1053+
for (MCRegUnit Unit : TRI.regunits(Reg.asMCReg()))
1054+
if (LiveRange *LR = getRegUnitLI(Unit))
1055+
updateRange(*LR, Unit, LaneBitmask::getNone());
10591056
}
10601057
if (hasRegMask)
10611058
updateRegMaskSlots();
@@ -1703,8 +1700,8 @@ LiveIntervals::repairIntervalsInRange(MachineBasicBlock *MBB,
17031700
}
17041701

17051702
void LiveIntervals::removePhysRegDefAt(MCRegister Reg, SlotIndex Pos) {
1706-
for (MCRegUnitIterator Unit(Reg, TRI); Unit.isValid(); ++Unit) {
1707-
if (LiveRange *LR = getCachedRegUnit(*Unit))
1703+
for (MCRegUnit Unit : TRI->regunits(Reg)) {
1704+
if (LiveRange *LR = getCachedRegUnit(Unit))
17081705
if (VNInfo *VNI = LR->getVNInfoAt(Pos))
17091706
LR->removeValNo(VNI);
17101707
}

llvm/lib/CodeGen/LiveRegMatrix.cpp

Lines changed: 8 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -93,8 +93,8 @@ static bool foreachUnit(const TargetRegisterInfo *TRI,
9393
}
9494
}
9595
} else {
96-
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
97-
if (Func(*Units, VRegInterval))
96+
for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
97+
if (Func(Unit, VRegInterval))
9898
return true;
9999
}
100100
}
@@ -136,8 +136,8 @@ void LiveRegMatrix::unassign(const LiveInterval &VirtReg) {
136136
}
137137

138138
bool LiveRegMatrix::isPhysRegUsed(MCRegister PhysReg) const {
139-
for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid(); ++Unit) {
140-
if (!Matrix[*Unit].empty())
139+
for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
140+
if (!Matrix[Unit].empty())
141141
return true;
142142
}
143143
return false;
@@ -216,7 +216,7 @@ bool LiveRegMatrix::checkInterference(SlotIndex Start, SlotIndex End,
216216
LR.addSegment(Seg);
217217

218218
// Check for interference with that segment
219-
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
219+
for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
220220
// LR is stack-allocated. LiveRegMatrix caches queries by a key that
221221
// includes the address of the live range. If (for the same reg unit) this
222222
// checkInterference overload is called twice, without any other query()
@@ -230,7 +230,7 @@ bool LiveRegMatrix::checkInterference(SlotIndex Start, SlotIndex End,
230230
// subtle bugs due to query identity. Avoiding caching, for example, would
231231
// greatly simplify things.
232232
LiveIntervalUnion::Query Q;
233-
Q.reset(UserTag, LR, Matrix[*Units]);
233+
Q.reset(UserTag, LR, Matrix[Unit]);
234234
if (Q.checkInterference())
235235
return true;
236236
}
@@ -239,8 +239,8 @@ bool LiveRegMatrix::checkInterference(SlotIndex Start, SlotIndex End,
239239

240240
Register LiveRegMatrix::getOneVReg(unsigned PhysReg) const {
241241
const LiveInterval *VRegInterval = nullptr;
242-
for (MCRegUnitIterator Unit(PhysReg, TRI); Unit.isValid(); ++Unit) {
243-
if ((VRegInterval = Matrix[*Unit].getOneVReg()))
242+
for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
243+
if ((VRegInterval = Matrix[Unit].getOneVReg()))
244244
return VRegInterval->reg();
245245
}
246246

llvm/lib/CodeGen/MLRegallocEvictAdvisor.cpp

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -611,8 +611,8 @@ bool MLEvictAdvisor::loadInterferenceFeatures(
611611
unsigned Cascade = RA.getExtraInfo().getCascadeOrCurrentNext(VirtReg.reg());
612612

613613
SmallVector<const LiveInterval *, MaxInterferences> InterferingIntervals;
614-
for (MCRegUnitIterator Units(PhysReg, TRI); Units.isValid(); ++Units) {
615-
LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, *Units);
614+
for (MCRegUnit Unit : TRI->regunits(PhysReg)) {
615+
LiveIntervalUnion::Query &Q = Matrix->query(VirtReg, Unit);
616616
// Different from the default heuristic, we don't make any assumptions
617617
// about what having more than 10 results in the query may mean.
618618
const auto &IFIntervals = Q.interferingVRegs(EvictInterferenceCutoff);

0 commit comments

Comments
 (0)