[llvm] [CodeGen] Introduce a RegisterUnit class to hold virtual reg or physical reg unit. NFC (PR #123768)
Craig Topper via llvm-commits
llvm-commits at lists.llvm.org
Wed Jan 22 23:47:57 PST 2025
https://github.com/topperc updated https://github.com/llvm/llvm-project/pull/123768
>From e8becd1ba3a7e0e23e4537c447d3724fadb11b85 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Tue, 21 Jan 2025 00:45:06 -0800
Subject: [PATCH 1/2] [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.
---
llvm/include/llvm/CodeGen/Register.h | 31 ++++
.../include/llvm/CodeGen/TargetRegisterInfo.h | 4 +-
llvm/lib/CodeGen/LiveIntervals.cpp | 25 +--
llvm/lib/CodeGen/MachineVerifier.cpp | 174 +++++++++---------
4 files changed, 135 insertions(+), 99 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/Register.h b/llvm/include/llvm/CodeGen/Register.h
index fac5f00110ef78..cb0db2bae928bc 100644
--- a/llvm/include/llvm/CodeGen/Register.h
+++ b/llvm/include/llvm/CodeGen/Register.h
@@ -160,6 +160,37 @@ template <> struct DenseMapInfo<Register> {
}
};
+/// Wrapper class representing a virtual register or register unit.
+class RegisterUnit {
+ unsigned RegUnit;
+
+public:
+ constexpr explicit RegisterUnit(MCRegUnit Unit) : RegUnit(Unit) {
+ assert(!Register::isVirtualRegister(RegUnit));
+ }
+ constexpr explicit RegisterUnit(Register Reg) : RegUnit(Reg.id()) {
+ assert(Reg.isVirtual());
+ }
+
+ constexpr bool isVirtual() const {
+ return Register::isVirtualRegister(RegUnit);
+ }
+
+ constexpr MCRegUnit asMCRegUnit() const {
+ assert(!isVirtual() && "Not a register unit");
+ return RegUnit;
+ }
+
+ constexpr Register asVirtualReg() const {
+ assert(isVirtual() && "Not a virtual register");
+ return Register(RegUnit);
+ }
+
+ constexpr bool operator==(const RegisterUnit &Other) const {
+ return RegUnit == Other.RegUnit;
+ }
+};
+
} // namespace llvm
#endif // LLVM_CODEGEN_REGISTER_H
diff --git a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
index 0bf72637de3989..63460f5a0dae36 100644
--- a/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
+++ b/llvm/include/llvm/CodeGen/TargetRegisterInfo.h
@@ -466,9 +466,9 @@ class TargetRegisterInfo : public MCRegisterInfo {
}
/// Returns true if Reg contains RegUnit.
- bool hasRegUnit(MCRegister Reg, Register RegUnit) const {
+ bool hasRegUnit(MCRegister Reg, MCRegUnit RegUnit) const {
for (MCRegUnit Unit : regunits(Reg))
- if (Register(Unit) == RegUnit)
+ if (Unit == RegUnit)
return true;
return false;
}
diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp
index f38527a3ce6a31..530bcac2be33d4 100644
--- a/llvm/lib/CodeGen/LiveIntervals.cpp
+++ b/llvm/lib/CodeGen/LiveIntervals.cpp
@@ -1066,10 +1066,10 @@ class LiveIntervals::HMEditor {
for (LiveInterval::SubRange &S : LI.subranges()) {
if ((S.LaneMask & LaneMask).none())
continue;
- updateRange(S, Reg, S.LaneMask);
+ updateRange(S, RegisterUnit(Reg), S.LaneMask);
}
}
- updateRange(LI, Reg, LaneBitmask::getNone());
+ updateRange(LI, RegisterUnit(Reg), LaneBitmask::getNone());
// If main range has a hole and we are moving a subrange use across
// the hole updateRange() cannot properly handle it since it only
// gets the LiveRange and not the whole LiveInterval. As a result
@@ -1096,7 +1096,7 @@ class LiveIntervals::HMEditor {
// precomputed live range.
for (MCRegUnit Unit : TRI.regunits(Reg.asMCReg()))
if (LiveRange *LR = getRegUnitLI(Unit))
- updateRange(*LR, Unit, LaneBitmask::getNone());
+ updateRange(*LR, RegisterUnit(Unit), LaneBitmask::getNone());
}
if (hasRegMask)
updateRegMaskSlots();
@@ -1105,17 +1105,17 @@ class LiveIntervals::HMEditor {
private:
/// Update a single live range, assuming an instruction has been moved from
/// OldIdx to NewIdx.
- void updateRange(LiveRange &LR, Register Reg, LaneBitmask LaneMask) {
+ void updateRange(LiveRange &LR, RegisterUnit Reg, LaneBitmask LaneMask) {
if (!Updated.insert(&LR).second)
return;
LLVM_DEBUG({
dbgs() << " ";
if (Reg.isVirtual()) {
- dbgs() << printReg(Reg);
+ dbgs() << printReg(Reg.asVirtualReg());
if (LaneMask.any())
dbgs() << " L" << PrintLaneMask(LaneMask);
} else {
- dbgs() << printRegUnit(Reg, &TRI);
+ dbgs() << printRegUnit(Reg.asMCRegUnit(), &TRI);
}
dbgs() << ":\t" << LR << '\n';
});
@@ -1302,7 +1302,7 @@ class LiveIntervals::HMEditor {
/// Update LR to reflect an instruction has been moved upwards from OldIdx
/// to NewIdx (NewIdx < OldIdx).
- void handleMoveUp(LiveRange &LR, Register Reg, LaneBitmask LaneMask) {
+ void handleMoveUp(LiveRange &LR, RegisterUnit RegUnit, LaneBitmask LaneMask) {
LiveRange::iterator E = LR.end();
// Segment going into OldIdx.
LiveRange::iterator OldIdxIn = LR.find(OldIdx.getBaseIndex());
@@ -1326,7 +1326,7 @@ class LiveIntervals::HMEditor {
SlotIndex DefBeforeOldIdx
= std::max(OldIdxIn->start.getDeadSlot(),
NewIdx.getRegSlot(OldIdxIn->end.isEarlyClobber()));
- OldIdxIn->end = findLastUseBefore(DefBeforeOldIdx, Reg, LaneMask);
+ OldIdxIn->end = findLastUseBefore(DefBeforeOldIdx, RegUnit, LaneMask);
// Did we have a Def at OldIdx? If not we are done now.
OldIdxOut = std::next(OldIdxIn);
@@ -1484,11 +1484,12 @@ class LiveIntervals::HMEditor {
}
// Return the last use of reg between NewIdx and OldIdx.
- SlotIndex findLastUseBefore(SlotIndex Before, Register Reg,
+ SlotIndex findLastUseBefore(SlotIndex Before, RegisterUnit RegUnit,
LaneBitmask LaneMask) {
- if (Reg.isVirtual()) {
+ if (RegUnit.isVirtual()) {
SlotIndex LastUse = Before;
- for (MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
+ for (MachineOperand &MO :
+ MRI.use_nodbg_operands(RegUnit.asVirtualReg())) {
if (MO.isUndef())
continue;
unsigned SubReg = MO.getSubReg();
@@ -1531,7 +1532,7 @@ class LiveIntervals::HMEditor {
// Check if MII uses Reg.
for (MIBundleOperands MO(*MII); MO.isValid(); ++MO)
if (MO->isReg() && !MO->isUndef() && MO->getReg().isPhysical() &&
- TRI.hasRegUnit(MO->getReg(), Reg))
+ TRI.hasRegUnit(MO->getReg(), RegUnit.asMCRegUnit()))
return Idx.getRegSlot();
}
// Didn't reach Before. It must be the first instruction in the block.
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index d41b11307e7bc0..f4e6b42a9bbf26 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -313,7 +313,7 @@ struct MachineVerifier {
void report(const Twine &Msg, const MachineInstr *MI);
void report_context(const LiveInterval &LI) const;
- void report_context(const LiveRange &LR, Register VRegUnit,
+ void report_context(const LiveRange &LR, RegisterUnit VRegUnit,
LaneBitmask LaneMask) const;
void report_context(const LiveRange::Segment &S) const;
void report_context(const VNInfo &VNI) const;
@@ -322,18 +322,18 @@ struct MachineVerifier {
void report_context_liverange(const LiveRange &LR) const;
void report_context_lanemask(LaneBitmask LaneMask) const;
void report_context_vreg(Register VReg) const;
- void report_context_vreg_regunit(Register VRegOrUnit) const;
+ void report_context_vreg_regunit(RegisterUnit VRegOrUnit) const;
void verifyInlineAsm(const MachineInstr *MI);
void checkLiveness(const MachineOperand *MO, unsigned MONum);
void checkLivenessAtUse(const MachineOperand *MO, unsigned MONum,
SlotIndex UseIdx, const LiveRange &LR,
- Register VRegOrUnit,
+ RegisterUnit VRegOrUnit,
LaneBitmask LaneMask = LaneBitmask::getNone());
void checkLivenessAtDef(const MachineOperand *MO, unsigned MONum,
SlotIndex DefIdx, const LiveRange &LR,
- Register VRegOrUnit, bool SubRangeCheck = false,
+ RegisterUnit VRegOrUnit, bool SubRangeCheck = false,
LaneBitmask LaneMask = LaneBitmask::getNone());
void markReachable(const MachineBasicBlock *MBB);
@@ -344,12 +344,12 @@ struct MachineVerifier {
void verifyLiveVariables();
void verifyLiveIntervals();
void verifyLiveInterval(const LiveInterval &);
- void verifyLiveRangeValue(const LiveRange &, const VNInfo *, Register,
+ void verifyLiveRangeValue(const LiveRange &, const VNInfo *, RegisterUnit,
LaneBitmask);
void verifyLiveRangeSegment(const LiveRange &,
- const LiveRange::const_iterator I, Register,
+ const LiveRange::const_iterator I, RegisterUnit,
LaneBitmask);
- void verifyLiveRange(const LiveRange &, Register,
+ void verifyLiveRange(const LiveRange &, RegisterUnit,
LaneBitmask LaneMask = LaneBitmask::getNone());
void verifyStackFrame();
@@ -636,7 +636,7 @@ void MachineVerifier::report_context(const LiveInterval &LI) const {
OS << "- interval: " << LI << '\n';
}
-void MachineVerifier::report_context(const LiveRange &LR, Register VRegUnit,
+void MachineVerifier::report_context(const LiveRange &LR, RegisterUnit VRegUnit,
LaneBitmask LaneMask) const {
report_context_liverange(LR);
report_context_vreg_regunit(VRegUnit);
@@ -664,11 +664,13 @@ void MachineVerifier::report_context_vreg(Register VReg) const {
OS << "- v. register: " << printReg(VReg, TRI) << '\n';
}
-void MachineVerifier::report_context_vreg_regunit(Register VRegOrUnit) const {
+void MachineVerifier::report_context_vreg_regunit(
+ RegisterUnit VRegOrUnit) const {
if (VRegOrUnit.isVirtual()) {
- report_context_vreg(VRegOrUnit);
+ report_context_vreg(VRegOrUnit.asVirtualReg());
} else {
- OS << "- regunit: " << printRegUnit(VRegOrUnit, TRI) << '\n';
+ OS << "- regunit: " << printRegUnit(VRegOrUnit.asMCRegUnit(), TRI)
+ << '\n';
}
}
@@ -2828,7 +2830,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
void MachineVerifier::checkLivenessAtUse(const MachineOperand *MO,
unsigned MONum, SlotIndex UseIdx,
const LiveRange &LR,
- Register VRegOrUnit,
+ RegisterUnit VRegOrUnit,
LaneBitmask LaneMask) {
const MachineInstr *MI = MO->getParent();
@@ -2863,7 +2865,7 @@ void MachineVerifier::checkLivenessAtUse(const MachineOperand *MO,
void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
unsigned MONum, SlotIndex DefIdx,
const LiveRange &LR,
- Register VRegOrUnit,
+ RegisterUnit VRegOrUnit,
bool SubRangeCheck,
LaneBitmask LaneMask) {
if (!LR.verify()) {
@@ -2973,13 +2975,13 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
if (MRI->isReservedRegUnit(Unit))
continue;
if (const LiveRange *LR = LiveInts->getCachedRegUnit(Unit))
- checkLivenessAtUse(MO, MONum, UseIdx, *LR, Unit);
+ checkLivenessAtUse(MO, MONum, UseIdx, *LR, RegisterUnit(Unit));
}
}
if (Reg.isVirtual()) {
// This is a virtual register interval.
- checkLivenessAtUse(MO, MONum, UseIdx, *LI, Reg);
+ checkLivenessAtUse(MO, MONum, UseIdx, *LI, RegisterUnit(Reg));
if (LI->hasSubRanges() && !MO->isDef()) {
LaneBitmask MOMask = SubRegIdx != 0
@@ -2989,7 +2991,8 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
for (const LiveInterval::SubRange &SR : LI->subranges()) {
if ((MOMask & SR.LaneMask).none())
continue;
- checkLivenessAtUse(MO, MONum, UseIdx, SR, Reg, SR.LaneMask);
+ checkLivenessAtUse(MO, MONum, UseIdx, SR, RegisterUnit(Reg),
+ SR.LaneMask);
LiveQueryResult LRQ = SR.Query(UseIdx);
if (LRQ.valueIn() || (MI->isPHI() && LRQ.valueOut()))
LiveInMask |= SR.LaneMask;
@@ -3081,7 +3084,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
DefIdx = DefIdx.getRegSlot(MO->isEarlyClobber());
if (Reg.isVirtual()) {
- checkLivenessAtDef(MO, MONum, DefIdx, *LI, Reg);
+ checkLivenessAtDef(MO, MONum, DefIdx, *LI, RegisterUnit(Reg));
if (LI->hasSubRanges()) {
LaneBitmask MOMask = SubRegIdx != 0
@@ -3090,7 +3093,8 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
for (const LiveInterval::SubRange &SR : LI->subranges()) {
if ((SR.LaneMask & MOMask).none())
continue;
- checkLivenessAtDef(MO, MONum, DefIdx, SR, Reg, true, SR.LaneMask);
+ checkLivenessAtDef(MO, MONum, DefIdx, SR, RegisterUnit(Reg), true,
+ SR.LaneMask);
}
}
}
@@ -3532,11 +3536,12 @@ void MachineVerifier::verifyLiveIntervals() {
// Verify all the cached regunit intervals.
for (unsigned i = 0, e = TRI->getNumRegUnits(); i != e; ++i)
if (const LiveRange *LR = LiveInts->getCachedRegUnit(i))
- verifyLiveRange(*LR, i);
+ verifyLiveRange(*LR, RegisterUnit(i));
}
void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
- const VNInfo *VNI, Register Reg,
+ const VNInfo *VNI,
+ RegisterUnit RegUnit,
LaneBitmask LaneMask) {
if (VNI->isUnused())
return;
@@ -3545,14 +3550,14 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
if (!DefVNI) {
report("Value not live at VNInfo def and not marked unused", MF);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(*VNI);
return;
}
if (DefVNI != VNI) {
report("Live segment at def has different VNInfo", MF);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(*VNI);
return;
}
@@ -3560,7 +3565,7 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(VNI->def);
if (!MBB) {
report("Invalid VNInfo definition index", MF);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(*VNI);
return;
}
@@ -3568,7 +3573,7 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
if (VNI->isPHIDef()) {
if (VNI->def != LiveInts->getMBBStartIdx(MBB)) {
report("PHIDef VNInfo is not defined at MBB start", MBB);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(*VNI);
}
return;
@@ -3578,57 +3583,56 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
const MachineInstr *MI = LiveInts->getInstructionFromIndex(VNI->def);
if (!MI) {
report("No instruction at VNInfo def index", MBB);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(*VNI);
return;
}
- if (Reg != 0) {
- bool hasDef = false;
- bool isEarlyClobber = false;
- for (ConstMIBundleOperands MOI(*MI); MOI.isValid(); ++MOI) {
- if (!MOI->isReg() || !MOI->isDef())
+ bool hasDef = false;
+ bool isEarlyClobber = false;
+ for (ConstMIBundleOperands MOI(*MI); MOI.isValid(); ++MOI) {
+ if (!MOI->isReg() || !MOI->isDef())
+ continue;
+ if (RegUnit.isVirtual()) {
+ if (MOI->getReg() != RegUnit.asVirtualReg())
continue;
- if (Reg.isVirtual()) {
- if (MOI->getReg() != Reg)
- continue;
- } else {
- if (!MOI->getReg().isPhysical() || !TRI->hasRegUnit(MOI->getReg(), Reg))
- continue;
- }
- if (LaneMask.any() &&
- (TRI->getSubRegIndexLaneMask(MOI->getSubReg()) & LaneMask).none())
+ } else {
+ if (!MOI->getReg().isPhysical() ||
+ !TRI->hasRegUnit(MOI->getReg(), RegUnit.asMCRegUnit()))
continue;
- hasDef = true;
- if (MOI->isEarlyClobber())
- isEarlyClobber = true;
}
+ if (LaneMask.any() &&
+ (TRI->getSubRegIndexLaneMask(MOI->getSubReg()) & LaneMask).none())
+ continue;
+ hasDef = true;
+ if (MOI->isEarlyClobber())
+ isEarlyClobber = true;
+ }
- if (!hasDef) {
- report("Defining instruction does not modify register", MI);
- report_context(LR, Reg, LaneMask);
- report_context(*VNI);
- }
+ if (!hasDef) {
+ report("Defining instruction does not modify register", MI);
+ report_context(LR, RegUnit, LaneMask);
+ report_context(*VNI);
+ }
- // Early clobber defs begin at USE slots, but other defs must begin at
- // DEF slots.
- if (isEarlyClobber) {
- if (!VNI->def.isEarlyClobber()) {
- report("Early clobber def must be at an early-clobber slot", MBB);
- report_context(LR, Reg, LaneMask);
- report_context(*VNI);
- }
- } else if (!VNI->def.isRegister()) {
- report("Non-PHI, non-early clobber def must be at a register slot", MBB);
- report_context(LR, Reg, LaneMask);
+ // Early clobber defs begin at USE slots, but other defs must begin at
+ // DEF slots.
+ if (isEarlyClobber) {
+ if (!VNI->def.isEarlyClobber()) {
+ report("Early clobber def must be at an early-clobber slot", MBB);
+ report_context(LR, RegUnit, LaneMask);
report_context(*VNI);
}
+ } else if (!VNI->def.isRegister()) {
+ report("Non-PHI, non-early clobber def must be at a register slot", MBB);
+ report_context(LR, RegUnit, LaneMask);
+ report_context(*VNI);
}
}
void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
const LiveRange::const_iterator I,
- Register Reg,
+ RegisterUnit RegUnit,
LaneBitmask LaneMask) {
const LiveRange::Segment &S = *I;
const VNInfo *VNI = S.valno;
@@ -3636,28 +3640,28 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
if (VNI->id >= LR.getNumValNums() || VNI != LR.getValNumInfo(VNI->id)) {
report("Foreign valno in live segment", MF);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(S);
report_context(*VNI);
}
if (VNI->isUnused()) {
report("Live segment valno is marked unused", MF);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(S);
}
const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(S.start);
if (!MBB) {
report("Bad start of live segment, no basic block", MF);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(S);
return;
}
SlotIndex MBBStartIdx = LiveInts->getMBBStartIdx(MBB);
if (S.start != MBBStartIdx && S.start != VNI->def) {
report("Live segment must begin at MBB entry or valno def", MBB);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(S);
}
@@ -3665,7 +3669,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
LiveInts->getMBBFromIndex(S.end.getPrevSlot());
if (!EndMBB) {
report("Bad end of live segment, no basic block", MF);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(S);
return;
}
@@ -3673,7 +3677,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
// Checks for non-live-out segments.
if (S.end != LiveInts->getMBBEndIdx(EndMBB)) {
// RegUnit intervals are allowed dead phis.
- if (!Reg.isVirtual() && VNI->isPHIDef() && S.start == VNI->def &&
+ if (!RegUnit.isVirtual() && VNI->isPHIDef() && S.start == VNI->def &&
S.end == VNI->def.getDeadSlot())
return;
@@ -3682,7 +3686,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
LiveInts->getInstructionFromIndex(S.end.getPrevSlot());
if (!MI) {
report("Live segment doesn't end at a valid instruction", EndMBB);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(S);
return;
}
@@ -3690,7 +3694,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
// The block slot must refer to a basic block boundary.
if (S.end.isBlock()) {
report("Live segment ends at B slot of an instruction", EndMBB);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(S);
}
@@ -3699,7 +3703,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
// That means there must be a dead def.
if (!SlotIndex::isSameInstr(S.start, S.end)) {
report("Live segment ending at dead slot spans instructions", EndMBB);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(S);
}
}
@@ -3715,21 +3719,21 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
report("Live segment ending at early clobber slot must be "
"redefined by an EC def in the same instruction",
EndMBB);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(S);
}
}
// The following checks only apply to virtual registers. Physreg liveness
// is too weird to check.
- if (Reg.isVirtual()) {
+ if (RegUnit.isVirtual()) {
// A live segment can end with either a redefinition, a kill flag on a
// use, or a dead flag on a def.
bool hasRead = false;
bool hasSubRegDef = false;
bool hasDeadDef = false;
for (ConstMIBundleOperands MOI(*MI); MOI.isValid(); ++MOI) {
- if (!MOI->isReg() || MOI->getReg() != Reg)
+ if (!MOI->isReg() || MOI->getReg() != RegUnit.asVirtualReg())
continue;
unsigned Sub = MOI->getSubReg();
LaneBitmask SLM =
@@ -3758,18 +3762,18 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
report(
"Instruction ending live segment on dead slot has no dead flag",
MI);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(S);
}
} else {
if (!hasRead) {
// When tracking subregister liveness, the main range must start new
// values on partial register writes, even if there is no read.
- if (!MRI->shouldTrackSubRegLiveness(Reg) || LaneMask.any() ||
- !hasSubRegDef) {
+ if (!MRI->shouldTrackSubRegLiveness(RegUnit.asVirtualReg()) ||
+ LaneMask.any() || !hasSubRegDef) {
report("Instruction ending live segment doesn't read the register",
MI);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(S);
}
}
@@ -3790,14 +3794,14 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
SmallVector<SlotIndex, 4> Undefs;
if (LaneMask.any()) {
- LiveInterval &OwnerLI = LiveInts->getInterval(Reg);
+ LiveInterval &OwnerLI = LiveInts->getInterval(RegUnit.asVirtualReg());
OwnerLI.computeSubRangeUndefs(Undefs, LaneMask, *MRI, *Indexes);
}
while (true) {
assert(LiveInts->isLiveInToMBB(LR, &*MFI));
// We don't know how to track physregs into a landing pad.
- if (!Reg.isVirtual() && MFI->isEHPad()) {
+ if (!RegUnit.isVirtual() && MFI->isEHPad()) {
if (&*MFI == EndMBB)
break;
++MFI;
@@ -3830,7 +3834,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
if (LiveRangeCalc::isJointlyDominated(Pred, Undefs, *Indexes))
continue;
report("Register not marked live out of predecessor", Pred);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
report_context(*VNI);
OS << " live into " << printMBBReference(*MFI) << '@'
<< LiveInts->getMBBStartIdx(&*MFI) << ", not live before " << PEnd
@@ -3841,7 +3845,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
// Only PHI-defs can take different predecessor values.
if (!IsPHI && PVNI != VNI) {
report("Different value live out of predecessor", Pred);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, RegUnit, LaneMask);
OS << "Valno #" << PVNI->id << " live out of "
<< printMBBReference(*Pred) << '@' << PEnd << "\nValno #" << VNI->id
<< " live into " << printMBBReference(*MFI) << '@'
@@ -3854,19 +3858,19 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
}
}
-void MachineVerifier::verifyLiveRange(const LiveRange &LR, Register Reg,
+void MachineVerifier::verifyLiveRange(const LiveRange &LR, RegisterUnit RegUnit,
LaneBitmask LaneMask) {
for (const VNInfo *VNI : LR.valnos)
- verifyLiveRangeValue(LR, VNI, Reg, LaneMask);
+ verifyLiveRangeValue(LR, VNI, RegUnit, LaneMask);
for (LiveRange::const_iterator I = LR.begin(), E = LR.end(); I != E; ++I)
- verifyLiveRangeSegment(LR, I, Reg, LaneMask);
+ verifyLiveRangeSegment(LR, I, RegUnit, LaneMask);
}
void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) {
Register Reg = LI.reg();
assert(Reg.isVirtual());
- verifyLiveRange(LI, Reg);
+ verifyLiveRange(LI, RegisterUnit(Reg));
if (LI.hasSubRanges()) {
LaneBitmask Mask;
@@ -3882,10 +3886,10 @@ void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) {
}
if (SR.empty()) {
report("Subrange must not be empty", MF);
- report_context(SR, LI.reg(), SR.LaneMask);
+ report_context(SR, RegisterUnit(LI.reg()), SR.LaneMask);
}
Mask |= SR.LaneMask;
- verifyLiveRange(SR, LI.reg(), SR.LaneMask);
+ verifyLiveRange(SR, RegisterUnit(LI.reg()), SR.LaneMask);
if (!LI.covers(SR)) {
report("A Subrange is not covered by the main range", MF);
report_context(LI);
>From 268ca2e664daed4b8f8a35f02fdbd0d642f51d59 Mon Sep 17 00:00:00 2001
From: Craig Topper <craig.topper at sifive.com>
Date: Wed, 22 Jan 2025 22:49:03 -0800
Subject: [PATCH 2/2] fixup! Rename to VirtRegOrUnit.
---
llvm/include/llvm/CodeGen/Register.h | 26 +++---
llvm/lib/CodeGen/LiveIntervals.cpp | 30 +++----
llvm/lib/CodeGen/MachineVerifier.cpp | 118 ++++++++++++++-------------
3 files changed, 89 insertions(+), 85 deletions(-)
diff --git a/llvm/include/llvm/CodeGen/Register.h b/llvm/include/llvm/CodeGen/Register.h
index cb0db2bae928bc..f8c6159a3c2dc4 100644
--- a/llvm/include/llvm/CodeGen/Register.h
+++ b/llvm/include/llvm/CodeGen/Register.h
@@ -161,33 +161,33 @@ template <> struct DenseMapInfo<Register> {
};
/// Wrapper class representing a virtual register or register unit.
-class RegisterUnit {
- unsigned RegUnit;
+class VirtRegOrUnit {
+ unsigned VRegOrUnit;
public:
- constexpr explicit RegisterUnit(MCRegUnit Unit) : RegUnit(Unit) {
- assert(!Register::isVirtualRegister(RegUnit));
+ constexpr explicit VirtRegOrUnit(MCRegUnit Unit) : VRegOrUnit(Unit) {
+ assert(!Register::isVirtualRegister(VRegOrUnit));
}
- constexpr explicit RegisterUnit(Register Reg) : RegUnit(Reg.id()) {
+ constexpr explicit VirtRegOrUnit(Register Reg) : VRegOrUnit(Reg.id()) {
assert(Reg.isVirtual());
}
- constexpr bool isVirtual() const {
- return Register::isVirtualRegister(RegUnit);
+ constexpr bool isVirtualReg() const {
+ return Register::isVirtualRegister(VRegOrUnit);
}
constexpr MCRegUnit asMCRegUnit() const {
- assert(!isVirtual() && "Not a register unit");
- return RegUnit;
+ assert(!isVirtualReg() && "Not a register unit");
+ return VRegOrUnit;
}
constexpr Register asVirtualReg() const {
- assert(isVirtual() && "Not a virtual register");
- return Register(RegUnit);
+ assert(isVirtualReg() && "Not a virtual register");
+ return Register(VRegOrUnit);
}
- constexpr bool operator==(const RegisterUnit &Other) const {
- return RegUnit == Other.RegUnit;
+ constexpr bool operator==(const VirtRegOrUnit &Other) const {
+ return VRegOrUnit == Other.VRegOrUnit;
}
};
diff --git a/llvm/lib/CodeGen/LiveIntervals.cpp b/llvm/lib/CodeGen/LiveIntervals.cpp
index 530bcac2be33d4..a3202b709ecd13 100644
--- a/llvm/lib/CodeGen/LiveIntervals.cpp
+++ b/llvm/lib/CodeGen/LiveIntervals.cpp
@@ -1066,10 +1066,10 @@ class LiveIntervals::HMEditor {
for (LiveInterval::SubRange &S : LI.subranges()) {
if ((S.LaneMask & LaneMask).none())
continue;
- updateRange(S, RegisterUnit(Reg), S.LaneMask);
+ updateRange(S, VirtRegOrUnit(Reg), S.LaneMask);
}
}
- updateRange(LI, RegisterUnit(Reg), LaneBitmask::getNone());
+ updateRange(LI, VirtRegOrUnit(Reg), LaneBitmask::getNone());
// If main range has a hole and we are moving a subrange use across
// the hole updateRange() cannot properly handle it since it only
// gets the LiveRange and not the whole LiveInterval. As a result
@@ -1096,7 +1096,7 @@ class LiveIntervals::HMEditor {
// precomputed live range.
for (MCRegUnit Unit : TRI.regunits(Reg.asMCReg()))
if (LiveRange *LR = getRegUnitLI(Unit))
- updateRange(*LR, RegisterUnit(Unit), LaneBitmask::getNone());
+ updateRange(*LR, VirtRegOrUnit(Unit), LaneBitmask::getNone());
}
if (hasRegMask)
updateRegMaskSlots();
@@ -1105,24 +1105,25 @@ class LiveIntervals::HMEditor {
private:
/// Update a single live range, assuming an instruction has been moved from
/// OldIdx to NewIdx.
- void updateRange(LiveRange &LR, RegisterUnit Reg, LaneBitmask LaneMask) {
+ void updateRange(LiveRange &LR, VirtRegOrUnit VRegOrUnit,
+ LaneBitmask LaneMask) {
if (!Updated.insert(&LR).second)
return;
LLVM_DEBUG({
dbgs() << " ";
- if (Reg.isVirtual()) {
- dbgs() << printReg(Reg.asVirtualReg());
+ if (VRegOrUnit.isVirtualReg()) {
+ dbgs() << printReg(VRegOrUnit.asVirtualReg());
if (LaneMask.any())
dbgs() << " L" << PrintLaneMask(LaneMask);
} else {
- dbgs() << printRegUnit(Reg.asMCRegUnit(), &TRI);
+ dbgs() << printRegUnit(VRegOrUnit.asMCRegUnit(), &TRI);
}
dbgs() << ":\t" << LR << '\n';
});
if (SlotIndex::isEarlierInstr(OldIdx, NewIdx))
handleMoveDown(LR);
else
- handleMoveUp(LR, Reg, LaneMask);
+ handleMoveUp(LR, VRegOrUnit, LaneMask);
LLVM_DEBUG(dbgs() << " -->\t" << LR << '\n');
assert(LR.verify());
}
@@ -1302,7 +1303,8 @@ class LiveIntervals::HMEditor {
/// Update LR to reflect an instruction has been moved upwards from OldIdx
/// to NewIdx (NewIdx < OldIdx).
- void handleMoveUp(LiveRange &LR, RegisterUnit RegUnit, LaneBitmask LaneMask) {
+ void handleMoveUp(LiveRange &LR, VirtRegOrUnit VRegOrUnit,
+ LaneBitmask LaneMask) {
LiveRange::iterator E = LR.end();
// Segment going into OldIdx.
LiveRange::iterator OldIdxIn = LR.find(OldIdx.getBaseIndex());
@@ -1326,7 +1328,7 @@ class LiveIntervals::HMEditor {
SlotIndex DefBeforeOldIdx
= std::max(OldIdxIn->start.getDeadSlot(),
NewIdx.getRegSlot(OldIdxIn->end.isEarlyClobber()));
- OldIdxIn->end = findLastUseBefore(DefBeforeOldIdx, RegUnit, LaneMask);
+ OldIdxIn->end = findLastUseBefore(DefBeforeOldIdx, VRegOrUnit, LaneMask);
// Did we have a Def at OldIdx? If not we are done now.
OldIdxOut = std::next(OldIdxIn);
@@ -1484,12 +1486,12 @@ class LiveIntervals::HMEditor {
}
// Return the last use of reg between NewIdx and OldIdx.
- SlotIndex findLastUseBefore(SlotIndex Before, RegisterUnit RegUnit,
+ SlotIndex findLastUseBefore(SlotIndex Before, VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask) {
- if (RegUnit.isVirtual()) {
+ if (VRegOrUnit.isVirtualReg()) {
SlotIndex LastUse = Before;
for (MachineOperand &MO :
- MRI.use_nodbg_operands(RegUnit.asVirtualReg())) {
+ MRI.use_nodbg_operands(VRegOrUnit.asVirtualReg())) {
if (MO.isUndef())
continue;
unsigned SubReg = MO.getSubReg();
@@ -1532,7 +1534,7 @@ class LiveIntervals::HMEditor {
// Check if MII uses Reg.
for (MIBundleOperands MO(*MII); MO.isValid(); ++MO)
if (MO->isReg() && !MO->isUndef() && MO->getReg().isPhysical() &&
- TRI.hasRegUnit(MO->getReg(), RegUnit.asMCRegUnit()))
+ TRI.hasRegUnit(MO->getReg(), VRegOrUnit.asMCRegUnit()))
return Idx.getRegSlot();
}
// Didn't reach Before. It must be the first instruction in the block.
diff --git a/llvm/lib/CodeGen/MachineVerifier.cpp b/llvm/lib/CodeGen/MachineVerifier.cpp
index f4e6b42a9bbf26..46ae3c6b055407 100644
--- a/llvm/lib/CodeGen/MachineVerifier.cpp
+++ b/llvm/lib/CodeGen/MachineVerifier.cpp
@@ -313,7 +313,7 @@ struct MachineVerifier {
void report(const Twine &Msg, const MachineInstr *MI);
void report_context(const LiveInterval &LI) const;
- void report_context(const LiveRange &LR, RegisterUnit VRegUnit,
+ void report_context(const LiveRange &LR, VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask) const;
void report_context(const LiveRange::Segment &S) const;
void report_context(const VNInfo &VNI) const;
@@ -322,18 +322,18 @@ struct MachineVerifier {
void report_context_liverange(const LiveRange &LR) const;
void report_context_lanemask(LaneBitmask LaneMask) const;
void report_context_vreg(Register VReg) const;
- void report_context_vreg_regunit(RegisterUnit VRegOrUnit) const;
+ void report_context_vreg_regunit(VirtRegOrUnit VRegOrUnit) const;
void verifyInlineAsm(const MachineInstr *MI);
void checkLiveness(const MachineOperand *MO, unsigned MONum);
void checkLivenessAtUse(const MachineOperand *MO, unsigned MONum,
SlotIndex UseIdx, const LiveRange &LR,
- RegisterUnit VRegOrUnit,
+ VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask = LaneBitmask::getNone());
void checkLivenessAtDef(const MachineOperand *MO, unsigned MONum,
SlotIndex DefIdx, const LiveRange &LR,
- RegisterUnit VRegOrUnit, bool SubRangeCheck = false,
+ VirtRegOrUnit VRegOrUnit, bool SubRangeCheck = false,
LaneBitmask LaneMask = LaneBitmask::getNone());
void markReachable(const MachineBasicBlock *MBB);
@@ -344,12 +344,12 @@ struct MachineVerifier {
void verifyLiveVariables();
void verifyLiveIntervals();
void verifyLiveInterval(const LiveInterval &);
- void verifyLiveRangeValue(const LiveRange &, const VNInfo *, RegisterUnit,
+ void verifyLiveRangeValue(const LiveRange &, const VNInfo *, VirtRegOrUnit,
LaneBitmask);
void verifyLiveRangeSegment(const LiveRange &,
- const LiveRange::const_iterator I, RegisterUnit,
+ const LiveRange::const_iterator I, VirtRegOrUnit,
LaneBitmask);
- void verifyLiveRange(const LiveRange &, RegisterUnit,
+ void verifyLiveRange(const LiveRange &, VirtRegOrUnit,
LaneBitmask LaneMask = LaneBitmask::getNone());
void verifyStackFrame();
@@ -636,10 +636,11 @@ void MachineVerifier::report_context(const LiveInterval &LI) const {
OS << "- interval: " << LI << '\n';
}
-void MachineVerifier::report_context(const LiveRange &LR, RegisterUnit VRegUnit,
+void MachineVerifier::report_context(const LiveRange &LR,
+ VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask) const {
report_context_liverange(LR);
- report_context_vreg_regunit(VRegUnit);
+ report_context_vreg_regunit(VRegOrUnit);
if (LaneMask.any())
report_context_lanemask(LaneMask);
}
@@ -665,8 +666,8 @@ void MachineVerifier::report_context_vreg(Register VReg) const {
}
void MachineVerifier::report_context_vreg_regunit(
- RegisterUnit VRegOrUnit) const {
- if (VRegOrUnit.isVirtual()) {
+ VirtRegOrUnit VRegOrUnit) const {
+ if (VRegOrUnit.isVirtualReg()) {
report_context_vreg(VRegOrUnit.asVirtualReg());
} else {
OS << "- regunit: " << printRegUnit(VRegOrUnit.asMCRegUnit(), TRI)
@@ -2830,7 +2831,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
void MachineVerifier::checkLivenessAtUse(const MachineOperand *MO,
unsigned MONum, SlotIndex UseIdx,
const LiveRange &LR,
- RegisterUnit VRegOrUnit,
+ VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask) {
const MachineInstr *MI = MO->getParent();
@@ -2865,7 +2866,7 @@ void MachineVerifier::checkLivenessAtUse(const MachineOperand *MO,
void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
unsigned MONum, SlotIndex DefIdx,
const LiveRange &LR,
- RegisterUnit VRegOrUnit,
+ VirtRegOrUnit VRegOrUnit,
bool SubRangeCheck,
LaneBitmask LaneMask) {
if (!LR.verify()) {
@@ -2910,7 +2911,7 @@ void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
if (MO->isDead()) {
LiveQueryResult LRQ = LR.Query(DefIdx);
if (!LRQ.isDeadDef()) {
- assert(VRegOrUnit.isVirtual() && "Expecting a virtual register.");
+ assert(VRegOrUnit.isVirtualReg() && "Expecting a virtual register.");
// A dead subreg def only tells us that the specific subreg is dead. There
// could be other non-dead defs of other subregs, or we could have other
// parts of the register being live through the instruction. So unless we
@@ -2975,13 +2976,13 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
if (MRI->isReservedRegUnit(Unit))
continue;
if (const LiveRange *LR = LiveInts->getCachedRegUnit(Unit))
- checkLivenessAtUse(MO, MONum, UseIdx, *LR, RegisterUnit(Unit));
+ checkLivenessAtUse(MO, MONum, UseIdx, *LR, VirtRegOrUnit(Unit));
}
}
if (Reg.isVirtual()) {
// This is a virtual register interval.
- checkLivenessAtUse(MO, MONum, UseIdx, *LI, RegisterUnit(Reg));
+ checkLivenessAtUse(MO, MONum, UseIdx, *LI, VirtRegOrUnit(Reg));
if (LI->hasSubRanges() && !MO->isDef()) {
LaneBitmask MOMask = SubRegIdx != 0
@@ -2991,7 +2992,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
for (const LiveInterval::SubRange &SR : LI->subranges()) {
if ((MOMask & SR.LaneMask).none())
continue;
- checkLivenessAtUse(MO, MONum, UseIdx, SR, RegisterUnit(Reg),
+ checkLivenessAtUse(MO, MONum, UseIdx, SR, VirtRegOrUnit(Reg),
SR.LaneMask);
LiveQueryResult LRQ = SR.Query(UseIdx);
if (LRQ.valueIn() || (MI->isPHI() && LRQ.valueOut()))
@@ -3084,7 +3085,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
DefIdx = DefIdx.getRegSlot(MO->isEarlyClobber());
if (Reg.isVirtual()) {
- checkLivenessAtDef(MO, MONum, DefIdx, *LI, RegisterUnit(Reg));
+ checkLivenessAtDef(MO, MONum, DefIdx, *LI, VirtRegOrUnit(Reg));
if (LI->hasSubRanges()) {
LaneBitmask MOMask = SubRegIdx != 0
@@ -3093,7 +3094,7 @@ void MachineVerifier::checkLiveness(const MachineOperand *MO, unsigned MONum) {
for (const LiveInterval::SubRange &SR : LI->subranges()) {
if ((SR.LaneMask & MOMask).none())
continue;
- checkLivenessAtDef(MO, MONum, DefIdx, SR, RegisterUnit(Reg), true,
+ checkLivenessAtDef(MO, MONum, DefIdx, SR, VirtRegOrUnit(Reg), true,
SR.LaneMask);
}
}
@@ -3536,12 +3537,12 @@ void MachineVerifier::verifyLiveIntervals() {
// Verify all the cached regunit intervals.
for (unsigned i = 0, e = TRI->getNumRegUnits(); i != e; ++i)
if (const LiveRange *LR = LiveInts->getCachedRegUnit(i))
- verifyLiveRange(*LR, RegisterUnit(i));
+ verifyLiveRange(*LR, VirtRegOrUnit(i));
}
void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
const VNInfo *VNI,
- RegisterUnit RegUnit,
+ VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask) {
if (VNI->isUnused())
return;
@@ -3550,14 +3551,14 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
if (!DefVNI) {
report("Value not live at VNInfo def and not marked unused", MF);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
return;
}
if (DefVNI != VNI) {
report("Live segment at def has different VNInfo", MF);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
return;
}
@@ -3565,7 +3566,7 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(VNI->def);
if (!MBB) {
report("Invalid VNInfo definition index", MF);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
return;
}
@@ -3573,7 +3574,7 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
if (VNI->isPHIDef()) {
if (VNI->def != LiveInts->getMBBStartIdx(MBB)) {
report("PHIDef VNInfo is not defined at MBB start", MBB);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
}
return;
@@ -3583,7 +3584,7 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
const MachineInstr *MI = LiveInts->getInstructionFromIndex(VNI->def);
if (!MI) {
report("No instruction at VNInfo def index", MBB);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
return;
}
@@ -3593,12 +3594,12 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
for (ConstMIBundleOperands MOI(*MI); MOI.isValid(); ++MOI) {
if (!MOI->isReg() || !MOI->isDef())
continue;
- if (RegUnit.isVirtual()) {
- if (MOI->getReg() != RegUnit.asVirtualReg())
+ if (VRegOrUnit.isVirtualReg()) {
+ if (MOI->getReg() != VRegOrUnit.asVirtualReg())
continue;
} else {
if (!MOI->getReg().isPhysical() ||
- !TRI->hasRegUnit(MOI->getReg(), RegUnit.asMCRegUnit()))
+ !TRI->hasRegUnit(MOI->getReg(), VRegOrUnit.asMCRegUnit()))
continue;
}
if (LaneMask.any() &&
@@ -3611,7 +3612,7 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
if (!hasDef) {
report("Defining instruction does not modify register", MI);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
}
@@ -3620,19 +3621,19 @@ void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
if (isEarlyClobber) {
if (!VNI->def.isEarlyClobber()) {
report("Early clobber def must be at an early-clobber slot", MBB);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
}
} else if (!VNI->def.isRegister()) {
report("Non-PHI, non-early clobber def must be at a register slot", MBB);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
}
}
void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
const LiveRange::const_iterator I,
- RegisterUnit RegUnit,
+ VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask) {
const LiveRange::Segment &S = *I;
const VNInfo *VNI = S.valno;
@@ -3640,28 +3641,28 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
if (VNI->id >= LR.getNumValNums() || VNI != LR.getValNumInfo(VNI->id)) {
report("Foreign valno in live segment", MF);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
report_context(*VNI);
}
if (VNI->isUnused()) {
report("Live segment valno is marked unused", MF);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
}
const MachineBasicBlock *MBB = LiveInts->getMBBFromIndex(S.start);
if (!MBB) {
report("Bad start of live segment, no basic block", MF);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
return;
}
SlotIndex MBBStartIdx = LiveInts->getMBBStartIdx(MBB);
if (S.start != MBBStartIdx && S.start != VNI->def) {
report("Live segment must begin at MBB entry or valno def", MBB);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
}
@@ -3669,7 +3670,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
LiveInts->getMBBFromIndex(S.end.getPrevSlot());
if (!EndMBB) {
report("Bad end of live segment, no basic block", MF);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
return;
}
@@ -3677,7 +3678,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
// Checks for non-live-out segments.
if (S.end != LiveInts->getMBBEndIdx(EndMBB)) {
// RegUnit intervals are allowed dead phis.
- if (!RegUnit.isVirtual() && VNI->isPHIDef() && S.start == VNI->def &&
+ if (!VRegOrUnit.isVirtualReg() && VNI->isPHIDef() && S.start == VNI->def &&
S.end == VNI->def.getDeadSlot())
return;
@@ -3686,7 +3687,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
LiveInts->getInstructionFromIndex(S.end.getPrevSlot());
if (!MI) {
report("Live segment doesn't end at a valid instruction", EndMBB);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
return;
}
@@ -3694,7 +3695,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
// The block slot must refer to a basic block boundary.
if (S.end.isBlock()) {
report("Live segment ends at B slot of an instruction", EndMBB);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
}
@@ -3703,7 +3704,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
// That means there must be a dead def.
if (!SlotIndex::isSameInstr(S.start, S.end)) {
report("Live segment ending at dead slot spans instructions", EndMBB);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
}
}
@@ -3719,21 +3720,21 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
report("Live segment ending at early clobber slot must be "
"redefined by an EC def in the same instruction",
EndMBB);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
}
}
// The following checks only apply to virtual registers. Physreg liveness
// is too weird to check.
- if (RegUnit.isVirtual()) {
+ if (VRegOrUnit.isVirtualReg()) {
// A live segment can end with either a redefinition, a kill flag on a
// use, or a dead flag on a def.
bool hasRead = false;
bool hasSubRegDef = false;
bool hasDeadDef = false;
for (ConstMIBundleOperands MOI(*MI); MOI.isValid(); ++MOI) {
- if (!MOI->isReg() || MOI->getReg() != RegUnit.asVirtualReg())
+ if (!MOI->isReg() || MOI->getReg() != VRegOrUnit.asVirtualReg())
continue;
unsigned Sub = MOI->getSubReg();
LaneBitmask SLM =
@@ -3762,18 +3763,18 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
report(
"Instruction ending live segment on dead slot has no dead flag",
MI);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
}
} else {
if (!hasRead) {
// When tracking subregister liveness, the main range must start new
// values on partial register writes, even if there is no read.
- if (!MRI->shouldTrackSubRegLiveness(RegUnit.asVirtualReg()) ||
+ if (!MRI->shouldTrackSubRegLiveness(VRegOrUnit.asVirtualReg()) ||
LaneMask.any() || !hasSubRegDef) {
report("Instruction ending live segment doesn't read the register",
MI);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
}
}
@@ -3794,14 +3795,14 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
SmallVector<SlotIndex, 4> Undefs;
if (LaneMask.any()) {
- LiveInterval &OwnerLI = LiveInts->getInterval(RegUnit.asVirtualReg());
+ LiveInterval &OwnerLI = LiveInts->getInterval(VRegOrUnit.asVirtualReg());
OwnerLI.computeSubRangeUndefs(Undefs, LaneMask, *MRI, *Indexes);
}
while (true) {
assert(LiveInts->isLiveInToMBB(LR, &*MFI));
// We don't know how to track physregs into a landing pad.
- if (!RegUnit.isVirtual() && MFI->isEHPad()) {
+ if (!VRegOrUnit.isVirtualReg() && MFI->isEHPad()) {
if (&*MFI == EndMBB)
break;
++MFI;
@@ -3834,7 +3835,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
if (LiveRangeCalc::isJointlyDominated(Pred, Undefs, *Indexes))
continue;
report("Register not marked live out of predecessor", Pred);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
OS << " live into " << printMBBReference(*MFI) << '@'
<< LiveInts->getMBBStartIdx(&*MFI) << ", not live before " << PEnd
@@ -3845,7 +3846,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
// Only PHI-defs can take different predecessor values.
if (!IsPHI && PVNI != VNI) {
report("Different value live out of predecessor", Pred);
- report_context(LR, RegUnit, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
OS << "Valno #" << PVNI->id << " live out of "
<< printMBBReference(*Pred) << '@' << PEnd << "\nValno #" << VNI->id
<< " live into " << printMBBReference(*MFI) << '@'
@@ -3858,19 +3859,20 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
}
}
-void MachineVerifier::verifyLiveRange(const LiveRange &LR, RegisterUnit RegUnit,
+void MachineVerifier::verifyLiveRange(const LiveRange &LR,
+ VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask) {
for (const VNInfo *VNI : LR.valnos)
- verifyLiveRangeValue(LR, VNI, RegUnit, LaneMask);
+ verifyLiveRangeValue(LR, VNI, VRegOrUnit, LaneMask);
for (LiveRange::const_iterator I = LR.begin(), E = LR.end(); I != E; ++I)
- verifyLiveRangeSegment(LR, I, RegUnit, LaneMask);
+ verifyLiveRangeSegment(LR, I, VRegOrUnit, LaneMask);
}
void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) {
Register Reg = LI.reg();
assert(Reg.isVirtual());
- verifyLiveRange(LI, RegisterUnit(Reg));
+ verifyLiveRange(LI, VirtRegOrUnit(Reg));
if (LI.hasSubRanges()) {
LaneBitmask Mask;
@@ -3886,10 +3888,10 @@ void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) {
}
if (SR.empty()) {
report("Subrange must not be empty", MF);
- report_context(SR, RegisterUnit(LI.reg()), SR.LaneMask);
+ report_context(SR, VirtRegOrUnit(LI.reg()), SR.LaneMask);
}
Mask |= SR.LaneMask;
- verifyLiveRange(SR, RegisterUnit(LI.reg()), SR.LaneMask);
+ verifyLiveRange(SR, VirtRegOrUnit(LI.reg()), SR.LaneMask);
if (!LI.covers(SR)) {
report("A Subrange is not covered by the main range", MF);
report_context(LI);
More information about the llvm-commits
mailing list