diff --git a/llvm/include/llvm/ADT/DenseMapInfo.h b/llvm/include/llvm/ADT/DenseMapInfo.h --- a/llvm/include/llvm/ADT/DenseMapInfo.h +++ b/llvm/include/llvm/ADT/DenseMapInfo.h @@ -23,6 +23,24 @@ namespace llvm { +namespace detail { + +/// Simplistic combination of 32-bit hash values into 32-bit hash values. +static inline unsigned combineHashValue(unsigned a, unsigned b) { + uint64_t key = (uint64_t)a << 32 | (uint64_t)b; + key += ~(key << 32); + key ^= (key >> 22); + key += ~(key << 13); + key ^= (key >> 8); + key += (key << 3); + key ^= (key >> 15); + key += ~(key << 27); + key ^= (key >> 31); + return (unsigned)key; +} + +} // end namespace detail + template struct DenseMapInfo { //static inline T getEmptyKey(); @@ -206,17 +224,8 @@ } static unsigned getHashValue(const Pair& PairVal) { - uint64_t key = (uint64_t)FirstInfo::getHashValue(PairVal.first) << 32 - | (uint64_t)SecondInfo::getHashValue(PairVal.second); - key += ~(key << 32); - key ^= (key >> 22); - key += ~(key << 13); - key ^= (key >> 8); - key += (key << 3); - key ^= (key >> 15); - key += ~(key << 27); - key ^= (key >> 31); - return (unsigned)key; + return detail::combineHashValue(FirstInfo::getHashValue(PairVal.first), + SecondInfo::getHashValue(PairVal.second)); } static bool isEqual(const Pair &LHS, const Pair &RHS) { @@ -225,6 +234,57 @@ } }; +// Provide DenseMapInfo for all tuples whose members have info. +template +struct DenseMapInfo> { + using Tuple = std::tuple; + + static inline Tuple getEmptyKey() { + return Tuple(DenseMapInfo::getEmptyKey()...); + } + + static inline Tuple getTombstoneKey() { + return Tuple(DenseMapInfo::getTombstoneKey()...); + } + + template + static unsigned getHashValueImpl(const Tuple &values, std::false_type) { + using EltType = typename std::tuple_element::type; + std::integral_constant atEnd; + return detail::combineHashValue( + DenseMapInfo::getHashValue(std::get(values)), + getHashValueImpl(values, atEnd)); + } + + template + static unsigned getHashValueImpl(const Tuple &values, std::true_type) { + return 0; + } + + static unsigned getHashValue(const std::tuple &values) { + std::integral_constant atEnd; + return getHashValueImpl<0>(values, atEnd); + } + + template + static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, std::false_type) { + using EltType = typename std::tuple_element::type; + std::integral_constant atEnd; + return DenseMapInfo::isEqual(std::get(lhs), std::get(rhs)) && + isEqualImpl(lhs, rhs, atEnd); + } + + template + static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, std::true_type) { + return true; + } + + static bool isEqual(const Tuple &lhs, const Tuple &rhs) { + std::integral_constant atEnd; + return isEqualImpl<0>(lhs, rhs, atEnd); + } +}; + // Provide DenseMapInfo for StringRefs. template <> struct DenseMapInfo { static inline StringRef getEmptyKey() { diff --git a/mlir/include/mlir/Support/STLExtras.h b/mlir/include/mlir/Support/STLExtras.h --- a/mlir/include/mlir/Support/STLExtras.h +++ b/mlir/include/mlir/Support/STLExtras.h @@ -399,74 +399,4 @@ : public FunctionTraits {}; } // end namespace mlir -// Allow tuples to be usable as DenseMap keys. -// TODO: Move this to upstream LLVM. - -/// Simplistic combination of 32-bit hash values into 32-bit hash values. -/// This function is taken from llvm/ADT/DenseMapInfo.h. -static inline unsigned llvm_combineHashValue(unsigned a, unsigned b) { - uint64_t key = (uint64_t)a << 32 | (uint64_t)b; - key += ~(key << 32); - key ^= (key >> 22); - key += ~(key << 13); - key ^= (key >> 8); - key += (key << 3); - key ^= (key >> 15); - key += ~(key << 27); - key ^= (key >> 31); - return (unsigned)key; -} - -namespace llvm { -template struct DenseMapInfo> { - using Tuple = std::tuple; - - static inline Tuple getEmptyKey() { - return Tuple(DenseMapInfo::getEmptyKey()...); - } - - static inline Tuple getTombstoneKey() { - return Tuple(DenseMapInfo::getTombstoneKey()...); - } - - template - static unsigned getHashValueImpl(const Tuple &values, std::false_type) { - using EltType = typename std::tuple_element::type; - std::integral_constant atEnd; - return llvm_combineHashValue( - DenseMapInfo::getHashValue(std::get(values)), - getHashValueImpl(values, atEnd)); - } - - template - static unsigned getHashValueImpl(const Tuple &values, std::true_type) { - return 0; - } - - static unsigned getHashValue(const std::tuple &values) { - std::integral_constant atEnd; - return getHashValueImpl<0>(values, atEnd); - } - - template - static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, std::false_type) { - using EltType = typename std::tuple_element::type; - std::integral_constant atEnd; - return DenseMapInfo::isEqual(std::get(lhs), std::get(rhs)) && - isEqualImpl(lhs, rhs, atEnd); - } - - template - static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, std::true_type) { - return true; - } - - static bool isEqual(const Tuple &lhs, const Tuple &rhs) { - std::integral_constant atEnd; - return isEqualImpl<0>(lhs, rhs, atEnd); - } -}; - -} // end namespace llvm - #endif // MLIR_SUPPORT_STLEXTRAS_H