[Mlir-commits] [mlir] f52ec5d - [llvm][DenseMapInfo] Add an info specialization for std::tuple
River Riddle
llvmlistbot at llvm.org
Tue Apr 14 15:22:33 PDT 2020
Author: River Riddle
Date: 2020-04-14T15:14:40-07:00
New Revision: f52ec5d5c088305298fa2a19e4c5b7380bcd98e8
URL: https://github.com/llvm/llvm-project/commit/f52ec5d5c088305298fa2a19e4c5b7380bcd98e8
DIFF: https://github.com/llvm/llvm-project/commit/f52ec5d5c088305298fa2a19e4c5b7380bcd98e8.diff
LOG: [llvm][DenseMapInfo] Add an info specialization for std::tuple
This revision adds a DenseMapInfo overload for std::tuples whose elements all have a DenseMapInfo. The implementation is similar to that of std::pair, and has been used within MLIR for over a year.
Differential Revision: https://reviews.llvm.org/D78057
Added:
Modified:
llvm/include/llvm/ADT/DenseMapInfo.h
mlir/include/mlir/Support/STLExtras.h
Removed:
################################################################################
diff --git a/llvm/include/llvm/ADT/DenseMapInfo.h b/llvm/include/llvm/ADT/DenseMapInfo.h
index 4005888c1c80..e465331ac6f7 100644
--- 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<typename T>
struct DenseMapInfo {
//static inline T getEmptyKey();
@@ -206,17 +224,8 @@ struct DenseMapInfo<std::pair<T, U>> {
}
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,56 @@ struct DenseMapInfo<std::pair<T, U>> {
}
};
+// Provide DenseMapInfo for all tuples whose members have info.
+template <typename... Ts> struct DenseMapInfo<std::tuple<Ts...>> {
+ using Tuple = std::tuple<Ts...>;
+
+ static inline Tuple getEmptyKey() {
+ return Tuple(DenseMapInfo<Ts>::getEmptyKey()...);
+ }
+
+ static inline Tuple getTombstoneKey() {
+ return Tuple(DenseMapInfo<Ts>::getTombstoneKey()...);
+ }
+
+ template <unsigned I>
+ static unsigned getHashValueImpl(const Tuple &values, std::false_type) {
+ using EltType = typename std::tuple_element<I, Tuple>::type;
+ std::integral_constant<bool, I + 1 == sizeof...(Ts)> atEnd;
+ return detail::combineHashValue(
+ DenseMapInfo<EltType>::getHashValue(std::get<I>(values)),
+ getHashValueImpl<I + 1>(values, atEnd));
+ }
+
+ template <unsigned I>
+ static unsigned getHashValueImpl(const Tuple &values, std::true_type) {
+ return 0;
+ }
+
+ static unsigned getHashValue(const std::tuple<Ts...> &values) {
+ std::integral_constant<bool, 0 == sizeof...(Ts)> atEnd;
+ return getHashValueImpl<0>(values, atEnd);
+ }
+
+ template <unsigned I>
+ static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, std::false_type) {
+ using EltType = typename std::tuple_element<I, Tuple>::type;
+ std::integral_constant<bool, I + 1 == sizeof...(Ts)> atEnd;
+ return DenseMapInfo<EltType>::isEqual(std::get<I>(lhs), std::get<I>(rhs)) &&
+ isEqualImpl<I + 1>(lhs, rhs, atEnd);
+ }
+
+ template <unsigned I>
+ 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<bool, 0 == sizeof...(Ts)> atEnd;
+ return isEqualImpl<0>(lhs, rhs, atEnd);
+ }
+};
+
// Provide DenseMapInfo for StringRefs.
template <> struct DenseMapInfo<StringRef> {
static inline StringRef getEmptyKey() {
diff --git a/mlir/include/mlir/Support/STLExtras.h b/mlir/include/mlir/Support/STLExtras.h
index 9a2b2d35bb49..ada69a927afa 100644
--- a/mlir/include/mlir/Support/STLExtras.h
+++ b/mlir/include/mlir/Support/STLExtras.h
@@ -399,74 +399,4 @@ struct FunctionTraits<ReturnType (&)(Args...), false>
: public FunctionTraits<ReturnType (*)(Args...)> {};
} // 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 <typename... Ts> struct DenseMapInfo<std::tuple<Ts...>> {
- using Tuple = std::tuple<Ts...>;
-
- static inline Tuple getEmptyKey() {
- return Tuple(DenseMapInfo<Ts>::getEmptyKey()...);
- }
-
- static inline Tuple getTombstoneKey() {
- return Tuple(DenseMapInfo<Ts>::getTombstoneKey()...);
- }
-
- template <unsigned I>
- static unsigned getHashValueImpl(const Tuple &values, std::false_type) {
- using EltType = typename std::tuple_element<I, Tuple>::type;
- std::integral_constant<bool, I + 1 == sizeof...(Ts)> atEnd;
- return llvm_combineHashValue(
- DenseMapInfo<EltType>::getHashValue(std::get<I>(values)),
- getHashValueImpl<I + 1>(values, atEnd));
- }
-
- template <unsigned I>
- static unsigned getHashValueImpl(const Tuple &values, std::true_type) {
- return 0;
- }
-
- static unsigned getHashValue(const std::tuple<Ts...> &values) {
- std::integral_constant<bool, 0 == sizeof...(Ts)> atEnd;
- return getHashValueImpl<0>(values, atEnd);
- }
-
- template <unsigned I>
- static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, std::false_type) {
- using EltType = typename std::tuple_element<I, Tuple>::type;
- std::integral_constant<bool, I + 1 == sizeof...(Ts)> atEnd;
- return DenseMapInfo<EltType>::isEqual(std::get<I>(lhs), std::get<I>(rhs)) &&
- isEqualImpl<I + 1>(lhs, rhs, atEnd);
- }
-
- template <unsigned I>
- 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<bool, 0 == sizeof...(Ts)> atEnd;
- return isEqualImpl<0>(lhs, rhs, atEnd);
- }
-};
-
-} // end namespace llvm
-
#endif // MLIR_SUPPORT_STLEXTRAS_H
More information about the Mlir-commits
mailing list