snip one more #include from Metadata.h
[oota-llvm.git] / lib / VMCore / Metadata.cpp
index 854f86cecf9471f0eb509b468482fc5c565bd102..8565b9e24593fdd486b5d52df77b70f13dd07d0e 100644 (file)
 //
 //===----------------------------------------------------------------------===//
 
-#include "LLVMContextImpl.h"
 #include "llvm/Metadata.h"
+#include "LLVMContextImpl.h"
 #include "llvm/LLVMContext.h"
 #include "llvm/Module.h"
 #include "llvm/Instruction.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/StringMap.h"
 #include "SymbolTableListTraitsImpl.h"
+#include "llvm/Support/ValueHandle.h"
 using namespace llvm;
 
 //===----------------------------------------------------------------------===//
@@ -28,6 +29,10 @@ using namespace llvm;
 //===----------------------------------------------------------------------===//
 // MDString implementation.
 //
+
+MDString::MDString(LLVMContext &C, StringRef S)
+  : MetadataBase(Type::getMetadataTy(C), Value::MDStringVal), Str(S) {}
+
 MDString *MDString::get(LLVMContext &Context, StringRef Str) {
   LLVMContextImpl *pImpl = Context.pImpl;
   StringMapEntry<MDString *> &Entry = 
@@ -42,20 +47,53 @@ MDString *MDString::get(LLVMContext &Context, const char *Str) {
   StringMapEntry<MDString *> &Entry = 
     pImpl->MDStringCache.GetOrCreateValue(Str ? StringRef(Str) : StringRef());
   MDString *&S = Entry.getValue();
-  if (!S) new MDString(Context, Entry.getKey());
+  if (!S) S = new MDString(Context, Entry.getKey());
   return S;
 }
 
+//===----------------------------------------------------------------------===//
+// MDNodeElement implementation.
+//
+
+// Use CallbackVH to hold MDNode elements.
+namespace llvm {
+class MDNodeElement : public CallbackVH {
+  MDNode *Parent;
+public:
+  MDNodeElement() {}
+  MDNodeElement(Value *V, MDNode *P) : CallbackVH(V), Parent(P) {}
+  ~MDNodeElement() {}
+  
+  virtual void deleted();
+  virtual void allUsesReplacedWith(Value *NV);
+};
+} // end namespace llvm.
+
+
+void MDNodeElement::deleted() {
+  Parent->replaceElement(this->operator Value*(), 0);
+}
+
+void MDNodeElement::allUsesReplacedWith(Value *NV) {
+  Parent->replaceElement(this->operator Value*(), NV);
+}
+
+
+
 //===----------------------------------------------------------------------===//
 // MDNode implementation.
 //
-MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals)
+
+MDNode::MDNode(LLVMContext &C, Value *const *Vals, unsigned NumVals,
+               bool isFunctionLocal)
   : MetadataBase(Type::getMetadataTy(C), Value::MDNodeVal) {
   NodeSize = NumVals;
-  Node = new ElementVH[NodeSize];
-  ElementVH *Ptr = Node;
+  Node = new MDNodeElement[NodeSize];
+  MDNodeElement *Ptr = Node;
   for (unsigned i = 0; i != NumVals; ++i) 
-    *Ptr++ = ElementVH(Vals[i], this);
+    *Ptr++ = MDNodeElement(Vals[i], this);
+  if (isFunctionLocal)
+    SubclassData |= FunctionLocalBit;
 }
 
 void MDNode::Profile(FoldingSetNodeID &ID) const {
@@ -63,7 +101,8 @@ void MDNode::Profile(FoldingSetNodeID &ID) const {
     ID.AddPointer(getElement(i));
 }
 
-MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) {
+MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals,
+                    bool isFunctionLocal) {
   LLVMContextImpl *pImpl = Context.pImpl;
   FoldingSetNodeID ID;
   for (unsigned i = 0; i != NumVals; ++i)
@@ -73,7 +112,7 @@ MDNode *MDNode::get(LLVMContext &Context, Value*const* Vals, unsigned NumVals) {
   MDNode *N = pImpl->MDNodeSet.FindNodeOrInsertPos(ID, InsertPoint);
   if (!N) {
     // InsertPoint will have been set by the FindNodeOrInsertPos call.
-    N = new MDNode(Context, Vals, NumVals);
+    N = new MDNode(Context, Vals, NumVals, isFunctionLocal);
     pImpl->MDNodeSet.InsertNode(N, InsertPoint);
   }
   return N;
@@ -87,6 +126,14 @@ MDNode::~MDNode() {
   Node = NULL;
 }
 
+/// getElement - Return specified element.
+Value *MDNode::getElement(unsigned i) const {
+  assert(i < getNumElements() && "Invalid element number!");
+  return Node[i];
+}
+
+
+
 // Replace value from this node's element list.
 void MDNode::replaceElement(Value *From, Value *To) {
   if (From == To || !getType())
@@ -115,7 +162,7 @@ void MDNode::replaceElement(Value *From, Value *To) {
   for (SmallVector<unsigned, 4>::iterator I = Indexes.begin(), E = Indexes.end(); 
        I != E; ++I) {
     unsigned Index = *I;
-    Node[Index] = ElementVH(To, this);
+    Node[Index] = MDNodeElement(To, this);
   }
 
   // Insert updated "this" into the context's folding node set.
@@ -141,15 +188,62 @@ void MDNode::replaceElement(Value *From, Value *To) {
   }
 }
 
+// getLocalFunction - Return false if MDNode's recursive function-localness is
+// invalid (local to more than one function).  Return true otherwise. If MDNode
+// has one function to which it is local, set LocalFunction to that function.
+bool MDNode::getLocalFunction(Function *LocalFunction,
+                              SmallPtrSet<MDNode *, 32> *VisitedMDNodes) {
+  if (!isFunctionLocal())
+    return true;
+    
+  if (!VisitedMDNodes)
+    VisitedMDNodes = new SmallPtrSet<MDNode *, 32>();
+    
+  if (!VisitedMDNodes->insert(this))
+    // MDNode has already been visited, nothing to do.
+    return true;
+
+  for (unsigned i = 0, e = getNumElements(); i != e; ++i) {
+    Value *V = getElement(i);
+    if (!V) continue;
+
+    Function *LocalFunctionTemp = NULL;
+    if (Instruction *I = dyn_cast<Instruction>(V))
+      LocalFunctionTemp = I->getParent()->getParent();
+    else if (MDNode *MD = dyn_cast<MDNode>(V))
+      if (!MD->getLocalFunction(LocalFunctionTemp, VisitedMDNodes))
+        // This MDNode's operand is function-locally invalid or local to a
+        // different function.
+        return false;
+
+    if (LocalFunctionTemp) {
+      if (!LocalFunction)
+        LocalFunction = LocalFunctionTemp;
+      else if (LocalFunction != LocalFunctionTemp)
+        // This MDNode contains operands that are local to different functions.
+        return false;
+    }
+  }
+    
+  return true;
+}
+
 //===----------------------------------------------------------------------===//
 // NamedMDNode implementation.
 //
+static SmallVector<TrackingVH<MetadataBase>, 4> &getNMDOps(void *Operands) {
+  return *(SmallVector<TrackingVH<MetadataBase>, 4>*)Operands;
+}
+
 NamedMDNode::NamedMDNode(LLVMContext &C, const Twine &N,
                          MetadataBase *const *MDs, 
                          unsigned NumMDs, Module *ParentModule)
   : MetadataBase(Type::getMetadataTy(C), Value::NamedMDNodeVal), Parent(0) {
   setName(N);
-
+    
+  Operands = new SmallVector<TrackingVH<MetadataBase>, 4>();
+    
+  SmallVector<TrackingVH<MetadataBase>, 4> &Node = getNMDOps(Operands);
   for (unsigned i = 0; i != NumMDs; ++i)
     Node.push_back(TrackingVH<MetadataBase>(MDs[i]));
 
@@ -160,12 +254,35 @@ NamedMDNode::NamedMDNode(LLVMContext &C, const Twine &N,
 NamedMDNode *NamedMDNode::Create(const NamedMDNode *NMD, Module *M) {
   assert(NMD && "Invalid source NamedMDNode!");
   SmallVector<MetadataBase *, 4> Elems;
+  Elems.reserve(NMD->getNumElements());
+  
   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);
 }
 
+NamedMDNode::~NamedMDNode() {
+  dropAllReferences();
+  delete &getNMDOps(Operands);
+}
+
+/// getNumElements - Return number of NamedMDNode elements.
+unsigned NamedMDNode::getNumElements() const {
+  return (unsigned)getNMDOps(Operands).size();
+}
+
+/// getElement - Return specified element.
+MetadataBase *NamedMDNode::getElement(unsigned i) const {
+  assert(i < getNumElements() && "Invalid element number!");
+  return getNMDOps(Operands)[i];
+}
+
+/// addElement - Add metadata element.
+void NamedMDNode::addElement(MetadataBase *M) {
+  getNMDOps(Operands).push_back(TrackingVH<MetadataBase>(M));
+}
+
 /// eraseFromParent - Drop all references and remove the node from parent
 /// module.
 void NamedMDNode::eraseFromParent() {
@@ -174,12 +291,9 @@ void NamedMDNode::eraseFromParent() {
 
 /// dropAllReferences - Remove all uses and clear node vector.
 void NamedMDNode::dropAllReferences() {
-  Node.clear();
+  getNMDOps(Operands).clear();
 }
 
-NamedMDNode::~NamedMDNode() {
-  dropAllReferences();
-}
 
 //===----------------------------------------------------------------------===//
 // MetadataContextImpl implementation.
@@ -213,7 +327,8 @@ public:
   MDNode *getMD(unsigned Kind, const Instruction *Inst);
 
   /// getMDs - Get the metadata attached to an Instruction.
-  void getMDs(const Instruction *Inst, SmallVectorImpl<MDPairTy> &MDs) const;
+  void getMDs(const Instruction *Inst,
+              SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs) const;
 
   /// addMD - Attach the metadata of given kind to an Instruction.
   void addMD(unsigned Kind, MDNode *Node, Instruction *Inst);
@@ -338,7 +453,8 @@ MDNode *MetadataContextImpl::getMD(unsigned MDKind, const Instruction *Inst) {
 
 /// getMDs - Get the metadata attached to an Instruction.
 void MetadataContextImpl::
-getMDs(const Instruction *Inst, SmallVectorImpl<MDPairTy> &MDs) const {
+getMDs(const Instruction *Inst,
+       SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs) const {
   MDStoreTy::const_iterator I = MetadataStore.find(Inst);
   if (I == MetadataStore.end())
     return;
@@ -433,7 +549,7 @@ MDNode *MetadataContext::getMD(unsigned Kind, const Instruction *Inst) {
 /// getMDs - Get the metadata attached to an Instruction.
 void MetadataContext::
 getMDs(const Instruction *Inst, 
-       SmallVectorImpl<std::pair<unsigned, TrackingVH<MDNode> > > &MDs) const {
+       SmallVectorImpl<std::pair<unsigned, MDNode*> > &MDs) const {
   return pImpl->getMDs(Inst, MDs);
 }