diff options
Diffstat (limited to 'contrib/llvm-project/llvm/lib/CodeGen/ReachingDefAnalysis.cpp')
| -rw-r--r-- | contrib/llvm-project/llvm/lib/CodeGen/ReachingDefAnalysis.cpp | 142 | 
1 files changed, 140 insertions, 2 deletions
diff --git a/contrib/llvm-project/llvm/lib/CodeGen/ReachingDefAnalysis.cpp b/contrib/llvm-project/llvm/lib/CodeGen/ReachingDefAnalysis.cpp index f05c97ad621e..3c1f9905afd0 100644 --- a/contrib/llvm-project/llvm/lib/CodeGen/ReachingDefAnalysis.cpp +++ b/contrib/llvm-project/llvm/lib/CodeGen/ReachingDefAnalysis.cpp @@ -6,9 +6,11 @@  //  //===----------------------------------------------------------------------===// +#include "llvm/CodeGen/LivePhysRegs.h"  #include "llvm/CodeGen/ReachingDefAnalysis.h"  #include "llvm/CodeGen/TargetRegisterInfo.h"  #include "llvm/CodeGen/TargetSubtargetInfo.h" +#include "llvm/Support/Debug.h"  using namespace llvm; @@ -131,8 +133,6 @@ void ReachingDefAnalysis::processBasicBlock(  }  bool ReachingDefAnalysis::runOnMachineFunction(MachineFunction &mf) { -  if (skipFunction(mf.getFunction())) -    return false;    MF = &mf;    TRI = MF->getSubtarget().getRegisterInfo(); @@ -188,7 +188,145 @@ int ReachingDefAnalysis::getReachingDef(MachineInstr *MI, int PhysReg) {    return LatestDef;  } +MachineInstr* ReachingDefAnalysis::getReachingMIDef(MachineInstr *MI, int PhysReg) { +  return getInstFromId(MI->getParent(), getReachingDef(MI, PhysReg)); +} + +bool ReachingDefAnalysis::hasSameReachingDef(MachineInstr *A, MachineInstr *B, +                                             int PhysReg) { +  MachineBasicBlock *ParentA = A->getParent(); +  MachineBasicBlock *ParentB = B->getParent(); +  if (ParentA != ParentB) +    return false; + +  return getReachingDef(A, PhysReg) == getReachingDef(B, PhysReg); +} + +MachineInstr *ReachingDefAnalysis::getInstFromId(MachineBasicBlock *MBB, +                                                 int InstId) { +  assert(static_cast<size_t>(MBB->getNumber()) < MBBReachingDefs.size() && +         "Unexpected basic block number."); +  assert(InstId < static_cast<int>(MBB->size()) && +         "Unexpected instruction id."); + +  if (InstId < 0) +    return nullptr; + +  for (auto &MI : *MBB) { +    if (InstIds.count(&MI) && InstIds[&MI] == InstId) +      return &MI; +  } +  return nullptr; +} +  int ReachingDefAnalysis::getClearance(MachineInstr *MI, MCPhysReg PhysReg) {    assert(InstIds.count(MI) && "Unexpected machine instuction.");    return InstIds[MI] - getReachingDef(MI, PhysReg);  } + +void ReachingDefAnalysis::getReachingLocalUses(MachineInstr *Def, int PhysReg, +    SmallVectorImpl<MachineInstr*> &Uses) { +  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; + +      Uses.push_back(&*MI); +      if (MO.isKill()) +        return; +    } +  } +} + +unsigned ReachingDefAnalysis::getNumUses(MachineInstr *Def, int PhysReg) { +  SmallVector<MachineInstr*, 4> Uses; +  getReachingLocalUses(Def, PhysReg, Uses); +  return Uses.size(); +} + +bool ReachingDefAnalysis::isRegUsedAfter(MachineInstr *MI, int PhysReg) { +  MachineBasicBlock *MBB = MI->getParent(); +  LivePhysRegs LiveRegs(*TRI); +  LiveRegs.addLiveOuts(*MBB); + +  // Yes if the register is live out of the basic block. +  if (LiveRegs.contains(PhysReg)) +    return true; + +  // Walk backwards through the block to see if the register is live at some +  // point. +  for (auto Last = MBB->rbegin(), End = MBB->rend(); Last != End; ++Last) { +    LiveRegs.stepBackward(*Last); +    if (LiveRegs.contains(PhysReg)) +      return InstIds[&*Last] > InstIds[MI]; +  } +  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); +  auto E = MI->getParent()->rend(); +  I++; + +  for ( ; I != E; I++) +    for (auto &MO : I->operands()) +      if (MO.isReg() && MO.isUse() && MO.getReg() == PhysReg) +        return &*I; + +  return nullptr; +} + +void ReachingDefAnalysis::getAllInstWithUseBefore(MachineInstr *MI, +    int PhysReg, SmallVectorImpl<MachineInstr*> &Uses) { +  MachineInstr *Use = nullptr; +  MachineInstr *Pos = MI; + +  while ((Use = getInstWithUseBefore(Pos, PhysReg))) { +    Uses.push_back(Use); +    Pos = Use; +  } +}  | 
