Skip to content

Commit e8becd1

Browse files
committed
[CodeGen] Introduce a RegisterUnit class to hold virtual reg or physical reg unit. NFC
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 RegisterUnit 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. The new class is in Register.h, but I can move it. I also fixed a place in MachineVerifier that was ignoring reg unit 0.
1 parent 8f5df88 commit e8becd1

File tree

4 files changed

+135
-99
lines changed

4 files changed

+135
-99
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 RegisterUnit {
165+
unsigned RegUnit;
166+
167+
public:
168+
constexpr explicit RegisterUnit(MCRegUnit Unit) : RegUnit(Unit) {
169+
assert(!Register::isVirtualRegister(RegUnit));
170+
}
171+
constexpr explicit RegisterUnit(Register Reg) : RegUnit(Reg.id()) {
172+
assert(Reg.isVirtual());
173+
}
174+
175+
constexpr bool isVirtual() const {
176+
return Register::isVirtualRegister(RegUnit);
177+
}
178+
179+
constexpr MCRegUnit asMCRegUnit() const {
180+
assert(!isVirtual() && "Not a register unit");
181+
return RegUnit;
182+
}
183+
184+
constexpr Register asVirtualReg() const {
185+
assert(isVirtual() && "Not a virtual register");
186+
return Register(RegUnit);
187+
}
188+
189+
constexpr bool operator==(const RegisterUnit &Other) const {
190+
return RegUnit == Other.RegUnit;
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: 13 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -1066,10 +1066,10 @@ class LiveIntervals::HMEditor {
10661066
for (LiveInterval::SubRange &S : LI.subranges()) {
10671067
if ((S.LaneMask & LaneMask).none())
10681068
continue;
1069-
updateRange(S, Reg, S.LaneMask);
1069+
updateRange(S, RegisterUnit(Reg), S.LaneMask);
10701070
}
10711071
}
1072-
updateRange(LI, Reg, LaneBitmask::getNone());
1072+
updateRange(LI, RegisterUnit(Reg), LaneBitmask::getNone());
10731073
// If main range has a hole and we are moving a subrange use across
10741074
// the hole updateRange() cannot properly handle it since it only
10751075
// gets the LiveRange and not the whole LiveInterval. As a result
@@ -1096,7 +1096,7 @@ class LiveIntervals::HMEditor {
10961096
// precomputed live range.
10971097
for (MCRegUnit Unit : TRI.regunits(Reg.asMCReg()))
10981098
if (LiveRange *LR = getRegUnitLI(Unit))
1099-
updateRange(*LR, Unit, LaneBitmask::getNone());
1099+
updateRange(*LR, RegisterUnit(Unit), LaneBitmask::getNone());
11001100
}
11011101
if (hasRegMask)
11021102
updateRegMaskSlots();
@@ -1105,17 +1105,17 @@ class LiveIntervals::HMEditor {
11051105
private:
11061106
/// Update a single live range, assuming an instruction has been moved from
11071107
/// OldIdx to NewIdx.
1108-
void updateRange(LiveRange &LR, Register Reg, LaneBitmask LaneMask) {
1108+
void updateRange(LiveRange &LR, RegisterUnit Reg, LaneBitmask LaneMask) {
11091109
if (!Updated.insert(&LR).second)
11101110
return;
11111111
LLVM_DEBUG({
11121112
dbgs() << " ";
11131113
if (Reg.isVirtual()) {
1114-
dbgs() << printReg(Reg);
1114+
dbgs() << printReg(Reg.asVirtualReg());
11151115
if (LaneMask.any())
11161116
dbgs() << " L" << PrintLaneMask(LaneMask);
11171117
} else {
1118-
dbgs() << printRegUnit(Reg, &TRI);
1118+
dbgs() << printRegUnit(Reg.asMCRegUnit(), &TRI);
11191119
}
11201120
dbgs() << ":\t" << LR << '\n';
11211121
});
@@ -1302,7 +1302,7 @@ class LiveIntervals::HMEditor {
13021302

13031303
/// Update LR to reflect an instruction has been moved upwards from OldIdx
13041304
/// to NewIdx (NewIdx < OldIdx).
1305-
void handleMoveUp(LiveRange &LR, Register Reg, LaneBitmask LaneMask) {
1305+
void handleMoveUp(LiveRange &LR, RegisterUnit RegUnit, LaneBitmask LaneMask) {
13061306
LiveRange::iterator E = LR.end();
13071307
// Segment going into OldIdx.
13081308
LiveRange::iterator OldIdxIn = LR.find(OldIdx.getBaseIndex());
@@ -1326,7 +1326,7 @@ class LiveIntervals::HMEditor {
13261326
SlotIndex DefBeforeOldIdx
13271327
= std::max(OldIdxIn->start.getDeadSlot(),
13281328
NewIdx.getRegSlot(OldIdxIn->end.isEarlyClobber()));
1329-
OldIdxIn->end = findLastUseBefore(DefBeforeOldIdx, Reg, LaneMask);
1329+
OldIdxIn->end = findLastUseBefore(DefBeforeOldIdx, RegUnit, LaneMask);
13301330

13311331
// Did we have a Def at OldIdx? If not we are done now.
13321332
OldIdxOut = std::next(OldIdxIn);
@@ -1484,11 +1484,12 @@ class LiveIntervals::HMEditor {
14841484
}
14851485

14861486
// Return the last use of reg between NewIdx and OldIdx.
1487-
SlotIndex findLastUseBefore(SlotIndex Before, Register Reg,
1487+
SlotIndex findLastUseBefore(SlotIndex Before, RegisterUnit RegUnit,
14881488
LaneBitmask LaneMask) {
1489-
if (Reg.isVirtual()) {
1489+
if (RegUnit.isVirtual()) {
14901490
SlotIndex LastUse = Before;
1491-
for (MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
1491+
for (MachineOperand &MO :
1492+
MRI.use_nodbg_operands(RegUnit.asVirtualReg())) {
14921493
if (MO.isUndef())
14931494
continue;
14941495
unsigned SubReg = MO.getSubReg();
@@ -1531,7 +1532,7 @@ class LiveIntervals::HMEditor {
15311532
// Check if MII uses Reg.
15321533
for (MIBundleOperands MO(*MII); MO.isValid(); ++MO)
15331534
if (MO->isReg() && !MO->isUndef() && MO->getReg().isPhysical() &&
1534-
TRI.hasRegUnit(MO->getReg(), Reg))
1535+
TRI.hasRegUnit(MO->getReg(), RegUnit.asMCRegUnit()))
15351536
return Idx.getRegSlot();
15361537
}
15371538
// Didn't reach Before. It must be the first instruction in the block.

0 commit comments

Comments
 (0)