[llvm] 1d06e75 - [ARM][RDA] add getUniqueReachingMIDef
Sam Parker via llvm-commits
llvm-commits at lists.llvm.org
Wed Feb 26 03:15:44 PST 2020
Author: Sam Parker
Date: 2020-02-26T11:15:26Z
New Revision: 1d06e75df2a332edae972876e0e2b08dca3ba925
URL: https://github.com/llvm/llvm-project/commit/1d06e75df2a332edae972876e0e2b08dca3ba925
DIFF: https://github.com/llvm/llvm-project/commit/1d06e75df2a332edae972876e0e2b08dca3ba925.diff
LOG: [ARM][RDA] add getUniqueReachingMIDef
Add getUniqueReachingMIDef to RDA which performs a global search for
a machine instruction that produces a unique definition of a given
register at a given point. Also add two helper functions
(getMIOperand) that wrap around this functionality to get the
incoming definition uses of a given instruction. These now replace
the uses of getReachingMIDef in ARMLowOverheadLoops. getReachingMIDef
has been renamed to getReachingLocalMIDef and has been made private
along with getInstFromId.
Differential Revision: https://reviews.llvm.org/D74605
Added:
Modified:
llvm/include/llvm/CodeGen/ReachingDefAnalysis.h
llvm/lib/CodeGen/ReachingDefAnalysis.cpp
llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
Removed:
################################################################################
diff --git a/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h b/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h
index 8aea57f683b6..3c6ab064e91f 100644
--- a/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h
+++ b/llvm/include/llvm/CodeGen/ReachingDefAnalysis.h
@@ -72,6 +72,7 @@ class ReachingDefAnalysis : public MachineFunctionPass {
const int ReachingDefDefaultVal = -(1 << 20);
using InstSet = SmallPtrSetImpl<MachineInstr*>;
+ using BlockSet = SmallPtrSetImpl<MachineBasicBlock*>;
public:
static char ID; // Pass identification, replacement for typeid
@@ -107,14 +108,6 @@ class ReachingDefAnalysis : public MachineFunctionPass {
/// PhysReg that reaches MI, relative to the begining of MI's basic block.
int getReachingDef(MachineInstr *MI, int PhysReg) const;
- /// Provides the instruction of the closest reaching def instruction of
- /// PhysReg that reaches MI, relative to the begining of MI's basic block.
- MachineInstr *getReachingMIDef(MachineInstr *MI, int PhysReg) const;
-
- /// Provides the MI, from the given block, corresponding to the Id or a
- /// nullptr if the id does not refer to the block.
- MachineInstr *getInstFromId(MachineBasicBlock *MBB, int InstId) const;
-
/// Return whether A and B use the same def of PhysReg.
bool hasSameReachingDef(MachineInstr *A, MachineInstr *B, int PhysReg) const;
@@ -127,6 +120,18 @@ class ReachingDefAnalysis : public MachineFunctionPass {
MachineInstr *getLocalLiveOutMIDef(MachineBasicBlock *MBB,
int PhysReg) const;
+ /// If a single MachineInstr creates the reaching definition, then return it.
+ /// Otherwise return null.
+ MachineInstr *getUniqueReachingMIDef(MachineInstr *MI, int PhysReg) const;
+
+ /// If a single MachineInstr creates the reaching definition, for MIs operand
+ /// at Idx, then return it. Otherwise return null.
+ MachineInstr *getMIOperand(MachineInstr *MI, unsigned Idx) const;
+
+ /// If a single MachineInstr creates the reaching definition, for MIs MO,
+ /// then return it. Otherwise return null.
+ MachineInstr *getMIOperand(MachineInstr *MI, MachineOperand &MO) const;
+
/// Provide whether the register has been defined in the same basic block as,
/// and before, MI.
bool hasLocalDefBefore(MachineInstr *MI, int PhysReg) const;
@@ -147,6 +152,11 @@ class ReachingDefAnalysis : public MachineFunctionPass {
void getReachingLocalUses(MachineInstr *MI, int PhysReg,
InstSet &Uses) const;
+ /// Search MBB for a definition of PhysReg and insert it into Defs. If no
+ /// definition is found, recursively search the predecessor blocks for them.
+ void getLiveOuts(MachineBasicBlock *MBB, int PhysReg, InstSet &Defs,
+ BlockSet &VisitedBBs) const;
+
/// For the given block, collect the instructions that use the live-in
/// value of the provided register. Return whether the value is still
/// live on exit.
@@ -210,6 +220,14 @@ class ReachingDefAnalysis : public MachineFunctionPass {
/// the redundant use-def chain.
bool isSafeToRemove(MachineInstr *MI, InstSet &Visited,
InstSet &ToRemove, InstSet &Ignore) const;
+
+ /// Provides the MI, from the given block, corresponding to the Id or a
+ /// nullptr if the id does not refer to the block.
+ MachineInstr *getInstFromId(MachineBasicBlock *MBB, int InstId) const;
+
+ /// Provides the instruction of the closest reaching def instruction of
+ /// PhysReg that reaches MI, relative to the begining of MI's basic block.
+ MachineInstr *getReachingLocalMIDef(MachineInstr *MI, int PhysReg) const;
};
} // namespace llvm
diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
index 74707ff84149..f523be2a3d62 100644
--- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
+++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp
@@ -195,7 +195,7 @@ int ReachingDefAnalysis::getReachingDef(MachineInstr *MI, int PhysReg) const {
return LatestDef;
}
-MachineInstr* ReachingDefAnalysis::getReachingMIDef(MachineInstr *MI,
+MachineInstr* ReachingDefAnalysis::getReachingLocalMIDef(MachineInstr *MI,
int PhysReg) const {
return getInstFromId(MI->getParent(), getReachingDef(MI, PhysReg));
}
@@ -250,7 +250,7 @@ void ReachingDefAnalysis::getReachingLocalUses(MachineInstr *Def, int PhysReg,
// If/when we find a new reaching def, we know that there's no more uses
// of 'Def'.
- if (getReachingMIDef(&*MI, PhysReg) != Def)
+ if (getReachingLocalMIDef(&*MI, PhysReg) != Def)
return;
for (auto &MO : MI->operands()) {
@@ -311,6 +311,59 @@ ReachingDefAnalysis::getGlobalUses(MachineInstr *MI, int PhysReg,
}
}
+void
+ReachingDefAnalysis::getLiveOuts(MachineBasicBlock *MBB, int PhysReg,
+ InstSet &Defs, BlockSet &VisitedBBs) const {
+ if (VisitedBBs.count(MBB))
+ return;
+
+ VisitedBBs.insert(MBB);
+ LivePhysRegs LiveRegs(*TRI);
+ LiveRegs.addLiveOuts(*MBB);
+ if (!LiveRegs.contains(PhysReg))
+ return;
+
+ if (auto *Def = getLocalLiveOutMIDef(MBB, PhysReg))
+ Defs.insert(Def);
+ else
+ for (auto *Pred : MBB->predecessors())
+ getLiveOuts(Pred, PhysReg, Defs, VisitedBBs);
+}
+
+MachineInstr *ReachingDefAnalysis::getUniqueReachingMIDef(MachineInstr *MI,
+ int PhysReg) const {
+ // If there's a local def before MI, return it.
+ MachineInstr *LocalDef = getReachingLocalMIDef(MI, PhysReg);
+ if (InstIds.lookup(LocalDef) < InstIds.lookup(MI))
+ return LocalDef;
+
+ SmallPtrSet<MachineBasicBlock*, 4> VisitedBBs;
+ SmallPtrSet<MachineInstr*, 2> Incoming;
+ for (auto *Pred : MI->getParent()->predecessors())
+ getLiveOuts(Pred, PhysReg, Incoming, VisitedBBs);
+
+ // If we have a local def and an incoming instruction, then there's not a
+ // unique instruction def.
+ if (!Incoming.empty() && LocalDef)
+ return nullptr;
+ else if (Incoming.size() == 1)
+ return *Incoming.begin();
+ else
+ return LocalDef;
+}
+
+MachineInstr *ReachingDefAnalysis::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 {
+ assert(MO.isReg() && "Expected register operand");
+ return getUniqueReachingMIDef(MI, MO.getReg());
+}
+
bool ReachingDefAnalysis::isRegUsedAfter(MachineInstr *MI, int PhysReg) const {
MachineBasicBlock *MBB = MI->getParent();
LivePhysRegs LiveRegs(*TRI);
@@ -337,7 +390,7 @@ bool ReachingDefAnalysis::isRegDefinedAfter(MachineInstr *MI,
return true;
if (auto *Def = getLocalLiveOutMIDef(MBB, PhysReg))
- return Def == getReachingMIDef(MI, PhysReg);
+ return Def == getReachingLocalMIDef(MI, PhysReg);
return false;
}
@@ -492,7 +545,7 @@ void ReachingDefAnalysis::collectLocalKilledOperands(MachineInstr *MI,
for (auto &MO : MI->uses()) {
if (!MO.isReg() || MO.getReg() == 0 || !MO.isKill())
continue;
- if (MachineInstr *Def = getReachingMIDef(MI, MO.getReg()))
+ if (MachineInstr *Def = getReachingLocalMIDef(MI, MO.getReg()))
if (IsDead(Def, MO.getReg()))
collectLocalKilledOperands(Def, Dead);
}
@@ -508,7 +561,7 @@ bool ReachingDefAnalysis::isSafeToDefRegAt(MachineInstr *MI, int PhysReg,
InstSet &Ignore) const {
// Check for any uses of the register after MI.
if (isRegUsedAfter(MI, PhysReg)) {
- if (auto *Def = getReachingMIDef(MI, PhysReg)) {
+ if (auto *Def = getReachingLocalMIDef(MI, PhysReg)) {
SmallPtrSet<MachineInstr*, 2> Uses;
getReachingLocalUses(Def, PhysReg, Uses);
for (auto *Use : Uses)
diff --git a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
index 3c63e9a544ed..a18f3d4797c6 100644
--- a/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
+++ b/llvm/lib/Target/ARM/ARMLowOverheadLoops.cpp
@@ -342,7 +342,7 @@ MachineInstr *LowOverheadLoop::isSafeToDefineLR() {
// Find an insertion point:
// - Is there a (mov lr, Count) before Start? If so, and nothing else writes
// to Count before Start, we can insert at that mov.
- if (auto *LRDef = RDA.getReachingMIDef(Start, ARM::LR))
+ if (auto *LRDef = RDA.getUniqueReachingMIDef(Start, ARM::LR))
if (IsMoveLR(LRDef) && RDA.hasSameReachingDef(Start, LRDef, CountReg))
return LRDef;
@@ -479,7 +479,7 @@ bool LowOverheadLoop::ValidateTailPredicate(MachineInstr *StartInsertPt) {
};
MBB = VCTP->getParent();
- if (MachineInstr *Def = RDA.getReachingMIDef(&MBB->back(), NumElements)) {
+ if (auto *Def = RDA.getUniqueReachingMIDef(&MBB->back(), NumElements)) {
SmallPtrSet<MachineInstr*, 2> ElementChain;
SmallPtrSet<MachineInstr*, 2> Ignore = { VCTP };
unsigned ExpectedVectorWidth = getTailPredVectorWidth(VCTP->getOpcode());
@@ -897,8 +897,7 @@ void ARMLowOverheadLoops::IterationCountDCE(LowOverheadLoop &LoLoop) {
if (!LoLoop.IsTailPredicationLegal())
return;
- auto *Def = RDA->getReachingMIDef(LoLoop.Start,
- LoLoop.Start->getOperand(0).getReg());
+ MachineInstr *Def = RDA->getMIOperand(LoLoop.Start, 0);
if (!Def)
return;
@@ -1131,6 +1130,9 @@ void ARMLowOverheadLoops::Expand(LowOverheadLoop &LoLoop) {
for (auto *MBB : reverse(PostOrder))
recomputeLivenessFlags(*MBB);
+
+ // We've moved, removed and inserted new instructions, so update RDA.
+ RDA->reset();
}
bool ARMLowOverheadLoops::RevertNonLoops() {
More information about the llvm-commits
mailing list