<div dir="ltr"><br><div class="gmail_extra"><br><div class="gmail_quote">On Mon, Jan 12, 2015 at 12:09 PM, Duncan P. N. Exon Smith <span dir="ltr"><<a href="mailto:dexonsmith@apple.com" target="_blank">dexonsmith@apple.com</a>></span> 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 Jan 12 14:09:34 2015<br>
New Revision: 225682<br>
<br>
URL: <a href="http://llvm.org/viewvc/llvm-project?rev=225682&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=225682&view=rev</a><br>
Log:<br>
IR: Split GenericMDNode into MDTuple and UniquableMDNode<br>
<br>
Split `GenericMDNode` into two classes (with more descriptive names).<br>
<br>
  - `UniquableMDNode` will be a common subclass for `MDNode`s that are<br>
    sometimes uniqued like constants, and sometimes 'distinct'.<br>
<br>
    This class gets the (short-lived) RAUW support and related API.<br>
<br>
  - `MDTuple` is the basic tuple that has always been returned by<br>
    `MDNode::get()`.  This is as opposed to more specific nodes to be<br>
    added soon, which have additional fields, custom assembly syntax,<br>
    and extra semantics.<br></blockquote><div><br></div><div>I don't mean to hinder progress, etc - but now that we've made the MDNode/Value split, is the "make debug info special" argument still (sufficiently) valid? Can we not make MDNodes sufficiently cheap while being general? <br><br>(Answer may well be 'no', but I'm just curious/wrapping my head around everything)</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex">
<br>
    This class gets the hash-related logic, since other sublcasses of<br>
    `UniquableMDNode` may need to hash based on other fields.<br>
<br>
To keep this diff from getting too big, I've added casts to `MDTuple`<br>
that won't really scale as new subclasses of `UniquableMDNode` are<br>
added, but I'll clean those up incrementally.<br>
<br>
(No functionality change intended.)<br>
<br>
Modified:<br>
    llvm/trunk/include/llvm/IR/Metadata.def<br>
    llvm/trunk/include/llvm/IR/Metadata.h<br>
    llvm/trunk/lib/AsmParser/LLParser.cpp<br>
    llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp<br>
    llvm/trunk/lib/IR/DIBuilder.cpp<br>
    llvm/trunk/lib/IR/LLVMContextImpl.cpp<br>
    llvm/trunk/lib/IR/LLVMContextImpl.h<br>
    llvm/trunk/lib/IR/Metadata.cpp<br>
    llvm/trunk/lib/IR/MetadataTracking.cpp<br>
    llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp<br>
<br>
Modified: llvm/trunk/include/llvm/IR/Metadata.def<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.def?rev=225682&r1=225681&r2=225682&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.def?rev=225682&r1=225681&r2=225682&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/Metadata.def (original)<br>
+++ llvm/trunk/include/llvm/IR/Metadata.def Mon Jan 12 14:09:34 2015<br>
@@ -37,7 +37,8 @@ HANDLE_METADATA_LEAF(ConstantAsMetadata)<br>
 HANDLE_METADATA_LEAF(LocalAsMetadata)<br>
 HANDLE_METADATA_BRANCH(MDNode)<br>
 HANDLE_METADATA_LEAF(MDNodeFwdDecl)<br>
-HANDLE_METADATA_LEAF(GenericMDNode)<br>
+HANDLE_METADATA_BRANCH(UniquableMDNode)<br>
+HANDLE_METADATA_LEAF(MDTuple)<br>
<br>
 #undef HANDLE_METADATA<br>
 #undef HANDLE_METADATA_LEAF<br>
<br>
Modified: llvm/trunk/include/llvm/IR/Metadata.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.h?rev=225682&r1=225681&r2=225682&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.h?rev=225682&r1=225681&r2=225682&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/include/llvm/IR/Metadata.h (original)<br>
+++ llvm/trunk/include/llvm/IR/Metadata.h Mon Jan 12 14:09:34 2015<br>
@@ -56,7 +56,7 @@ protected:<br>
<br>
 public:<br>
   enum MetadataKind {<br>
-    GenericMDNodeKind,<br>
+    MDTupleKind,<br>
     MDNodeFwdDeclKind,<br>
     ConstantAsMetadataKind,<br>
     LocalAsMetadataKind,<br>
@@ -158,7 +158,7 @@ public:<br>
   /// \brief Resolve all uses of this.<br>
   ///<br>
   /// Resolve all uses of this, turning off RAUW permanently.  If \c<br>
-  /// ResolveUsers, call \a GenericMDNode::resolve() on any users whose last<br>
+  /// ResolveUsers, call \a UniquableMDNode::resolve() on any users whose last<br>
   /// operand is resolved.<br>
   void resolveAllUses(bool ResolveUsers = true);<br>
<br>
@@ -682,7 +682,7 @@ public:<br>
<br>
   /// \brief Methods for support type inquiry through isa, cast, and dyn_cast:<br>
   static bool classof(const Metadata *MD) {<br>
-    return MD->getMetadataID() == GenericMDNodeKind ||<br>
+    return MD->getMetadataID() == MDTupleKind ||<br>
            MD->getMetadataID() == MDNodeFwdDeclKind;<br>
   }<br>
<br>
@@ -698,46 +698,46 @@ public:<br>
   static MDNode *getMostGenericRange(MDNode *A, MDNode *B);<br>
 };<br>
<br>
-/// \brief Generic metadata node.<br>
+/// \brief Uniquable 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>
-class GenericMDNode : public MDNode {<br>
-  friend class Metadata;<br>
+/// A uniquable metadata node.  This contains the basic functionality<br>
+/// for implementing sub-types of \a MDNode that can be uniqued like<br>
+/// constants.<br>
+///<br>
+/// There is limited support for RAUW at construction time.  At<br>
+/// construction time, if any operands are an instance of \a<br>
+/// MDNodeFwdDecl (or another unresolved \a UniquableMDNode, which<br>
+/// indicates an \a MDNodeFwdDecl in its path), the node itself will be<br>
+/// unresolved.  As soon as all operands become resolved, it will drop<br>
+/// RAUW support permanently.<br>
+///<br>
+/// If an unresolved node is part of a cycle, \a resolveCycles() needs<br>
+/// to be called on some member of the cycle when each \a MDNodeFwdDecl<br>
+/// has been removed.<br>
+class UniquableMDNode : public MDNode {<br>
+  friend class ReplaceableMetadataImpl;<br>
   friend class MDNode;<br>
   friend class LLVMContextImpl;<br>
-  friend class ReplaceableMetadataImpl;<br>
<br>
   /// \brief Support RAUW as long as one of its arguments is replaceable.<br>
   ///<br>
-  /// If an operand is an \a MDNodeFwdDecl (or a replaceable \a GenericMDNode),<br>
-  /// support RAUW to support uniquing as forward declarations are resolved.<br>
-  /// As soon as operands have been resolved, drop support.<br>
-  ///<br>
   /// FIXME: Save memory by storing this in a pointer union with the<br>
   /// LLVMContext, and adding an LLVMContext reference to RMI.<br>
   std::unique_ptr<ReplaceableMetadataImpl> ReplaceableUses;<br>
<br>
+protected:<br>
   /// \brief Create a new node.<br>
   ///<br>
   /// If \c AllowRAUW, then if any operands are unresolved support RAUW.  RAUW<br>
   /// will be dropped once all operands have been resolved (or if \a<br>
   /// resolveCycles() is called).<br>
-  GenericMDNode(LLVMContext &C, ArrayRef<Metadata *> Vals, bool AllowRAUW);<br>
-  ~GenericMDNode();<br>
-<br>
-  void setHash(unsigned Hash) { MDNodeSubclassData = Hash; }<br>
-  void recalculateHash();<br>
+  UniquableMDNode(LLVMContext &C, unsigned ID, ArrayRef<Metadata *> Vals,<br>
+                  bool AllowRAUW);<br>
+  ~UniquableMDNode();<br>
<br>
 public:<br>
-  /// \brief Get the hash, if any.<br>
-  unsigned getHash() const { return MDNodeSubclassData; }<br>
-<br>
   static bool classof(const Metadata *MD) {<br>
-    return MD->getMetadataID() == GenericMDNodeKind;<br>
+    return MD->getMetadataID() == MDTupleKind;<br>
   }<br>
<br>
   /// \brief Check whether any operands are forward declarations.<br>
@@ -766,11 +766,36 @@ private:<br>
   void decrementUnresolvedOperandCount();<br>
 };<br>
<br>
+/// \brief Tuple of metadata.<br>
+///<br>
+/// This is the simple \a MDNode arbitrary tuple.  Nodes are uniqued by<br>
+/// default based on their operands.<br>
+class MDTuple : public UniquableMDNode {<br>
+  friend class LLVMContextImpl;<br>
+  friend class UniquableMDNode;<br>
+  friend class MDNode;<br>
+<br>
+  MDTuple(LLVMContext &C, ArrayRef<Metadata *> Vals, bool AllowRAUW)<br>
+      : UniquableMDNode(C, MDTupleKind, Vals, AllowRAUW) {}<br>
+  ~MDTuple();<br>
+<br>
+  void setHash(unsigned Hash) { MDNodeSubclassData = Hash; }<br>
+  void recalculateHash();<br>
+<br>
+public:<br>
+  /// \brief Get the hash, if any.<br>
+  unsigned getHash() const { return MDNodeSubclassData; }<br>
+<br>
+  static bool classof(const Metadata *MD) {<br>
+    return MD->getMetadataID() == MDTupleKind;<br>
+  }<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>
+/// Forward declaration of metadata, in the form of a basic tuple.  Unlike \a<br>
+/// MDTuple, this class has full support for RAUW, is not owned, is not<br>
+/// uniqued, and is suitable for forward references.<br>
 class MDNodeFwdDecl : public MDNode, ReplaceableMetadataImpl {<br>
   friend class Metadata;<br>
   friend class MDNode;<br>
<br>
Modified: llvm/trunk/lib/AsmParser/LLParser.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=225682&r1=225681&r2=225682&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/AsmParser/LLParser.cpp?rev=225682&r1=225681&r2=225682&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/AsmParser/LLParser.cpp (original)<br>
+++ llvm/trunk/lib/AsmParser/LLParser.cpp Mon Jan 12 14:09:34 2015<br>
@@ -169,8 +169,8 @@ bool LLParser::ValidateEndOfModule() {<br>
<br>
   // Resolve metadata cycles.<br>
   for (auto &N : NumberedMetadata)<br>
-    if (auto *G = cast_or_null<GenericMDNode>(N))<br>
-      G->resolveCycles();<br>
+    if (auto *U = cast_or_null<UniquableMDNode>(N))<br>
+      U->resolveCycles();<br>
<br>
   // Look for intrinsic functions and CallInst that need to be upgraded<br>
   for (Module::iterator FI = M->begin(), FE = M->end(); FI != FE; )<br>
<br>
Modified: llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=225682&r1=225681&r2=225682&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp?rev=225682&r1=225681&r2=225682&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp (original)<br>
+++ llvm/trunk/lib/Bitcode/Reader/BitcodeReader.cpp Mon Jan 12 14:09:34 2015<br>
@@ -558,8 +558,8 @@ void BitcodeReaderMDValueList::tryToReso<br>
   // Resolve any cycles.<br>
   for (auto &MD : MDValuePtrs) {<br>
     assert(!(MD && isa<MDNodeFwdDecl>(MD)) && "Unexpected forward reference");<br>
-    if (auto *G = dyn_cast_or_null<GenericMDNode>(MD))<br>
-      G->resolveCycles();<br>
+    if (auto *N = dyn_cast_or_null<UniquableMDNode>(MD))<br>
+      N->resolveCycles();<br>
   }<br>
 }<br>
<br>
<br>
Modified: llvm/trunk/lib/IR/DIBuilder.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DIBuilder.cpp?rev=225682&r1=225681&r2=225682&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DIBuilder.cpp?rev=225682&r1=225681&r2=225682&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/DIBuilder.cpp (original)<br>
+++ llvm/trunk/lib/IR/DIBuilder.cpp Mon Jan 12 14:09:34 2015<br>
@@ -55,7 +55,8 @@ DIBuilder::DIBuilder(Module &m, bool All<br>
       AllowUnresolvedNodes(AllowUnresolvedNodes) {}<br>
<br>
 static bool isUnresolved(MDNode *N) {<br>
-  return N && (isa<MDNodeFwdDecl>(N) || !cast<GenericMDNode>(N)->isResolved());<br>
+  return N &&<br>
+         (isa<MDNodeFwdDecl>(N) || !cast<UniquableMDNode>(N)->isResolved());<br>
 }<br>
<br>
 void DIBuilder::trackIfUnresolved(MDNode *N) {<br>
@@ -110,7 +111,7 @@ void DIBuilder::finalize() {<br>
   // cycles.<br>
   for (const auto &N : UnresolvedNodes)<br>
     if (N)<br>
-      cast<GenericMDNode>(N)->resolveCycles();<br>
+      cast<UniquableMDNode>(N)->resolveCycles();<br>
   UnresolvedNodes.clear();<br>
<br>
   // Can't handle unresolved nodes anymore.<br>
<br>
Modified: llvm/trunk/lib/IR/LLVMContextImpl.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=225682&r1=225681&r2=225682&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=225682&r1=225681&r2=225682&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/LLVMContextImpl.cpp (original)<br>
+++ llvm/trunk/lib/IR/LLVMContextImpl.cpp Mon Jan 12 14:09:34 2015<br>
@@ -135,17 +135,17 @@ LLVMContextImpl::~LLVMContextImpl() {<br>
   for (auto &Pair : ValuesAsMetadata)<br>
     delete Pair.second;<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<GenericMDNode *, 8> MDNodes;<br>
-  MDNodes.reserve(MDNodeSet.size() + NonUniquedMDNodes.size());<br>
-  MDNodes.append(MDNodeSet.begin(), MDNodeSet.end());<br>
-  MDNodes.append(NonUniquedMDNodes.begin(), NonUniquedMDNodes.end());<br>
-  for (GenericMDNode *I : MDNodes)<br>
+  // Destroy MDNodes.  ~MDNode can move and remove nodes between the MDTuples<br>
+  // and the DistinctMDNodes sets, so copy the values out first.<br>
+  SmallVector<UniquableMDNode *, 8> Uniquables;<br>
+  Uniquables.reserve(MDTuples.size() + DistinctMDNodes.size());<br>
+  Uniquables.append(MDTuples.begin(), MDTuples.end());<br>
+  Uniquables.append(DistinctMDNodes.begin(), DistinctMDNodes.end());<br>
+  for (UniquableMDNode *I : Uniquables)<br>
     I->dropAllReferences();<br>
-  for (GenericMDNode *I : MDNodes)<br>
-    delete I;<br>
-  assert(MDNodeSet.empty() && NonUniquedMDNodes.empty() &&<br>
+  for (UniquableMDNode *I : Uniquables)<br>
+    delete cast<MDTuple>(I);<br>
+  assert(MDTuples.empty() && DistinctMDNodes.empty() &&<br>
          "Destroying all MDNodes didn't empty the Context's sets.");<br>
<br>
   // Destroy MDStrings.<br>
<br>
Modified: llvm/trunk/lib/IR/LLVMContextImpl.h<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=225682&r1=225681&r2=225682&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=225682&r1=225681&r2=225682&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/LLVMContextImpl.h (original)<br>
+++ llvm/trunk/lib/IR/LLVMContextImpl.h Mon Jan 12 14:09:34 2015<br>
@@ -166,11 +166,11 @@ struct FunctionTypeKeyInfo {<br>
   }<br>
 };<br>
<br>
-/// \brief DenseMapInfo for GenericMDNode.<br>
+/// \brief DenseMapInfo for MDTuple.<br>
 ///<br>
 /// Note that we don't need the is-function-local bit, since that's implicit in<br>
 /// the operands.<br>
-struct GenericMDNodeInfo {<br>
+struct MDTupleInfo {<br>
   struct KeyTy {<br>
     ArrayRef<Metadata *> RawOps;<br>
     ArrayRef<MDOperand> Ops;<br>
@@ -179,10 +179,10 @@ struct GenericMDNodeInfo {<br>
     KeyTy(ArrayRef<Metadata *> Ops)<br>
         : RawOps(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {}<br>
<br>
-    KeyTy(GenericMDNode *N)<br>
+    KeyTy(MDTuple *N)<br>
         : Ops(N->op_begin(), N->op_end()), Hash(N->getHash()) {}<br>
<br>
-    bool operator==(const GenericMDNode *RHS) const {<br>
+    bool operator==(const MDTuple *RHS) const {<br>
       if (RHS == getEmptyKey() || RHS == getTombstoneKey())<br>
         return false;<br>
       if (Hash != RHS->getHash())<br>
@@ -191,26 +191,26 @@ struct GenericMDNodeInfo {<br>
       return RawOps.empty() ? compareOps(Ops, RHS) : compareOps(RawOps, RHS);<br>
     }<br>
     template <class T><br>
-    static bool compareOps(ArrayRef<T> Ops, const GenericMDNode *RHS) {<br>
+    static bool compareOps(ArrayRef<T> Ops, const MDTuple *RHS) {<br>
       if (Ops.size() != RHS->getNumOperands())<br>
         return false;<br>
       return std::equal(Ops.begin(), Ops.end(), RHS->op_begin());<br>
     }<br>
   };<br>
-  static inline GenericMDNode *getEmptyKey() {<br>
-    return DenseMapInfo<GenericMDNode *>::getEmptyKey();<br>
+  static inline MDTuple *getEmptyKey() {<br>
+    return DenseMapInfo<MDTuple *>::getEmptyKey();<br>
   }<br>
-  static inline GenericMDNode *getTombstoneKey() {<br>
-    return DenseMapInfo<GenericMDNode *>::getTombstoneKey();<br>
+  static inline MDTuple *getTombstoneKey() {<br>
+    return DenseMapInfo<MDTuple *>::getTombstoneKey();<br>
   }<br>
   static unsigned getHashValue(const KeyTy &Key) { return Key.Hash; }<br>
-  static unsigned getHashValue(const GenericMDNode *U) {<br>
+  static unsigned getHashValue(const MDTuple *U) {<br>
     return U->getHash();<br>
   }<br>
-  static bool isEqual(const KeyTy &LHS, const GenericMDNode *RHS) {<br>
+  static bool isEqual(const KeyTy &LHS, const MDTuple *RHS) {<br>
     return LHS == RHS;<br>
   }<br>
-  static bool isEqual(const GenericMDNode *LHS, const GenericMDNode *RHS) {<br>
+  static bool isEqual(const MDTuple *LHS, const MDTuple *RHS) {<br>
     return LHS == RHS;<br>
   }<br>
 };<br>
@@ -245,13 +245,13 @@ public:<br>
   DenseMap<Value *, ValueAsMetadata *> ValuesAsMetadata;<br>
   DenseMap<Metadata *, MetadataAsValue *> MetadataAsValues;<br>
<br>
-  DenseSet<GenericMDNode *, GenericMDNodeInfo> MDNodeSet;<br>
+  DenseSet<MDTuple *, MDTupleInfo> MDTuples;<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<GenericMDNode *, 1> NonUniquedMDNodes;<br>
+  SmallPtrSet<UniquableMDNode *, 1> DistinctMDNodes;<br>
<br>
   DenseMap<Type*, ConstantAggregateZero*> CAZConstants;<br>
<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=225682&r1=225681&r2=225682&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Metadata.cpp?rev=225682&r1=225681&r2=225682&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/Metadata.cpp (original)<br>
+++ llvm/trunk/lib/IR/Metadata.cpp Mon Jan 12 14:09:34 2015<br>
@@ -222,8 +222,8 @@ void ReplaceableMetadataImpl::resolveAll<br>
     if (Owner.is<MetadataAsValue *>())<br>
       continue;<br>
<br>
-    // Resolve GenericMDNodes that point at this.<br>
-    auto *OwnerMD = dyn_cast<GenericMDNode>(Owner.get<Metadata *>());<br>
+    // Resolve UniquableMDNodes that point at this.<br>
+    auto *OwnerMD = dyn_cast<UniquableMDNode>(Owner.get<Metadata *>());<br>
     if (!OwnerMD)<br>
       continue;<br>
     if (OwnerMD->isResolved())<br>
@@ -400,7 +400,7 @@ MDNode::MDNode(LLVMContext &Context, uns<br>
 bool MDNode::isResolved() const {<br>
   if (isa<MDNodeFwdDecl>(this))<br>
     return false;<br>
-  return cast<GenericMDNode>(this)->isResolved();<br>
+  return cast<UniquableMDNode>(this)->isResolved();<br>
 }<br>
<br>
 static bool isOperandUnresolved(Metadata *Op) {<br>
@@ -409,9 +409,9 @@ static bool isOperandUnresolved(Metadata<br>
   return false;<br>
 }<br>
<br>
-GenericMDNode::GenericMDNode(LLVMContext &C, ArrayRef<Metadata *> Vals,<br>
-                             bool AllowRAUW)<br>
-    : MDNode(C, GenericMDNodeKind, Vals) {<br>
+UniquableMDNode::UniquableMDNode(LLVMContext &C, unsigned ID,<br>
+                                 ArrayRef<Metadata *> Vals, bool AllowRAUW)<br>
+    : MDNode(C, ID, Vals) {<br>
   if (!AllowRAUW)<br>
     return;<br>
<br>
@@ -427,16 +427,14 @@ GenericMDNode::GenericMDNode(LLVMContext<br>
   SubclassData32 = NumUnresolved;<br>
 }<br>
<br>
-GenericMDNode::~GenericMDNode() {<br>
-  LLVMContextImpl *pImpl = getContext().pImpl;<br>
+UniquableMDNode::~UniquableMDNode() {<br>
   if (isStoredDistinctInContext())<br>
-    pImpl->NonUniquedMDNodes.erase(this);<br>
-  else<br>
-    pImpl->MDNodeSet.erase(this);<br>
+    getContext().pImpl->DistinctMDNodes.erase(this);<br>
+<br>
   dropAllReferences();<br>
 }<br>
<br>
-void GenericMDNode::resolve() {<br>
+void UniquableMDNode::resolve() {<br>
   assert(!isResolved() && "Expected this to be unresolved");<br>
<br>
   // Move the map, so that this immediately looks resolved.<br>
@@ -448,7 +446,7 @@ void GenericMDNode::resolve() {<br>
   Uses->resolveAllUses();<br>
 }<br>
<br>
-void GenericMDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) {<br>
+void UniquableMDNode::resolveAfterOperandChange(Metadata *Old, Metadata *New) {<br>
   assert(SubclassData32 != 0 && "Expected unresolved operands");<br>
<br>
   // Check if an operand was resolved.<br>
@@ -458,13 +456,13 @@ void GenericMDNode::resolveAfterOperandC<br>
     decrementUnresolvedOperandCount();<br>
 }<br>
<br>
-void GenericMDNode::decrementUnresolvedOperandCount() {<br>
+void UniquableMDNode::decrementUnresolvedOperandCount() {<br>
   if (!--SubclassData32)<br>
     // Last unresolved operand has just been resolved.<br>
     resolve();<br>
 }<br>
<br>
-void GenericMDNode::resolveCycles() {<br>
+void UniquableMDNode::resolveCycles() {<br>
   if (isResolved())<br>
     return;<br>
<br>
@@ -477,13 +475,18 @@ void GenericMDNode::resolveCycles() {<br>
       continue;<br>
     assert(!isa<MDNodeFwdDecl>(Op) &&<br>
            "Expected all forward declarations to be resolved");<br>
-    if (auto *N = dyn_cast<GenericMDNode>(Op))<br>
+    if (auto *N = dyn_cast<UniquableMDNode>(Op))<br>
       if (!N->isResolved())<br>
         N->resolveCycles();<br>
   }<br>
 }<br>
<br>
-void GenericMDNode::recalculateHash() {<br>
+MDTuple::~MDTuple() {<br>
+  if (!isStoredDistinctInContext())<br>
+    getContext().pImpl->MDTuples.erase(this);<br>
+}<br>
+<br>
+void MDTuple::recalculateHash() {<br>
   setHash(hash_combine_range(op_begin(), op_end()));<br>
 #ifndef NDEBUG<br>
   {<br>
@@ -498,10 +501,10 @@ void GenericMDNode::recalculateHash() {<br>
 void MDNode::dropAllReferences() {<br>
   for (unsigned I = 0, E = NumOperands; I != E; ++I)<br>
     setOperand(I, nullptr);<br>
-  if (auto *G = dyn_cast<GenericMDNode>(this))<br>
-    if (!G->isResolved()) {<br>
-      G->ReplaceableUses->resolveAllUses(/* ResolveUsers */ false);<br>
-      G->ReplaceableUses.reset();<br>
+  if (auto *N = dyn_cast<UniquableMDNode>(this))<br>
+    if (!N->isResolved()) {<br>
+      N->ReplaceableUses->resolveAllUses(/* ResolveUsers */ false);<br>
+      N->ReplaceableUses.reset();<br>
     }<br>
 }<br>
<br>
@@ -522,7 +525,7 @@ namespace llvm {<br>
 static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); }<br>
 }<br>
<br>
-void GenericMDNode::handleChangedOperand(void *Ref, Metadata *New) {<br>
+void UniquableMDNode::handleChangedOperand(void *Ref, Metadata *New) {<br>
   unsigned Op = static_cast<MDOperand *>(Ref) - op_begin();<br>
   assert(Op < getNumOperands() && "Expected valid operand");<br>
<br>
@@ -534,8 +537,8 @@ void GenericMDNode::handleChangedOperand<br>
     return;<br>
   }<br>
<br>
-  auto &Store = getContext().pImpl->MDNodeSet;<br>
-  Store.erase(this);<br>
+  auto &Store = getContext().pImpl->MDTuples;<br>
+  Store.erase(cast<MDTuple>(this));<br>
<br>
   Metadata *Old = getOperand(Op);<br>
   setOperand(Op, New);<br>
@@ -549,11 +552,11 @@ void GenericMDNode::handleChangedOperand<br>
   }<br>
<br>
   // Re-unique the node.<br>
-  recalculateHash();<br>
-  GenericMDNodeInfo::KeyTy Key(this);<br>
+  cast<MDTuple>(this)->recalculateHash();<br>
+  MDTupleInfo::KeyTy Key(cast<MDTuple>(this));<br>
   auto I = Store.find_as(Key);<br>
   if (I == Store.end()) {<br>
-    Store.insert(this);<br>
+    Store.insert(cast<MDTuple>(this));<br>
<br>
     if (!isResolved())<br>
       resolveAfterOperandChange(Old, New);<br>
@@ -570,7 +573,7 @@ void GenericMDNode::handleChangedOperand<br>
     for (unsigned O = 0, E = getNumOperands(); O != E; ++O)<br>
       setOperand(O, nullptr);<br>
     ReplaceableUses->replaceAllUsesWith(*I);<br>
-    delete this;<br>
+    delete cast<MDTuple>(this);<br>
     return;<br>
   }<br>
<br>
@@ -580,9 +583,9 @@ void GenericMDNode::handleChangedOperand<br>
<br>
 MDNode *MDNode::getMDNode(LLVMContext &Context, ArrayRef<Metadata *> MDs,<br>
                           bool Insert) {<br>
-  auto &Store = Context.pImpl->MDNodeSet;<br>
+  auto &Store = Context.pImpl->MDTuples;<br>
<br>
-  GenericMDNodeInfo::KeyTy Key(MDs);<br>
+  MDTupleInfo::KeyTy Key(MDs);<br>
   auto I = Store.find_as(Key);<br>
   if (I != Store.end())<br>
     return *I;<br>
@@ -590,14 +593,14 @@ MDNode *MDNode::getMDNode(LLVMContext &C<br>
     return nullptr;<br>
<br>
   // Coallocate space for the node and Operands together, then placement new.<br>
-  auto *N = new (MDs.size()) GenericMDNode(Context, MDs, /* AllowRAUW */ true);<br>
+  auto *N = new (MDs.size()) MDTuple(Context, MDs, /* AllowRAUW */ true);<br>
   N->setHash(Key.Hash);<br>
   Store.insert(N);<br>
   return N;<br>
 }<br>
<br>
 MDNode *MDNode::getDistinct(LLVMContext &Context, ArrayRef<Metadata *> MDs) {<br>
-  auto *N = new (MDs.size()) GenericMDNode(Context, MDs, /* AllowRAUW */ false);<br>
+  auto *N = new (MDs.size()) MDTuple(Context, MDs, /* AllowRAUW */ false);<br>
   N->storeDistinctInContext();<br>
   return N;<br>
 }<br>
@@ -616,9 +619,9 @@ void MDNode::deleteTemporary(MDNode *N)<br>
 void MDNode::storeDistinctInContext() {<br>
   assert(!IsDistinctInContext && "Expected newly distinct metadata");<br>
   IsDistinctInContext = true;<br>
-  auto *G = cast<GenericMDNode>(this);<br>
-  G->setHash(0);<br>
-  getContext().pImpl->NonUniquedMDNodes.insert(G);<br>
+  auto *T = cast<MDTuple>(this);<br>
+  T->setHash(0);<br>
+  getContext().pImpl->DistinctMDNodes.insert(T);<br>
 }<br>
<br>
 void MDNode::replaceOperandWith(unsigned I, Metadata *New) {<br>
@@ -630,7 +633,7 @@ void MDNode::replaceOperandWith(unsigned<br>
     return;<br>
   }<br>
<br>
-  cast<GenericMDNode>(this)->handleChangedOperand(mutable_begin() + I, New);<br>
+  cast<UniquableMDNode>(this)->handleChangedOperand(mutable_begin() + I, New);<br>
 }<br>
<br>
 void MDNode::setOperand(unsigned I, Metadata *New) {<br>
<br>
Modified: llvm/trunk/lib/IR/MetadataTracking.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/MetadataTracking.cpp?rev=225682&r1=225681&r2=225682&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/MetadataTracking.cpp?rev=225682&r1=225681&r2=225682&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/IR/MetadataTracking.cpp (original)<br>
+++ llvm/trunk/lib/IR/MetadataTracking.cpp Mon Jan 12 14:09:34 2015<br>
@@ -18,8 +18,8 @@ using namespace llvm;<br>
<br>
 ReplaceableMetadataImpl *ReplaceableMetadataImpl::get(Metadata &MD) {<br>
   if (auto *N = dyn_cast<MDNode>(&MD)) {<br>
-    if (auto *G = dyn_cast<GenericMDNode>(N))<br>
-      return G->ReplaceableUses.get();<br>
+    if (auto *U = dyn_cast<UniquableMDNode>(N))<br>
+      return U->ReplaceableUses.get();<br>
     return cast<MDNodeFwdDecl>(N);<br>
   }<br>
   return dyn_cast<ValueAsMetadata>(&MD);<br>
<br>
Modified: llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp<br>
URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp?rev=225682&r1=225681&r2=225682&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp?rev=225682&r1=225681&r2=225682&view=diff</a><br>
==============================================================================<br>
--- llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp (original)<br>
+++ llvm/trunk/lib/Transforms/Utils/ValueMapper.cpp Mon Jan 12 14:09:34 2015<br>
@@ -260,8 +260,8 @@ Metadata *llvm::MapMetadata(const Metada<br>
                             ValueMaterializer *Materializer) {<br>
   Metadata *NewMD = MapMetadataImpl(MD, VM, Flags, TypeMapper, Materializer);<br>
   if (NewMD && NewMD != MD)<br>
-    if (auto *G = dyn_cast<GenericMDNode>(NewMD))<br>
-      G->resolveCycles();<br>
+    if (auto *N = dyn_cast<UniquableMDNode>(NewMD))<br>
+      N->resolveCycles();<br>
   return NewMD;<br>
 }<br>
<br>
<br>
<br>
_______________________________________________<br>
llvm-commits mailing list<br>
<a href="mailto:llvm-commits@cs.uiuc.edu">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/mailman/listinfo/llvm-commits</a><br>
</blockquote></div><br></div></div>