X-Git-Url: http://demsky.eecs.uci.edu/git/?a=blobdiff_plain;f=lib%2FVMCore%2FMetadata.cpp;h=8ae584e920709d2452a4f74ff93bc5d71716d3e0;hb=fb2674d0de83cbf3b79c269bc694f612de148950;hp=eb4544c98249d7eaa410845da9a52c8e890131cc;hpb=0631fce85050f8f633e5fd032875d9151e0db4da;p=oota-llvm.git diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index eb4544c9824..8ae584e9207 100644 --- a/lib/VMCore/Metadata.cpp +++ b/lib/VMCore/Metadata.cpp @@ -15,6 +15,7 @@ #include "llvm/Metadata.h" #include "llvm/LLVMContext.h" #include "llvm/Module.h" +#include "llvm/Instruction.h" #include "SymbolTableListTraitsImpl.h" using namespace llvm; @@ -55,7 +56,7 @@ MDString *MDString::get(LLVMContext &Context, const StringRef &Str) { StringMapEntry &Entry = pImpl->MDStringCache.GetOrCreateValue(Str); MDString *&S = Entry.getValue(); - if (!S) S = new MDString(Entry.getKeyData(), + if (!S) S = new MDString(Context, Entry.getKeyData(), Entry.getKeyLength()); return S; @@ -64,15 +65,18 @@ MDString *MDString::get(LLVMContext &Context, const StringRef &Str) { //===----------------------------------------------------------------------===// //MDNode implementation // -MDNode::MDNode(Value*const* Vals, unsigned NumVals) - : MetadataBase(Type::MetadataTy, Value::MDNodeVal) { +MDNode::MDNode(LLVMContext &C, Value*const* Vals, unsigned NumVals) + : MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) { NumOperands = 0; resizeOperands(NumVals); for (unsigned i = 0; i != NumVals; ++i) { // Only record metadata uses. if (MetadataBase *MB = dyn_cast_or_null(Vals[i])) OperandList[NumOperands++] = MB; - Node.push_back(WeakVH(Vals[i])); + else if(Vals[i] && + Vals[i]->getType()->getTypeID() == Type::MetadataTyID) + OperandList[NumOperands++] = Vals[i]; + Node.push_back(ElementVH(Vals[i], this)); } } @@ -83,12 +87,26 @@ void MDNode::Profile(FoldingSetNodeID &ID) const { MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) { LLVMContextImpl *pImpl = Context.pImpl; - std::vector V; - V.reserve(NumVals); - for (unsigned i = 0; i < NumVals; ++i) - V.push_back(Vals[i]); + FoldingSetNodeID ID; + for (unsigned i = 0; i != NumVals; ++i) + ID.AddPointer(Vals[i]); + + pImpl->ConstantsLock.reader_acquire(); + void *InsertPoint; + MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); + pImpl->ConstantsLock.reader_release(); - return pImpl->MDNodeSet.getOrCreate(Type::MetadataTy, V); + if (!N) { + sys::SmartScopedWriter Writer(pImpl->ConstantsLock); + N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); + if (!N) { + // InsertPoint will have been set by the FindNodeOrInsertPos call. + N = new MDNode(Context, Vals, NumVals); + pImpl->MDNodeSet.InsertNode(N, InsertPoint); + } + } + + return N; } /// dropAllReferences - Remove all uses and clear node vector. @@ -98,14 +116,105 @@ void MDNode::dropAllReferences() { } MDNode::~MDNode() { + { + LLVMContextImpl *pImpl = getType()->getContext().pImpl; + sys::SmartScopedWriter Writer(pImpl->ConstantsLock); + pImpl->MDNodeSet.RemoveNode(this); + } dropAllReferences(); } + +// Replace value from this node's element list. +void MDNode::replaceElement(Value *From, Value *To) { + if (From == To || !getType()) + return; + LLVMContext &Context = getType()->getContext(); + LLVMContextImpl *pImpl = Context.pImpl; + + // Find value. This is a linear search, do something if it consumes + // lot of time. It is possible that to have multiple instances of + // From in this MDNode's element list. + SmallVector Indexes; + unsigned Index = 0; + for (SmallVector::iterator I = Node.begin(), + E = Node.end(); I != E; ++I, ++Index) { + Value *V = *I; + if (V && V == From) + Indexes.push_back(Index); + } + + if (Indexes.empty()) + return; + + // Remove "this" from the context map. + { + sys::SmartScopedWriter Writer(pImpl->ConstantsLock); + pImpl->MDNodeSet.RemoveNode(this); + } + + // MDNode only lists metadata elements in operand list, because MDNode + // used by MDNode is considered a valid use. However on the side, MDNode + // using a non-metadata value is not considered a "use" of non-metadata + // value. + SmallVector OpIndexes; + unsigned OpIndex = 0; + for (User::op_iterator OI = op_begin(), OE = op_end(); + OI != OE; ++OI, OpIndex++) { + if (*OI == From) + OpIndexes.push_back(OpIndex); + } + if (MetadataBase *MDTo = dyn_cast_or_null(To)) { + for (SmallVector::iterator OI = OpIndexes.begin(), + OE = OpIndexes.end(); OI != OE; ++OI) + setOperand(*OI, MDTo); + } else { + for (SmallVector::iterator OI = OpIndexes.begin(), + OE = OpIndexes.end(); OI != OE; ++OI) + setOperand(*OI, 0); + } + + // Replace From element(s) in place. + for (SmallVector::iterator I = Indexes.begin(), E = Indexes.end(); + I != E; ++I) { + unsigned Index = *I; + Node[Index] = ElementVH(To, this); + } + + // Insert updated "this" into the context's folding node set. + // If a node with same element list already exist then before inserting + // updated "this" into the folding node set, replace all uses of existing + // node with updated "this" node. + FoldingSetNodeID ID; + Profile(ID); + pImpl->ConstantsLock.reader_acquire(); + void *InsertPoint; + MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); + pImpl->ConstantsLock.reader_release(); + + if (N) { + N->replaceAllUsesWith(this); + delete N; + N = 0; + } + + { + sys::SmartScopedWriter Writer(pImpl->ConstantsLock); + N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint); + if (!N) { + // InsertPoint will have been set by the FindNodeOrInsertPos call. + N = this; + pImpl->MDNodeSet.InsertNode(N, InsertPoint); + } + } +} + //===----------------------------------------------------------------------===// //NamedMDNode implementation // -NamedMDNode::NamedMDNode(const Twine &N, MetadataBase*const* MDs, +NamedMDNode::NamedMDNode(LLVMContext &C, const Twine &N, + MetadataBase*const* MDs, unsigned NumMDs, Module *ParentModule) - : MetadataBase(Type::MetadataTy, Value::NamedMDNodeVal), Parent(0) { + : MetadataBase(Type::getMetadataTy(C), Value::NamedMDNodeVal), Parent(0) { setName(N); NumOperands = 0; resizeOperands(NumMDs); @@ -119,6 +228,15 @@ NamedMDNode::NamedMDNode(const Twine &N, MetadataBase*const* MDs, ParentModule->getNamedMDList().push_back(this); } +NamedMDNode *NamedMDNode::Create(const NamedMDNode *NMD, Module *M) { + assert (NMD && "Invalid source NamedMDNode!"); + SmallVector Elems; + for (unsigned i = 0, e = NMD->getNumElements(); i != e; ++i) + Elems.push_back(NMD->getElement(i)); + return new NamedMDNode(NMD->getContext(), NMD->getName().data(), + Elems.data(), Elems.size(), M); +} + /// eraseFromParent - Drop all references and remove the node from parent /// module. void NamedMDNode::eraseFromParent() { @@ -134,3 +252,89 @@ void NamedMDNode::dropAllReferences() { NamedMDNode::~NamedMDNode() { dropAllReferences(); } + +//===----------------------------------------------------------------------===// +//Metadata implementation +// + +/// RegisterMDKind - Register a new metadata kind and return its ID. +/// A metadata kind can be registered only once. +MDKindID Metadata::RegisterMDKind(const char *Name) { + MDKindID Count = MDHandlerNames.size(); + StringMap::iterator I = MDHandlerNames.find(Name); + assert(I == MDHandlerNames.end() && "Already registered MDKind!"); + MDHandlerNames[Name] = Count + 1; + return Count + 1; +} + +/// getMDKind - Return metadata kind. If the requested metadata kind +/// is not registered then return 0. +MDKindID Metadata::getMDKind(const char *Name) { + StringMap::iterator I = MDHandlerNames.find(Name); + if (I == MDHandlerNames.end()) + return 0; + + return I->getValue(); +} + +/// setMD - Attach the metadata of given kind with an Instruction. +void Metadata::setMD(MDKindID MDKind, MDNode *Node, Instruction *Inst) { + MDStoreTy::iterator I = MetadataStore.find(Inst); + Inst->HasMetadata = true; + if (I == MetadataStore.end()) { + MDMapTy Info; + Info.push_back(std::make_pair(MDKind, Node)); + MetadataStore.insert(std::make_pair(Inst, Info)); + return; + } + + MDMapTy &Info = I->second; + Info.push_back(std::make_pair(MDKind, Node)); + return; +} + +/// getMD - Get the metadata of given kind attached with an Instruction. +/// If the metadata is not found then return 0. +MDNode *Metadata::getMD(MDKindID MDKind, const Instruction *Inst) { + MDNode *Node = NULL; + MDStoreTy::iterator I = MetadataStore.find(Inst); + if (I == MetadataStore.end()) + return Node; + + MDMapTy &Info = I->second; + for (MDMapTy::iterator I = Info.begin(), E = Info.end(); I != E; ++I) + if (I->first == MDKind) + Node = dyn_cast_or_null(I->second); + return Node; +} + +/// getMDs - Get the metadata attached with an Instruction. +const Metadata::MDMapTy *Metadata::getMDs(const Instruction *Inst) { + MDStoreTy::iterator I = MetadataStore.find(Inst); + if (I == MetadataStore.end()) + return NULL; + + return &(I->second); +} + +/// getHandlerNames - Get handler names. This is used by bitcode +/// writer. +const StringMap *Metadata::getHandlerNames() { + return &MDHandlerNames; +} + +/// ValueIsDeleted - This handler is used to update metadata store +/// when a value is deleted. +void Metadata::ValueIsDeleted(const Instruction *Inst) { + // Find Metadata handles for this instruction. + MDStoreTy::iterator I = MetadataStore.find(Inst); + if (I == MetadataStore.end()) + return; + MDMapTy &Info = I->second; + + // FIXME : Give all metadata handlers a chance to adjust. + + // Remove the entries for this instruction. + Info.clear(); + MetadataStore.erase(Inst); +}