diff options
Diffstat (limited to 'llvm')
| -rw-r--r-- | llvm/include/llvm/Analysis/PHITransAddr.h | 8 | ||||
| -rw-r--r-- | llvm/lib/Analysis/PHITransAddr.cpp | 69 | 
2 files changed, 77 insertions, 0 deletions
| diff --git a/llvm/include/llvm/Analysis/PHITransAddr.h b/llvm/include/llvm/Analysis/PHITransAddr.h index 8257396a09f..d090dc38f1d 100644 --- a/llvm/include/llvm/Analysis/PHITransAddr.h +++ b/llvm/include/llvm/Analysis/PHITransAddr.h @@ -80,6 +80,13 @@ public:    Value *PHITranslateWithInsertion(BasicBlock *CurBB, BasicBlock *PredBB,                                     const DominatorTree &DT,                                     SmallVectorImpl<Instruction*> &NewInsts); +   +  void dump() const; +   +  /// Verify - Check internal consistency of this data structure.  Though it +  /// claims to return a bool, it actually aborts on error and always returns +  /// true. +  bool Verify() const;  private:    Value *PHITranslateSubExpr(Value *V, BasicBlock *CurBB, BasicBlock *PredBB); @@ -103,6 +110,7 @@ private:    /// array that are due to the specified instruction that is about to be    /// removed from the address, and add any corresponding to V.  This returns V.    Value *ReplaceInstWithValue(Instruction *I, Value *V); +    };  } // end namespace llvm diff --git a/llvm/lib/Analysis/PHITransAddr.cpp b/llvm/lib/Analysis/PHITransAddr.cpp index edb41f7f4cc..187924f45a8 100644 --- a/llvm/lib/Analysis/PHITransAddr.cpp +++ b/llvm/lib/Analysis/PHITransAddr.cpp @@ -14,6 +14,7 @@  #include "llvm/Analysis/PHITransAddr.h"  #include "llvm/Analysis/Dominators.h"  #include "llvm/Analysis/InstructionSimplify.h" +#include "llvm/Support/raw_ostream.h"  using namespace llvm;  static bool CanPHITrans(Instruction *Inst) { @@ -32,6 +33,72 @@ static bool CanPHITrans(Instruction *Inst) {    return false;  } +void PHITransAddr::dump() const { +  if (Addr == 0) { +    errs() << "PHITransAddr: null\n"; +    return; +  } +  errs() << "PHITransAddr: " << *Addr << "\n"; +  for (unsigned i = 0, e = InstInputs.size(); i != e; ++i) +    errs() << "  Input #" << i << " is " << *InstInputs[i] << "\n"; +} + + +static bool VerifySubExpr(Value *Expr, +                          SmallVectorImpl<Instruction*> &InstInputs) { +  // If this is a non-instruction value, there is nothing to do. +  Instruction *I = dyn_cast<Instruction>(Expr); +  if (I == 0) return true; +   +  // If it's an instruction, it is either in Tmp or its operands recursively +  // are. +  SmallVectorImpl<Instruction*>::iterator Entry = +    std::find(InstInputs.begin(), InstInputs.end(), I); +  if (Entry != InstInputs.end()) { +    InstInputs.erase(Entry); +    return true; +  } +   +  // If it isn't in the InstInputs list it is a subexpr incorporated into the +  // address.  Sanity check that it is phi translatable. +  if (!CanPHITrans(I)) { +    errs() << "Non phi translatable instruction found in PHITransAddr, either " +              "something is missing from InstInputs or CanPHITrans is wrong:\n"; +    errs() << *I << '\n'; +    return false; +  } +   +  // Validate the operands of the instruction. +  for (unsigned i = 0, e = I->getNumOperands(); i != e; ++i) +    if (!VerifySubExpr(I->getOperand(i), InstInputs)) +      return false; + +  return true; +} + +/// Verify - Check internal consistency of this data structure.  If the +/// structure is valid, it returns true.  If invalid, it prints errors and +/// returns false. +bool PHITransAddr::Verify() const { +  if (Addr == 0) return true; +   +  SmallVector<Instruction*, 8> Tmp(InstInputs.begin(), InstInputs.end());   +   +  if (!VerifySubExpr(Addr, Tmp)) +    return false; +   +  if (!Tmp.empty()) { +    errs() << "PHITransAddr inconsistent, contains extra instructions:\n"; +    for (unsigned i = 0, e = InstInputs.size(); i != e; ++i) +      errs() << "  InstInput #" << i << " is " << *InstInputs[i] << "\n"; +    return false; +  } +   +  // a-ok. +  return true; +} + +  /// IsPotentiallyPHITranslatable - If this needs PHI translation, return true  /// if we have some hope of doing it.  This should be used as a filter to  /// avoid calling PHITranslateValue in hopeless situations. @@ -236,7 +303,9 @@ Value *PHITransAddr::PHITranslateSubExpr(Value *V, BasicBlock *CurBB,  /// CurBB to Pred, updating our state the reflect any needed changes.  This  /// returns true on failure and sets Addr to null.  bool PHITransAddr::PHITranslateValue(BasicBlock *CurBB, BasicBlock *PredBB) { +  assert(Verify() && "Invalid PHITransAddr!");    Addr = PHITranslateSubExpr(Addr, CurBB, PredBB); +  assert(Verify() && "Invalid PHITransAddr!");    return Addr == 0;  } | 

