diff options
author | Sam Parker <sam.parker@arm.com> | 2020-02-26 11:14:54 +0000 |
---|---|---|
committer | Sam Parker <sam.parker@arm.com> | 2020-02-26 11:15:26 +0000 |
commit | 1d06e75df2a332edae972876e0e2b08dca3ba925 (patch) | |
tree | 6fa5692e0b8d195515d727e179fbe7ffba4943b6 /llvm/lib/CodeGen/ReachingDefAnalysis.cpp | |
parent | a059be72c4f72b5be8d789eece60d53f3f6b9041 (diff) | |
download | llvm-1d06e75df2a332edae972876e0e2b08dca3ba925.zip llvm-1d06e75df2a332edae972876e0e2b08dca3ba925.tar.gz llvm-1d06e75df2a332edae972876e0e2b08dca3ba925.tar.bz2 |
[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
Diffstat (limited to 'llvm/lib/CodeGen/ReachingDefAnalysis.cpp')
-rw-r--r-- | llvm/lib/CodeGen/ReachingDefAnalysis.cpp | 63 |
1 files changed, 58 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp index 74707ff..f523be2 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) |