[llvm] r226531 - IR: Detect whether to call recalculateHash() via SFINAE, NFC
Duncan P. N. Exon Smith
dexonsmith at apple.com
Mon Jan 19 16:57:33 PST 2015
Author: dexonsmith
Date: Mon Jan 19 18:57:33 2015
New Revision: 226531
URL: http://llvm.org/viewvc/llvm-project?rev=226531&view=rev
Log:
IR: Detect whether to call recalculateHash() via SFINAE, NFC
Rather than relying on updating switch statements correctly, detect
whether `setHash()` exists in the subclass. If so, call
`recalculateHash()` and `setHash(0)` appropriately.
Modified:
llvm/trunk/include/llvm/IR/Metadata.h
llvm/trunk/lib/IR/Metadata.cpp
Modified: llvm/trunk/include/llvm/IR/Metadata.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/IR/Metadata.h?rev=226531&r1=226530&r2=226531&view=diff
==============================================================================
--- llvm/trunk/include/llvm/IR/Metadata.h (original)
+++ llvm/trunk/include/llvm/IR/Metadata.h Mon Jan 19 18:57:33 2015
@@ -825,6 +825,20 @@ private:
MDNode *uniquify();
void eraseFromStore();
+ template <class NodeTy> struct HasCachedHash;
+ template <class NodeTy>
+ static void dispatchRecalculateHash(NodeTy *N, std::true_type) {
+ N->recalculateHash();
+ }
+ template <class NodeTy>
+ static void dispatchRecalculateHash(NodeTy *N, std::false_type) {}
+ template <class NodeTy>
+ static void dispatchResetHash(NodeTy *N, std::true_type) {
+ N->setHash(0);
+ }
+ template <class NodeTy>
+ static void dispatchResetHash(NodeTy *N, std::false_type) {}
+
public:
typedef const MDOperand *op_iterator;
typedef iterator_range<op_iterator> op_range;
Modified: llvm/trunk/lib/IR/Metadata.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/Metadata.cpp?rev=226531&r1=226530&r2=226531&view=diff
==============================================================================
--- llvm/trunk/lib/IR/Metadata.cpp (original)
+++ llvm/trunk/lib/IR/Metadata.cpp Mon Jan 19 18:57:33 2015
@@ -620,26 +620,31 @@ static T *uniquifyImpl(T *N, DenseSet<T
return N;
}
-MDNode *MDNode::uniquify() {
- // Recalculate hash, if necessary.
- switch (getMetadataID()) {
- default:
- break;
- case MDTupleKind:
- cast<MDTuple>(this)->recalculateHash();
- break;
- case GenericDwarfNodeKind:
- cast<GenericDwarfNode>(this)->recalculateHash();
- break;
- }
+template <class NodeTy> struct MDNode::HasCachedHash {
+ typedef char Yes[1];
+ typedef char No[2];
+ template <class U, U Val> struct SFINAE {};
+
+ template <class U>
+ static Yes &check(SFINAE<void (U::*)(unsigned), &U::setHash> *);
+ template <class U> static No &check(...);
+
+ static const bool value = sizeof(check<NodeTy>(nullptr)) == sizeof(Yes);
+};
+MDNode *MDNode::uniquify() {
// Try to insert into uniquing store.
switch (getMetadataID()) {
default:
llvm_unreachable("Invalid subclass of MDNode");
#define HANDLE_MDNODE_LEAF(CLASS) \
- case CLASS##Kind: \
- return uniquifyImpl(cast<CLASS>(this), getContext().pImpl->CLASS##s);
+ case CLASS##Kind: { \
+ CLASS *SubclassThis = cast<CLASS>(this); \
+ std::integral_constant<bool, HasCachedHash<CLASS>::value> \
+ ShouldRecalculateHash; \
+ dispatchRecalculateHash(SubclassThis, ShouldRecalculateHash); \
+ return uniquifyImpl(SubclassThis, getContext().pImpl->CLASS##s); \
+ }
#include "llvm/IR/Metadata.def"
}
}
@@ -774,10 +779,20 @@ void MDNode::deleteTemporary(MDNode *N)
void MDNode::storeDistinctInContext() {
assert(isResolved() && "Expected resolved nodes");
Storage = Distinct;
- if (auto *T = dyn_cast<MDTuple>(this))
- T->setHash(0);
- else if (auto *G = dyn_cast<GenericDwarfNode>(this))
- G->setHash(0);
+
+ // Reset the hash.
+ switch (getMetadataID()) {
+ default:
+ llvm_unreachable("Invalid subclass of MDNode");
+#define HANDLE_MDNODE_LEAF(CLASS) \
+ case CLASS##Kind: { \
+ std::integral_constant<bool, HasCachedHash<CLASS>::value> ShouldResetHash; \
+ dispatchResetHash(cast<CLASS>(this), ShouldResetHash); \
+ break; \
+ }
+#include "llvm/IR/Metadata.def"
+ }
+
getContext().pImpl->DistinctMDNodes.insert(this);
}
More information about the llvm-commits
mailing list