Skip to content

Commit ac1ba1f

Browse files
authored
[CodeGen] Introduce a VirtRegOrUnit class to hold virtual reg or physical reg unit. NFC (llvm#123768)
LiveIntervals and MachineVerifier were previously using Register to store this, but reg units are different than physical registers. One important difference is that 0 is a valid reg unit number, but it is not a valid phyiscal register. This patch introduces a new VirtRegOrUnit class that is distinct from Register. It can be be converted to/from a virtual Register or a MCRegUnit. I've made all conversions explicit and used assertions to check the validity. I also fixed a place in MachineVerifier that was ignoring reg unit 0.
1 parent 3b35b4c commit ac1ba1f

File tree

4 files changed

+144
-104
lines changed

4 files changed

+144
-104
lines changed

llvm/include/llvm/CodeGen/Register.h

Lines changed: 31 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -160,6 +160,37 @@ template <> struct DenseMapInfo<Register> {
160160
}
161161
};
162162

163+
/// Wrapper class representing a virtual register or register unit.
164+
class VirtRegOrUnit {
165+
unsigned VRegOrUnit;
166+
167+
public:
168+
constexpr explicit VirtRegOrUnit(MCRegUnit Unit) : VRegOrUnit(Unit) {
169+
assert(!Register::isVirtualRegister(VRegOrUnit));
170+
}
171+
constexpr explicit VirtRegOrUnit(Register Reg) : VRegOrUnit(Reg.id()) {
172+
assert(Reg.isVirtual());
173+
}
174+
175+
constexpr bool isVirtualReg() const {
176+
return Register::isVirtualRegister(VRegOrUnit);
177+
}
178+
179+
constexpr MCRegUnit asMCRegUnit() const {
180+
assert(!isVirtualReg() && "Not a register unit");
181+
return VRegOrUnit;
182+
}
183+
184+
constexpr Register asVirtualReg() const {
185+
assert(isVirtualReg() && "Not a virtual register");
186+
return Register(VRegOrUnit);
187+
}
188+
189+
constexpr bool operator==(const VirtRegOrUnit &Other) const {
190+
return VRegOrUnit == Other.VRegOrUnit;
191+
}
192+
};
193+
163194
} // namespace llvm
164195

165196
#endif // LLVM_CODEGEN_REGISTER_H

llvm/include/llvm/CodeGen/TargetRegisterInfo.h

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -466,9 +466,9 @@ class TargetRegisterInfo : public MCRegisterInfo {
466466
}
467467

468468
/// Returns true if Reg contains RegUnit.
469-
bool hasRegUnit(MCRegister Reg, Register RegUnit) const {
469+
bool hasRegUnit(MCRegister Reg, MCRegUnit RegUnit) const {
470470
for (MCRegUnit Unit : regunits(Reg))
471-
if (Register(Unit) == RegUnit)
471+
if (Unit == RegUnit)
472472
return true;
473473
return false;
474474
}

llvm/lib/CodeGen/LiveIntervals.cpp

Lines changed: 17 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -1080,10 +1080,10 @@ class LiveIntervals::HMEditor {
10801080
for (LiveInterval::SubRange &S : LI.subranges()) {
10811081
if ((S.LaneMask & LaneMask).none())
10821082
continue;
1083-
updateRange(S, Reg, S.LaneMask);
1083+
updateRange(S, VirtRegOrUnit(Reg), S.LaneMask);
10841084
}
10851085
}
1086-
updateRange(LI, Reg, LaneBitmask::getNone());
1086+
updateRange(LI, VirtRegOrUnit(Reg), LaneBitmask::getNone());
10871087
// If main range has a hole and we are moving a subrange use across
10881088
// the hole updateRange() cannot properly handle it since it only
10891089
// gets the LiveRange and not the whole LiveInterval. As a result
@@ -1110,7 +1110,7 @@ class LiveIntervals::HMEditor {
11101110
// precomputed live range.
11111111
for (MCRegUnit Unit : TRI.regunits(Reg.asMCReg()))
11121112
if (LiveRange *LR = getRegUnitLI(Unit))
1113-
updateRange(*LR, Unit, LaneBitmask::getNone());
1113+
updateRange(*LR, VirtRegOrUnit(Unit), LaneBitmask::getNone());
11141114
}
11151115
if (hasRegMask)
11161116
updateRegMaskSlots();
@@ -1119,24 +1119,25 @@ class LiveIntervals::HMEditor {
11191119
private:
11201120
/// Update a single live range, assuming an instruction has been moved from
11211121
/// OldIdx to NewIdx.
1122-
void updateRange(LiveRange &LR, Register Reg, LaneBitmask LaneMask) {
1122+
void updateRange(LiveRange &LR, VirtRegOrUnit VRegOrUnit,
1123+
LaneBitmask LaneMask) {
11231124
if (!Updated.insert(&LR).second)
11241125
return;
11251126
LLVM_DEBUG({
11261127
dbgs() << " ";
1127-
if (Reg.isVirtual()) {
1128-
dbgs() << printReg(Reg);
1128+
if (VRegOrUnit.isVirtualReg()) {
1129+
dbgs() << printReg(VRegOrUnit.asVirtualReg());
11291130
if (LaneMask.any())
11301131
dbgs() << " L" << PrintLaneMask(LaneMask);
11311132
} else {
1132-
dbgs() << printRegUnit(Reg, &TRI);
1133+
dbgs() << printRegUnit(VRegOrUnit.asMCRegUnit(), &TRI);
11331134
}
11341135
dbgs() << ":\t" << LR << '\n';
11351136
});
11361137
if (SlotIndex::isEarlierInstr(OldIdx, NewIdx))
11371138
handleMoveDown(LR);
11381139
else
1139-
handleMoveUp(LR, Reg, LaneMask);
1140+
handleMoveUp(LR, VRegOrUnit, LaneMask);
11401141
LLVM_DEBUG(dbgs() << " -->\t" << LR << '\n');
11411142
assert(LR.verify());
11421143
}
@@ -1316,7 +1317,8 @@ class LiveIntervals::HMEditor {
13161317

13171318
/// Update LR to reflect an instruction has been moved upwards from OldIdx
13181319
/// to NewIdx (NewIdx < OldIdx).
1319-
void handleMoveUp(LiveRange &LR, Register Reg, LaneBitmask LaneMask) {
1320+
void handleMoveUp(LiveRange &LR, VirtRegOrUnit VRegOrUnit,
1321+
LaneBitmask LaneMask) {
13201322
LiveRange::iterator E = LR.end();
13211323
// Segment going into OldIdx.
13221324
LiveRange::iterator OldIdxIn = LR.find(OldIdx.getBaseIndex());
@@ -1340,7 +1342,7 @@ class LiveIntervals::HMEditor {
13401342
SlotIndex DefBeforeOldIdx
13411343
= std::max(OldIdxIn->start.getDeadSlot(),
13421344
NewIdx.getRegSlot(OldIdxIn->end.isEarlyClobber()));
1343-
OldIdxIn->end = findLastUseBefore(DefBeforeOldIdx, Reg, LaneMask);
1345+
OldIdxIn->end = findLastUseBefore(DefBeforeOldIdx, VRegOrUnit, LaneMask);
13441346

13451347
// Did we have a Def at OldIdx? If not we are done now.
13461348
OldIdxOut = std::next(OldIdxIn);
@@ -1498,11 +1500,12 @@ class LiveIntervals::HMEditor {
14981500
}
14991501

15001502
// Return the last use of reg between NewIdx and OldIdx.
1501-
SlotIndex findLastUseBefore(SlotIndex Before, Register Reg,
1503+
SlotIndex findLastUseBefore(SlotIndex Before, VirtRegOrUnit VRegOrUnit,
15021504
LaneBitmask LaneMask) {
1503-
if (Reg.isVirtual()) {
1505+
if (VRegOrUnit.isVirtualReg()) {
15041506
SlotIndex LastUse = Before;
1505-
for (MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
1507+
for (MachineOperand &MO :
1508+
MRI.use_nodbg_operands(VRegOrUnit.asVirtualReg())) {
15061509
if (MO.isUndef())
15071510
continue;
15081511
unsigned SubReg = MO.getSubReg();
@@ -1545,7 +1548,7 @@ class LiveIntervals::HMEditor {
15451548
// Check if MII uses Reg.
15461549
for (MIBundleOperands MO(*MII); MO.isValid(); ++MO)
15471550
if (MO->isReg() && !MO->isUndef() && MO->getReg().isPhysical() &&
1548-
TRI.hasRegUnit(MO->getReg(), Reg))
1551+
TRI.hasRegUnit(MO->getReg(), VRegOrUnit.asMCRegUnit()))
15491552
return Idx.getRegSlot();
15501553
}
15511554
// Didn't reach Before. It must be the first instruction in the block.

0 commit comments

Comments
 (0)