diff options
| -rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 73 | ||||
| -rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.h | 77 | 
2 files changed, 56 insertions, 94 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 69eadd9ee41..dfa215c2ed7 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -146,64 +146,67 @@ namespace {      /// Provide fast operand accessors -    DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); +    //DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value);    };  } - -  // FIXME: can we inherit this from ConstantExpr? +// FIXME: can we inherit this from ConstantExpr?  template <>  struct OperandTraits<ConstantPlaceHolder> : FixedNumOperandTraits<1> {  }; - -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(ConstantPlaceHolder, Value)  } -void BitcodeReaderValueList::resize(unsigned Desired) { -  if (Desired > Capacity) { -    // Since we expect many values to come from the bitcode file we better -    // allocate the double amount, so that the array size grows exponentially -    // at each reallocation.  Also, add a small amount of 100 extra elements -    // each time, to reallocate less frequently when the array is still small. -    // -    Capacity = Desired * 2 + 100; -    Use *New = allocHungoffUses(Capacity); -    Use *Old = OperandList; -    unsigned Ops = getNumOperands(); -    for (int i(Ops - 1); i >= 0; --i) -      New[i] = Old[i].get(); -    OperandList = New; -    if (Old) Use::zap(Old, Old + Ops, true); + +void BitcodeReaderValueList::AssignValue(Value *V, unsigned Idx) { +  if (Idx == size()) { +    push_back(V); +    return; +  } +   +  if (Idx >= size()) +    resize(Idx+1); +   +  WeakVH &OldV = ValuePtrs[Idx]; +  if (OldV == 0) { +    OldV = V; +    return; +  } +   +  // Handle constants and non-constants (e.g. instrs) differently for +  // efficiency. +  if (Constant *PHC = dyn_cast<Constant>(&*OldV)) { +    ResolveConstants.push_back(std::make_pair(PHC, Idx)); +    OldV = V; +  } else { +    // If there was a forward reference to this value, replace it. +    Value *PrevVal = OldV; +    OldV->replaceAllUsesWith(V); +    delete PrevVal;    }  } +    Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx,                                                      const Type *Ty) { -  if (Idx >= size()) { -    // Insert a bunch of null values. +  if (Idx >= size())      resize(Idx + 1); -    NumOperands = Idx+1; -  } -  if (Value *V = OperandList[Idx]) { +  if (Value *V = ValuePtrs[Idx]) {      assert(Ty == V->getType() && "Type mismatch in constant table!");      return cast<Constant>(V);    }    // Create and return a placeholder, which will later be RAUW'd.    Constant *C = new ConstantPlaceHolder(Ty); -  OperandList[Idx] = C; +  ValuePtrs[Idx] = C;    return C;  }  Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, const Type *Ty) { -  if (Idx >= size()) { -    // Insert a bunch of null values. +  if (Idx >= size())      resize(Idx + 1); -    NumOperands = Idx+1; -  } -  if (Value *V = OperandList[Idx]) { +  if (Value *V = ValuePtrs[Idx]) {      assert((Ty == 0 || Ty == V->getType()) && "Type mismatch in value table!");      return V;    } @@ -213,7 +216,7 @@ Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, const Type *Ty) {    // Create and return a placeholder, which will later be RAUW'd.    Value *V = new Argument(Ty); -  OperandList[Idx] = V; +  ValuePtrs[Idx] = V;    return V;  } @@ -232,7 +235,7 @@ void BitcodeReaderValueList::ResolveConstantForwardRefs() {    SmallVector<Constant*, 64> NewOps;    while (!ResolveConstants.empty()) { -    Value *RealVal = getOperand(ResolveConstants.back().second); +    Value *RealVal = operator[](ResolveConstants.back().second);      Constant *Placeholder = ResolveConstants.back().first;      ResolveConstants.pop_back(); @@ -268,7 +271,7 @@ void BitcodeReaderValueList::ResolveConstantForwardRefs() {                               std::pair<Constant*, unsigned>(cast<Constant>(*I),                                                              0));            assert(It != ResolveConstants.end() && It->first == *I); -          NewOp = this->getOperand(It->second); +          NewOp = operator[](It->second);          }          NewOps.push_back(cast<Constant>(NewOp)); @@ -2064,7 +2067,7 @@ Module *BitcodeReader::materializeModule(std::string *ErrInfo) {          if (CallInst* CI = dyn_cast<CallInst>(*UI++))            UpgradeIntrinsicCall(CI, I->second);        } -      ValueList.replaceUsesOfWith(I->first, I->second); +      I->first->replaceAllUsesWith(I->second);        I->first->eraseFromParent();      }    } diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.h b/llvm/lib/Bitcode/Reader/BitcodeReader.h index 0b72b340154..1fbf219fb8e 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.h +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.h @@ -20,6 +20,7 @@  #include "llvm/OperandTraits.h"  #include "llvm/Bitcode/BitstreamReader.h"  #include "llvm/Bitcode/LLVMBitCodes.h" +#include "llvm/Support/ValueHandle.h"  #include "llvm/ADT/DenseMap.h"  #include <vector> @@ -30,8 +31,8 @@ namespace llvm {  //                          BitcodeReaderValueList Class  //===----------------------------------------------------------------------===// -class BitcodeReaderValueList : public User { -  unsigned Capacity; +class BitcodeReaderValueList { +  std::vector<WeakVH> ValuePtrs;    /// ResolveConstants - As we resolve forward-referenced constants, we add    /// information about them to this vector.  This allows us to resolve them in @@ -43,88 +44,46 @@ class BitcodeReaderValueList : public User {    typedef std::vector<std::pair<Constant*, unsigned> > ResolveConstantsTy;    ResolveConstantsTy ResolveConstants;  public: -  BitcodeReaderValueList() : User(Type::VoidTy, Value::ArgumentVal, 0, 0) -                           , Capacity(0) {} +  BitcodeReaderValueList() {}    ~BitcodeReaderValueList() {      assert(ResolveConstants.empty() && "Constants not resolved?");    } -  /// Provide fast operand accessors -  DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); -    // vector compatibility methods -  unsigned size() const { return getNumOperands(); } -  void resize(unsigned); +  unsigned size() const { return ValuePtrs.size(); } +  void resize(unsigned N) { ValuePtrs.resize(N); }    void push_back(Value *V) { -    unsigned OldOps(NumOperands), NewOps(NumOperands + 1); -    resize(NewOps); -    NumOperands = NewOps; -    OperandList[OldOps] = V; +    ValuePtrs.push_back(V);    }    void clear() {      assert(ResolveConstants.empty() && "Constants not resolved?"); -    if (OperandList) dropHungoffUses(OperandList); -    Capacity = 0; +    ValuePtrs.clear();    } -  Value *operator[](unsigned i) const { return getOperand(i); } +  Value *operator[](unsigned i) const { +    assert(i < ValuePtrs.size()); +    return ValuePtrs[i]; +  } -  Value *back() const { return getOperand(size() - 1); } -  void pop_back() { setOperand(size() - 1, 0); --NumOperands; } -  bool empty() const { return NumOperands == 0; } +  Value *back() const { return ValuePtrs.back(); } +    void pop_back() { ValuePtrs.pop_back(); } +  bool empty() const { return ValuePtrs.empty(); }    void shrinkTo(unsigned N) { -    assert(N <= NumOperands && "Invalid shrinkTo request!"); -    while (NumOperands > N) -      pop_back(); +    assert(N <= size() && "Invalid shrinkTo request!"); +    ValuePtrs.resize(N);    } -  virtual void print(std::ostream&) const {}    Constant *getConstantFwdRef(unsigned Idx, const Type *Ty);    Value *getValueFwdRef(unsigned Idx, const Type *Ty); -  void AssignValue(Value *V, unsigned Idx) { -    if (Idx == size()) { -      push_back(V); -    } else if (Value *OldV = getOperand(Idx)) { -      // Handle constants and non-constants (e.g. instrs) differently for -      // efficiency. -      if (Constant *PHC = dyn_cast<Constant>(OldV)) { -        ResolveConstants.push_back(std::make_pair(PHC, Idx)); -        setOperand(Idx, V); -      } else { -        // If there was a forward reference to this value, replace it. -        setOperand(Idx, V); -        OldV->replaceAllUsesWith(V); -        delete OldV; -      } -    } else { -      initVal(Idx, V); -    } -  } +  void AssignValue(Value *V, unsigned Idx);    /// ResolveConstantForwardRefs - Once all constants are read, this method bulk    /// resolves any forward references.    void ResolveConstantForwardRefs(); -   -private: -  void initVal(unsigned Idx, Value *V) { -    if (Idx >= size()) { -      // Insert a bunch of null values. -      resize(Idx * 2 + 1); -    } -    assert(getOperand(Idx) == 0 && "Cannot init an already init'd Use!"); -    OperandList[Idx] = V; -  }  }; -template <> -struct OperandTraits<BitcodeReaderValueList> -  : HungoffOperandTraits</*16 FIXME*/> { -}; - -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitcodeReaderValueList, Value)   -  class BitcodeReader : public ModuleProvider {    MemoryBuffer *Buffer;    BitstreamReader Stream;  | 

