[llvm] ac1ba1f - [CodeGen] Introduce a VirtRegOrUnit class to hold virtual reg or physical reg unit. NFC (#123768)
via llvm-commits
llvm-commits at lists.llvm.org
Fri Jan 24 18:30:33 PST 2025
Author: Craig Topper
Date: 2025-01-24T18:30:28-08:00
New Revision: ac1ba1f9dd7013852cd27f514467f57ee0e6ed16
URL: https://github.com/llvm/llvm-project/commit/ac1ba1f9dd7013852cd27f514467f57ee0e6ed16
DIFF: https://github.com/llvm/llvm-project/commit/ac1ba1f9dd7013852cd27f514467f57ee0e6ed16.diff
LOG: [CodeGen] Introduce a VirtRegOrUnit class to hold virtual reg or physical reg unit. NFC (#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.
Added:
Modified:
llvm/include/llvm/CodeGen/Register.h
llvm/include/llvm/CodeGen/TargetRegisterInfo.h
llvm/lib/CodeGen/LiveIntervals.cpp
llvm/lib/CodeGen/MachineVerifier.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/Register.h b/llvm/include/llvm/CodeGen/Register.h
index fac5f00110ef78..f8c6159a3c2dc4 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 VirtRegOrUnit {
+ unsigned VRegOrUnit;
+
+public:
+ constexpr explicit VirtRegOrUnit(MCRegUnit Unit) : VRegOrUnit(Unit) {
+ assert(!Register::isVirtualRegister(VRegOrUnit));
+ }
+ constexpr explicit VirtRegOrUnit(Register Reg) : VRegOrUnit(Reg.id()) {
+ assert(Reg.isVirtual());
+ }
+
+ constexpr bool isVirtualReg() const {
+ return Register::isVirtualRegister(VRegOrUnit);
+ }
+
+ constexpr MCRegUnit asMCRegUnit() const {
+ assert(!isVirtualReg() && "Not a register unit");
+ return VRegOrUnit;
+ }
+
+ constexpr Register asVirtualReg() const {
+ assert(isVirtualReg() && "Not a virtual register");
+ return Register(VRegOrUnit);
+ }
+
+ constexpr bool operator==(const VirtRegOrUnit &Other) const {
+ return VRegOrUnit == Other.VRegOrUnit;
+ }
+};
+
} // 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 4fdfcf547542d6..3485a27335f13e 100644
--- a/llvm/lib/CodeGen/LiveIntervals.cpp
+++ b/llvm/lib/CodeGen/LiveIntervals.cpp
@@ -1080,10 +1080,10 @@ class LiveIntervals::HMEditor {
for (LiveInterval::SubRange &S : LI.subranges()) {
if ((S.LaneMask & LaneMask).none())
continue;
- updateRange(S, Reg, S.LaneMask);
+ updateRange(S, VirtRegOrUnit(Reg), S.LaneMask);
}
}
- updateRange(LI, 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
@@ -1110,7 +1110,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, VirtRegOrUnit(Unit), LaneBitmask::getNone());
}
if (hasRegMask)
updateRegMaskSlots();
@@ -1119,24 +1119,25 @@ 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, VirtRegOrUnit VRegOrUnit,
+ LaneBitmask LaneMask) {
if (!Updated.insert(&LR).second)
return;
LLVM_DEBUG({
dbgs() << " ";
- if (Reg.isVirtual()) {
- dbgs() << printReg(Reg);
+ if (VRegOrUnit.isVirtualReg()) {
+ dbgs() << printReg(VRegOrUnit.asVirtualReg());
if (LaneMask.any())
dbgs() << " L" << PrintLaneMask(LaneMask);
} else {
- dbgs() << printRegUnit(Reg, &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());
}
@@ -1316,7 +1317,8 @@ 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, VirtRegOrUnit VRegOrUnit,
+ LaneBitmask LaneMask) {
LiveRange::iterator E = LR.end();
// Segment going into OldIdx.
LiveRange::iterator OldIdxIn = LR.find(OldIdx.getBaseIndex());
@@ -1340,7 +1342,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, VRegOrUnit, LaneMask);
// Did we have a Def at OldIdx? If not we are done now.
OldIdxOut = std::next(OldIdxIn);
@@ -1498,11 +1500,12 @@ class LiveIntervals::HMEditor {
}
// Return the last use of reg between NewIdx and OldIdx.
- SlotIndex findLastUseBefore(SlotIndex Before, Register Reg,
+ SlotIndex findLastUseBefore(SlotIndex Before, VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask) {
- if (Reg.isVirtual()) {
+ if (VRegOrUnit.isVirtualReg()) {
SlotIndex LastUse = Before;
- for (MachineOperand &MO : MRI.use_nodbg_operands(Reg)) {
+ for (MachineOperand &MO :
+ MRI.use_nodbg_operands(VRegOrUnit.asVirtualReg())) {
if (MO.isUndef())
continue;
unsigned SubReg = MO.getSubReg();
@@ -1545,7 +1548,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(), 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 d41b11307e7bc0..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, Register 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(Register 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,
- Register VRegOrUnit,
+ VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask = LaneBitmask::getNone());
void checkLivenessAtDef(const MachineOperand *MO, unsigned MONum,
SlotIndex DefIdx, const LiveRange &LR,
- Register 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 *, Register,
+ void verifyLiveRangeValue(const LiveRange &, const VNInfo *, VirtRegOrUnit,
LaneBitmask);
void verifyLiveRangeSegment(const LiveRange &,
- const LiveRange::const_iterator I, Register,
+ const LiveRange::const_iterator I, VirtRegOrUnit,
LaneBitmask);
- void verifyLiveRange(const LiveRange &, Register,
+ 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, Register 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);
}
@@ -664,11 +665,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 {
- if (VRegOrUnit.isVirtual()) {
- report_context_vreg(VRegOrUnit);
+void MachineVerifier::report_context_vreg_regunit(
+ VirtRegOrUnit VRegOrUnit) const {
+ if (VRegOrUnit.isVirtualReg()) {
+ report_context_vreg(VRegOrUnit.asVirtualReg());
} else {
- OS << "- regunit: " << printRegUnit(VRegOrUnit, TRI) << '\n';
+ OS << "- regunit: " << printRegUnit(VRegOrUnit.asMCRegUnit(), TRI)
+ << '\n';
}
}
@@ -2828,7 +2831,7 @@ MachineVerifier::visitMachineOperand(const MachineOperand *MO, unsigned MONum) {
void MachineVerifier::checkLivenessAtUse(const MachineOperand *MO,
unsigned MONum, SlotIndex UseIdx,
const LiveRange &LR,
- Register VRegOrUnit,
+ VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask) {
const MachineInstr *MI = MO->getParent();
@@ -2863,7 +2866,7 @@ void MachineVerifier::checkLivenessAtUse(const MachineOperand *MO,
void MachineVerifier::checkLivenessAtDef(const MachineOperand *MO,
unsigned MONum, SlotIndex DefIdx,
const LiveRange &LR,
- Register VRegOrUnit,
+ VirtRegOrUnit VRegOrUnit,
bool SubRangeCheck,
LaneBitmask LaneMask) {
if (!LR.verify()) {
@@ -2908,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
@@ -2973,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, Unit);
+ checkLivenessAtUse(MO, MONum, UseIdx, *LR, VirtRegOrUnit(Unit));
}
}
if (Reg.isVirtual()) {
// This is a virtual register interval.
- checkLivenessAtUse(MO, MONum, UseIdx, *LI, Reg);
+ checkLivenessAtUse(MO, MONum, UseIdx, *LI, VirtRegOrUnit(Reg));
if (LI->hasSubRanges() && !MO->isDef()) {
LaneBitmask MOMask = SubRegIdx != 0
@@ -2989,7 +2992,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, VirtRegOrUnit(Reg),
+ SR.LaneMask);
LiveQueryResult LRQ = SR.Query(UseIdx);
if (LRQ.valueIn() || (MI->isPHI() && LRQ.valueOut()))
LiveInMask |= SR.LaneMask;
@@ -3081,7 +3085,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, VirtRegOrUnit(Reg));
if (LI->hasSubRanges()) {
LaneBitmask MOMask = SubRegIdx != 0
@@ -3090,7 +3094,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, VirtRegOrUnit(Reg), true,
+ SR.LaneMask);
}
}
}
@@ -3532,11 +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, i);
+ verifyLiveRange(*LR, VirtRegOrUnit(i));
}
void MachineVerifier::verifyLiveRangeValue(const LiveRange &LR,
- const VNInfo *VNI, Register Reg,
+ const VNInfo *VNI,
+ VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask) {
if (VNI->isUnused())
return;
@@ -3545,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, Reg, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
return;
}
if (DefVNI != VNI) {
report("Live segment at def has
diff erent VNInfo", MF);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
return;
}
@@ -3560,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, Reg, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
return;
}
@@ -3568,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, Reg, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
}
return;
@@ -3578,57 +3584,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, VRegOrUnit, 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 (VRegOrUnit.isVirtualReg()) {
+ if (MOI->getReg() != VRegOrUnit.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(), VRegOrUnit.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, VRegOrUnit, 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, 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, VRegOrUnit, LaneMask);
+ report_context(*VNI);
}
}
void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
const LiveRange::const_iterator I,
- Register Reg,
+ VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask) {
const LiveRange::Segment &S = *I;
const VNInfo *VNI = S.valno;
@@ -3636,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, Reg, 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, Reg, 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, Reg, 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, Reg, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
}
@@ -3665,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, Reg, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
return;
}
@@ -3673,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 (!Reg.isVirtual() && VNI->isPHIDef() && S.start == VNI->def &&
+ if (!VRegOrUnit.isVirtualReg() && VNI->isPHIDef() && S.start == VNI->def &&
S.end == VNI->def.getDeadSlot())
return;
@@ -3682,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, Reg, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
return;
}
@@ -3690,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, Reg, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
}
@@ -3699,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, Reg, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
}
}
@@ -3715,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, Reg, 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 (Reg.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() != Reg)
+ if (!MOI->isReg() || MOI->getReg() != VRegOrUnit.asVirtualReg())
continue;
unsigned Sub = MOI->getSubReg();
LaneBitmask SLM =
@@ -3758,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, Reg, 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(Reg) || LaneMask.any() ||
- !hasSubRegDef) {
+ if (!MRI->shouldTrackSubRegLiveness(VRegOrUnit.asVirtualReg()) ||
+ LaneMask.any() || !hasSubRegDef) {
report("Instruction ending live segment doesn't read the register",
MI);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(S);
}
}
@@ -3790,14 +3795,14 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
SmallVector<SlotIndex, 4> Undefs;
if (LaneMask.any()) {
- LiveInterval &OwnerLI = LiveInts->getInterval(Reg);
+ 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 (!Reg.isVirtual() && MFI->isEHPad()) {
+ if (!VRegOrUnit.isVirtualReg() && MFI->isEHPad()) {
if (&*MFI == EndMBB)
break;
++MFI;
@@ -3830,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, Reg, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
report_context(*VNI);
OS << " live into " << printMBBReference(*MFI) << '@'
<< LiveInts->getMBBStartIdx(&*MFI) << ", not live before " << PEnd
@@ -3841,7 +3846,7 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
// Only PHI-defs can take
diff erent predecessor values.
if (!IsPHI && PVNI != VNI) {
report("Different value live out of predecessor", Pred);
- report_context(LR, Reg, LaneMask);
+ report_context(LR, VRegOrUnit, LaneMask);
OS << "Valno #" << PVNI->id << " live out of "
<< printMBBReference(*Pred) << '@' << PEnd << "\nValno #" << VNI->id
<< " live into " << printMBBReference(*MFI) << '@'
@@ -3854,19 +3859,20 @@ void MachineVerifier::verifyLiveRangeSegment(const LiveRange &LR,
}
}
-void MachineVerifier::verifyLiveRange(const LiveRange &LR, Register Reg,
+void MachineVerifier::verifyLiveRange(const LiveRange &LR,
+ VirtRegOrUnit VRegOrUnit,
LaneBitmask LaneMask) {
for (const VNInfo *VNI : LR.valnos)
- verifyLiveRangeValue(LR, VNI, Reg, LaneMask);
+ verifyLiveRangeValue(LR, VNI, VRegOrUnit, LaneMask);
for (LiveRange::const_iterator I = LR.begin(), E = LR.end(); I != E; ++I)
- verifyLiveRangeSegment(LR, I, Reg, LaneMask);
+ verifyLiveRangeSegment(LR, I, VRegOrUnit, LaneMask);
}
void MachineVerifier::verifyLiveInterval(const LiveInterval &LI) {
Register Reg = LI.reg();
assert(Reg.isVirtual());
- verifyLiveRange(LI, Reg);
+ verifyLiveRange(LI, VirtRegOrUnit(Reg));
if (LI.hasSubRanges()) {
LaneBitmask Mask;
@@ -3882,10 +3888,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, VirtRegOrUnit(LI.reg()), SR.LaneMask);
}
Mask |= SR.LaneMask;
- verifyLiveRange(SR, 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