summaryrefslogtreecommitdiffstats
path: root/llvm/lib
diff options
context:
space:
mode:
authorDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-01-20 00:57:33 +0000
committerDuncan P. N. Exon Smith <dexonsmith@apple.com>2015-01-20 00:57:33 +0000
commit0f529998a5355fde5662719c56e74492802cb816 (patch)
tree457b8814fda7c62a99ff439f0c673efb624130e5 /llvm/lib
parentee3626ec165dd02a3aef95cdfb297bba1e43d97a (diff)
downloadbcm5719-llvm-0f529998a5355fde5662719c56e74492802cb816.tar.gz
bcm5719-llvm-0f529998a5355fde5662719c56e74492802cb816.zip
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. llvm-svn: 226531
Diffstat (limited to 'llvm/lib')
-rw-r--r--llvm/lib/IR/Metadata.cpp51
1 files changed, 33 insertions, 18 deletions
diff --git a/llvm/lib/IR/Metadata.cpp b/llvm/lib/IR/Metadata.cpp
index 5f5708565d4..97976308fcd 100644
--- a/llvm/lib/IR/Metadata.cpp
+++ b/llvm/lib/IR/Metadata.cpp
@@ -620,26 +620,31 @@ static T *uniquifyImpl(T *N, DenseSet<T *, InfoT> &Store) {
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);
}
OpenPOWER on IntegriCloud