aboutsummaryrefslogtreecommitdiff
path: root/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
diff options
context:
space:
mode:
authorMikhail Gudim <mgudim@gmail.com>2025-09-19 09:38:34 -0400
committerGitHub <noreply@github.com>2025-09-19 09:38:34 -0400
commit562146499c391f72d3bed6d91a80d432af14db49 (patch)
tree2e0fa94a670da21ef0067325968c9781d2d8e12f /llvm/lib/CodeGen/ReachingDefAnalysis.cpp
parentba49062914f01f68cf3c4e067139a24b29a0e45b (diff)
downloadllvm-562146499c391f72d3bed6d91a80d432af14db49.zip
llvm-562146499c391f72d3bed6d91a80d432af14db49.tar.gz
llvm-562146499c391f72d3bed6d91a80d432af14db49.tar.bz2
[CodeGen][NewPM] Port `ReachingDefAnalysis` to new pass manager. (#159572)
In this commit: (1) Added new pass manager support for `ReachingDefAnalysis`. (2) Added printer pass. (3) Make old pass manager use `ReachingDefInfoWrapperPass`
Diffstat (limited to 'llvm/lib/CodeGen/ReachingDefAnalysis.cpp')
-rw-r--r--llvm/lib/CodeGen/ReachingDefAnalysis.cpp224
1 files changed, 134 insertions, 90 deletions
diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
index a589ef7..40a8907 100644
--- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
+++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
@@ -20,13 +20,62 @@ using namespace llvm;
#define DEBUG_TYPE "reaching-defs-analysis"
-static cl::opt<bool> PrintAllReachingDefs("print-all-reaching-defs", cl::Hidden,
- cl::desc("Used for test purpuses"),
- cl::Hidden);
+AnalysisKey ReachingDefAnalysis::Key;
-char ReachingDefAnalysis::ID = 0;
-INITIALIZE_PASS(ReachingDefAnalysis, DEBUG_TYPE, "ReachingDefAnalysis", false,
- true)
+ReachingDefAnalysis::Result
+ReachingDefAnalysis::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ ReachingDefInfo RDI;
+ RDI.run(MF);
+ return RDI;
+}
+
+PreservedAnalyses
+ReachingDefPrinterPass::run(MachineFunction &MF,
+ MachineFunctionAnalysisManager &MFAM) {
+ MFPropsModifier _(*this, MF);
+
+ auto &RDI = MFAM.getResult<ReachingDefAnalysis>(MF);
+ OS << "Reaching definitions for for machine function: " << MF.getName()
+ << '\n';
+ RDI.print(OS);
+ return PreservedAnalyses::all();
+}
+
+INITIALIZE_PASS(ReachingDefInfoWrapperPass, DEBUG_TYPE,
+ "Reaching Definitions Analysis", false, true)
+
+char ReachingDefInfoWrapperPass::ID = 0;
+
+ReachingDefInfoWrapperPass::ReachingDefInfoWrapperPass()
+ : MachineFunctionPass(ID) {
+ initializeReachingDefInfoWrapperPassPass(*PassRegistry::getPassRegistry());
+}
+
+ReachingDefInfo::ReachingDefInfo() = default;
+ReachingDefInfo::ReachingDefInfo(ReachingDefInfo &&) = default;
+ReachingDefInfo::~ReachingDefInfo() = default;
+
+bool ReachingDefInfo::invalidate(
+ MachineFunction &MF, const PreservedAnalyses &PA,
+ MachineFunctionAnalysisManager::Invalidator &) {
+ // Check whether the analysis, all analyses on machine functions, or the
+ // machine function's CFG have been preserved.
+ auto PAC = PA.getChecker<ReachingDefAnalysis>();
+ return !PAC.preserved() &&
+ !PAC.preservedSet<AllAnalysesOn<MachineFunction>>() &&
+ !PAC.preservedSet<CFGAnalyses>();
+}
+
+void ReachingDefInfoWrapperPass::getAnalysisUsage(AnalysisUsage &AU) const {
+ AU.setPreservesAll();
+ MachineFunctionPass::getAnalysisUsage(AU);
+}
+
+MachineFunctionProperties
+ReachingDefInfoWrapperPass::getRequiredProperties() const {
+ return MachineFunctionProperties().setNoVRegs();
+}
static bool isValidReg(const MachineOperand &MO) {
return MO.isReg() && MO.getReg();
@@ -64,7 +113,7 @@ static bool isFIDef(const MachineInstr &MI, int FrameIndex,
return false;
}
-void ReachingDefAnalysis::enterBasicBlock(MachineBasicBlock *MBB) {
+void ReachingDefInfo::enterBasicBlock(MachineBasicBlock *MBB) {
unsigned MBBNumber = MBB->getNumber();
assert(MBBNumber < MBBReachingDefs.numBlockIDs() &&
"Unexpected basic block number.");
@@ -116,7 +165,7 @@ void ReachingDefAnalysis::enterBasicBlock(MachineBasicBlock *MBB) {
MBBReachingDefs.append(MBBNumber, Unit, LiveRegs[Unit]);
}
-void ReachingDefAnalysis::leaveBasicBlock(MachineBasicBlock *MBB) {
+void ReachingDefInfo::leaveBasicBlock(MachineBasicBlock *MBB) {
assert(!LiveRegs.empty() && "Must enter basic block first.");
unsigned MBBNumber = MBB->getNumber();
assert(MBBNumber < MBBOutRegsInfos.size() &&
@@ -134,7 +183,7 @@ void ReachingDefAnalysis::leaveBasicBlock(MachineBasicBlock *MBB) {
LiveRegs.clear();
}
-void ReachingDefAnalysis::processDefs(MachineInstr *MI) {
+void ReachingDefInfo::processDefs(MachineInstr *MI) {
assert(!MI->isDebugInstr() && "Won't process debug instructions");
unsigned MBBNumber = MI->getParent()->getNumber();
@@ -167,7 +216,7 @@ void ReachingDefAnalysis::processDefs(MachineInstr *MI) {
++CurInstr;
}
-void ReachingDefAnalysis::reprocessBasicBlock(MachineBasicBlock *MBB) {
+void ReachingDefInfo::reprocessBasicBlock(MachineBasicBlock *MBB) {
unsigned MBBNumber = MBB->getNumber();
assert(MBBNumber < MBBReachingDefs.numBlockIDs() &&
"Unexpected basic block number.");
@@ -212,7 +261,7 @@ void ReachingDefAnalysis::reprocessBasicBlock(MachineBasicBlock *MBB) {
}
}
-void ReachingDefAnalysis::processBasicBlock(
+void ReachingDefInfo::processBasicBlock(
const LoopTraversal::TraversedMBBInfo &TraversedMBB) {
MachineBasicBlock *MBB = TraversedMBB.MBB;
LLVM_DEBUG(dbgs() << printMBBReference(*MBB)
@@ -232,12 +281,22 @@ void ReachingDefAnalysis::processBasicBlock(
leaveBasicBlock(MBB);
}
-void ReachingDefAnalysis::printAllReachingDefs(MachineFunction &MF) {
- dbgs() << "RDA results for " << MF.getName() << "\n";
+void ReachingDefInfo::run(MachineFunction &mf) {
+ MF = &mf;
+ const TargetSubtargetInfo &STI = MF->getSubtarget();
+ TRI = STI.getRegisterInfo();
+ TII = STI.getInstrInfo();
+ LLVM_DEBUG(dbgs() << "********** REACHING DEFINITION ANALYSIS **********\n");
+ init();
+ traverse();
+}
+
+void ReachingDefInfo::print(raw_ostream &OS) {
+ OS << "RDA results for " << MF->getName() << "\n";
int Num = 0;
DenseMap<MachineInstr *, int> InstToNumMap;
SmallPtrSet<MachineInstr *, 2> Defs;
- for (MachineBasicBlock &MBB : MF) {
+ for (MachineBasicBlock &MBB : *MF) {
for (MachineInstr &MI : MBB) {
for (MachineOperand &MO : MI.operands()) {
Register Reg;
@@ -256,37 +315,29 @@ void ReachingDefAnalysis::printAllReachingDefs(MachineFunction &MF) {
continue;
Defs.clear();
getGlobalReachingDefs(&MI, Reg, Defs);
- MO.print(dbgs(), TRI);
+ MO.print(OS, TRI);
SmallVector<int, 0> Nums;
for (MachineInstr *Def : Defs)
Nums.push_back(InstToNumMap[Def]);
llvm::sort(Nums);
- dbgs() << ":{ ";
+ OS << ":{ ";
for (int Num : Nums)
- dbgs() << Num << " ";
- dbgs() << "}\n";
+ OS << Num << " ";
+ OS << "}\n";
}
- dbgs() << Num << ": " << MI << "\n";
+ OS << Num << ": " << MI << "\n";
InstToNumMap[&MI] = Num;
++Num;
}
}
}
-bool ReachingDefAnalysis::runOnMachineFunction(MachineFunction &mf) {
- MF = &mf;
- const TargetSubtargetInfo &STI = MF->getSubtarget();
- TRI = STI.getRegisterInfo();
- TII = STI.getInstrInfo();
- LLVM_DEBUG(dbgs() << "********** REACHING DEFINITION ANALYSIS **********\n");
- init();
- traverse();
- if (PrintAllReachingDefs)
- printAllReachingDefs(*MF);
+bool ReachingDefInfoWrapperPass::runOnMachineFunction(MachineFunction &mf) {
+ RDI.run(mf);
return false;
}
-void ReachingDefAnalysis::releaseMemory() {
+void ReachingDefInfo::releaseMemory() {
// Clear the internal vectors.
MBBOutRegsInfos.clear();
MBBReachingDefs.clear();
@@ -295,13 +346,13 @@ void ReachingDefAnalysis::releaseMemory() {
LiveRegs.clear();
}
-void ReachingDefAnalysis::reset() {
+void ReachingDefInfo::reset() {
releaseMemory();
init();
traverse();
}
-void ReachingDefAnalysis::init() {
+void ReachingDefInfo::init() {
NumRegUnits = TRI->getNumRegUnits();
NumStackObjects = MF->getFrameInfo().getNumObjects();
ObjectIndexBegin = MF->getFrameInfo().getObjectIndexBegin();
@@ -312,7 +363,7 @@ void ReachingDefAnalysis::init() {
TraversedMBBOrder = Traversal.traverse(*MF);
}
-void ReachingDefAnalysis::traverse() {
+void ReachingDefInfo::traverse() {
// Traverse the basic blocks.
for (LoopTraversal::TraversedMBBInfo TraversedMBB : TraversedMBBOrder)
processBasicBlock(TraversedMBB);
@@ -331,7 +382,7 @@ void ReachingDefAnalysis::traverse() {
#endif
}
-int ReachingDefAnalysis::getReachingDef(MachineInstr *MI, Register Reg) const {
+int ReachingDefInfo::getReachingDef(MachineInstr *MI, Register Reg) const {
assert(InstIds.count(MI) && "Unexpected machine instuction.");
int InstId = InstIds.lookup(MI);
int DefRes = ReachingDefDefaultVal;
@@ -367,15 +418,15 @@ int ReachingDefAnalysis::getReachingDef(MachineInstr *MI, Register Reg) const {
return LatestDef;
}
-MachineInstr *ReachingDefAnalysis::getReachingLocalMIDef(MachineInstr *MI,
- Register Reg) const {
+MachineInstr *ReachingDefInfo::getReachingLocalMIDef(MachineInstr *MI,
+ Register Reg) const {
return hasLocalDefBefore(MI, Reg)
? getInstFromId(MI->getParent(), getReachingDef(MI, Reg))
: nullptr;
}
-bool ReachingDefAnalysis::hasSameReachingDef(MachineInstr *A, MachineInstr *B,
- Register Reg) const {
+bool ReachingDefInfo::hasSameReachingDef(MachineInstr *A, MachineInstr *B,
+ Register Reg) const {
MachineBasicBlock *ParentA = A->getParent();
MachineBasicBlock *ParentB = B->getParent();
if (ParentA != ParentB)
@@ -384,8 +435,8 @@ bool ReachingDefAnalysis::hasSameReachingDef(MachineInstr *A, MachineInstr *B,
return getReachingDef(A, Reg) == getReachingDef(B, Reg);
}
-MachineInstr *ReachingDefAnalysis::getInstFromId(MachineBasicBlock *MBB,
- int InstId) const {
+MachineInstr *ReachingDefInfo::getInstFromId(MachineBasicBlock *MBB,
+ int InstId) const {
assert(static_cast<size_t>(MBB->getNumber()) <
MBBReachingDefs.numBlockIDs() &&
"Unexpected basic block number.");
@@ -404,18 +455,17 @@ MachineInstr *ReachingDefAnalysis::getInstFromId(MachineBasicBlock *MBB,
return nullptr;
}
-int ReachingDefAnalysis::getClearance(MachineInstr *MI, Register Reg) const {
+int ReachingDefInfo::getClearance(MachineInstr *MI, Register Reg) const {
assert(InstIds.count(MI) && "Unexpected machine instuction.");
return InstIds.lookup(MI) - getReachingDef(MI, Reg);
}
-bool ReachingDefAnalysis::hasLocalDefBefore(MachineInstr *MI,
- Register Reg) const {
+bool ReachingDefInfo::hasLocalDefBefore(MachineInstr *MI, Register Reg) const {
return getReachingDef(MI, Reg) >= 0;
}
-void ReachingDefAnalysis::getReachingLocalUses(MachineInstr *Def, Register Reg,
- InstSet &Uses) const {
+void ReachingDefInfo::getReachingLocalUses(MachineInstr *Def, Register Reg,
+ InstSet &Uses) const {
MachineBasicBlock *MBB = Def->getParent();
MachineBasicBlock::iterator MI = MachineBasicBlock::iterator(Def);
while (++MI != MBB->end()) {
@@ -438,8 +488,8 @@ void ReachingDefAnalysis::getReachingLocalUses(MachineInstr *Def, Register Reg,
}
}
-bool ReachingDefAnalysis::getLiveInUses(MachineBasicBlock *MBB, Register Reg,
- InstSet &Uses) const {
+bool ReachingDefInfo::getLiveInUses(MachineBasicBlock *MBB, Register Reg,
+ InstSet &Uses) const {
for (MachineInstr &MI :
instructionsWithoutDebug(MBB->instr_begin(), MBB->instr_end())) {
for (auto &MO : MI.operands()) {
@@ -456,8 +506,8 @@ bool ReachingDefAnalysis::getLiveInUses(MachineBasicBlock *MBB, Register Reg,
return isReachingDefLiveOut(&*Last, Reg);
}
-void ReachingDefAnalysis::getGlobalUses(MachineInstr *MI, Register Reg,
- InstSet &Uses) const {
+void ReachingDefInfo::getGlobalUses(MachineInstr *MI, Register Reg,
+ InstSet &Uses) const {
MachineBasicBlock *MBB = MI->getParent();
// Collect the uses that each def touches within the block.
@@ -481,8 +531,8 @@ void ReachingDefAnalysis::getGlobalUses(MachineInstr *MI, Register Reg,
}
}
-void ReachingDefAnalysis::getGlobalReachingDefs(MachineInstr *MI, Register Reg,
- InstSet &Defs) const {
+void ReachingDefInfo::getGlobalReachingDefs(MachineInstr *MI, Register Reg,
+ InstSet &Defs) const {
if (auto *Def = getUniqueReachingMIDef(MI, Reg)) {
Defs.insert(Def);
return;
@@ -492,15 +542,14 @@ void ReachingDefAnalysis::getGlobalReachingDefs(MachineInstr *MI, Register Reg,
getLiveOuts(MBB, Reg, Defs);
}
-void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB, Register Reg,
- InstSet &Defs) const {
+void ReachingDefInfo::getLiveOuts(MachineBasicBlock *MBB, Register Reg,
+ InstSet &Defs) const {
SmallPtrSet<MachineBasicBlock*, 2> VisitedBBs;
getLiveOuts(MBB, Reg, Defs, VisitedBBs);
}
-void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB, Register Reg,
- InstSet &Defs,
- BlockSet &VisitedBBs) const {
+void ReachingDefInfo::getLiveOuts(MachineBasicBlock *MBB, Register Reg,
+ InstSet &Defs, BlockSet &VisitedBBs) const {
if (VisitedBBs.count(MBB))
return;
@@ -517,8 +566,8 @@ void ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB, Register Reg,
getLiveOuts(Pred, Reg, Defs, VisitedBBs);
}
-MachineInstr *ReachingDefAnalysis::getUniqueReachingMIDef(MachineInstr *MI,
- Register Reg) const {
+MachineInstr *ReachingDefInfo::getUniqueReachingMIDef(MachineInstr *MI,
+ Register Reg) const {
// If there's a local def before MI, return it.
MachineInstr *LocalDef = getReachingLocalMIDef(MI, Reg);
if (LocalDef && InstIds.lookup(LocalDef) < InstIds.lookup(MI))
@@ -537,19 +586,19 @@ MachineInstr *ReachingDefAnalysis::getUniqueReachingMIDef(MachineInstr *MI,
return nullptr;
}
-MachineInstr *ReachingDefAnalysis::getMIOperand(MachineInstr *MI,
- unsigned Idx) const {
+MachineInstr *ReachingDefInfo::getMIOperand(MachineInstr *MI,
+ unsigned Idx) const {
assert(MI->getOperand(Idx).isReg() && "Expected register operand");
return getUniqueReachingMIDef(MI, MI->getOperand(Idx).getReg());
}
-MachineInstr *ReachingDefAnalysis::getMIOperand(MachineInstr *MI,
- MachineOperand &MO) const {
+MachineInstr *ReachingDefInfo::getMIOperand(MachineInstr *MI,
+ MachineOperand &MO) const {
assert(MO.isReg() && "Expected register operand");
return getUniqueReachingMIDef(MI, MO.getReg());
}
-bool ReachingDefAnalysis::isRegUsedAfter(MachineInstr *MI, Register Reg) const {
+bool ReachingDefInfo::isRegUsedAfter(MachineInstr *MI, Register Reg) const {
MachineBasicBlock *MBB = MI->getParent();
LiveRegUnits LiveRegs(*TRI);
LiveRegs.addLiveOuts(*MBB);
@@ -569,8 +618,7 @@ bool ReachingDefAnalysis::isRegUsedAfter(MachineInstr *MI, Register Reg) const {
return false;
}
-bool ReachingDefAnalysis::isRegDefinedAfter(MachineInstr *MI,
- Register Reg) const {
+bool ReachingDefInfo::isRegDefinedAfter(MachineInstr *MI, Register Reg) const {
MachineBasicBlock *MBB = MI->getParent();
auto Last = MBB->getLastNonDebugInstr();
if (Last != MBB->end() &&
@@ -583,8 +631,8 @@ bool ReachingDefAnalysis::isRegDefinedAfter(MachineInstr *MI,
return false;
}
-bool ReachingDefAnalysis::isReachingDefLiveOut(MachineInstr *MI,
- Register Reg) const {
+bool ReachingDefInfo::isReachingDefLiveOut(MachineInstr *MI,
+ Register Reg) const {
MachineBasicBlock *MBB = MI->getParent();
LiveRegUnits LiveRegs(*TRI);
LiveRegs.addLiveOuts(*MBB);
@@ -604,8 +652,8 @@ bool ReachingDefAnalysis::isReachingDefLiveOut(MachineInstr *MI,
return true;
}
-MachineInstr *ReachingDefAnalysis::getLocalLiveOutMIDef(MachineBasicBlock *MBB,
- Register Reg) const {
+MachineInstr *ReachingDefInfo::getLocalLiveOutMIDef(MachineBasicBlock *MBB,
+ Register Reg) const {
LiveRegUnits LiveRegs(*TRI);
LiveRegs.addLiveOuts(*MBB);
if (Reg.isPhysical() && LiveRegs.available(Reg))
@@ -639,9 +687,8 @@ static bool mayHaveSideEffects(MachineInstr &MI) {
// Can we safely move 'From' to just before 'To'? To satisfy this, 'From' must
// not define a register that is used by any instructions, after and including,
// 'To'. These instructions also must not redefine any of Froms operands.
-template<typename Iterator>
-bool ReachingDefAnalysis::isSafeToMove(MachineInstr *From,
- MachineInstr *To) const {
+template <typename Iterator>
+bool ReachingDefInfo::isSafeToMove(MachineInstr *From, MachineInstr *To) const {
if (From->getParent() != To->getParent() || From == To)
return false;
@@ -669,8 +716,8 @@ bool ReachingDefAnalysis::isSafeToMove(MachineInstr *From,
return true;
}
-bool ReachingDefAnalysis::isSafeToMoveForwards(MachineInstr *From,
- MachineInstr *To) const {
+bool ReachingDefInfo::isSafeToMoveForwards(MachineInstr *From,
+ MachineInstr *To) const {
using Iterator = MachineBasicBlock::iterator;
// Walk forwards until we find the instruction.
for (auto I = Iterator(From), E = From->getParent()->end(); I != E; ++I)
@@ -679,8 +726,8 @@ bool ReachingDefAnalysis::isSafeToMoveForwards(MachineInstr *From,
return false;
}
-bool ReachingDefAnalysis::isSafeToMoveBackwards(MachineInstr *From,
- MachineInstr *To) const {
+bool ReachingDefInfo::isSafeToMoveBackwards(MachineInstr *From,
+ MachineInstr *To) const {
using Iterator = MachineBasicBlock::reverse_iterator;
// Walk backwards until we find the instruction.
for (auto I = Iterator(From), E = From->getParent()->rend(); I != E; ++I)
@@ -689,23 +736,21 @@ bool ReachingDefAnalysis::isSafeToMoveBackwards(MachineInstr *From,
return false;
}
-bool ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI,
- InstSet &ToRemove) const {
+bool ReachingDefInfo::isSafeToRemove(MachineInstr *MI,
+ InstSet &ToRemove) const {
SmallPtrSet<MachineInstr*, 1> Ignore;
SmallPtrSet<MachineInstr*, 2> Visited;
return isSafeToRemove(MI, Visited, ToRemove, Ignore);
}
-bool
-ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI, InstSet &ToRemove,
- InstSet &Ignore) const {
+bool ReachingDefInfo::isSafeToRemove(MachineInstr *MI, InstSet &ToRemove,
+ InstSet &Ignore) const {
SmallPtrSet<MachineInstr*, 2> Visited;
return isSafeToRemove(MI, Visited, ToRemove, Ignore);
}
-bool
-ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI, InstSet &Visited,
- InstSet &ToRemove, InstSet &Ignore) const {
+bool ReachingDefInfo::isSafeToRemove(MachineInstr *MI, InstSet &Visited,
+ InstSet &ToRemove, InstSet &Ignore) const {
if (Visited.count(MI) || Ignore.count(MI))
return true;
else if (mayHaveSideEffects(*MI)) {
@@ -733,8 +778,8 @@ ReachingDefAnalysis::isSafeToRemove(MachineInstr *MI, InstSet &Visited,
return true;
}
-void ReachingDefAnalysis::collectKilledOperands(MachineInstr *MI,
- InstSet &Dead) const {
+void ReachingDefInfo::collectKilledOperands(MachineInstr *MI,
+ InstSet &Dead) const {
Dead.insert(MI);
auto IsDead = [this, &Dead](MachineInstr *Def, Register Reg) {
if (mayHaveSideEffects(*Def))
@@ -765,14 +810,13 @@ void ReachingDefAnalysis::collectKilledOperands(MachineInstr *MI,
}
}
-bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI,
- Register Reg) const {
+bool ReachingDefInfo::isSafeToDefRegAt(MachineInstr *MI, Register Reg) const {
SmallPtrSet<MachineInstr*, 1> Ignore;
return isSafeToDefRegAt(MI, Reg, Ignore);
}
-bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI, Register Reg,
- InstSet &Ignore) const {
+bool ReachingDefInfo::isSafeToDefRegAt(MachineInstr *MI, Register Reg,
+ InstSet &Ignore) const {
// Check for any uses of the register after MI.
if (isRegUsedAfter(MI, Reg)) {
if (auto *Def = getReachingLocalMIDef(MI, Reg)) {