[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