diff options
author | Devang Patel <dpatel@apple.com> | 2009-08-04 06:00:18 +0000 |
---|---|---|
committer | Devang Patel <dpatel@apple.com> | 2009-08-04 06:00:18 +0000 |
commit | 05eb617da534e392c07997e78d2c4593ed8ae1cd (patch) | |
tree | 0c270c72e2a3399ca9a816526b1bdcc4a439d8e1 /llvm/lib/Bitcode | |
parent | b58dc1c667f4d67cafe6870db685062c65c8d2b6 (diff) | |
download | bcm5719-llvm-05eb617da534e392c07997e78d2c4593ed8ae1cd.tar.gz bcm5719-llvm-05eb617da534e392c07997e78d2c4593ed8ae1cd.zip |
Use separate ValueList for metadata.
This fixes PR4666.
llvm-svn: 78056
Diffstat (limited to 'llvm/lib/Bitcode')
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.cpp | 50 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Reader/BitcodeReader.h | 43 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/BitcodeWriter.cpp | 4 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.cpp | 81 | ||||
-rw-r--r-- | llvm/lib/Bitcode/Writer/ValueEnumerator.h | 15 |
5 files changed, 149 insertions, 44 deletions
diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp index 81fdbd29afb..4ad97b12d62 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.cpp +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.cpp @@ -34,6 +34,7 @@ void BitcodeReader::FreeState() { Buffer = 0; std::vector<PATypeHolder>().swap(TypeList); ValueList.clear(); + MDValueList.clear(); std::vector<AttrListPtr>().swap(MAttributes); std::vector<BasicBlock*>().swap(FunctionBBs); @@ -312,6 +313,41 @@ void BitcodeReaderValueList::ResolveConstantForwardRefs() { } } +void BitcodeReaderMDValueList::AssignValue(Value *V, unsigned Idx) { + if (Idx == size()) { + push_back(V); + return; + } + + if (Idx >= size()) + resize(Idx+1); + + WeakVH &OldV = MDValuePtrs[Idx]; + if (OldV == 0) { + OldV = V; + return; + } + + // If there was a forward reference to this value, replace it. + Value *PrevVal = OldV; + OldV->replaceAllUsesWith(V); + delete PrevVal; +} + +Value *BitcodeReaderMDValueList::getValueFwdRef(unsigned Idx) { + if (Idx >= size()) + resize(Idx + 1); + + if (Value *V = MDValuePtrs[Idx]) { + assert(V->getType() == Type::MetadataTy && "Type mismatch in value table!"); + return V; + } + + // Create and return a placeholder, which will later be RAUW'd. + Value *V = new Argument(Type::MetadataTy); + MDValuePtrs[Idx] = V; + return V; +} const Type *BitcodeReader::getTypeByID(unsigned ID, bool isTypeTable) { // If the TypeID is in range, return it. @@ -700,7 +736,7 @@ bool BitcodeReader::ParseValueSymbolTable() { } bool BitcodeReader::ParseMetadata() { - unsigned NextValueNo = ValueList.size(); + unsigned NextValueNo = MDValueList.size(); if (Stream.EnterSubBlock(bitc::METADATA_BLOCK_ID)) return Error("Malformed block record"); @@ -752,13 +788,13 @@ bool BitcodeReader::ParseMetadata() { unsigned Size = Record.size(); SmallVector<MetadataBase*, 8> Elts; for (unsigned i = 0; i != Size; ++i) { - Value *MD = ValueList.getValueFwdRef(Record[i], Type::MetadataTy); + Value *MD = MDValueList.getValueFwdRef(Record[i]); if (MetadataBase *B = dyn_cast<MetadataBase>(MD)) Elts.push_back(B); } Value *V = NamedMDNode::Create(Name.c_str(), Elts.data(), Elts.size(), TheModule); - ValueList.AssignValue(V, NextValueNo++); + MDValueList.AssignValue(V, NextValueNo++); break; } case bitc::METADATA_NODE: { @@ -769,13 +805,15 @@ bool BitcodeReader::ParseMetadata() { SmallVector<Value*, 8> Elts; for (unsigned i = 0; i != Size; i += 2) { const Type *Ty = getTypeByID(Record[i], false); - if (Ty != Type::VoidTy) + if (Ty == Type::MetadataTy) + Elts.push_back(MDValueList.getValueFwdRef(Record[i+1])); + else if (Ty != Type::VoidTy) Elts.push_back(ValueList.getValueFwdRef(Record[i+1], Ty)); else Elts.push_back(NULL); } Value *V = MDNode::get(Context, &Elts[0], Elts.size()); - ValueList.AssignValue(V, NextValueNo++); + MDValueList.AssignValue(V, NextValueNo++); break; } case bitc::METADATA_STRING: { @@ -786,7 +824,7 @@ bool BitcodeReader::ParseMetadata() { String[i] = Record[i]; Value *V = MDString::get(Context, StringRef(String.data(), String.size())); - ValueList.AssignValue(V, NextValueNo++); + MDValueList.AssignValue(V, NextValueNo++); break; } } diff --git a/llvm/lib/Bitcode/Reader/BitcodeReader.h b/llvm/lib/Bitcode/Reader/BitcodeReader.h index 77dabdee2dc..bd048885a65 100644 --- a/llvm/lib/Bitcode/Reader/BitcodeReader.h +++ b/llvm/lib/Bitcode/Reader/BitcodeReader.h @@ -86,6 +86,41 @@ public: void ResolveConstantForwardRefs(); }; + +//===----------------------------------------------------------------------===// +// BitcodeReaderMDValueList Class +//===----------------------------------------------------------------------===// + +class BitcodeReaderMDValueList { + std::vector<WeakVH> MDValuePtrs; + + LLVMContext& Context; +public: + BitcodeReaderMDValueList(LLVMContext& C) : Context(C) {} + + // vector compatibility methods + unsigned size() const { return MDValuePtrs.size(); } + void resize(unsigned N) { MDValuePtrs.resize(N); } + void push_back(Value *V) { MDValuePtrs.push_back(V); } + void clear() { MDValuePtrs.clear(); } + Value *back() const { return MDValuePtrs.back(); } + void pop_back() { MDValuePtrs.pop_back(); } + bool empty() const { return MDValuePtrs.empty(); } + + Value *operator[](unsigned i) const { + assert(i < MDValuePtrs.size()); + return MDValuePtrs[i]; + } + + void shrinkTo(unsigned N) { + assert(N <= size() && "Invalid shrinkTo request!"); + MDValuePtrs.resize(N); + } + + Value *getValueFwdRef(unsigned Idx); + void AssignValue(Value *V, unsigned Idx); +}; + class BitcodeReader : public ModuleProvider { LLVMContext& Context; MemoryBuffer *Buffer; @@ -96,6 +131,7 @@ class BitcodeReader : public ModuleProvider { std::vector<PATypeHolder> TypeList; BitcodeReaderValueList ValueList; + BitcodeReaderMDValueList MDValueList; std::vector<std::pair<GlobalVariable*, unsigned> > GlobalInits; std::vector<std::pair<GlobalAlias*, unsigned> > AliasInits; @@ -127,7 +163,7 @@ class BitcodeReader : public ModuleProvider { DenseMap<Function*, std::pair<uint64_t, unsigned> > DeferredFunctionInfo; public: explicit BitcodeReader(MemoryBuffer *buffer, LLVMContext& C) - : Context(C), Buffer(buffer), ErrorString(0), ValueList(C) { + : Context(C), Buffer(buffer), ErrorString(0), ValueList(C), MDValueList(C) { HasReversedFunctionsWithBodies = false; } ~BitcodeReader() { @@ -160,7 +196,10 @@ public: private: const Type *getTypeByID(unsigned ID, bool isTypeTable = false); Value *getFnValueByID(unsigned ID, const Type *Ty) { - return ValueList.getValueFwdRef(ID, Ty); + if (Ty == Type::MetadataTy) + return MDValueList.getValueFwdRef(ID); + else + return ValueList.getValueFwdRef(ID, Ty); } BasicBlock *getBasicBlock(unsigned ID) const { if (ID >= FunctionBBs.size()) return 0; // Invalid ID diff --git a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp index 6bd40ba0e5b..a5c28fcc763 100644 --- a/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp +++ b/llvm/lib/Bitcode/Writer/BitcodeWriter.cpp @@ -492,7 +492,7 @@ static void WriteMDNode(const MDNode *N, static void WriteModuleMetadata(const ValueEnumerator &VE, BitstreamWriter &Stream) { - const ValueEnumerator::ValueList &Vals = VE.getValues(); + const ValueEnumerator::ValueList &Vals = VE.getMDValues(); bool StartedMetadataBlock = false; unsigned MDSAbbrev = 0; SmallVector<uint64_t, 64> Record; @@ -601,8 +601,6 @@ static void WriteConstants(unsigned FirstVal, unsigned LastVal, const Type *LastTy = 0; for (unsigned i = FirstVal; i != LastVal; ++i) { const Value *V = Vals[i].first; - if (isa<MetadataBase>(V)) - continue; // If we need to switch types, do so now. if (V->getType() != LastTy) { LastTy = V->getType(); diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp index 7583bb96c9e..4712dea7629 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.cpp @@ -114,6 +114,18 @@ ValueEnumerator::ValueEnumerator(const Module *M) { TypeMap[Types[i].first] = i+1; } +unsigned ValueEnumerator::getValueID(const Value *V) const { + if (isa<MetadataBase>(V)) { + ValueMapType::const_iterator I = MDValueMap.find(V); + assert(I != MDValueMap.end() && "Value not in slotcalculator!"); + return I->second-1; + } + + ValueMapType::const_iterator I = ValueMap.find(V); + assert(I != ValueMap.end() && "Value not in slotcalculator!"); + return I->second-1; +} + // Optimize constant ordering. namespace { struct CstSortPredicate { @@ -165,9 +177,51 @@ void ValueEnumerator::EnumerateValueSymbolTable(const ValueSymbolTable &VST) { EnumerateValue(VI->getValue()); } +void ValueEnumerator::EnumerateMetadata(const MetadataBase *MD) { + // Check to see if it's already in! + unsigned &MDValueID = MDValueMap[MD]; + if (MDValueID) { + // Increment use count. + MDValues[MDValueID-1].second++; + return; + } + + // Enumerate the type of this value. + EnumerateType(MD->getType()); + + if (const MDNode *N = dyn_cast<MDNode>(MD)) { + MDValues.push_back(std::make_pair(MD, 1U)); + MDValueMap[MD] = MDValues.size(); + MDValueID = MDValues.size(); + for (MDNode::const_elem_iterator I = N->elem_begin(), E = N->elem_end(); + I != E; ++I) { + if (*I) + EnumerateValue(*I); + else + EnumerateType(Type::VoidTy); + } + return; + } else if (const NamedMDNode *N = dyn_cast<NamedMDNode>(MD)) { + for(NamedMDNode::const_elem_iterator I = N->elem_begin(), + E = N->elem_end(); I != E; ++I) { + MetadataBase *M = *I; + EnumerateValue(M); + } + MDValues.push_back(std::make_pair(MD, 1U)); + MDValueMap[MD] = Values.size(); + return; + } + + // Add the value. + MDValues.push_back(std::make_pair(MD, 1U)); + MDValueID = MDValues.size(); +} + void ValueEnumerator::EnumerateValue(const Value *V) { assert(V->getType() != Type::VoidTy && "Can't insert void values!"); - + if (const MetadataBase *MB = dyn_cast<MetadataBase>(V)) + return EnumerateMetadata(MB); + // Check to see if it's already in! unsigned &ValueID = ValueMap[V]; if (ValueID) { @@ -207,31 +261,6 @@ void ValueEnumerator::EnumerateValue(const Value *V) { } } - if (const MDNode *N = dyn_cast<MDNode>(V)) { - Values.push_back(std::make_pair(V, 1U)); - ValueMap[V] = Values.size(); - ValueID = Values.size(); - for (MDNode::const_elem_iterator I = N->elem_begin(), E = N->elem_end(); - I != E; ++I) { - if (*I) - EnumerateValue(*I); - else - EnumerateType(Type::VoidTy); - } - return; - } - - if (const NamedMDNode *N = dyn_cast<NamedMDNode>(V)) { - for(NamedMDNode::const_elem_iterator I = N->elem_begin(), - E = N->elem_end(); I != E; ++I) { - MetadataBase *M = *I; - EnumerateValue(M); - } - Values.push_back(std::make_pair(V, 1U)); - ValueMap[V] = Values.size(); - return; - } - // Add the value. Values.push_back(std::make_pair(V, 1U)); ValueID = Values.size(); diff --git a/llvm/lib/Bitcode/Writer/ValueEnumerator.h b/llvm/lib/Bitcode/Writer/ValueEnumerator.h index 40eeabb2b6a..b5106f0809f 100644 --- a/llvm/lib/Bitcode/Writer/ValueEnumerator.h +++ b/llvm/lib/Bitcode/Writer/ValueEnumerator.h @@ -25,6 +25,7 @@ class Value; class BasicBlock; class Function; class Module; +class MetadataBase; class AttrListPtr; class TypeSymbolTable; class ValueSymbolTable; @@ -44,7 +45,9 @@ private: typedef DenseMap<const Value*, unsigned> ValueMapType; ValueMapType ValueMap; ValueList Values; - + ValueList MDValues; + ValueMapType MDValueMap; + typedef DenseMap<void*, unsigned> AttributeMapType; AttributeMapType AttributeMap; std::vector<AttrListPtr> Attributes; @@ -64,12 +67,8 @@ private: public: ValueEnumerator(const Module *M); - unsigned getValueID(const Value *V) const { - ValueMapType::const_iterator I = ValueMap.find(V); - assert(I != ValueMap.end() && "Value not in slotcalculator!"); - return I->second-1; - } - + unsigned getValueID(const Value *V) const; + unsigned getTypeID(const Type *T) const { TypeMapType::const_iterator I = TypeMap.find(T); assert(I != TypeMap.end() && "Type not in ValueEnumerator!"); @@ -91,6 +90,7 @@ public: } const ValueList &getValues() const { return Values; } + const ValueList &getMDValues() const { return MDValues; } const TypeList &getTypes() const { return Types; } const std::vector<const BasicBlock*> &getBasicBlocks() const { return BasicBlocks; @@ -108,6 +108,7 @@ public: private: void OptimizeConstants(unsigned CstStart, unsigned CstEnd); + void EnumerateMetadata(const MetadataBase *MD); void EnumerateValue(const Value *V); void EnumerateType(const Type *T); void EnumerateOperandType(const Value *V); |