<br><br><div class="gmail_quote">On Mon Nov 17 2014 at 4:45:03 PM Duncan P. N. Exon Smith <<a href="mailto:dexonsmith@apple.com">dexonsmith@apple.com</a>> wrote:<br><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">Author: dexonsmith<br>
Date: Mon Nov 17 18:37:17 2014<br>
New Revision: 222205<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=222205&view=rev" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project?rev=222205&view=rev</a><br>
Log:<br>
IR: Split MDNode into GenericMDNode and MDNodeFwdDecl<br>
<br></blockquote><div><br></div><div>Small bikeshedding:</div><div><br></div><div><span style="font-size:13.3333339691162px">Replaceable</span>NDNode maybe?</div><div> </div><div>Best name I've been able to come up with so far.</div><div><br></div><div>-eric</div><div><br></div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
Split `MDNode` into two classes:<br>
<br>
  - `GenericMDNode`, which is uniquable (and for now, always starts<br>
    uniqued).  Once `Metadata` is split from the `Value` hierarchy, this<br>
    class will lose the ability to RAUW itself.<br>
<br>
  - `MDNodeFwdDecl`, which is used for the "temporary" interface, is<br>
    never uniqued, and isn't managed by `LLVMContext` at all.<br>
<br>
I've left most of the guts in `MDNode` for now, but I'll incrementally<br>
move things to the right places (or delete the functionality, as<br>
appropriate).<br>
<br>
Part of PR21532.<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/IR/<u></u>Metadata.h<br>
    llvm/trunk/include/llvm/IR/<u></u>Value.h<br>
    llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp<br>
    llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h<br>
    llvm/trunk/lib/IR/Metadata.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<u></u>Metadata.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.h?rev=222205&r1=222204&r2=222205&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/Metadata.h?rev=222205&<u></u>r1=222204&r2=222205&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>Metadata.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>Metadata.h Mon Nov 17 18:37:17 2014<br>
@@ -45,7 +45,9 @@ protected:<br>
<br>
 public:<br>
   static bool classof(const Value *V) {<br>
-    return V->getValueID() == MDNodeVal || V->getValueID() == MDStringVal;<br>
+    return V->getValueID() == GenericMDNodeVal ||<br>
+           V->getValueID() == MDNodeFwdDeclVal ||<br>
+           V->getValueID() == MDStringVal;<br>
   }<br>
 };<br>
<br>
@@ -137,14 +139,16 @@ struct DenseMapInfo<AAMDNodes> {<br>
 class MDNodeOperand;<br>
<br>
 //===-------------------------<u></u>------------------------------<u></u>---------------===//<br>
-/// \brief Generic tuple of metadata.<br>
+/// \brief Tuple of metadata.<br>
 class MDNode : public Metadata {<br>
   MDNode(const MDNode &) LLVM_DELETED_FUNCTION;<br>
   void operator=(const MDNode &) LLVM_DELETED_FUNCTION;<br>
   friend class MDNodeOperand;<br>
   friend class LLVMContextImpl;<br>
<br>
-  /// \brief If the MDNode is uniqued cache the hash to speed up lookup.<br>
+protected:<br>
+  // TODO: Sink this into GenericMDNode.  Can't do this until operands are<br>
+  // allocated at the front (currently they're at the back).<br>
   unsigned Hash;<br>
<br>
   /// \brief Subclass data enums.<br>
@@ -174,7 +178,8 @@ class MDNode : public Metadata {<br>
   void replaceOperand(MDNodeOperand *Op, Value *NewVal);<br>
   ~MDNode();<br>
<br>
-  MDNode(LLVMContext &C, ArrayRef<Value*> Vals, bool isFunctionLocal);<br>
+  MDNode(LLVMContext &C, unsigned ID, ArrayRef<Value *> Vals,<br>
+         bool isFunctionLocal);<br>
<br>
   static MDNode *getMDNode(LLVMContext &C, ArrayRef<Value*> Vals,<br>
                            FunctionLocalness FL, bool Insert = true);<br>
@@ -223,12 +228,10 @@ public:<br>
   /// code because it recursively visits all the MDNode's operands.<br>
   const Function *getFunction() const;<br>
<br>
-  /// \brief Get the hash, if any.<br>
-  unsigned getHash() const { return Hash; }<br>
-<br>
   /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:<br>
   static bool classof(const Value *V) {<br>
-    return V->getValueID() == MDNodeVal;<br>
+    return V->getValueID() == GenericMDNodeVal ||<br>
+           V->getValueID() == MDNodeFwdDeclVal;<br>
   }<br>
<br>
   /// \brief Check whether MDNode is a vtable access.<br>
@@ -241,10 +244,8 @@ public:<br>
   static AAMDNodes getMostGenericAA(const AAMDNodes &A, const AAMDNodes &B);<br>
   static MDNode *getMostGenericFPMath(MDNode *A, MDNode *B);<br>
   static MDNode *getMostGenericRange(MDNode *A, MDNode *B);<br>
-private:<br>
-  /// \brief Delete this node.  Only when there are no uses.<br>
-  void destroy();<br>
<br>
+protected:<br>
   bool isNotUniqued() const {<br>
     return (getSubclassDataFromValue() & NotUniquedBit) != 0;<br>
   }<br>
@@ -257,6 +258,61 @@ private:<br>
   }<br>
 };<br>
<br>
+/// \brief Generic metadata node.<br>
+///<br>
+/// Generic metadata nodes, with opt-out support for uniquing.<br>
+///<br>
+/// Although nodes are uniqued by default, \a GenericMDNode has no support for<br>
+/// RAUW.  If an operand change (due to RAUW or otherwise) causes a uniquing<br>
+/// collision, the uniquing bit is dropped.<br>
+///<br>
+/// TODO: Make uniquing opt-out (status: mandatory, sometimes dropped).<br>
+/// TODO: Drop support for RAUW.<br>
+class GenericMDNode : public MDNode {<br>
+  friend class MDNode;<br>
+<br>
+  GenericMDNode(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)<br>
+      : MDNode(C, GenericMDNodeVal, Vals, isFunctionLocal) {}<br>
+  ~GenericMDNode();<br>
+<br>
+public:<br>
+  /// \brief Get the hash, if any.<br>
+  unsigned getHash() const { return Hash; }<br>
+<br>
+  static bool classof(const Value *V) {<br>
+    return V->getValueID() == GenericMDNodeVal;<br>
+  }<br>
+<br>
+private:<br>
+  /// \brief Delete this node.  Only when there are no uses.<br>
+  void destroy();<br>
+  friend class MDNode;<br>
+  friend class LLVMContextImpl;<br>
+};<br>
+<br>
+/// \brief Forward declaration of metadata.<br>
+///<br>
+/// Forward declaration of metadata, in the form of a metadata node.  Unlike \a<br>
+/// GenericMDNode, this class has support for RAUW and is suitable for forward<br>
+/// references.<br>
+class MDNodeFwdDecl : public MDNode {<br>
+  friend class MDNode;<br>
+<br>
+  MDNodeFwdDecl(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)<br>
+      : MDNode(C, MDNodeFwdDeclVal, Vals, isFunctionLocal) {}<br>
+  ~MDNodeFwdDecl() {}<br>
+<br>
+public:<br>
+  static bool classof(const Value *V) {<br>
+    return V->getValueID() == MDNodeFwdDeclVal;<br>
+  }<br>
+<br>
+private:<br>
+  /// \brief Delete this node.  Only when there are no uses.<br>
+  void destroy();<br>
+  friend class MDNode;<br>
+};<br>
+<br>
 //===-------------------------<u></u>------------------------------<u></u>---------------===//<br>
 /// \brief A tuple of MDNodes.<br>
 ///<br>
<br>
Modified: llvm/trunk/include/llvm/IR/<u></u>Value.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Value.h?rev=222205&r1=222204&r2=222205&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/include/<u></u>llvm/IR/Value.h?rev=222205&r1=<u></u>222204&r2=222205&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/include/llvm/IR/<u></u>Value.h (original)<br>
+++ llvm/trunk/include/llvm/IR/<u></u>Value.h Mon Nov 17 18:37:17 2014<br>
@@ -345,7 +345,8 @@ public:<br>
     ConstantStructVal,        // This is an instance of ConstantStruct<br>
     ConstantVectorVal,        // This is an instance of ConstantVector<br>
     ConstantPointerNullVal,   // This is an instance of ConstantPointerNull<br>
-    MDNodeVal,                // This is an instance of MDNode<br>
+    GenericMDNodeVal,         // This is an instance of GenericMDNode<br>
+    MDNodeFwdDeclVal,         // This is an instance of MDNodeFwdDecl<br>
     MDStringVal,              // This is an instance of MDString<br>
     InlineAsmVal,             // This is an instance of InlineAsm<br>
     InstructionVal,           // This is an instance of Instruction<br>
@@ -681,7 +682,8 @@ template <> struct isa_impl<GlobalObject<br>
<br>
 template <> struct isa_impl<MDNode, Value> {<br>
   static inline bool doit(const Value &Val) {<br>
-    return Val.getValueID() == Value::MDNodeVal;<br>
+    return Val.getValueID() == Value::GenericMDNodeVal ||<br>
+           Val.getValueID() == Value::MDNodeFwdDeclVal;<br>
   }<br>
 };<br>
<br>
<br>
Modified: llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=222205&r1=222204&r2=222205&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp?rev=<u></u>222205&r1=222204&r2=222205&<u></u>view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp (original)<br>
+++ llvm/trunk/lib/IR/<u></u>LLVMContextImpl.cpp Mon Nov 17 18:37:17 2014<br>
@@ -122,13 +122,12 @@ LLVMContextImpl::~<u></u>LLVMContextImpl() {<br>
<br>
   // Destroy MDNodes.  ~MDNode can move and remove nodes between the MDNodeSet<br>
   // and the NonUniquedMDNodes sets, so copy the values out first.<br>
-  SmallVector<MDNode*, 8> MDNodes;<br>
+  SmallVector<GenericMDNode *, 8> MDNodes;<br>
   MDNodes.reserve(MDNodeSet.<u></u>size() + NonUniquedMDNodes.size());<br>
   MDNodes.append(MDNodeSet.<u></u>begin(), MDNodeSet.end());<br>
   MDNodes.append(<u></u>NonUniquedMDNodes.begin(), NonUniquedMDNodes.end());<br>
-  for (SmallVectorImpl<MDNode *>::iterator I = MDNodes.begin(),<br>
-         E = MDNodes.end(); I != E; ++I)<br>
-    (*I)->destroy();<br>
+  for (auto &I : MDNodes)<br>
+    I->destroy();<br>
   assert(MDNodeSet.empty() && NonUniquedMDNodes.empty() &&<br>
          "Destroying all MDNodes didn't empty the Context's sets.");<br>
<br>
<br>
Modified: llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=222205&r1=222204&r2=222205&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h?rev=222205&<u></u>r1=222204&r2=222205&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h (original)<br>
+++ llvm/trunk/lib/IR/<u></u>LLVMContextImpl.h Mon Nov 17 18:37:17 2014<br>
@@ -191,7 +191,7 @@ struct FunctionTypeKeyInfo {<br>
   }<br>
 };<br>
<br>
-/// \brief DenseMapInfo for MDNode.<br>
+/// \brief DenseMapInfo for GenericMDNode.<br>
 ///<br>
 /// Note that we don't need the is-function-local bit, since that's implicit in<br>
 /// the operands.<br>
@@ -203,7 +203,7 @@ struct GenericMDNodeInfo {<br>
     KeyTy(ArrayRef<Value *> Ops)<br>
         : Ops(Ops), Hash(hash_combine_range(Ops.<u></u>begin(), Ops.end())) {}<br>
<br>
-    KeyTy(MDNode *N, SmallVectorImpl<Value *> &Storage) {<br>
+    KeyTy(GenericMDNode *N, SmallVectorImpl<Value *> &Storage) {<br>
       Storage.resize(N-><u></u>getNumOperands());<br>
       for (unsigned I = 0, E = N->getNumOperands(); I != E; ++I)<br>
         Storage[I] = N->getOperand(I);<br>
@@ -211,7 +211,7 @@ struct GenericMDNodeInfo {<br>
       Hash = hash_combine_range(Ops.begin()<u></u>, Ops.end());<br>
     }<br>
<br>
-    bool operator==(const MDNode *RHS) const {<br>
+    bool operator==(const GenericMDNode *RHS) const {<br>
       if (RHS == getEmptyKey() || RHS == getTombstoneKey())<br>
         return false;<br>
       if (Hash != RHS->getHash() || Ops.size() != RHS->getNumOperands())<br>
@@ -222,20 +222,20 @@ struct GenericMDNodeInfo {<br>
       return true;<br>
     }<br>
   };<br>
-  static inline MDNode *getEmptyKey() {<br>
-    return DenseMapInfo<MDNode *>::getEmptyKey();<br>
+  static inline GenericMDNode *getEmptyKey() {<br>
+    return DenseMapInfo<GenericMDNode *>::getEmptyKey();<br>
   }<br>
-  static inline MDNode *getTombstoneKey() {<br>
-    return DenseMapInfo<MDNode *>::getTombstoneKey();<br>
+  static inline GenericMDNode *getTombstoneKey() {<br>
+    return DenseMapInfo<GenericMDNode *>::getTombstoneKey();<br>
   }<br>
   static unsigned getHashValue(const KeyTy &Key) { return Key.Hash; }<br>
-  static unsigned getHashValue(const MDNode *U) {<br>
+  static unsigned getHashValue(const GenericMDNode *U) {<br>
     return U->getHash();<br>
   }<br>
-  static bool isEqual(const KeyTy &LHS, const MDNode *RHS) {<br>
+  static bool isEqual(const KeyTy &LHS, const GenericMDNode *RHS) {<br>
     return LHS == RHS;<br>
   }<br>
-  static bool isEqual(const MDNode *LHS, const MDNode *RHS) {<br>
+  static bool isEqual(const GenericMDNode *LHS, const GenericMDNode *RHS) {<br>
     return LHS == RHS;<br>
   }<br>
 };<br>
@@ -293,14 +293,14 @@ public:<br>
<br>
   StringMap<MDString> MDStringCache;<br>
<br>
-  DenseSet<MDNode *, GenericMDNodeInfo> MDNodeSet;<br>
+  DenseSet<GenericMDNode *, GenericMDNodeInfo> MDNodeSet;<br>
<br>
   // MDNodes may be uniqued or not uniqued.  When they're not uniqued, they<br>
   // aren't in the MDNodeSet, but they're still shared between objects, so no<br>
   // one object can destroy them.  This set allows us to at least destroy them<br>
   // on Context destruction.<br>
-  SmallPtrSet<MDNode*, 1> NonUniquedMDNodes;<br>
-<br>
+  SmallPtrSet<GenericMDNode *, 1> NonUniquedMDNodes;<br>
+<br>
   DenseMap<Type*, ConstantAggregateZero*> CAZConstants;<br>
<br>
   typedef ConstantUniqueMap<<u></u>ConstantArray> ArrayConstantsTy;<br>
<br>
Modified: llvm/trunk/lib/IR/Metadata.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Metadata.cpp?rev=222205&r1=222204&r2=222205&view=diff" target="_blank">http://llvm.org/viewvc/llvm-<u></u>project/llvm/trunk/lib/IR/<u></u>Metadata.cpp?rev=222205&r1=<u></u>222204&r2=222205&view=diff</a><br>
==============================<u></u>==============================<u></u>==================<br>
--- llvm/trunk/lib/IR/Metadata.cpp (original)<br>
+++ llvm/trunk/lib/IR/Metadata.cpp Mon Nov 17 18:37:17 2014<br>
@@ -108,6 +108,11 @@ void MDNodeOperand::<u></u>allUsesReplacedWith(<br>
<br>
 /// \brief Get the MDNodeOperand's coallocated on the end of the MDNode.<br>
 static MDNodeOperand *getOperandPtr(MDNode *N, unsigned Op) {<br>
+  static_assert(sizeof(<u></u>GenericMDNode) == sizeof(MDNode),<br>
+                "Expected subclasses to have no size overhead");<br>
+  static_assert(sizeof(<u></u>MDNodeFwdDecl) == sizeof(MDNode),<br>
+                "Expected subclasses to have no size overhead");<br>
+<br>
   // Use <= instead of < to permit a one-past-the-end address.<br>
   assert(Op <= N->getNumOperands() && "Invalid operand number");<br>
   return reinterpret_cast<<u></u>MDNodeOperand*>(N + 1) + Op;<br>
@@ -118,8 +123,9 @@ void MDNode::replaceOperandWith(<u></u>unsigned<br>
   replaceOperand(Op, Val);<br>
 }<br>
<br>
-MDNode::MDNode(LLVMContext &C, ArrayRef<Value *> Vals, bool isFunctionLocal)<br>
-    : Metadata(C, Value::MDNodeVal), Hash(0) {<br>
+MDNode::MDNode(LLVMContext &C, unsigned ID, ArrayRef<Value *> Vals,<br>
+               bool isFunctionLocal)<br>
+    : Metadata(C, ID), Hash(0) {<br>
   NumOperands = Vals.size();<br>
<br>
   if (isFunctionLocal)<br>
@@ -137,16 +143,18 @@ MDNode::MDNode(LLVMContext &C, ArrayRef<<br>
   }<br>
 }<br>
<br>
-/// ~MDNode - Destroy MDNode.<br>
-MDNode::~MDNode() {<br>
-  assert((<u></u>getSubclassDataFromValue() & DestroyFlag) != 0 &&<br>
-         "Not being destroyed through destroy()?");<br>
+GenericMDNode::~<u></u>GenericMDNode() {<br>
   LLVMContextImpl *pImpl = getType()->getContext().pImpl;<br>
   if (isNotUniqued()) {<br>
     pImpl->NonUniquedMDNodes.<u></u>erase(this);<br>
   } else {<br>
     pImpl->MDNodeSet.erase(this);<br>
   }<br>
+}<br>
+<br>
+MDNode::~MDNode() {<br>
+  assert((<u></u>getSubclassDataFromValue() & DestroyFlag) != 0 &&<br>
+         "Not being destroyed through destroy()?");<br>
<br>
   // Destroy the operands.<br>
   for (MDNodeOperand *Op = getOperandPtr(this, 0), *E = Op+NumOperands;<br>
@@ -209,10 +217,17 @@ const Function *MDNode::getFunction() co<br>
 }<br>
<br>
 // destroy - Delete this node.  Only when there are no uses.<br>
-void MDNode::destroy() {<br>
+void GenericMDNode::destroy() {<br>
+  setValueSubclassData(<u></u>getSubclassDataFromValue() | DestroyFlag);<br>
+  // Placement delete, then free the memory.<br>
+  this->~GenericMDNode();<br>
+  free(this);<br>
+}<br>
+<br>
+void MDNodeFwdDecl::destroy() {<br>
   setValueSubclassData(<u></u>getSubclassDataFromValue() | DestroyFlag);<br>
   // Placement delete, then free the memory.<br>
-  this->~MDNode();<br>
+  this->~MDNodeFwdDecl();<br>
   free(this);<br>
 }<br>
<br>
@@ -253,8 +268,9 @@ MDNode *MDNode::getMDNode(LLVMContext &C<br>
   }<br>
<br>
   // Coallocate space for the node and Operands together, then placement new.<br>
-  void *Ptr = malloc(sizeof(MDNode) + Vals.size() * sizeof(MDNodeOperand));<br>
-  MDNode *N = new (Ptr) MDNode(Context, Vals, isFunctionLocal);<br>
+  void *Ptr =<br>
+      malloc(sizeof(GenericMDNode) + Vals.size() * sizeof(MDNodeOperand));<br>
+  GenericMDNode *N = new (Ptr) GenericMDNode(Context, Vals, isFunctionLocal);<br>
<br>
   N->Hash = Key.Hash;<br>
   Store.insert(N);<br>
@@ -276,9 +292,9 @@ MDNode *MDNode::getIfExists(<u></u>LLVMContext<br>
 }<br>
<br>
 MDNode *MDNode::getTemporary(<u></u>LLVMContext &Context, ArrayRef<Value*> Vals) {<br>
-  MDNode *N =<br>
-    (MDNode *)malloc(sizeof(MDNode) + Vals.size() * sizeof(MDNodeOperand));<br>
-  N = new (N) MDNode(Context, Vals, FL_No);<br>
+  MDNode *N = (MDNode *)malloc(sizeof(MDNodeFwdDecl) +<br>
+                               Vals.size() * sizeof(MDNodeOperand));<br>
+  N = new (N) MDNodeFwdDecl(Context, Vals, FL_No);<br>
   N->setValueSubclassData(N-><u></u>getSubclassDataFromValue() |<br>
                           NotUniquedBit);<br>
   LeakDetector::<u></u>addGarbageObject(N);<br>
@@ -287,16 +303,13 @@ MDNode *MDNode::getTemporary(<u></u>LLVMContext<br>
<br>
 void MDNode::deleteTemporary(MDNode *N) {<br>
   assert(N->use_empty() && "Temporary MDNode has uses!");<br>
-  assert(!N->getContext().pImpl-<u></u>>MDNodeSet.erase(N) &&<br>
-         "Deleting a non-temporary uniqued node!");<br>
-  assert(!N->getContext().pImpl-<u></u>>NonUniquedMDNodes.erase(N) &&<br>
-         "Deleting a non-temporary non-uniqued node!");<br>
+  assert(isa<MDNodeFwdDecl>(N) && "Expected forward declaration");<br>
   assert((N-><u></u>getSubclassDataFromValue() & NotUniquedBit) &&<br>
          "Temporary MDNode does not have NotUniquedBit set!");<br>
   assert((N-><u></u>getSubclassDataFromValue() & DestroyFlag) == 0 &&<br>
          "Temporary MDNode has DestroyFlag set!");<br>
   LeakDetector::<u></u>removeGarbageObject(N);<br>
-  N->destroy();<br>
+  cast<MDNodeFwdDecl>(N)-><u></u>destroy();<br>
 }<br>
<br>
 /// \brief Return specified operand.<br>
@@ -308,8 +321,9 @@ Value *MDNode::getOperand(unsigned i) co<br>
 void MDNode::setIsNotUniqued() {<br>
   setValueSubclassData(<u></u>getSubclassDataFromValue() | NotUniquedBit);<br>
   LLVMContextImpl *pImpl = getType()->getContext().pImpl;<br>
-  Hash = 0;<br>
-  pImpl->NonUniquedMDNodes.<u></u>insert(this);<br>
+  auto *G = cast<GenericMDNode>(this);<br>
+  G->Hash = 0;<br>
+  pImpl->NonUniquedMDNodes.<u></u>insert(G);<br>
 }<br>
<br>
 // Replace value from this node's operand list.<br>
@@ -345,9 +359,10 @@ void MDNode::replaceOperand(<u></u>MDNodeOperan<br>
   }<br>
<br>
   auto &Store = getContext().pImpl->MDNodeSet;<br>
+  auto *N = cast<GenericMDNode>(this);<br>
<br>
   // Remove "this" from the context map.<br>
-  Store.erase(this);<br>
+  Store.erase(N);<br>
<br>
   // Update the operand.<br>
   Op->set(To);<br>
@@ -365,16 +380,16 @@ void MDNode::replaceOperand(<u></u>MDNodeOperan<br>
   // check to see if another node with the same operands already exists in the<br>
   // set.  If so, then this node is redundant.<br>
   SmallVector<Value *, 8> Vals;<br>
-  GenericMDNodeInfo::KeyTy Key(this, Vals);<br>
+  GenericMDNodeInfo::KeyTy Key(N, Vals);<br>
   auto I = Store.find_as(Key);<br>
   if (I != Store.end()) {<br>
-    replaceAllUsesWith(*I);<br>
-    destroy();<br>
+    N->replaceAllUsesWith(*I);<br>
+    N->destroy();<br>
     return;<br>
   }<br>
<br>
-  this->Hash = Key.Hash;<br>
-  Store.insert(this);<br>
+  N->Hash = Key.Hash;<br>
+  Store.insert(N);<br>
<br>
   // If this MDValue was previously function-local but no longer is, clear<br>
   // its function-local flag.<br>
<br>
<br>
______________________________<u></u>_________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
<a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/<u></u>mailman/listinfo/llvm-commits</a><br>
</blockquote></div>