1 //===- ValueMap.h - Safe map from Values to data ----------------*- C++ -*-===//
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
7 //===----------------------------------------------------------------------===//
9 // This file defines the ValueMap class. ValueMap maps Value* or any subclass
10 // to an arbitrary other type. It provides the DenseMap interface but updates
11 // itself to remain safe when keys are RAUWed or deleted. By default, when a
12 // key is RAUWed from V1 to V2, the old mapping V1->target is removed, and a new
13 // mapping V2->target is added. If V2 already existed, its old target is
14 // overwritten. When a key is deleted, its mapping is removed.
16 // You can override a ValueMap's Config parameter to control exactly what
17 // happens on RAUW and destruction and to get called back on each event. It's
18 // legal to call back into the ValueMap from a Config's callbacks. Config
19 // parameters should inherit from ValueMapConfig<KeyT> to get default
20 // implementations of all the methods ValueMap uses. See ValueMapConfig for
21 // documentation of the functions you can override.
23 //===----------------------------------------------------------------------===//
25 #ifndef LLVM_IR_VALUEMAP_H
26 #define LLVM_IR_VALUEMAP_H
28 #include "llvm/ADT/DenseMap.h"
29 #include "llvm/ADT/DenseMapInfo.h"
30 #include "llvm/ADT/None.h"
31 #include "llvm/ADT/Optional.h"
32 #include "llvm/IR/TrackingMDRef.h"
33 #include "llvm/IR/ValueHandle.h"
34 #include "llvm/Support/Casting.h"
35 #include "llvm/Support/Mutex.h"
36 #include "llvm/Support/UniqueLock.h"
41 #include <type_traits>
46 template<typename KeyT
, typename ValueT
, typename Config
>
47 class ValueMapCallbackVH
;
48 template<typename DenseMapT
, typename KeyT
>
49 class ValueMapIterator
;
50 template<typename DenseMapT
, typename KeyT
>
51 class ValueMapConstIterator
;
53 /// This class defines the default behavior for configurable aspects of
54 /// ValueMap<>. User Configs should inherit from this class to be as compatible
55 /// as possible with future versions of ValueMap.
56 template<typename KeyT
, typename MutexT
= sys::Mutex
>
57 struct ValueMapConfig
{
58 using mutex_type
= MutexT
;
60 /// If FollowRAUW is true, the ValueMap will update mappings on RAUW. If it's
61 /// false, the ValueMap will leave the original mapping in place.
62 enum { FollowRAUW
= true };
64 // All methods will be called with a first argument of type ExtraData. The
65 // default implementations in this class take a templated first argument so
66 // that users' subclasses can use any type they want without having to
67 // override all the defaults.
70 template<typename ExtraDataT
>
71 static void onRAUW(const ExtraDataT
& /*Data*/, KeyT
/*Old*/, KeyT
/*New*/) {}
72 template<typename ExtraDataT
>
73 static void onDelete(const ExtraDataT
&/*Data*/, KeyT
/*Old*/) {}
75 /// Returns a mutex that should be acquired around any changes to the map.
76 /// This is only acquired from the CallbackVH (and held around calls to onRAUW
77 /// and onDelete) and not inside other ValueMap methods. NULL means that no
78 /// mutex is necessary.
79 template<typename ExtraDataT
>
80 static mutex_type
*getMutex(const ExtraDataT
&/*Data*/) { return nullptr; }
83 /// See the file comment.
84 template<typename KeyT
, typename ValueT
, typename Config
=ValueMapConfig
<KeyT
>>
86 friend class ValueMapCallbackVH
<KeyT
, ValueT
, Config
>;
88 using ValueMapCVH
= ValueMapCallbackVH
<KeyT
, ValueT
, Config
>;
89 using MapT
= DenseMap
<ValueMapCVH
, ValueT
, DenseMapInfo
<ValueMapCVH
>>;
90 using MDMapT
= DenseMap
<const Metadata
*, TrackingMDRef
>;
91 using ExtraData
= typename
Config::ExtraData
;
94 Optional
<MDMapT
> MDMap
;
96 bool MayMapMetadata
= true;
99 using key_type
= KeyT
;
100 using mapped_type
= ValueT
;
101 using value_type
= std::pair
<KeyT
, ValueT
>;
102 using size_type
= unsigned;
104 explicit ValueMap(unsigned NumInitBuckets
= 64)
105 : Map(NumInitBuckets
), Data() {}
106 explicit ValueMap(const ExtraData
&Data
, unsigned NumInitBuckets
= 64)
107 : Map(NumInitBuckets
), Data(Data
) {}
108 // ValueMap can't be copied nor moved, beucase the callbacks store pointer
110 ValueMap(const ValueMap
&) = delete;
111 ValueMap(ValueMap
&&) = delete;
112 ValueMap
&operator=(const ValueMap
&) = delete;
113 ValueMap
&operator=(ValueMap
&&) = delete;
115 bool hasMD() const { return bool(MDMap
); }
121 Optional
<MDMapT
> &getMDMap() { return MDMap
; }
123 bool mayMapMetadata() const { return MayMapMetadata
; }
124 void enableMapMetadata() { MayMapMetadata
= true; }
125 void disableMapMetadata() { MayMapMetadata
= false; }
127 /// Get the mapped metadata, if it's in the map.
128 Optional
<Metadata
*> getMappedMD(const Metadata
*MD
) const {
131 auto Where
= MDMap
->find(MD
);
132 if (Where
== MDMap
->end())
134 return Where
->second
.get();
137 using iterator
= ValueMapIterator
<MapT
, KeyT
>;
138 using const_iterator
= ValueMapConstIterator
<MapT
, KeyT
>;
140 inline iterator
begin() { return iterator(Map
.begin()); }
141 inline iterator
end() { return iterator(Map
.end()); }
142 inline const_iterator
begin() const { return const_iterator(Map
.begin()); }
143 inline const_iterator
end() const { return const_iterator(Map
.end()); }
145 bool empty() const { return Map
.empty(); }
146 size_type
size() const { return Map
.size(); }
148 /// Grow the map so that it has at least Size buckets. Does not shrink
149 void resize(size_t Size
) { Map
.resize(Size
); }
156 /// Return 1 if the specified key is in the map, 0 otherwise.
157 size_type
count(const KeyT
&Val
) const {
158 return Map
.find_as(Val
) == Map
.end() ? 0 : 1;
161 iterator
find(const KeyT
&Val
) {
162 return iterator(Map
.find_as(Val
));
164 const_iterator
find(const KeyT
&Val
) const {
165 return const_iterator(Map
.find_as(Val
));
168 /// lookup - Return the entry for the specified key, or a default
169 /// constructed value if no such entry exists.
170 ValueT
lookup(const KeyT
&Val
) const {
171 typename
MapT::const_iterator I
= Map
.find_as(Val
);
172 return I
!= Map
.end() ? I
->second
: ValueT();
175 // Inserts key,value pair into the map if the key isn't already in the map.
176 // If the key is already in the map, it returns false and doesn't update the
178 std::pair
<iterator
, bool> insert(const std::pair
<KeyT
, ValueT
> &KV
) {
179 auto MapResult
= Map
.insert(std::make_pair(Wrap(KV
.first
), KV
.second
));
180 return std::make_pair(iterator(MapResult
.first
), MapResult
.second
);
183 std::pair
<iterator
, bool> insert(std::pair
<KeyT
, ValueT
> &&KV
) {
185 Map
.insert(std::make_pair(Wrap(KV
.first
), std::move(KV
.second
)));
186 return std::make_pair(iterator(MapResult
.first
), MapResult
.second
);
189 /// insert - Range insertion of pairs.
190 template<typename InputIt
>
191 void insert(InputIt I
, InputIt E
) {
196 bool erase(const KeyT
&Val
) {
197 typename
MapT::iterator I
= Map
.find_as(Val
);
204 void erase(iterator I
) {
205 return Map
.erase(I
.base());
208 value_type
& FindAndConstruct(const KeyT
&Key
) {
209 return Map
.FindAndConstruct(Wrap(Key
));
212 ValueT
&operator[](const KeyT
&Key
) {
213 return Map
[Wrap(Key
)];
216 /// isPointerIntoBucketsArray - Return true if the specified pointer points
217 /// somewhere into the ValueMap's array of buckets (i.e. either to a key or
218 /// value in the ValueMap).
219 bool isPointerIntoBucketsArray(const void *Ptr
) const {
220 return Map
.isPointerIntoBucketsArray(Ptr
);
223 /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
224 /// array. In conjunction with the previous method, this can be used to
225 /// determine whether an insertion caused the ValueMap to reallocate.
226 const void *getPointerIntoBucketsArray() const {
227 return Map
.getPointerIntoBucketsArray();
231 // Takes a key being looked up in the map and wraps it into a
232 // ValueMapCallbackVH, the actual key type of the map. We use a helper
233 // function because ValueMapCVH is constructed with a second parameter.
234 ValueMapCVH
Wrap(KeyT key
) const {
235 // The only way the resulting CallbackVH could try to modify *this (making
236 // the const_cast incorrect) is if it gets inserted into the map. But then
237 // this function must have been called from a non-const method, making the
239 return ValueMapCVH(key
, const_cast<ValueMap
*>(this));
243 // This CallbackVH updates its ValueMap when the contained Value changes,
244 // according to the user's preferences expressed through the Config object.
245 template <typename KeyT
, typename ValueT
, typename Config
>
246 class ValueMapCallbackVH final
: public CallbackVH
{
247 friend class ValueMap
<KeyT
, ValueT
, Config
>;
248 friend struct DenseMapInfo
<ValueMapCallbackVH
>;
250 using ValueMapT
= ValueMap
<KeyT
, ValueT
, Config
>;
251 using KeySansPointerT
= typename
std::remove_pointer
<KeyT
>::type
;
255 ValueMapCallbackVH(KeyT Key
, ValueMapT
*Map
)
256 : CallbackVH(const_cast<Value
*>(static_cast<const Value
*>(Key
))),
259 // Private constructor used to create empty/tombstone DenseMap keys.
260 ValueMapCallbackVH(Value
*V
) : CallbackVH(V
), Map(nullptr) {}
263 KeyT
Unwrap() const { return cast_or_null
<KeySansPointerT
>(getValPtr()); }
265 void deleted() override
{
266 // Make a copy that won't get changed even when *this is destroyed.
267 ValueMapCallbackVH
Copy(*this);
268 typename
Config::mutex_type
*M
= Config::getMutex(Copy
.Map
->Data
);
269 unique_lock
<typename
Config::mutex_type
> Guard
;
271 Guard
= unique_lock
<typename
Config::mutex_type
>(*M
);
272 Config::onDelete(Copy
.Map
->Data
, Copy
.Unwrap()); // May destroy *this.
273 Copy
.Map
->Map
.erase(Copy
); // Definitely destroys *this.
276 void allUsesReplacedWith(Value
*new_key
) override
{
277 assert(isa
<KeySansPointerT
>(new_key
) &&
278 "Invalid RAUW on key of ValueMap<>");
279 // Make a copy that won't get changed even when *this is destroyed.
280 ValueMapCallbackVH
Copy(*this);
281 typename
Config::mutex_type
*M
= Config::getMutex(Copy
.Map
->Data
);
282 unique_lock
<typename
Config::mutex_type
> Guard
;
284 Guard
= unique_lock
<typename
Config::mutex_type
>(*M
);
286 KeyT typed_new_key
= cast
<KeySansPointerT
>(new_key
);
287 // Can destroy *this:
288 Config::onRAUW(Copy
.Map
->Data
, Copy
.Unwrap(), typed_new_key
);
289 if (Config::FollowRAUW
) {
290 typename
ValueMapT::MapT::iterator I
= Copy
.Map
->Map
.find(Copy
);
291 // I could == Copy.Map->Map.end() if the onRAUW callback already
292 // removed the old mapping.
293 if (I
!= Copy
.Map
->Map
.end()) {
294 ValueT
Target(std::move(I
->second
));
295 Copy
.Map
->Map
.erase(I
); // Definitely destroys *this.
296 Copy
.Map
->insert(std::make_pair(typed_new_key
, std::move(Target
)));
302 template<typename KeyT
, typename ValueT
, typename Config
>
303 struct DenseMapInfo
<ValueMapCallbackVH
<KeyT
, ValueT
, Config
>> {
304 using VH
= ValueMapCallbackVH
<KeyT
, ValueT
, Config
>;
306 static inline VH
getEmptyKey() {
307 return VH(DenseMapInfo
<Value
*>::getEmptyKey());
310 static inline VH
getTombstoneKey() {
311 return VH(DenseMapInfo
<Value
*>::getTombstoneKey());
314 static unsigned getHashValue(const VH
&Val
) {
315 return DenseMapInfo
<KeyT
>::getHashValue(Val
.Unwrap());
318 static unsigned getHashValue(const KeyT
&Val
) {
319 return DenseMapInfo
<KeyT
>::getHashValue(Val
);
322 static bool isEqual(const VH
&LHS
, const VH
&RHS
) {
326 static bool isEqual(const KeyT
&LHS
, const VH
&RHS
) {
327 return LHS
== RHS
.getValPtr();
331 template<typename DenseMapT
, typename KeyT
>
332 class ValueMapIterator
:
333 public std::iterator
<std::forward_iterator_tag
,
334 std::pair
<KeyT
, typename
DenseMapT::mapped_type
>,
336 using BaseT
= typename
DenseMapT::iterator
;
337 using ValueT
= typename
DenseMapT::mapped_type
;
342 ValueMapIterator() : I() {}
343 ValueMapIterator(BaseT I
) : I(I
) {}
345 BaseT
base() const { return I
; }
347 struct ValueTypeProxy
{
351 ValueTypeProxy
*operator->() { return this; }
353 operator std::pair
<KeyT
, ValueT
>() const {
354 return std::make_pair(first
, second
);
358 ValueTypeProxy
operator*() const {
359 ValueTypeProxy Result
= {I
->first
.Unwrap(), I
->second
};
363 ValueTypeProxy
operator->() const {
367 bool operator==(const ValueMapIterator
&RHS
) const {
370 bool operator!=(const ValueMapIterator
&RHS
) const {
374 inline ValueMapIterator
& operator++() { // Preincrement
378 ValueMapIterator
operator++(int) { // Postincrement
379 ValueMapIterator tmp
= *this; ++*this; return tmp
;
383 template<typename DenseMapT
, typename KeyT
>
384 class ValueMapConstIterator
:
385 public std::iterator
<std::forward_iterator_tag
,
386 std::pair
<KeyT
, typename
DenseMapT::mapped_type
>,
388 using BaseT
= typename
DenseMapT::const_iterator
;
389 using ValueT
= typename
DenseMapT::mapped_type
;
394 ValueMapConstIterator() : I() {}
395 ValueMapConstIterator(BaseT I
) : I(I
) {}
396 ValueMapConstIterator(ValueMapIterator
<DenseMapT
, KeyT
> Other
)
399 BaseT
base() const { return I
; }
401 struct ValueTypeProxy
{
403 const ValueT
& second
;
404 ValueTypeProxy
*operator->() { return this; }
405 operator std::pair
<KeyT
, ValueT
>() const {
406 return std::make_pair(first
, second
);
410 ValueTypeProxy
operator*() const {
411 ValueTypeProxy Result
= {I
->first
.Unwrap(), I
->second
};
415 ValueTypeProxy
operator->() const {
419 bool operator==(const ValueMapConstIterator
&RHS
) const {
422 bool operator!=(const ValueMapConstIterator
&RHS
) const {
426 inline ValueMapConstIterator
& operator++() { // Preincrement
430 ValueMapConstIterator
operator++(int) { // Postincrement
431 ValueMapConstIterator tmp
= *this; ++*this; return tmp
;
435 } // end namespace llvm
437 #endif // LLVM_IR_VALUEMAP_H