LLVM 23.0.0git
DenseMapInfo.h
Go to the documentation of this file.
1//===- llvm/ADT/DenseMapInfo.h - Type traits for DenseMap -------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file defines DenseMapInfo traits for DenseMap.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ADT_DENSEMAPINFO_H
15#define LLVM_ADT_DENSEMAPINFO_H
16
17#include <cstddef>
18#include <cstdint>
19#include <optional>
20#include <tuple>
21#include <type_traits>
22#include <utility>
23
24namespace llvm {
25
26namespace densemap::detail {
27// A bit mixer with very low latency using one multiplications and one
28// xor-shift. The constant is from splitmix64.
30 x *= 0xbf58476d1ce4e5b9u;
31 x ^= x >> 31;
32 return x;
33}
34} // namespace densemap::detail
35
36namespace detail {
37
38/// Simplistic combination of 32-bit hash values into 32-bit hash values.
39inline unsigned combineHashValue(unsigned a, unsigned b) {
40 uint64_t x = (uint64_t)a << 32 | (uint64_t)b;
41 return (unsigned)densemap::detail::mix(x);
42}
43
44} // end namespace detail
45
46/// An information struct used to provide DenseMap with the various necessary
47/// components for a given value type `T`. `Enable` is an optional additional
48/// parameter that is used to support SFINAE (generally using std::enable_if_t)
49/// in derived DenseMapInfo specializations; in non-SFINAE use cases this should
50/// just be `void`.
51template <typename T, typename Enable = void> struct DenseMapInfo {
52 // static unsigned getHashValue(const T &Val);
53 // static bool isEqual(const T &LHS, const T &RHS);
54};
55
56// Provide DenseMapInfo for all pointers. Avoid requiring T to be complete so
57// clients can instantiate DenseMap<T*, ...> with forward declared key types.
58template <typename T> struct DenseMapInfo<T *> {
59 static unsigned getHashValue(const T *PtrVal) {
60 return densemap::detail::mix(reinterpret_cast<uintptr_t>(PtrVal));
61 }
62
63 static bool isEqual(const T *LHS, const T *RHS) { return LHS == RHS; }
64};
65
66// Provide DenseMapInfo for all integral types.
67template <typename T>
68struct DenseMapInfo<T, std::enable_if_t<std::is_integral_v<T>>> {
69 static unsigned getHashValue(const T &Val) {
70 if constexpr (std::is_unsigned_v<T> && sizeof(T) > sizeof(unsigned))
71 return densemap::detail::mix(Val);
72 else
73 return static_cast<unsigned>(Val *
74 static_cast<std::make_unsigned_t<T>>(37U));
75 }
76
77 static bool isEqual(const T &LHS, const T &RHS) { return LHS == RHS; }
78};
79
80// Provide DenseMapInfo for all pairs whose members have info.
81template<typename T, typename U>
82struct DenseMapInfo<std::pair<T, U>> {
83 using Pair = std::pair<T, U>;
86
87 static unsigned getHashValue(const Pair& PairVal) {
88 return detail::combineHashValue(FirstInfo::getHashValue(PairVal.first),
89 SecondInfo::getHashValue(PairVal.second));
90 }
91
92 // Expose an additional function intended to be used by other
93 // specializations of DenseMapInfo without needing to know how
94 // to combine hash values manually
95 static unsigned getHashValuePiecewise(const T &First, const U &Second) {
96 return detail::combineHashValue(FirstInfo::getHashValue(First),
97 SecondInfo::getHashValue(Second));
98 }
99
100 static bool isEqual(const Pair &LHS, const Pair &RHS) {
101 return FirstInfo::isEqual(LHS.first, RHS.first) &&
102 SecondInfo::isEqual(LHS.second, RHS.second);
103 }
104};
105
106// Provide DenseMapInfo for all tuples whose members have info.
107template <typename... Ts> struct DenseMapInfo<std::tuple<Ts...>> {
108 using Tuple = std::tuple<Ts...>;
109
110 template <unsigned I> static unsigned getHashValueImpl(const Tuple &values) {
111 if constexpr (I == sizeof...(Ts)) {
112 return 0;
113 } else {
114 using EltType = std::tuple_element_t<I, Tuple>;
116 DenseMapInfo<EltType>::getHashValue(std::get<I>(values)),
118 }
119 }
120
121 static unsigned getHashValue(const std::tuple<Ts...> &values) {
122 return getHashValueImpl<0>(values);
123 }
124
125 template <std::size_t... Is>
126 static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs,
127 std::index_sequence<Is...>) {
128 return (DenseMapInfo<std::tuple_element_t<Is, Tuple>>::isEqual(
129 std::get<Is>(lhs), std::get<Is>(rhs)) &&
130 ...);
131 }
132
133 static bool isEqual(const Tuple &lhs, const Tuple &rhs) {
134 return isEqualImpl(lhs, rhs, std::index_sequence_for<Ts...>{});
135 }
136};
137
138// Provide DenseMapInfo for enum classes.
139template <typename Enum>
140struct DenseMapInfo<Enum, std::enable_if_t<std::is_enum_v<Enum>>> {
141 using UnderlyingType = std::underlying_type_t<Enum>;
143
144 static unsigned getHashValue(const Enum &Val) {
145 return Info::getHashValue(static_cast<UnderlyingType>(Val));
146 }
147
148 static bool isEqual(const Enum &LHS, const Enum &RHS) { return LHS == RHS; }
149};
150
151template <typename T> struct DenseMapInfo<std::optional<T>> {
152 using Optional = std::optional<T>;
154
155 static unsigned getHashValue(const Optional &OptionalVal) {
156 if (OptionalVal)
157 return detail::combineHashValue(1, Info::getHashValue(*OptionalVal));
158 return 0;
159 }
160
161 static bool isEqual(const Optional &LHS, const Optional &RHS) {
162 if (LHS && RHS) {
163 return Info::isEqual(LHS.value(), RHS.value());
164 }
165 return !LHS && !RHS;
166 }
167};
168} // end namespace llvm
169
170#endif // LLVM_ADT_DENSEMAPINFO_H
static unsigned getHashValueImpl(SimpleValue Val)
Definition EarlyCSE.cpp:216
static bool isEqualImpl(SimpleValue LHS, SimpleValue RHS)
Definition EarlyCSE.cpp:337
#define I(x, y, z)
Definition MD5.cpp:57
#define T
Value * RHS
Value * LHS
uint64_t mix(uint64_t x)
unsigned combineHashValue(unsigned a, unsigned b)
Simplistic combination of 32-bit hash values into 32-bit hash values.
This is an optimization pass for GlobalISel generic memory operations.
@ First
Helpers to iterate all locations in the MemoryEffectsBase class.
Definition ModRef.h:74
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:860
static unsigned getHashValue(const T *PtrVal)
static bool isEqual(const T *LHS, const T *RHS)
static unsigned getHashValue(const Optional &OptionalVal)
static bool isEqual(const Optional &LHS, const Optional &RHS)
static unsigned getHashValuePiecewise(const T &First, const U &Second)
static unsigned getHashValue(const Pair &PairVal)
static bool isEqual(const Pair &LHS, const Pair &RHS)
static bool isEqualImpl(const Tuple &lhs, const Tuple &rhs, std::index_sequence< Is... >)
static unsigned getHashValue(const std::tuple< Ts... > &values)
static bool isEqual(const Tuple &lhs, const Tuple &rhs)
static unsigned getHashValueImpl(const Tuple &values)
An information struct used to provide DenseMap with the various necessary components for a given valu...