From 46e7740a4433383e6e5561f089a091c22125bd07 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Tue, 31 Mar 2009 22:55:09 +0000 Subject: [PATCH] reimplement BitcodeReaderValueList in terms of WeakVH instead of making it be an LLVM IR User object. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@68156 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/Bitcode/Reader/BitcodeReader.cpp | 73 +++++++++++++------------- lib/Bitcode/Reader/BitcodeReader.h | 77 +++++++--------------------- 2 files changed, 56 insertions(+), 94 deletions(-) diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index 69eadd9ee41..dfa215c2ed7 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/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 : 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(&*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(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 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(cast(*I), 0)); assert(It != ResolveConstants.end() && It->first == *I); - NewOp = this->getOperand(It->second); + NewOp = operator[](It->second); } NewOps.push_back(cast(NewOp)); @@ -2064,7 +2067,7 @@ Module *BitcodeReader::materializeModule(std::string *ErrInfo) { if (CallInst* CI = dyn_cast(*UI++)) UpgradeIntrinsicCall(CI, I->second); } - ValueList.replaceUsesOfWith(I->first, I->second); + I->first->replaceAllUsesWith(I->second); I->first->eraseFromParent(); } } diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index 0b72b340154..1fbf219fb8e 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/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 @@ -30,8 +31,8 @@ namespace llvm { // BitcodeReaderValueList Class //===----------------------------------------------------------------------===// -class BitcodeReaderValueList : public User { - unsigned Capacity; +class BitcodeReaderValueList { + std::vector 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 > 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(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 - : HungoffOperandTraits { -}; - -DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitcodeReaderValueList, Value) - class BitcodeReader : public ModuleProvider { MemoryBuffer *Buffer; BitstreamReader Stream; -- 2.34.1