From: Devang Patel Date: Wed, 16 Sep 2009 18:09:00 +0000 (+0000) Subject: Add llvm::Metadata to manage metadata used in a context. X-Git-Url: http://plrg.eecs.uci.edu/git/?a=commitdiff_plain;h=937b1e92a9862862722732cb0f72d5ade77ac4c8;p=oota-llvm.git Add llvm::Metadata to manage metadata used in a context. This interface will be used to attach metadata with an instruction. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@82060 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/include/llvm/LLVMContext.h b/include/llvm/LLVMContext.h index 56a640ea11c..5e8cd1a88e0 100644 --- a/include/llvm/LLVMContext.h +++ b/include/llvm/LLVMContext.h @@ -18,7 +18,7 @@ namespace llvm { class LLVMContextImpl; - +class Metadata; /// This is an important class for using LLVM in a threaded context. It /// (opaquely) owns and manages the core "global" data of LLVM's core /// infrastructure, including the type and constant uniquing tables. @@ -30,6 +30,7 @@ class LLVMContext { void operator=(LLVMContext&); public: LLVMContextImpl* pImpl; + Metadata &getMetadata(); bool RemoveDeadMetadata(); LLVMContext(); ~LLVMContext(); diff --git a/include/llvm/Metadata.h b/include/llvm/Metadata.h index 0844006396d..66a10a87e11 100644 --- a/include/llvm/Metadata.h +++ b/include/llvm/Metadata.h @@ -22,12 +22,16 @@ #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/SmallPtrSet.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/SmallSet.h" +#include "llvm/ADT/StringMap.h" #include "llvm/ADT/ilist_node.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/ValueHandle.h" namespace llvm { class Constant; +class Instruction; class LLVMContext; //===----------------------------------------------------------------------===// @@ -300,6 +304,48 @@ public: } }; +//===----------------------------------------------------------------------===// +/// Metadata - +/// Metadata manages metadata used in a context. + +/// MDKindID - This id identifies metadata kind the metadata store. Valid +/// ID values are 1 or higher. This ID is set by RegisterMDKind. +typedef unsigned MDKindID; +class Metadata { +private: + typedef std::pair MDPairTy; + typedef SmallVector MDMapTy; + typedef DenseMap MDStoreTy; + + /// MetadataStore - Collection of metadata used in this context. + MDStoreTy MetadataStore; + + /// MDHandlerNames - Map to hold metadata handler names. + StringMap MDHandlerNames; + +public: + + /// RegisterMDKind - Register a new metadata kind and return its ID. + /// A metadata kind can be registered only once. + MDKindID RegisterMDKind(const char *Name); + + /// getMDKind - Return metadata kind. If the requested metadata kind + /// is not registered then return 0. + MDKindID getMDKind(const char *Name); + + /// getMD - Get the metadata of given kind attached with an Instruction. + /// If the metadata is not found then return 0. + MDNode *getMD(MDKindID Kind, const Instruction *Inst); + + /// setMD - Attach the metadata of given kind with an Instruction. + void setMD(MDKindID Kind, MDNode *Node, Instruction *Inst); + + /// ValueIsDeleted - This handler is used to update metadata store + /// when a value is deleted. + void ValueIsDeleted(Value *V) {} + void ValueIsDeleted(const Instruction *Inst); +}; + } // end llvm namespace #endif diff --git a/include/llvm/Value.h b/include/llvm/Value.h index 5aa2ea0e1be..87c4dc2df30 100644 --- a/include/llvm/Value.h +++ b/include/llvm/Value.h @@ -42,6 +42,7 @@ class raw_ostream; class AssemblyAnnotationWriter; class ValueHandleBase; class LLVMContext; +class Metadata; //===----------------------------------------------------------------------===// // Value Class @@ -63,6 +64,7 @@ class LLVMContext; class Value { const unsigned char SubclassID; // Subclass identifier (for isa/dyn_cast) unsigned char HasValueHandle : 1; // Has a ValueHandle pointing to this? + unsigned char HasMetadata : 1; // Has a metadata attached to this ? protected: /// SubclassOptionalData - This member is similar to SubclassData, however it /// is for holding information which may be used to aid optimization, but @@ -81,6 +83,7 @@ private: friend class ValueSymbolTable; // Allow ValueSymbolTable to directly mod Name. friend class SymbolTable; // Allow SymbolTable to directly poke Name. friend class ValueHandleBase; + friend class Metadata; friend class AbstractTypeUser; ValueName *Name; diff --git a/lib/VMCore/LLVMContext.cpp b/lib/VMCore/LLVMContext.cpp index 7d233d99216..03f04366a44 100644 --- a/lib/VMCore/LLVMContext.cpp +++ b/lib/VMCore/LLVMContext.cpp @@ -70,3 +70,7 @@ bool LLVMContext::RemoveDeadMetadata() { } return Changed; } + +Metadata &LLVMContext::getMetadata() { + return pImpl->TheMetadata; +} diff --git a/lib/VMCore/LLVMContextImpl.h b/lib/VMCore/LLVMContextImpl.h index cef770c8bf8..e4660c277de 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -179,6 +179,7 @@ public: typedef DenseMap ValueHandlesTy; ValueHandlesTy ValueHandles; + Metadata TheMetadata; LLVMContextImpl(LLVMContext &C) : TheTrueVal(0), TheFalseVal(0), VoidTy(C, Type::VoidTyID), LabelTy(C, Type::LabelTyID), diff --git a/lib/VMCore/Metadata.cpp b/lib/VMCore/Metadata.cpp index 1163b4709ce..062fb96e5bf 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; @@ -251,3 +252,74 @@ 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; +} + +/// 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); +} diff --git a/lib/VMCore/Value.cpp b/lib/VMCore/Value.cpp index f6740626096..92a5b702cf9 100644 --- a/lib/VMCore/Value.cpp +++ b/lib/VMCore/Value.cpp @@ -60,6 +60,11 @@ Value::Value(const Type *ty, unsigned scid) } Value::~Value() { + if (HasMetadata) { + LLVMContext &Context = getContext(); + Context.pImpl->TheMetadata.ValueIsDeleted(this); + } + // Notify all ValueHandles (if present) that this value is going away. if (HasValueHandle) ValueHandleBase::ValueIsDeleted(this);