diff options
-rw-r--r-- | include/llvm/LLVMContext.h | 3 | ||||
-rw-r--r-- | include/llvm/Metadata.h | 46 | ||||
-rw-r--r-- | include/llvm/Value.h | 3 | ||||
-rw-r--r-- | lib/VMCore/LLVMContext.cpp | 4 | ||||
-rw-r--r-- | lib/VMCore/LLVMContextImpl.h | 1 | ||||
-rw-r--r-- | lib/VMCore/Metadata.cpp | 72 | ||||
-rw-r--r-- | lib/VMCore/Value.cpp | 5 |
7 files changed, 133 insertions, 1 deletions
diff --git a/include/llvm/LLVMContext.h b/include/llvm/LLVMContext.h index 56a640e..5e8cd1a 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 0844006..66a10a8 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<MDKindID, WeakVH> MDPairTy; + typedef SmallVector<MDPairTy, 2> MDMapTy; + typedef DenseMap<const Instruction *, MDMapTy> MDStoreTy; + + /// MetadataStore - Collection of metadata used in this context. + MDStoreTy MetadataStore; + + /// MDHandlerNames - Map to hold metadata handler names. + StringMap<unsigned> 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 5aa2ea0..87c4dc2 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 7d233d9..03f0436 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 cef770c..e4660c2 100644 --- a/lib/VMCore/LLVMContextImpl.h +++ b/lib/VMCore/LLVMContextImpl.h @@ -179,6 +179,7 @@ public: typedef DenseMap<Value*, ValueHandleBase*> 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 1163b47..062fb96 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<unsigned>::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<unsigned>::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<MDNode>(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 f674062..92a5b70 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); |