diff options
| author | Dimitry Andric <dim@FreeBSD.org> | 2012-12-02 13:10:19 +0000 | 
|---|---|---|
| committer | Dimitry Andric <dim@FreeBSD.org> | 2012-12-02 13:10:19 +0000 | 
| commit | 522600a229b950314b5f4af84eba4f3e8a0ffea1 (patch) | |
| tree | 32b4679ab4b8f28e5228daafc65e9dc436935353 /lib/CodeGen/MachineBasicBlock.cpp | |
| parent | 902a7b529820e6a0aa85f98f21afaeb1805a22f8 (diff) | |
Notes
Diffstat (limited to 'lib/CodeGen/MachineBasicBlock.cpp')
| -rw-r--r-- | lib/CodeGen/MachineBasicBlock.cpp | 90 | 
1 files changed, 83 insertions, 7 deletions
| diff --git a/lib/CodeGen/MachineBasicBlock.cpp b/lib/CodeGen/MachineBasicBlock.cpp index fa6b4502c4ab..18d021d521d6 100644 --- a/lib/CodeGen/MachineBasicBlock.cpp +++ b/lib/CodeGen/MachineBasicBlock.cpp @@ -21,7 +21,7 @@  #include "llvm/MC/MCAsmInfo.h"  #include "llvm/MC/MCContext.h"  #include "llvm/Target/TargetRegisterInfo.h" -#include "llvm/Target/TargetData.h" +#include "llvm/DataLayout.h"  #include "llvm/Target/TargetInstrInfo.h"  #include "llvm/Target/TargetMachine.h"  #include "llvm/Assembly/Writer.h" @@ -145,7 +145,8 @@ MachineBasicBlock::iterator MachineBasicBlock::getFirstNonPHI() {    instr_iterator I = instr_begin(), E = instr_end();    while (I != E && I->isPHI())      ++I; -  assert(!I->isInsideBundle() && "First non-phi MI cannot be inside a bundle!"); +  assert((I == E || !I->isInsideBundle()) && +         "First non-phi MI cannot be inside a bundle!");    return I;  } @@ -156,7 +157,7 @@ MachineBasicBlock::SkipPHIsAndLabels(MachineBasicBlock::iterator I) {      ++I;    // FIXME: This needs to change if we wish to bundle labels / dbg_values    // inside the bundle. -  assert(!I->isInsideBundle() && +  assert((I == E || !I->isInsideBundle()) &&           "First non-phi / non-label instruction is inside a bundle!");    return I;  } @@ -228,9 +229,11 @@ const MachineBasicBlock *MachineBasicBlock::getLandingPadSuccessor() const {    return 0;  } +#if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)  void MachineBasicBlock::dump() const {    print(dbgs());  } +#endif  StringRef MachineBasicBlock::getName() const {    if (const BasicBlock *LBB = getBasicBlock()) @@ -243,7 +246,7 @@ StringRef MachineBasicBlock::getName() const {  std::string MachineBasicBlock::getFullName() const {    std::string Name;    if (getParent()) -    Name = (getParent()->getFunction()->getName() + ":").str(); +    Name = (getParent()->getName() + ":").str();    if (getBasicBlock())      Name += getBasicBlock()->getName();    else @@ -942,12 +945,11 @@ MachineBasicBlock::findDebugLoc(instr_iterator MBBI) {  /// getSuccWeight - Return weight of the edge from this block to MBB.  /// -uint32_t MachineBasicBlock::getSuccWeight(const MachineBasicBlock *succ) const { +uint32_t MachineBasicBlock::getSuccWeight(const_succ_iterator Succ) const {    if (Weights.empty())      return 0; -  const_succ_iterator I = std::find(Successors.begin(), Successors.end(), succ); -  return *getWeightIterator(I); +  return *getWeightIterator(Succ);  }  /// getWeightIterator - Return wight iterator corresonding to the I successor @@ -970,6 +972,80 @@ getWeightIterator(MachineBasicBlock::const_succ_iterator I) const {    return Weights.begin() + index;  } +/// Return whether (physical) register "Reg" has been <def>ined and not <kill>ed +/// as of just before "MI". +///  +/// Search is localised to a neighborhood of +/// Neighborhood instructions before (searching for defs or kills) and N +/// instructions after (searching just for defs) MI. +MachineBasicBlock::LivenessQueryResult +MachineBasicBlock::computeRegisterLiveness(const TargetRegisterInfo *TRI, +                                           unsigned Reg, MachineInstr *MI, +                                           unsigned Neighborhood) { +   +  unsigned N = Neighborhood; +  MachineBasicBlock *MBB = MI->getParent(); + +  // Start by searching backwards from MI, looking for kills, reads or defs. + +  MachineBasicBlock::iterator I(MI); +  // If this is the first insn in the block, don't search backwards. +  if (I != MBB->begin()) { +    do { +      --I; + +      MachineOperandIteratorBase::PhysRegInfo Analysis = +        MIOperands(I).analyzePhysReg(Reg, TRI); + +      if (Analysis.Kills) +        // Register killed, so isn't live. +        return LQR_Dead; + +      else if (Analysis.DefinesOverlap || Analysis.ReadsOverlap) +        // Defined or read without a previous kill - live. +        return (Analysis.Defines || Analysis.Reads) ?  +          LQR_Live : LQR_OverlappingLive; + +    } while (I != MBB->begin() && --N > 0); +  } + +  // Did we get to the start of the block? +  if (I == MBB->begin()) { +    // If so, the register's state is definitely defined by the live-in state. +    for (MCRegAliasIterator RAI(Reg, TRI, /*IncludeSelf=*/true); +         RAI.isValid(); ++RAI) { +      if (MBB->isLiveIn(*RAI)) +        return (*RAI == Reg) ? LQR_Live : LQR_OverlappingLive; +    } + +    return LQR_Dead; +  } + +  N = Neighborhood; + +  // Try searching forwards from MI, looking for reads or defs. +  I = MachineBasicBlock::iterator(MI); +  // If this is the last insn in the block, don't search forwards. +  if (I != MBB->end()) { +    for (++I; I != MBB->end() && N > 0; ++I, --N) { +      MachineOperandIteratorBase::PhysRegInfo Analysis = +        MIOperands(I).analyzePhysReg(Reg, TRI); + +      if (Analysis.ReadsOverlap) +        // Used, therefore must have been live. +        return (Analysis.Reads) ? +          LQR_Live : LQR_OverlappingLive; + +      else if (Analysis.DefinesOverlap) +        // Defined (but not read) therefore cannot have been live. +        return LQR_Dead; +    } +  } + +  // At this point we have no idea of the liveness of the register. +  return LQR_Unknown; +} +  void llvm::WriteAsOperand(raw_ostream &OS, const MachineBasicBlock *MBB,                            bool t) {    OS << "BB#" << MBB->getNumber(); | 
