[llvm] r226519 - IR: Extract MDNodeOpsKey, NFC

Duncan P. N. Exon Smith dexonsmith at apple.com
Mon Jan 19 14:53:19 PST 2015


Author: dexonsmith
Date: Mon Jan 19 16:53:18 2015
New Revision: 226519

URL: http://llvm.org/viewvc/llvm-project?rev=226519&view=rev
Log:
IR: Extract MDNodeOpsKey, NFC

Make the MDTuple operand hashing logic reusable.

Modified:
    llvm/trunk/lib/IR/LLVMContextImpl.cpp
    llvm/trunk/lib/IR/LLVMContextImpl.h
    llvm/trunk/lib/IR/Metadata.cpp

Modified: llvm/trunk/lib/IR/LLVMContextImpl.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.cpp?rev=226519&r1=226518&r2=226519&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.cpp (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.cpp Mon Jan 19 16:53:18 2015
@@ -163,6 +163,40 @@ LLVMContextImpl::~LLVMContextImpl() {
   MDStringCache.clear();
 }
 
+namespace llvm {
+/// \brief Make MDOperand transparent for hashing.
+///
+/// This overload of an implementation detail of the hashing library makes
+/// MDOperand hash to the same value as a \a Metadata pointer.
+///
+/// Note that overloading \a hash_value() as follows:
+///
+/// \code
+///     size_t hash_value(const MDOperand &X) { return hash_value(X.get()); }
+/// \endcode
+///
+/// does not cause MDOperand to be transparent.  In particular, a bare pointer
+/// doesn't get hashed before it's combined, whereas \a MDOperand would.
+static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); }
+}
+
+unsigned MDNodeOpsKey::calculateHash(MDNode *N) {
+  unsigned Hash = hash_combine_range(N->op_begin(), N->op_end());
+#ifndef NDEBUG
+  {
+    SmallVector<Metadata *, 8> MDs(N->op_begin(), N->op_end());
+    unsigned RawHash = calculateHash(MDs);
+    assert(Hash == RawHash &&
+           "Expected hash of MDOperand to equal hash of Metadata*");
+  }
+#endif
+  return Hash;
+}
+
+unsigned MDNodeOpsKey::calculateHash(ArrayRef<Metadata *> Ops) {
+  return hash_combine_range(Ops.begin(), Ops.end());
+}
+
 // ConstantsContext anchors
 void UnaryConstantExpr::anchor() { }
 

Modified: llvm/trunk/lib/IR/LLVMContextImpl.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/LLVMContextImpl.h?rev=226519&r1=226518&r2=226519&view=diff
==============================================================================
--- llvm/trunk/lib/IR/LLVMContextImpl.h (original)
+++ llvm/trunk/lib/IR/LLVMContextImpl.h Mon Jan 19 16:53:18 2015
@@ -167,35 +167,62 @@ struct FunctionTypeKeyInfo {
   }
 };
 
+/// \brief Structure for hashing arbitrary MDNode operands.
+class MDNodeOpsKey {
+  ArrayRef<Metadata *> RawOps;
+  ArrayRef<MDOperand> Ops;
+
+  unsigned Hash;
+
+protected:
+  MDNodeOpsKey(ArrayRef<Metadata *> Ops)
+      : RawOps(Ops), Hash(calculateHash(Ops)) {}
+
+  template <class NodeTy>
+  MDNodeOpsKey(NodeTy *N)
+      : Ops(N->op_begin(), N->op_end()), Hash(N->getHash()) {}
+
+  template <class NodeTy> bool compareOps(const NodeTy *RHS) 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);
+  }
+
+  static unsigned calculateHash(MDNode *N);
+
+private:
+  template <class T>
+  static bool compareOps(ArrayRef<T> Ops, const MDNode *RHS) {
+    if (Ops.size() != RHS->getNumOperands())
+      return false;
+    return std::equal(Ops.begin(), Ops.end(), RHS->op_begin());
+  }
+
+  static unsigned calculateHash(ArrayRef<Metadata *> Ops);
+
+public:
+  unsigned getHash() const { return Hash; }
+};
+
 /// \brief DenseMapInfo for MDTuple.
 ///
 /// Note that we don't need the is-function-local bit, since that's implicit in
 /// the operands.
 struct MDTupleInfo {
-  struct KeyTy {
-    ArrayRef<Metadata *> RawOps;
-    ArrayRef<MDOperand> Ops;
-    unsigned Hash;
-
-    KeyTy(ArrayRef<Metadata *> Ops)
-        : RawOps(Ops), Hash(hash_combine_range(Ops.begin(), Ops.end())) {}
-
-    KeyTy(MDTuple *N)
-        : Ops(N->op_begin(), N->op_end()), Hash(N->getHash()) {}
+  struct KeyTy : MDNodeOpsKey {
+    KeyTy(ArrayRef<Metadata *> Ops) : MDNodeOpsKey(Ops) {}
+    KeyTy(MDTuple *N) : MDNodeOpsKey(N) {}
 
     bool operator==(const MDTuple *RHS) const {
       if (RHS == getEmptyKey() || RHS == getTombstoneKey())
         return false;
-      if (Hash != RHS->getHash())
-        return false;
-      assert((RawOps.empty() || Ops.empty()) && "Two sets of operands?");
-      return RawOps.empty() ? compareOps(Ops, RHS) : compareOps(RawOps, RHS);
+      return compareOps(RHS);
     }
-    template <class T>
-    static bool compareOps(ArrayRef<T> Ops, const MDTuple *RHS) {
-      if (Ops.size() != RHS->getNumOperands())
-        return false;
-      return std::equal(Ops.begin(), Ops.end(), RHS->op_begin());
+
+    static unsigned calculateHash(MDTuple *N) {
+      return MDNodeOpsKey::calculateHash(N);
     }
   };
   static inline MDTuple *getEmptyKey() {
@@ -204,10 +231,8 @@ struct MDTupleInfo {
   static inline MDTuple *getTombstoneKey() {
     return DenseMapInfo<MDTuple *>::getTombstoneKey();
   }
-  static unsigned getHashValue(const KeyTy &Key) { return Key.Hash; }
-  static unsigned getHashValue(const MDTuple *U) {
-    return U->getHash();
-  }
+  static unsigned getHashValue(const KeyTy &Key) { return Key.getHash(); }
+  static unsigned getHashValue(const MDTuple *U) { return U->getHash(); }
   static bool isEqual(const KeyTy &LHS, const MDTuple *RHS) {
     return LHS == RHS;
   }

Modified: llvm/trunk/lib/IR/Metadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Metadata.cpp?rev=226519&r1=226518&r2=226519&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Metadata.cpp (original)
+++ llvm/trunk/lib/IR/Metadata.cpp Mon Jan 19 16:53:18 2015
@@ -515,15 +515,7 @@ void UniquableMDNode::resolveCycles() {
 }
 
 void MDTuple::recalculateHash() {
-  setHash(hash_combine_range(op_begin(), op_end()));
-#ifndef NDEBUG
-  {
-    SmallVector<Metadata *, 8> MDs(op_begin(), op_end());
-    unsigned RawHash = hash_combine_range(MDs.begin(), MDs.end());
-    assert(getHash() == RawHash &&
-           "Expected hash of MDOperand to equal hash of Metadata*");
-  }
-#endif
+  setHash(MDTupleInfo::KeyTy::calculateHash(this));
 }
 
 void MDNode::dropAllReferences() {
@@ -536,23 +528,6 @@ void MDNode::dropAllReferences() {
     }
 }
 
-namespace llvm {
-/// \brief Make MDOperand transparent for hashing.
-///
-/// This overload of an implementation detail of the hashing library makes
-/// MDOperand hash to the same value as a \a Metadata pointer.
-///
-/// Note that overloading \a hash_value() as follows:
-///
-/// \code
-///     size_t hash_value(const MDOperand &X) { return hash_value(X.get()); }
-/// \endcode
-///
-/// does not cause MDOperand to be transparent.  In particular, a bare pointer
-/// doesn't get hashed before it's combined, whereas \a MDOperand would.
-static const Metadata *get_hashable_data(const MDOperand &X) { return X.get(); }
-}
-
 void UniquableMDNode::handleChangedOperand(void *Ref, Metadata *New) {
   unsigned Op = static_cast<MDOperand *>(Ref) - op_begin();
   assert(Op < getNumOperands() && "Expected valid operand");
@@ -687,7 +662,7 @@ MDTuple *MDTuple::getImpl(LLVMContext &C
       return N;
     if (!ShouldCreate)
       return nullptr;
-    Hash = Key.Hash;
+    Hash = Key.getHash();
   } else {
     assert(ShouldCreate && "Expected non-uniqued nodes to always be created");
   }





More information about the llvm-commits mailing list