diff options
Diffstat (limited to 'lib/Bitcode')
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.cpp | 51 | ||||
-rw-r--r-- | lib/Bitcode/Reader/BitcodeReader.h | 50 |
2 files changed, 74 insertions, 27 deletions
diff --git a/lib/Bitcode/Reader/BitcodeReader.cpp b/lib/Bitcode/Reader/BitcodeReader.cpp index ec25f52..78cd1de 100644 --- a/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/lib/Bitcode/Reader/BitcodeReader.cpp @@ -23,6 +23,7 @@ #include "llvm/ADT/SmallVector.h" #include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" +#include "llvm/OperandTraits.h" using namespace llvm; void BitcodeReader::FreeState() { @@ -115,55 +116,81 @@ static int GetDecodedBinaryOpcode(unsigned Val, const Type *Ty) { } } - +namespace llvm { namespace { /// @brief A class for maintaining the slot number definition /// as a placeholder for the actual definition for forward constants defs. class ConstantPlaceHolder : public ConstantExpr { ConstantPlaceHolder(); // DO NOT IMPLEMENT void operator=(const ConstantPlaceHolder &); // DO NOT IMPLEMENT - Use Op; public: // allocate space for exactly one operand void *operator new(size_t s) { return User::operator new(s, 1); } explicit ConstantPlaceHolder(const Type *Ty) - : ConstantExpr(Ty, Instruction::UserOp1, &Op, 1), - Op(UndefValue::get(Type::Int32Ty), this) { + : ConstantExpr(Ty, Instruction::UserOp1, &Op<0>(), 1) { + Op<0>() = UndefValue::get(Type::Int32Ty); } + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); }; } + + // 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); + } +} + Constant *BitcodeReaderValueList::getConstantFwdRef(unsigned Idx, const Type *Ty) { if (Idx >= size()) { // Insert a bunch of null values. - Uses.resize(Idx+1); - OperandList = &Uses[0]; + resize(Idx + 1); NumOperands = Idx+1; } - if (Value *V = Uses[Idx]) { + if (Value *V = OperandList[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); - Uses[Idx].init(C, this); + OperandList[Idx].init(C, this); return C; } Value *BitcodeReaderValueList::getValueFwdRef(unsigned Idx, const Type *Ty) { if (Idx >= size()) { // Insert a bunch of null values. - Uses.resize(Idx+1); - OperandList = &Uses[0]; + resize(Idx + 1); NumOperands = Idx+1; } - if (Value *V = Uses[Idx]) { + if (Value *V = OperandList[Idx]) { assert((Ty == 0 || Ty == V->getType()) && "Type mismatch in value table!"); return V; } @@ -173,7 +200,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); - Uses[Idx].init(V, this); + OperandList[Idx].init(V, this); return V; } diff --git a/lib/Bitcode/Reader/BitcodeReader.h b/lib/Bitcode/Reader/BitcodeReader.h index 86b00a5..c35846f 100644 --- a/lib/Bitcode/Reader/BitcodeReader.h +++ b/lib/Bitcode/Reader/BitcodeReader.h @@ -17,7 +17,7 @@ #include "llvm/ModuleProvider.h" #include "llvm/ParameterAttributes.h" #include "llvm/Type.h" -#include "llvm/User.h" +#include "llvm/OperandTraits.h" #include "llvm/Bitcode/BitstreamReader.h" #include "llvm/Bitcode/LLVMBitCodes.h" #include "llvm/ADT/DenseMap.h" @@ -26,32 +26,43 @@ namespace llvm { class MemoryBuffer; +//===----------------------------------------------------------------------===// +// BitcodeReaderValueList Class +//===----------------------------------------------------------------------===// + class BitcodeReaderValueList : public User { - std::vector<Use> Uses; + unsigned Capacity; public: - BitcodeReaderValueList() : User(Type::VoidTy, Value::ArgumentVal, 0, 0) {} - + BitcodeReaderValueList() : User(Type::VoidTy, Value::ArgumentVal, 0, 0) + , Capacity(0) {} + + /// Provide fast operand accessors + DECLARE_TRANSPARENT_OPERAND_ACCESSORS(Value); + // vector compatibility methods unsigned size() const { return getNumOperands(); } + void resize(unsigned); void push_back(Value *V) { - Uses.push_back(Use(V, this)); - OperandList = &Uses[0]; - ++NumOperands; + unsigned OldOps(NumOperands), NewOps(NumOperands + 1); + resize(NewOps); + NumOperands = NewOps; + OperandList[OldOps] = V; } void clear() { - std::vector<Use>().swap(Uses); + if (OperandList) dropHungoffUses(OperandList); + Capacity = 0; } Value *operator[](unsigned i) const { return getOperand(i); } - Value *back() const { return Uses.back(); } - void pop_back() { Uses.pop_back(); --NumOperands; } + Value *back() const { return getOperand(size() - 1); } + void pop_back() { setOperand(size() - 1, 0); --NumOperands; } bool empty() const { return NumOperands == 0; } void shrinkTo(unsigned N) { assert(N <= NumOperands && "Invalid shrinkTo request!"); - Uses.resize(N); - NumOperands = N; + while (NumOperands > N) + pop_back(); } virtual void print(std::ostream&) const {} @@ -73,11 +84,20 @@ public: private: void initVal(unsigned Idx, Value *V) { - assert(Uses[Idx] == 0 && "Cannot init an already init'd Use!"); - Uses[Idx].init(V, this); + 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].init(V, this); } }; - + +template <> +struct OperandTraits<BitcodeReaderValueList> : HungoffOperandTraits</*16 FIXME*/> { +}; + +DEFINE_TRANSPARENT_OPERAND_ACCESSORS(BitcodeReaderValueList, Value) class BitcodeReader : public ModuleProvider { MemoryBuffer *Buffer; |