diff options
author | Sam Parker <sam.parker@arm.com> | 2019-12-20 09:32:36 +0000 |
---|---|---|
committer | Sam Parker <sam.parker@arm.com> | 2019-12-20 09:34:18 +0000 |
commit | acbc9aed726d4b7428691e026a214cb26ee2cf94 (patch) | |
tree | 93e611317cbbc73893c2dad4d901d55b864d79f9 /llvm/lib/CodeGen/ReachingDefAnalysis.cpp | |
parent | 0ca9d2fd39264054501927ba6d3c5330159458d7 (diff) | |
download | bcm5719-llvm-acbc9aed726d4b7428691e026a214cb26ee2cf94.tar.gz bcm5719-llvm-acbc9aed726d4b7428691e026a214cb26ee2cf94.zip |
[ARM][MVE] Fixes for tail predication.
1) Fix an issue with the incorrect value being used for the number of
elements being passed to [d|w]lstp. We were trying to check that
the value was available at LoopStart, but this doesn't consider
that the last instruction in the block could also define the
register. Two helpers have been added to RDA for this.
2) Insert some code to now try to move the element count def or the
insertion point so that we can perform more tail predication.
3) Related to (1), the same off-by-one could prevent us from
generating a low-overhead loop when a mov lr could have been
the last instruction in the block.
4) Fix up some instruction attributes so that not all the
low-overhead loop instructions are labelled as branches and
terminators - as this is not true for dls/dlstp.
Differential Revision: https://reviews.llvm.org/D71609
Diffstat (limited to 'llvm/lib/CodeGen/ReachingDefAnalysis.cpp')
-rw-r--r-- | llvm/lib/CodeGen/ReachingDefAnalysis.cpp | 46 |
1 files changed, 41 insertions, 5 deletions
diff --git a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp index e5b422e0b7e..61ae3b75ab5 100644 --- a/llvm/lib/CodeGen/ReachingDefAnalysis.cpp +++ b/llvm/lib/CodeGen/ReachingDefAnalysis.cpp @@ -231,15 +231,15 @@ void ReachingDefAnalysis::getReachingLocalUses(MachineInstr *Def, int PhysReg, MachineBasicBlock *MBB = Def->getParent(); MachineBasicBlock::iterator MI = MachineBasicBlock::iterator(Def); while (++MI != MBB->end()) { + // If/when we find a new reaching def, we know that there's no more uses + // of 'Def'. + if (getReachingMIDef(&*MI, PhysReg) != Def) + return; + for (auto &MO : MI->operands()) { if (!MO.isReg() || !MO.isUse() || MO.getReg() != PhysReg) continue; - // If/when we find a new reaching def, we know that there's no more uses - // of 'Def'. - if (getReachingMIDef(&*MI, PhysReg) != Def) - return; - Uses.push_back(&*MI); if (MO.isKill()) return; @@ -272,6 +272,42 @@ bool ReachingDefAnalysis::isRegUsedAfter(MachineInstr *MI, int PhysReg) { return false; } +bool ReachingDefAnalysis::isReachingDefLiveOut(MachineInstr *MI, int PhysReg) { + MachineBasicBlock *MBB = MI->getParent(); + LivePhysRegs LiveRegs(*TRI); + LiveRegs.addLiveOuts(*MBB); + if (!LiveRegs.contains(PhysReg)) + return false; + + MachineInstr *Last = &MBB->back(); + int Def = getReachingDef(MI, PhysReg); + if (getReachingDef(Last, PhysReg) != Def) + return false; + + // Finally check that the last instruction doesn't redefine the register. + for (auto &MO : Last->operands()) + if (MO.isReg() && MO.isDef() && MO.getReg() == PhysReg) + return false; + + return true; +} + +MachineInstr* ReachingDefAnalysis::getLocalLiveOutMIDef(MachineBasicBlock *MBB, + int PhysReg) { + LivePhysRegs LiveRegs(*TRI); + LiveRegs.addLiveOuts(*MBB); + if (!LiveRegs.contains(PhysReg)) + return nullptr; + + MachineInstr *Last = &MBB->back(); + int Def = getReachingDef(Last, PhysReg); + for (auto &MO : Last->operands()) + if (MO.isReg() && MO.isDef() && MO.getReg() == PhysReg) + return Last; + + return Def < 0 ? nullptr : getInstFromId(MBB, Def); +} + MachineInstr *ReachingDefAnalysis::getInstWithUseBefore(MachineInstr *MI, int PhysReg) { auto I = MachineBasicBlock::reverse_iterator(MI); |