Add llvm::Metadata to manage metadata used in a context.
authorDevang Patel <dpatel@apple.com>
Wed, 16 Sep 2009 18:09:00 +0000 (18:09 +0000)
committerDevang Patel <dpatel@apple.com>
Wed, 16 Sep 2009 18:09:00 +0000 (18:09 +0000)
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

include/llvm/LLVMContext.h
include/llvm/Metadata.h
include/llvm/Value.h
lib/VMCore/LLVMContext.cpp
lib/VMCore/LLVMContextImpl.h
lib/VMCore/Metadata.cpp
lib/VMCore/Value.cpp

index 56a640ea11c9138ac38c3a21ba792427db82667e..5e8cd1a88e026c3bc2e03a9f70b86e442d1bdc9e 100644 (file)
@@ -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();
index 0844006396d8a0e2f7b56d7ace1be4d47fa6f2e0..66a10a87e1151be501ad4196343e1539bd46b2f6 100644 (file)
 #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
index 5aa2ea0e1bee809d99033772af8ba9833e8d38dd..87c4dc2df30911440d11123d6a4666c1ce70f844 100644 (file)
@@ -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;
 
index 7d233d992163b675ffd291fa24de5b54f0da20b6..03f04366a44b8014544f8701a00ee106d374445f 100644 (file)
@@ -70,3 +70,7 @@ bool LLVMContext::RemoveDeadMetadata() {
   }
   return Changed;
 }
+
+Metadata &LLVMContext::getMetadata() {
+  return pImpl->TheMetadata;
+}
index cef770c8bf81c33432991e636e13aeab472f72c0..e4660c277debb5d9796c1966558c1cd412dffa87 100644 (file)
@@ -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),
index 1163b4709ceb05eedc03caad2b092a25afe77f16..062fb96e5bf996dc3aaca6a1c76f0f9edb2130fe 100644 (file)
@@ -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);
+}
index f6740626096398327e56050983aefcc3baafd93d..92a5b702cf92fa3e2d71953f22ca23ab736cce8f 100644 (file)
@@ -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);