IR: Introduce GenericDwarfNode

As part of PR22235, introduce `DwarfNode` and `GenericDwarfNode`.  The
former is a metadata node with a DWARF tag.  The latter matches our
current (generic) schema of a header with string (and stringified
integer) data and an arbitrary number of operands.

This doesn't move it into place yet; that change will require a large
number of testcase updates.

llvm-svn: 226529
diff --git a/llvm/lib/IR/LLVMContextImpl.h b/llvm/lib/IR/LLVMContextImpl.h
index 092104f..4604d9b 100644
--- a/llvm/lib/IR/LLVMContextImpl.h
+++ b/llvm/lib/IR/LLVMContextImpl.h
@@ -179,25 +179,27 @@
       : RawOps(Ops), Hash(calculateHash(Ops)) {}
 
   template <class NodeTy>
-  MDNodeOpsKey(NodeTy *N)
-      : Ops(N->op_begin(), N->op_end()), Hash(N->getHash()) {}
+  MDNodeOpsKey(NodeTy *N, unsigned Offset = 0)
+      : Ops(N->op_begin() + Offset, N->op_end()), Hash(N->getHash()) {}
 
-  template <class NodeTy> bool compareOps(const NodeTy *RHS) const {
+  template <class NodeTy>
+  bool compareOps(const NodeTy *RHS, unsigned Offset = 0) const {
     if (getHash() != RHS->getHash())
       return false;
 
     assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
-    return RawOps.empty() ? compareOps(Ops, RHS) : compareOps(RawOps, RHS);
+    return RawOps.empty() ? compareOps(Ops, RHS, Offset)
+                          : compareOps(RawOps, RHS, Offset);
   }
 
-  static unsigned calculateHash(MDNode *N);
+  static unsigned calculateHash(MDNode *N, unsigned Offset = 0);
 
 private:
   template <class T>
-  static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS) {
-    if (Ops.size() != RHS->getNumOperands())
+  static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS, unsigned Offset) {
+    if (Ops.size() != RHS->getNumOperands() - Offset)
       return false;
-    return std::equal(Ops.begin(), Ops.end(), RHS->op_begin());
+    return std::equal(Ops.begin(), Ops.end(), RHS->op_begin() + Offset);
   }
 
   static unsigned calculateHash(ArrayRef<Metadata *> Ops);
@@ -283,6 +285,48 @@
   }
 };
 
+/// \brief DenseMapInfo for GenericDwarfNode.
+struct GenericDwarfNodeInfo {
+  struct KeyTy : MDNodeOpsKey {
+    unsigned Tag;
+    MDString *Header;
+    KeyTy(unsigned Tag, MDString *Header, ArrayRef<Metadata *> DwarfOps)
+        : MDNodeOpsKey(DwarfOps), Tag(Tag), Header(Header) {}
+    KeyTy(GenericDwarfNode *N)
+        : MDNodeOpsKey(N, 1), Tag(N->getTag()), Header(N->getHeader()) {}
+
+    bool operator==(const GenericDwarfNode *RHS) const {
+      if (RHS == getEmptyKey() || RHS == getTombstoneKey())
+        return false;
+      return Tag == RHS->getTag() && Header == RHS->getHeader() &&
+             compareOps(RHS, 1);
+    }
+
+    static unsigned calculateHash(GenericDwarfNode *N) {
+      return MDNodeOpsKey::calculateHash(N, 1);
+    }
+  };
+  static inline GenericDwarfNode *getEmptyKey() {
+    return DenseMapInfo<GenericDwarfNode *>::getEmptyKey();
+  }
+  static inline GenericDwarfNode *getTombstoneKey() {
+    return DenseMapInfo<GenericDwarfNode *>::getTombstoneKey();
+  }
+  static unsigned getHashValue(const KeyTy &Key) {
+    return hash_combine(Key.getHash(), Key.Tag, Key.Header);
+  }
+  static unsigned getHashValue(const GenericDwarfNode *U) {
+    return hash_combine(U->getHash(), U->getTag(), U->getHeader());
+  }
+  static bool isEqual(const KeyTy &LHS, const GenericDwarfNode *RHS) {
+    return LHS == RHS;
+  }
+  static bool isEqual(const GenericDwarfNode *LHS,
+                      const GenericDwarfNode *RHS) {
+    return LHS == RHS;
+  }
+};
+
 class LLVMContextImpl {
 public:
   /// OwnedModules - The set of modules instantiated in this context, and which
@@ -315,6 +359,7 @@
 
   DenseSet<MDTuple *, MDTupleInfo> MDTuples;
   DenseSet<MDLocation *, MDLocationInfo> MDLocations;
+  DenseSet<GenericDwarfNode *, GenericDwarfNodeInfo> GenericDwarfNodes;
 
   // MDNodes may be uniqued or not uniqued.  When they're not uniqued, they
   // aren't in the MDNodeSet, but they're still shared between objects, so no