diff options
| author | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-01-20 00:57:33 +0000 |
|---|---|---|
| committer | Duncan P. N. Exon Smith <dexonsmith@apple.com> | 2015-01-20 00:57:33 +0000 |
| commit | 0f529998a5355fde5662719c56e74492802cb816 (patch) | |
| tree | 457b8814fda7c62a99ff439f0c673efb624130e5 /llvm/lib | |
| parent | ee3626ec165dd02a3aef95cdfb297bba1e43d97a (diff) | |
| download | bcm5719-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.cpp | 51 |
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); } |

