LLVM 22.0.0git
DenseMap.h
Go to the documentation of this file.
1//===- llvm/ADT/DenseMap.h - Dense probed hash table ------------*- 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 the DenseMap class.
11///
12//===----------------------------------------------------------------------===//
13
14#ifndef LLVM_ADT_DENSEMAP_H
15#define LLVM_ADT_DENSEMAP_H
16
17#include "llvm/ADT/ADL.h"
20#include "llvm/ADT/STLExtras.h"
28#include <algorithm>
29#include <cassert>
30#include <cstddef>
31#include <cstring>
32#include <initializer_list>
33#include <iterator>
34#include <new>
35#include <type_traits>
36#include <utility>
37
38namespace llvm {
39
40namespace detail {
41
42// We extend a pair to allow users to override the bucket type with their own
43// implementation without requiring two members.
44template <typename KeyT, typename ValueT>
45struct DenseMapPair : public std::pair<KeyT, ValueT> {
46 using std::pair<KeyT, ValueT>::pair;
47
48 KeyT &getFirst() { return std::pair<KeyT, ValueT>::first; }
49 const KeyT &getFirst() const { return std::pair<KeyT, ValueT>::first; }
50 ValueT &getSecond() { return std::pair<KeyT, ValueT>::second; }
51 const ValueT &getSecond() const { return std::pair<KeyT, ValueT>::second; }
52};
53
54} // end namespace detail
55
56template <typename KeyT, typename ValueT,
57 typename KeyInfoT = DenseMapInfo<KeyT>,
59 bool IsConst = false>
60class DenseMapIterator;
61
62template <typename DerivedT, typename KeyT, typename ValueT, typename KeyInfoT,
63 typename BucketT>
65 template <typename T>
66 using const_arg_type_t = typename const_pointer_or_const_ref<T>::type;
67
68public:
70 using key_type = KeyT;
71 using mapped_type = ValueT;
72 using value_type = BucketT;
73
77
78 inline iterator begin() {
79 return iterator::makeBegin(buckets(), empty(), *this);
80 }
81 inline iterator end() { return iterator::makeEnd(buckets(), *this); }
82 inline const_iterator begin() const {
83 return const_iterator::makeBegin(buckets(), empty(), *this);
84 }
85 inline const_iterator end() const {
86 return const_iterator::makeEnd(buckets(), *this);
87 }
88
89 // Return an iterator to iterate over keys in the map.
90 inline auto keys() {
91 return map_range(*this, [](const BucketT &P) { return P.getFirst(); });
92 }
93
94 // Return an iterator to iterate over values in the map.
95 inline auto values() {
96 return map_range(*this, [](const BucketT &P) { return P.getSecond(); });
97 }
98
99 inline auto keys() const {
100 return map_range(*this, [](const BucketT &P) { return P.getFirst(); });
101 }
102
103 inline auto values() const {
104 return map_range(*this, [](const BucketT &P) { return P.getSecond(); });
105 }
106
107 [[nodiscard]] bool empty() const { return getNumEntries() == 0; }
108 unsigned size() const { return getNumEntries(); }
109
110 /// Grow the densemap so that it can contain at least \p NumEntries items
111 /// before resizing again.
112 void reserve(size_type NumEntries) {
113 auto NumBuckets = getMinBucketToReserveForEntries(NumEntries);
115 if (NumBuckets > getNumBuckets())
116 grow(NumBuckets);
117 }
118
119 void clear() {
121 if (getNumEntries() == 0 && getNumTombstones() == 0)
122 return;
123
124 // If the capacity of the array is huge, and the # elements used is small,
125 // shrink the array.
126 if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) {
127 shrink_and_clear();
128 return;
129 }
130
131 const KeyT EmptyKey = getEmptyKey();
132 if constexpr (std::is_trivially_destructible_v<ValueT>) {
133 // Use a simpler loop when values don't need destruction.
134 for (BucketT &B : buckets())
135 B.getFirst() = EmptyKey;
136 } else {
137 const KeyT TombstoneKey = getTombstoneKey();
138 unsigned NumEntries = getNumEntries();
139 for (BucketT &B : buckets()) {
140 if (!KeyInfoT::isEqual(B.getFirst(), EmptyKey)) {
141 if (!KeyInfoT::isEqual(B.getFirst(), TombstoneKey)) {
142 B.getSecond().~ValueT();
143 --NumEntries;
144 }
145 B.getFirst() = EmptyKey;
146 }
147 }
148 assert(NumEntries == 0 && "Node count imbalance!");
149 (void)NumEntries;
150 }
151 setNumEntries(0);
152 setNumTombstones(0);
153 }
154
155 /// Return true if the specified key is in the map, false otherwise.
156 bool contains(const_arg_type_t<KeyT> Val) const {
157 return doFind(Val) != nullptr;
158 }
159
160 /// Return 1 if the specified key is in the map, 0 otherwise.
161 size_type count(const_arg_type_t<KeyT> Val) const {
162 return contains(Val) ? 1 : 0;
163 }
164
165 iterator find(const_arg_type_t<KeyT> Val) { return find_as(Val); }
166 const_iterator find(const_arg_type_t<KeyT> Val) const { return find_as(Val); }
167
168 /// Alternate version of find() which allows a different, and possibly
169 /// less expensive, key type.
170 /// The DenseMapInfo is responsible for supplying methods
171 /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key
172 /// type used.
173 template <class LookupKeyT> iterator find_as(const LookupKeyT &Val) {
174 if (BucketT *Bucket = doFind(Val))
175 return makeIterator(Bucket);
176 return end();
177 }
178 template <class LookupKeyT>
179 const_iterator find_as(const LookupKeyT &Val) const {
180 if (const BucketT *Bucket = doFind(Val))
181 return makeConstIterator(Bucket);
182 return end();
183 }
184
185 /// lookup - Return the entry for the specified key, or a default
186 /// constructed value if no such entry exists.
187 ValueT lookup(const_arg_type_t<KeyT> Val) const {
188 if (const BucketT *Bucket = doFind(Val))
189 return Bucket->getSecond();
190 return ValueT();
191 }
192
193 // Return the entry with the specified key, or \p Default. This variant is
194 // useful, because `lookup` cannot be used with non-default-constructible
195 // values.
196 template <typename U = std::remove_cv_t<ValueT>>
197 ValueT lookup_or(const_arg_type_t<KeyT> Val, U &&Default) const {
198 if (const BucketT *Bucket = doFind(Val))
199 return Bucket->getSecond();
200 return Default;
201 }
202
203 /// at - Return the entry for the specified key, or abort if no such
204 /// entry exists.
205 const ValueT &at(const_arg_type_t<KeyT> Val) const {
206 auto Iter = this->find(std::move(Val));
207 assert(Iter != this->end() && "DenseMap::at failed due to a missing key");
208 return Iter->second;
209 }
210
211 // Inserts key,value pair into the map if the key isn't already in the map.
212 // If the key is already in the map, it returns false and doesn't update the
213 // value.
214 std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
215 return try_emplace_impl(KV.first, KV.second);
216 }
217
218 // Inserts key,value pair into the map if the key isn't already in the map.
219 // If the key is already in the map, it returns false and doesn't update the
220 // value.
221 std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
222 return try_emplace_impl(std::move(KV.first), std::move(KV.second));
223 }
224
225 // Inserts key,value pair into the map if the key isn't already in the map.
226 // The value is constructed in-place if the key is not in the map, otherwise
227 // it is not moved.
228 template <typename... Ts>
229 std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&...Args) {
230 return try_emplace_impl(std::move(Key), std::forward<Ts>(Args)...);
231 }
232
233 // Inserts key,value pair into the map if the key isn't already in the map.
234 // The value is constructed in-place if the key is not in the map, otherwise
235 // it is not moved.
236 template <typename... Ts>
237 std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&...Args) {
238 return try_emplace_impl(Key, std::forward<Ts>(Args)...);
239 }
240
241 /// Alternate version of insert() which allows a different, and possibly
242 /// less expensive, key type.
243 /// The DenseMapInfo is responsible for supplying methods
244 /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key
245 /// type used.
246 template <typename LookupKeyT>
247 std::pair<iterator, bool> insert_as(std::pair<KeyT, ValueT> &&KV,
248 const LookupKeyT &Val) {
249 BucketT *TheBucket;
250 if (LookupBucketFor(Val, TheBucket))
251 return {makeIterator(TheBucket), false}; // Already in map.
252
253 // Otherwise, insert the new element.
254 TheBucket = findBucketForInsertion(Val, TheBucket);
255 TheBucket->getFirst() = std::move(KV.first);
256 ::new (&TheBucket->getSecond()) ValueT(std::move(KV.second));
257 return {makeIterator(TheBucket), true};
258 }
259
260 /// insert - Range insertion of pairs.
261 template <typename InputIt> void insert(InputIt I, InputIt E) {
262 for (; I != E; ++I)
263 insert(*I);
264 }
265
266 /// Inserts range of 'std::pair<KeyT, ValueT>' values into the map.
267 template <typename Range> void insert_range(Range &&R) {
268 insert(adl_begin(R), adl_end(R));
269 }
270
271 template <typename V>
272 std::pair<iterator, bool> insert_or_assign(const KeyT &Key, V &&Val) {
273 auto Ret = try_emplace(Key, std::forward<V>(Val));
274 if (!Ret.second)
275 Ret.first->second = std::forward<V>(Val);
276 return Ret;
277 }
278
279 template <typename V>
280 std::pair<iterator, bool> insert_or_assign(KeyT &&Key, V &&Val) {
281 auto Ret = try_emplace(std::move(Key), std::forward<V>(Val));
282 if (!Ret.second)
283 Ret.first->second = std::forward<V>(Val);
284 return Ret;
285 }
286
287 template <typename... Ts>
288 std::pair<iterator, bool> emplace_or_assign(const KeyT &Key, Ts &&...Args) {
289 auto Ret = try_emplace(Key, std::forward<Ts>(Args)...);
290 if (!Ret.second)
291 Ret.first->second = ValueT(std::forward<Ts>(Args)...);
292 return Ret;
293 }
294
295 template <typename... Ts>
296 std::pair<iterator, bool> emplace_or_assign(KeyT &&Key, Ts &&...Args) {
297 auto Ret = try_emplace(std::move(Key), std::forward<Ts>(Args)...);
298 if (!Ret.second)
299 Ret.first->second = ValueT(std::forward<Ts>(Args)...);
300 return Ret;
301 }
302
303 bool erase(const KeyT &Val) {
304 BucketT *TheBucket = doFind(Val);
305 if (!TheBucket)
306 return false; // not in map.
307
308 TheBucket->getSecond().~ValueT();
309 TheBucket->getFirst() = getTombstoneKey();
310 decrementNumEntries();
311 incrementNumTombstones();
312 return true;
313 }
315 BucketT *TheBucket = &*I;
316 TheBucket->getSecond().~ValueT();
317 TheBucket->getFirst() = getTombstoneKey();
318 decrementNumEntries();
319 incrementNumTombstones();
320 }
321
322 ValueT &operator[](const KeyT &Key) {
323 return lookupOrInsertIntoBucket(Key).first->second;
324 }
325
326 ValueT &operator[](KeyT &&Key) {
327 return lookupOrInsertIntoBucket(std::move(Key)).first->second;
328 }
329
330 /// isPointerIntoBucketsArray - Return true if the specified pointer points
331 /// somewhere into the DenseMap's array of buckets (i.e. either to a key or
332 /// value in the DenseMap).
333 bool isPointerIntoBucketsArray(const void *Ptr) const {
334 return Ptr >= getBuckets() && Ptr < getBucketsEnd();
335 }
336
337 /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
338 /// array. In conjunction with the previous method, this can be used to
339 /// determine whether an insertion caused the DenseMap to reallocate.
340 const void *getPointerIntoBucketsArray() const { return getBuckets(); }
341
342protected:
343 DenseMapBase() = default;
344
345 void destroyAll() {
346 if (getNumBuckets() == 0) // Nothing to do.
347 return;
348
349 const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
350 for (BucketT &B : buckets()) {
351 if (!KeyInfoT::isEqual(B.getFirst(), EmptyKey) &&
352 !KeyInfoT::isEqual(B.getFirst(), TombstoneKey))
353 B.getSecond().~ValueT();
354 B.getFirst().~KeyT();
355 }
356 }
357
358 void initEmpty() {
359 setNumEntries(0);
360 setNumTombstones(0);
361
362 assert((getNumBuckets() & (getNumBuckets() - 1)) == 0 &&
363 "# initial buckets must be a power of two!");
364 const KeyT EmptyKey = getEmptyKey();
365 for (BucketT &B : buckets())
366 ::new (&B.getFirst()) KeyT(EmptyKey);
367 }
368
369 /// Returns the number of buckets to allocate to ensure that the DenseMap can
370 /// accommodate \p NumEntries without need to grow().
371 unsigned getMinBucketToReserveForEntries(unsigned NumEntries) {
372 // Ensure that "NumEntries * 4 < NumBuckets * 3"
373 if (NumEntries == 0)
374 return 0;
375 // +1 is required because of the strict inequality.
376 // For example, if NumEntries is 48, we need to return 128.
377 return NextPowerOf2(NumEntries * 4 / 3 + 1);
378 }
379
381 initEmpty();
382
383 // Insert all the old elements.
384 const KeyT EmptyKey = getEmptyKey();
385 const KeyT TombstoneKey = getTombstoneKey();
386 for (BucketT &B : OldBuckets) {
387 if (!KeyInfoT::isEqual(B.getFirst(), EmptyKey) &&
388 !KeyInfoT::isEqual(B.getFirst(), TombstoneKey)) {
389 // Insert the key/value into the new table.
390 BucketT *DestBucket;
391 bool FoundVal = LookupBucketFor(B.getFirst(), DestBucket);
392 (void)FoundVal; // silence warning.
393 assert(!FoundVal && "Key already in new map?");
394 DestBucket->getFirst() = std::move(B.getFirst());
395 ::new (&DestBucket->getSecond()) ValueT(std::move(B.getSecond()));
396 incrementNumEntries();
397
398 // Free the value.
399 B.getSecond().~ValueT();
400 }
401 B.getFirst().~KeyT();
402 }
403 }
404
405 template <typename OtherBaseT>
408 assert(&other != this);
409 assert(getNumBuckets() == other.getNumBuckets());
410
411 setNumEntries(other.getNumEntries());
412 setNumTombstones(other.getNumTombstones());
413
414 BucketT *Buckets = getBuckets();
415 const BucketT *OtherBuckets = other.getBuckets();
416 const size_t NumBuckets = getNumBuckets();
417 if constexpr (std::is_trivially_copyable_v<KeyT> &&
418 std::is_trivially_copyable_v<ValueT>) {
419 memcpy(reinterpret_cast<void *>(Buckets), OtherBuckets,
420 NumBuckets * sizeof(BucketT));
421 } else {
422 const KeyT EmptyKey = getEmptyKey();
423 const KeyT TombstoneKey = getTombstoneKey();
424 for (size_t I = 0; I < NumBuckets; ++I) {
425 ::new (&Buckets[I].getFirst()) KeyT(OtherBuckets[I].getFirst());
426 if (!KeyInfoT::isEqual(Buckets[I].getFirst(), EmptyKey) &&
427 !KeyInfoT::isEqual(Buckets[I].getFirst(), TombstoneKey))
428 ::new (&Buckets[I].getSecond()) ValueT(OtherBuckets[I].getSecond());
429 }
430 }
431 }
432
433 static unsigned getHashValue(const KeyT &Val) {
434 return KeyInfoT::getHashValue(Val);
435 }
436
437 template <typename LookupKeyT>
438 static unsigned getHashValue(const LookupKeyT &Val) {
439 return KeyInfoT::getHashValue(Val);
440 }
441
442 static const KeyT getEmptyKey() {
443 static_assert(std::is_base_of_v<DenseMapBase, DerivedT>,
444 "Must pass the derived type to this template!");
445 return KeyInfoT::getEmptyKey();
446 }
447
448 static const KeyT getTombstoneKey() { return KeyInfoT::getTombstoneKey(); }
449
450private:
451 template <typename KeyArgT, typename... Ts>
452 std::pair<BucketT *, bool> lookupOrInsertIntoBucket(KeyArgT &&Key,
453 Ts &&...Args) {
454 BucketT *TheBucket = nullptr;
455 if (LookupBucketFor(Key, TheBucket))
456 return {TheBucket, false}; // Already in the map.
457
458 // Otherwise, insert the new element.
459 TheBucket = findBucketForInsertion(Key, TheBucket);
460 TheBucket->getFirst() = std::forward<KeyArgT>(Key);
461 ::new (&TheBucket->getSecond()) ValueT(std::forward<Ts>(Args)...);
462 return {TheBucket, true};
463 }
464
465 template <typename KeyArgT, typename... Ts>
466 std::pair<iterator, bool> try_emplace_impl(KeyArgT &&Key, Ts &&...Args) {
467 auto [Bucket, Inserted] = lookupOrInsertIntoBucket(
468 std::forward<KeyArgT>(Key), std::forward<Ts>(Args)...);
469 return {makeIterator(Bucket), Inserted};
470 }
471
472 iterator makeIterator(BucketT *TheBucket) {
473 return iterator::makeIterator(TheBucket, buckets(), *this);
474 }
475
476 const_iterator makeConstIterator(const BucketT *TheBucket) const {
477 return const_iterator::makeIterator(TheBucket, buckets(), *this);
478 }
479
480 unsigned getNumEntries() const {
481 return static_cast<const DerivedT *>(this)->getNumEntries();
482 }
483
484 void setNumEntries(unsigned Num) {
485 static_cast<DerivedT *>(this)->setNumEntries(Num);
486 }
487
488 void incrementNumEntries() { setNumEntries(getNumEntries() + 1); }
489
490 void decrementNumEntries() { setNumEntries(getNumEntries() - 1); }
491
492 unsigned getNumTombstones() const {
493 return static_cast<const DerivedT *>(this)->getNumTombstones();
494 }
495
496 void setNumTombstones(unsigned Num) {
497 static_cast<DerivedT *>(this)->setNumTombstones(Num);
498 }
499
500 void incrementNumTombstones() { setNumTombstones(getNumTombstones() + 1); }
501
502 void decrementNumTombstones() { setNumTombstones(getNumTombstones() - 1); }
503
504 const BucketT *getBuckets() const {
505 return static_cast<const DerivedT *>(this)->getBuckets();
506 }
507
508 BucketT *getBuckets() { return static_cast<DerivedT *>(this)->getBuckets(); }
509
510 unsigned getNumBuckets() const {
511 return static_cast<const DerivedT *>(this)->getNumBuckets();
512 }
513
514 BucketT *getBucketsEnd() { return getBuckets() + getNumBuckets(); }
515
516 const BucketT *getBucketsEnd() const {
517 return getBuckets() + getNumBuckets();
518 }
519
520 iterator_range<BucketT *> buckets() {
521 return llvm::make_range(getBuckets(), getBucketsEnd());
522 }
523
524 iterator_range<const BucketT *> buckets() const {
525 return llvm::make_range(getBuckets(), getBucketsEnd());
526 }
527
528 void grow(unsigned AtLeast) { static_cast<DerivedT *>(this)->grow(AtLeast); }
529
530 void shrink_and_clear() { static_cast<DerivedT *>(this)->shrink_and_clear(); }
531
532 template <typename LookupKeyT>
533 BucketT *findBucketForInsertion(const LookupKeyT &Lookup,
534 BucketT *TheBucket) {
536
537 // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
538 // the buckets are empty (meaning that many are filled with tombstones),
539 // grow the table.
540 //
541 // The later case is tricky. For example, if we had one empty bucket with
542 // tons of tombstones, failing lookups (e.g. for insertion) would have to
543 // probe almost the entire table until it found the empty bucket. If the
544 // table completely filled with tombstones, no lookup would ever succeed,
545 // causing infinite loops in lookup.
546 unsigned NewNumEntries = getNumEntries() + 1;
547 unsigned NumBuckets = getNumBuckets();
548 if (LLVM_UNLIKELY(NewNumEntries * 4 >= NumBuckets * 3)) {
549 this->grow(NumBuckets * 2);
550 LookupBucketFor(Lookup, TheBucket);
551 } else if (LLVM_UNLIKELY(NumBuckets -
552 (NewNumEntries + getNumTombstones()) <=
553 NumBuckets / 8)) {
554 this->grow(NumBuckets);
555 LookupBucketFor(Lookup, TheBucket);
556 }
557 assert(TheBucket);
558
559 // Only update the state after we've grown our bucket space appropriately
560 // so that when growing buckets we have self-consistent entry count.
561 incrementNumEntries();
562
563 // If we are writing over a tombstone, remember this.
564 const KeyT EmptyKey = getEmptyKey();
565 if (!KeyInfoT::isEqual(TheBucket->getFirst(), EmptyKey))
566 decrementNumTombstones();
567
568 return TheBucket;
569 }
570
571 template <typename LookupKeyT>
572 const BucketT *doFind(const LookupKeyT &Val) const {
573 const BucketT *BucketsPtr = getBuckets();
574 const unsigned NumBuckets = getNumBuckets();
575 if (NumBuckets == 0)
576 return nullptr;
577
578 const KeyT EmptyKey = getEmptyKey();
579 unsigned BucketNo = getHashValue(Val) & (NumBuckets - 1);
580 unsigned ProbeAmt = 1;
581 while (true) {
582 const BucketT *Bucket = BucketsPtr + BucketNo;
583 if (LLVM_LIKELY(KeyInfoT::isEqual(Val, Bucket->getFirst())))
584 return Bucket;
585 if (LLVM_LIKELY(KeyInfoT::isEqual(Bucket->getFirst(), EmptyKey)))
586 return nullptr;
587
588 // Otherwise, it's a hash collision or a tombstone, continue quadratic
589 // probing.
590 BucketNo += ProbeAmt++;
591 BucketNo &= NumBuckets - 1;
592 }
593 }
594
595 template <typename LookupKeyT> BucketT *doFind(const LookupKeyT &Val) {
596 return const_cast<BucketT *>(
597 static_cast<const DenseMapBase *>(this)->doFind(Val));
598 }
599
600 /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
601 /// FoundBucket. If the bucket contains the key and a value, this returns
602 /// true, otherwise it returns a bucket with an empty marker or tombstone and
603 /// returns false.
604 template <typename LookupKeyT>
605 bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) {
606 BucketT *BucketsPtr = getBuckets();
607 const unsigned NumBuckets = getNumBuckets();
608
609 if (NumBuckets == 0) {
610 FoundBucket = nullptr;
611 return false;
612 }
613
614 // FoundTombstone - Keep track of whether we find a tombstone while probing.
615 BucketT *FoundTombstone = nullptr;
616 const KeyT EmptyKey = getEmptyKey();
617 const KeyT TombstoneKey = getTombstoneKey();
618 assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
619 !KeyInfoT::isEqual(Val, TombstoneKey) &&
620 "Empty/Tombstone value shouldn't be inserted into map!");
621
622 unsigned BucketNo = getHashValue(Val) & (NumBuckets - 1);
623 unsigned ProbeAmt = 1;
624 while (true) {
625 BucketT *ThisBucket = BucketsPtr + BucketNo;
626 // Found Val's bucket? If so, return it.
627 if (LLVM_LIKELY(KeyInfoT::isEqual(Val, ThisBucket->getFirst()))) {
628 FoundBucket = ThisBucket;
629 return true;
630 }
631
632 // If we found an empty bucket, the key doesn't exist in the set.
633 // Insert it and return the default value.
634 if (LLVM_LIKELY(KeyInfoT::isEqual(ThisBucket->getFirst(), EmptyKey))) {
635 // If we've already seen a tombstone while probing, fill it in instead
636 // of the empty bucket we eventually probed to.
637 FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
638 return false;
639 }
640
641 // If this is a tombstone, remember it. If Val ends up not in the map, we
642 // prefer to return it than something that would require more probing.
643 if (KeyInfoT::isEqual(ThisBucket->getFirst(), TombstoneKey) &&
644 !FoundTombstone)
645 FoundTombstone = ThisBucket; // Remember the first tombstone found.
646
647 // Otherwise, it's a hash collision or a tombstone, continue quadratic
648 // probing.
649 BucketNo += ProbeAmt++;
650 BucketNo &= (NumBuckets - 1);
651 }
652 }
653
654public:
655 /// Return the approximate size (in bytes) of the actual map.
656 /// This is just the raw memory used by DenseMap.
657 /// If entries are pointers to objects, the size of the referenced objects
658 /// are not included.
659 size_t getMemorySize() const { return getNumBuckets() * sizeof(BucketT); }
660};
661
662/// Equality comparison for DenseMap.
663///
664/// Iterates over elements of LHS confirming that each (key, value) pair in LHS
665/// is also in RHS, and that no additional pairs are in RHS.
666/// Equivalent to N calls to RHS.find and N value comparisons. Amortized
667/// complexity is linear, worst case is O(N^2) (if every hash collides).
668template <typename DerivedT, typename KeyT, typename ValueT, typename KeyInfoT,
669 typename BucketT>
673 if (LHS.size() != RHS.size())
674 return false;
675
676 for (auto &KV : LHS) {
677 auto I = RHS.find(KV.first);
678 if (I == RHS.end() || I->second != KV.second)
679 return false;
680 }
681
682 return true;
683}
684
685/// Inequality comparison for DenseMap.
686///
687/// Equivalent to !(LHS == RHS). See operator== for performance notes.
688template <typename DerivedT, typename KeyT, typename ValueT, typename KeyInfoT,
689 typename BucketT>
695
696template <typename KeyT, typename ValueT,
697 typename KeyInfoT = DenseMapInfo<KeyT>,
699class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
700 KeyT, ValueT, KeyInfoT, BucketT> {
701 friend class DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
702
703 // Lift some types from the dependent base class into this class for
704 // simplicity of referring to them.
706
707 BucketT *Buckets;
708 unsigned NumEntries;
709 unsigned NumTombstones;
710 unsigned NumBuckets;
711
712public:
713 /// Create a DenseMap with an optional \p NumElementsToReserve to guarantee
714 /// that this number of elements can be inserted in the map without grow().
715 explicit DenseMap(unsigned NumElementsToReserve = 0) {
716 init(NumElementsToReserve);
717 }
718
719 DenseMap(const DenseMap &other) : BaseT() {
720 init(0);
721 copyFrom(other);
722 }
723
724 DenseMap(DenseMap &&other) : BaseT() {
725 init(0);
726 swap(other);
727 }
728
729 template <typename InputIt> DenseMap(const InputIt &I, const InputIt &E) {
730 init(std::distance(I, E));
731 this->insert(I, E);
732 }
733
734 template <typename RangeT>
737
738 DenseMap(std::initializer_list<typename BaseT::value_type> Vals)
739 : DenseMap(Vals.begin(), Vals.end()) {}
740
742 this->destroyAll();
743 deallocateBuckets();
744 }
745
747 this->incrementEpoch();
748 RHS.incrementEpoch();
749 std::swap(Buckets, RHS.Buckets);
750 std::swap(NumEntries, RHS.NumEntries);
751 std::swap(NumTombstones, RHS.NumTombstones);
752 std::swap(NumBuckets, RHS.NumBuckets);
753 }
754
755 DenseMap &operator=(const DenseMap &other) {
756 if (&other != this)
757 copyFrom(other);
758 return *this;
759 }
760
762 this->destroyAll();
763 deallocateBuckets();
764 init(0);
765 swap(other);
766 return *this;
767 }
768
769 void copyFrom(const DenseMap &other) {
770 this->destroyAll();
771 deallocateBuckets();
772 if (allocateBuckets(other.NumBuckets)) {
773 this->BaseT::copyFrom(other);
774 } else {
775 NumEntries = 0;
776 NumTombstones = 0;
777 }
778 }
779
780 void grow(unsigned AtLeast) {
781 unsigned OldNumBuckets = NumBuckets;
782 BucketT *OldBuckets = Buckets;
783
784 allocateBuckets(std::max<unsigned>(
785 64, static_cast<unsigned>(NextPowerOf2(AtLeast - 1))));
786 assert(Buckets);
787 if (!OldBuckets) {
788 this->BaseT::initEmpty();
789 return;
790 }
791
792 this->moveFromOldBuckets(
793 llvm::make_range(OldBuckets, OldBuckets + OldNumBuckets));
794
795 // Free the old table.
796 deallocate_buffer(OldBuckets, sizeof(BucketT) * OldNumBuckets,
797 alignof(BucketT));
798 }
799
801 unsigned OldNumBuckets = NumBuckets;
802 unsigned OldNumEntries = NumEntries;
803 this->destroyAll();
804
805 // Reduce the number of buckets.
806 unsigned NewNumBuckets = 0;
807 if (OldNumEntries)
808 NewNumBuckets = std::max(64, 1 << (Log2_32_Ceil(OldNumEntries) + 1));
809 if (NewNumBuckets == NumBuckets) {
810 this->BaseT::initEmpty();
811 return;
812 }
813
814 deallocate_buffer(Buckets, sizeof(BucketT) * OldNumBuckets,
815 alignof(BucketT));
816 init(NewNumBuckets);
817 }
818
819private:
820 unsigned getNumEntries() const { return NumEntries; }
821
822 void setNumEntries(unsigned Num) { NumEntries = Num; }
823
824 unsigned getNumTombstones() const { return NumTombstones; }
825
826 void setNumTombstones(unsigned Num) { NumTombstones = Num; }
827
828 BucketT *getBuckets() const { return Buckets; }
829
830 unsigned getNumBuckets() const { return NumBuckets; }
831
832 void deallocateBuckets() {
833 deallocate_buffer(Buckets, sizeof(BucketT) * NumBuckets, alignof(BucketT));
834 }
835
836 bool allocateBuckets(unsigned Num) {
837 NumBuckets = Num;
838 if (NumBuckets == 0) {
839 Buckets = nullptr;
840 return false;
841 }
842
843 Buckets = static_cast<BucketT *>(
844 allocate_buffer(sizeof(BucketT) * NumBuckets, alignof(BucketT)));
845 return true;
846 }
847
848 void init(unsigned InitNumEntries) {
849 auto InitBuckets = BaseT::getMinBucketToReserveForEntries(InitNumEntries);
850 if (allocateBuckets(InitBuckets)) {
851 this->BaseT::initEmpty();
852 } else {
853 NumEntries = 0;
854 NumTombstones = 0;
855 }
856 }
857};
858
859template <typename KeyT, typename ValueT, unsigned InlineBuckets = 4,
860 typename KeyInfoT = DenseMapInfo<KeyT>,
863 : public DenseMapBase<
864 SmallDenseMap<KeyT, ValueT, InlineBuckets, KeyInfoT, BucketT>, KeyT,
865 ValueT, KeyInfoT, BucketT> {
866 friend class DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
867
868 // Lift some types from the dependent base class into this class for
869 // simplicity of referring to them.
871
872 static_assert(isPowerOf2_64(InlineBuckets),
873 "InlineBuckets must be a power of 2.");
874
875 unsigned Small : 1;
876 unsigned NumEntries : 31;
877 unsigned NumTombstones;
878
879 struct LargeRep {
880 BucketT *Buckets;
881 unsigned NumBuckets;
883 return llvm::make_range(Buckets, Buckets + NumBuckets);
884 }
885 };
886
887 /// A "union" of an inline bucket array and the struct representing
888 /// a large bucket. This union will be discriminated by the 'Small' bit.
889 AlignedCharArrayUnion<BucketT[InlineBuckets], LargeRep> storage;
890
891public:
892 explicit SmallDenseMap(unsigned NumElementsToReserve = 0) {
893 init(NumElementsToReserve);
894 }
895
896 SmallDenseMap(const SmallDenseMap &other) : BaseT() {
897 init(0);
898 copyFrom(other);
899 }
900
901 SmallDenseMap(SmallDenseMap &&other) : BaseT() {
902 init(0);
903 swap(other);
904 }
905
906 template <typename InputIt>
907 SmallDenseMap(const InputIt &I, const InputIt &E) {
908 init(std::distance(I, E));
909 this->insert(I, E);
910 }
911
912 template <typename RangeT>
915
916 SmallDenseMap(std::initializer_list<typename BaseT::value_type> Vals)
917 : SmallDenseMap(Vals.begin(), Vals.end()) {}
918
920 this->destroyAll();
921 deallocateBuckets();
922 }
923
925 unsigned TmpNumEntries = RHS.NumEntries;
926 RHS.NumEntries = NumEntries;
927 NumEntries = TmpNumEntries;
928 std::swap(NumTombstones, RHS.NumTombstones);
929
930 const KeyT EmptyKey = this->getEmptyKey();
931 const KeyT TombstoneKey = this->getTombstoneKey();
932 if (Small && RHS.Small) {
933 // If we're swapping inline bucket arrays, we have to cope with some of
934 // the tricky bits of DenseMap's storage system: the buckets are not
935 // fully initialized. Thus we swap every key, but we may have
936 // a one-directional move of the value.
937 for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
938 BucketT *LHSB = &getInlineBuckets()[i],
939 *RHSB = &RHS.getInlineBuckets()[i];
940 bool hasLHSValue = (!KeyInfoT::isEqual(LHSB->getFirst(), EmptyKey) &&
941 !KeyInfoT::isEqual(LHSB->getFirst(), TombstoneKey));
942 bool hasRHSValue = (!KeyInfoT::isEqual(RHSB->getFirst(), EmptyKey) &&
943 !KeyInfoT::isEqual(RHSB->getFirst(), TombstoneKey));
944 if (hasLHSValue && hasRHSValue) {
945 // Swap together if we can...
946 std::swap(*LHSB, *RHSB);
947 continue;
948 }
949 // Swap separately and handle any asymmetry.
950 std::swap(LHSB->getFirst(), RHSB->getFirst());
951 if (hasLHSValue) {
952 ::new (&RHSB->getSecond()) ValueT(std::move(LHSB->getSecond()));
953 LHSB->getSecond().~ValueT();
954 } else if (hasRHSValue) {
955 ::new (&LHSB->getSecond()) ValueT(std::move(RHSB->getSecond()));
956 RHSB->getSecond().~ValueT();
957 }
958 }
959 return;
960 }
961 if (!Small && !RHS.Small) {
962 std::swap(*getLargeRep(), *RHS.getLargeRep());
963 return;
964 }
965
966 SmallDenseMap &SmallSide = Small ? *this : RHS;
967 SmallDenseMap &LargeSide = Small ? RHS : *this;
968
969 // First stash the large side's rep and move the small side across.
970 LargeRep TmpRep = std::move(*LargeSide.getLargeRep());
971 LargeSide.getLargeRep()->~LargeRep();
972 LargeSide.Small = true;
973 // This is similar to the standard move-from-old-buckets, but the bucket
974 // count hasn't actually rotated in this case. So we have to carefully
975 // move construct the keys and values into their new locations, but there
976 // is no need to re-hash things.
977 for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
978 BucketT *NewB = &LargeSide.getInlineBuckets()[i],
979 *OldB = &SmallSide.getInlineBuckets()[i];
980 ::new (&NewB->getFirst()) KeyT(std::move(OldB->getFirst()));
981 OldB->getFirst().~KeyT();
982 if (!KeyInfoT::isEqual(NewB->getFirst(), EmptyKey) &&
983 !KeyInfoT::isEqual(NewB->getFirst(), TombstoneKey)) {
984 ::new (&NewB->getSecond()) ValueT(std::move(OldB->getSecond()));
985 OldB->getSecond().~ValueT();
986 }
987 }
988
989 // The hard part of moving the small buckets across is done, just move
990 // the TmpRep into its new home.
991 SmallSide.Small = false;
992 new (SmallSide.getLargeRep()) LargeRep(std::move(TmpRep));
993 }
994
996 if (&other != this)
997 copyFrom(other);
998 return *this;
999 }
1000
1002 this->destroyAll();
1003 deallocateBuckets();
1004 init(0);
1005 swap(other);
1006 return *this;
1007 }
1008
1009 void copyFrom(const SmallDenseMap &other) {
1010 this->destroyAll();
1011 deallocateBuckets();
1012 Small = true;
1013 if (other.getNumBuckets() > InlineBuckets) {
1014 Small = false;
1015 new (getLargeRep()) LargeRep(allocateBuckets(other.getNumBuckets()));
1016 }
1017 this->BaseT::copyFrom(other);
1018 }
1019
1020 void init(unsigned InitNumEntries) {
1021 auto InitBuckets = BaseT::getMinBucketToReserveForEntries(InitNumEntries);
1022 Small = true;
1023 if (InitBuckets > InlineBuckets) {
1024 Small = false;
1025 new (getLargeRep()) LargeRep(allocateBuckets(InitBuckets));
1026 }
1027 this->BaseT::initEmpty();
1028 }
1029
1030 void grow(unsigned AtLeast) {
1031 if (AtLeast > InlineBuckets)
1032 AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast - 1));
1033
1034 if (Small) {
1035 // First move the inline buckets into a temporary storage.
1037 BucketT *TmpBegin = reinterpret_cast<BucketT *>(&TmpStorage);
1038 BucketT *TmpEnd = TmpBegin;
1039
1040 // Loop over the buckets, moving non-empty, non-tombstones into the
1041 // temporary storage. Have the loop move the TmpEnd forward as it goes.
1042 const KeyT EmptyKey = this->getEmptyKey();
1043 const KeyT TombstoneKey = this->getTombstoneKey();
1044 for (BucketT &B : inlineBuckets()) {
1045 if (!KeyInfoT::isEqual(B.getFirst(), EmptyKey) &&
1046 !KeyInfoT::isEqual(B.getFirst(), TombstoneKey)) {
1047 assert(size_t(TmpEnd - TmpBegin) < InlineBuckets &&
1048 "Too many inline buckets!");
1049 ::new (&TmpEnd->getFirst()) KeyT(std::move(B.getFirst()));
1050 ::new (&TmpEnd->getSecond()) ValueT(std::move(B.getSecond()));
1051 ++TmpEnd;
1052 B.getSecond().~ValueT();
1053 }
1054 B.getFirst().~KeyT();
1055 }
1056
1057 // AtLeast == InlineBuckets can happen if there are many tombstones,
1058 // and grow() is used to remove them. Usually we always switch to the
1059 // large rep here.
1060 if (AtLeast > InlineBuckets) {
1061 Small = false;
1062 new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
1063 }
1064 this->moveFromOldBuckets(llvm::make_range(TmpBegin, TmpEnd));
1065 return;
1066 }
1067
1068 LargeRep OldRep = std::move(*getLargeRep());
1069 getLargeRep()->~LargeRep();
1070 if (AtLeast <= InlineBuckets) {
1071 Small = true;
1072 } else {
1073 new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
1074 }
1075
1076 this->moveFromOldBuckets(OldRep.buckets());
1077
1078 // Free the old table.
1079 deallocate_buffer(OldRep.Buckets, sizeof(BucketT) * OldRep.NumBuckets,
1080 alignof(BucketT));
1081 }
1082
1084 unsigned OldSize = this->size();
1085 this->destroyAll();
1086
1087 // Reduce the number of buckets.
1088 unsigned NewNumBuckets = 0;
1089 if (OldSize) {
1090 NewNumBuckets = 1 << (Log2_32_Ceil(OldSize) + 1);
1091 if (NewNumBuckets > InlineBuckets && NewNumBuckets < 64u)
1092 NewNumBuckets = 64;
1093 }
1094 if ((Small && NewNumBuckets <= InlineBuckets) ||
1095 (!Small && NewNumBuckets == getLargeRep()->NumBuckets)) {
1096 this->BaseT::initEmpty();
1097 return;
1098 }
1099
1100 deallocateBuckets();
1101 init(NewNumBuckets);
1102 }
1103
1104private:
1105 unsigned getNumEntries() const { return NumEntries; }
1106
1107 void setNumEntries(unsigned Num) {
1108 // NumEntries is hardcoded to be 31 bits wide.
1109 assert(Num < (1U << 31) && "Cannot support more than 1<<31 entries");
1110 NumEntries = Num;
1111 }
1112
1113 unsigned getNumTombstones() const { return NumTombstones; }
1114
1115 void setNumTombstones(unsigned Num) { NumTombstones = Num; }
1116
1117 const BucketT *getInlineBuckets() const {
1118 assert(Small);
1119 // Note that this cast does not violate aliasing rules as we assert that
1120 // the memory's dynamic type is the small, inline bucket buffer, and the
1121 // 'storage' is a POD containing a char buffer.
1122 return reinterpret_cast<const BucketT *>(&storage);
1123 }
1124
1125 BucketT *getInlineBuckets() {
1126 return const_cast<BucketT *>(
1127 const_cast<const SmallDenseMap *>(this)->getInlineBuckets());
1128 }
1129
1130 const LargeRep *getLargeRep() const {
1131 assert(!Small);
1132 // Note, same rule about aliasing as with getInlineBuckets.
1133 return reinterpret_cast<const LargeRep *>(&storage);
1134 }
1135
1136 LargeRep *getLargeRep() {
1137 return const_cast<LargeRep *>(
1138 const_cast<const SmallDenseMap *>(this)->getLargeRep());
1139 }
1140
1141 const BucketT *getBuckets() const {
1142 return Small ? getInlineBuckets() : getLargeRep()->Buckets;
1143 }
1144
1145 BucketT *getBuckets() {
1146 return const_cast<BucketT *>(
1147 const_cast<const SmallDenseMap *>(this)->getBuckets());
1148 }
1149
1150 unsigned getNumBuckets() const {
1151 return Small ? InlineBuckets : getLargeRep()->NumBuckets;
1152 }
1153
1154 iterator_range<BucketT *> inlineBuckets() {
1155 BucketT *Begin = getInlineBuckets();
1156 return llvm::make_range(Begin, Begin + InlineBuckets);
1157 }
1158
1159 void deallocateBuckets() {
1160 if (Small)
1161 return;
1162
1163 deallocate_buffer(getLargeRep()->Buckets,
1164 sizeof(BucketT) * getLargeRep()->NumBuckets,
1165 alignof(BucketT));
1166 getLargeRep()->~LargeRep();
1167 }
1168
1169 LargeRep allocateBuckets(unsigned Num) {
1170 assert(Num > InlineBuckets && "Must allocate more buckets than are inline");
1171 LargeRep Rep = {static_cast<BucketT *>(allocate_buffer(
1172 sizeof(BucketT) * Num, alignof(BucketT))),
1173 Num};
1174 return Rep;
1175 }
1176};
1177
1178template <typename KeyT, typename ValueT, typename KeyInfoT, typename Bucket,
1179 bool IsConst>
1180class DenseMapIterator : DebugEpochBase::HandleBase {
1181 friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>;
1182 friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, false>;
1183
1184public:
1186 using value_type = std::conditional_t<IsConst, const Bucket, Bucket>;
1189 using iterator_category = std::forward_iterator_tag;
1190
1191private:
1192 using BucketItTy =
1193 std::conditional_t<shouldReverseIterate<KeyT>(),
1194 std::reverse_iterator<pointer>, pointer>;
1195
1196 BucketItTy Ptr = {};
1197 BucketItTy End = {};
1198
1199 DenseMapIterator(BucketItTy Pos, BucketItTy E, const DebugEpochBase &Epoch)
1200 : DebugEpochBase::HandleBase(&Epoch), Ptr(Pos), End(E) {
1201 assert(isHandleInSync() && "invalid construction!");
1202 }
1203
1204public:
1205 DenseMapIterator() = default;
1206
1207 static DenseMapIterator makeBegin(iterator_range<pointer> Buckets,
1208 bool IsEmpty, const DebugEpochBase &Epoch) {
1209 // When the map is empty, avoid the overhead of advancing/retreating past
1210 // empty buckets.
1211 if (IsEmpty)
1212 return makeEnd(Buckets, Epoch);
1213 auto R = maybeReverse(Buckets);
1214 DenseMapIterator Iter(R.begin(), R.end(), Epoch);
1215 Iter.AdvancePastEmptyBuckets();
1216 return Iter;
1217 }
1218
1219 static DenseMapIterator makeEnd(iterator_range<pointer> Buckets,
1220 const DebugEpochBase &Epoch) {
1221 auto R = maybeReverse(Buckets);
1222 return DenseMapIterator(R.end(), R.end(), Epoch);
1223 }
1224
1225 static DenseMapIterator makeIterator(pointer P,
1227 const DebugEpochBase &Epoch) {
1228 auto R = maybeReverse(Buckets);
1229 constexpr int Offset = shouldReverseIterate<KeyT>() ? 1 : 0;
1230 return DenseMapIterator(BucketItTy(P + Offset), R.end(), Epoch);
1231 }
1232
1233 // Converting ctor from non-const iterators to const iterators. SFINAE'd out
1234 // for const iterator destinations so it doesn't end up as a user defined copy
1235 // constructor.
1236 template <bool IsConstSrc,
1237 typename = std::enable_if_t<!IsConstSrc && IsConst>>
1239 const DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, IsConstSrc> &I)
1240 : DebugEpochBase::HandleBase(I), Ptr(I.Ptr), End(I.End) {}
1241
1243 assert(isHandleInSync() && "invalid iterator access!");
1244 assert(Ptr != End && "dereferencing end() iterator");
1245 return *Ptr;
1246 }
1247 pointer operator->() const { return &operator*(); }
1248
1249 friend bool operator==(const DenseMapIterator &LHS,
1250 const DenseMapIterator &RHS) {
1251 assert((!LHS.getEpochAddress() || LHS.isHandleInSync()) &&
1252 "handle not in sync!");
1253 assert((!RHS.getEpochAddress() || RHS.isHandleInSync()) &&
1254 "handle not in sync!");
1255 assert(LHS.getEpochAddress() == RHS.getEpochAddress() &&
1256 "comparing incomparable iterators!");
1257 return LHS.Ptr == RHS.Ptr;
1258 }
1259
1260 friend bool operator!=(const DenseMapIterator &LHS,
1261 const DenseMapIterator &RHS) {
1262 return !(LHS == RHS);
1263 }
1264
1265 inline DenseMapIterator &operator++() { // Preincrement
1266 assert(isHandleInSync() && "invalid iterator access!");
1267 assert(Ptr != End && "incrementing end() iterator");
1268 ++Ptr;
1269 AdvancePastEmptyBuckets();
1270 return *this;
1271 }
1272 DenseMapIterator operator++(int) { // Postincrement
1273 assert(isHandleInSync() && "invalid iterator access!");
1274 DenseMapIterator tmp = *this;
1275 ++*this;
1276 return tmp;
1277 }
1278
1279private:
1280 void AdvancePastEmptyBuckets() {
1281 assert(Ptr <= End);
1282 const KeyT Empty = KeyInfoT::getEmptyKey();
1283 const KeyT Tombstone = KeyInfoT::getTombstoneKey();
1284
1285 while (Ptr != End && (KeyInfoT::isEqual(Ptr->getFirst(), Empty) ||
1286 KeyInfoT::isEqual(Ptr->getFirst(), Tombstone)))
1287 ++Ptr;
1288 }
1289
1290 static auto maybeReverse(iterator_range<pointer> Range) {
1291 if constexpr (shouldReverseIterate<KeyT>())
1292 return reverse(Range);
1293 else
1294 return Range;
1295 }
1296};
1297
1298template <typename KeyT, typename ValueT, typename KeyInfoT>
1300 return X.getMemorySize();
1301}
1302
1303} // end namespace llvm
1304
1305#endif // LLVM_ADT_DENSEMAP_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_UNLIKELY(EXPR)
Definition Compiler.h:336
#define LLVM_LIKELY(EXPR)
Definition Compiler.h:335
This file defines DenseMapInfo traits for DenseMap.
This file defines the DebugEpochBase and DebugEpochBase::HandleBase classes.
#define I(x, y, z)
Definition MD5.cpp:58
This file defines counterparts of C library allocation functions defined in the namespace 'std'.
ConstantRange Range(APInt(BitWidth, Low), APInt(BitWidth, High))
#define P(N)
This file contains some templates that are useful if you are working with the STL at all.
This file contains library features backported from future STL versions.
static TableGen::Emitter::OptClass< SkeletonEmitter > X("gen-skeleton-class", "Generate example skeleton class")
LocallyHashedType DenseMapInfo< LocallyHashedType >::Empty
LocallyHashedType DenseMapInfo< LocallyHashedType >::Tombstone
static int Lookup(ArrayRef< TableEntry > Table, unsigned Opcode)
Value * RHS
Value * LHS
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
Definition DenseMap.h:187
iterator find(const_arg_type_t< KeyT > Val)
Definition DenseMap.h:165
static unsigned getHashValue(const KeyT &Val)
Definition DenseMap.h:433
unsigned size_type
Definition DenseMap.h:69
static const KeyT getEmptyKey()
Definition DenseMap.h:442
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:229
std::pair< iterator, bool > insert(std::pair< KeyT, ValueT > &&KV)
Definition DenseMap.h:221
bool erase(const KeyT &Val)
Definition DenseMap.h:303
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT > iterator
Definition DenseMap.h:74
std::pair< iterator, bool > insert_as(std::pair< KeyT, ValueT > &&KV, const LookupKeyT &Val)
Alternate version of insert() which allows a different, and possibly less expensive,...
Definition DenseMap.h:247
DenseMapBase()=default
const_iterator find_as(const LookupKeyT &Val) const
Definition DenseMap.h:179
const_iterator end() const
Definition DenseMap.h:85
void moveFromOldBuckets(iterator_range< BucketT * > OldBuckets)
Definition DenseMap.h:380
iterator find_as(const LookupKeyT &Val)
Alternate version of find() which allows a different, and possibly less expensive,...
Definition DenseMap.h:173
unsigned size() const
Definition DenseMap.h:108
const_iterator find(const_arg_type_t< KeyT > Val) const
Definition DenseMap.h:166
bool empty() const
Definition DenseMap.h:107
std::pair< iterator, bool > emplace_or_assign(const KeyT &Key, Ts &&...Args)
Definition DenseMap.h:288
void insert(InputIt I, InputIt E)
insert - Range insertion of pairs.
Definition DenseMap.h:261
iterator begin()
Definition DenseMap.h:78
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
Definition DenseMap.h:161
DenseMapIterator< KeyT, ValueT, KeyInfoT, BucketT, true > const_iterator
Definition DenseMap.h:75
iterator end()
Definition DenseMap.h:81
static const KeyT getTombstoneKey()
Definition DenseMap.h:448
const ValueT & at(const_arg_type_t< KeyT > Val) const
at - Return the entry for the specified key, or abort if no such entry exists.
Definition DenseMap.h:205
bool isPointerIntoBucketsArray(const void *Ptr) const
isPointerIntoBucketsArray - Return true if the specified pointer points somewhere into the DenseMap's...
Definition DenseMap.h:333
void copyFrom(const DenseMapBase< OtherBaseT, KeyT, ValueT, KeyInfoT, BucketT > &other)
Definition DenseMap.h:406
bool contains(const_arg_type_t< KeyT > Val) const
Return true if the specified key is in the map, false otherwise.
Definition DenseMap.h:156
std::pair< iterator, bool > try_emplace(const KeyT &Key, Ts &&...Args)
Definition DenseMap.h:237
const_iterator begin() const
Definition DenseMap.h:82
std::pair< iterator, bool > emplace_or_assign(KeyT &&Key, Ts &&...Args)
Definition DenseMap.h:296
void insert_range(Range &&R)
Inserts range of 'std::pair<KeyT, ValueT>' values into the map.
Definition DenseMap.h:267
const void * getPointerIntoBucketsArray() const
getPointerIntoBucketsArray() - Return an opaque pointer into the buckets array.
Definition DenseMap.h:340
std::pair< iterator, bool > insert_or_assign(KeyT &&Key, V &&Val)
Definition DenseMap.h:280
ValueT lookup_or(const_arg_type_t< KeyT > Val, U &&Default) const
Definition DenseMap.h:197
unsigned getMinBucketToReserveForEntries(unsigned NumEntries)
Returns the number of buckets to allocate to ensure that the DenseMap can accommodate NumEntries with...
Definition DenseMap.h:371
static unsigned getHashValue(const LookupKeyT &Val)
Definition DenseMap.h:438
ValueT & operator[](const KeyT &Key)
Definition DenseMap.h:322
BucketT value_type
Definition DenseMap.h:72
auto keys() const
Definition DenseMap.h:99
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
Definition DenseMap.h:214
void erase(iterator I)
Definition DenseMap.h:314
std::pair< iterator, bool > insert_or_assign(const KeyT &Key, V &&Val)
Definition DenseMap.h:272
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again.
Definition DenseMap.h:112
ValueT & operator[](KeyT &&Key)
Definition DenseMap.h:326
auto values() const
Definition DenseMap.h:103
size_t getMemorySize() const
Return the approximate size (in bytes) of the actual map.
Definition DenseMap.h:659
std::conditional_t< IsConst, const BucketT, BucketT > value_type
Definition DenseMap.h:1186
static DenseMapIterator makeIterator(pointer P, iterator_range< pointer > Buckets, const DebugEpochBase &Epoch)
Definition DenseMap.h:1225
friend bool operator!=(const DenseMapIterator &LHS, const DenseMapIterator &RHS)
Definition DenseMap.h:1260
DenseMapIterator & operator++()
Definition DenseMap.h:1265
pointer operator->() const
Definition DenseMap.h:1247
reference operator*() const
Definition DenseMap.h:1242
static DenseMapIterator makeBegin(iterator_range< pointer > Buckets, bool IsEmpty, const DebugEpochBase &Epoch)
Definition DenseMap.h:1207
DenseMapIterator operator++(int)
Definition DenseMap.h:1272
DenseMapIterator(const DenseMapIterator< KeyT, ValueT, KeyInfoT, Bucket, IsConstSrc > &I)
Definition DenseMap.h:1238
friend bool operator==(const DenseMapIterator &LHS, const DenseMapIterator &RHS)
Definition DenseMap.h:1249
static DenseMapIterator makeEnd(iterator_range< pointer > Buckets, const DebugEpochBase &Epoch)
Definition DenseMap.h:1219
DenseMap(std::initializer_list< typename BaseT::value_type > Vals)
Definition DenseMap.h:738
DenseMap(unsigned NumElementsToReserve=0)
Create a DenseMap with an optional NumElementsToReserve to guarantee that this number of elements can...
Definition DenseMap.h:715
void copyFrom(const DenseMap &other)
Definition DenseMap.h:769
void shrink_and_clear()
Definition DenseMap.h:800
DenseMap & operator=(DenseMap &&other)
Definition DenseMap.h:761
void grow(unsigned AtLeast)
Definition DenseMap.h:780
DenseMap(llvm::from_range_t, const RangeT &Range)
Definition DenseMap.h:735
DenseMap(const DenseMap &other)
Definition DenseMap.h:719
void swap(DenseMap &RHS)
Definition DenseMap.h:746
DenseMap(const InputIt &I, const InputIt &E)
Definition DenseMap.h:729
DenseMap(DenseMap &&other)
Definition DenseMap.h:724
DenseMap & operator=(const DenseMap &other)
Definition DenseMap.h:755
void grow(unsigned AtLeast)
Definition DenseMap.h:1030
SmallDenseMap(const InputIt &I, const InputIt &E)
Definition DenseMap.h:907
void swap(SmallDenseMap &RHS)
Definition DenseMap.h:924
SmallDenseMap & operator=(SmallDenseMap &&other)
Definition DenseMap.h:1001
SmallDenseMap & operator=(const SmallDenseMap &other)
Definition DenseMap.h:995
SmallDenseMap(unsigned NumElementsToReserve=0)
Definition DenseMap.h:892
void init(unsigned InitNumEntries)
Definition DenseMap.h:1020
SmallDenseMap(std::initializer_list< typename BaseT::value_type > Vals)
Definition DenseMap.h:916
SmallDenseMap(SmallDenseMap &&other)
Definition DenseMap.h:901
SmallDenseMap(const SmallDenseMap &other)
Definition DenseMap.h:896
void copyFrom(const SmallDenseMap &other)
Definition DenseMap.h:1009
SmallDenseMap(llvm::from_range_t, const RangeT &Range)
Definition DenseMap.h:913
A range adaptor for a pair of iterators.
constexpr char IsConst[]
Key for Kernel::Arg::Metadata::mIsConst.
These are wrappers over isa* function that allow them to be used in generic algorithms such as llvm:a...
Definition ADL.h:123
This is an optimization pass for GlobalISel generic memory operations.
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
Definition MathExtras.h:355
@ Offset
Definition DWP.cpp:477
constexpr auto adl_begin(RangeT &&range) -> decltype(adl_detail::begin_impl(std::forward< RangeT >(range)))
Returns the begin iterator to range using std::begin and function found through Argument-Dependent Lo...
Definition ADL.h:78
BitVector::size_type capacity_in_bytes(const BitVector &X)
Definition BitVector.h:828
bool operator!=(uint64_t V1, const APInt &V2)
Definition APInt.h:2113
iterator_range< T > make_range(T x, T y)
Convenience function for iterating over sub-ranges.
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
Definition MathExtras.h:293
constexpr auto adl_end(RangeT &&range) -> decltype(adl_detail::end_impl(std::forward< RangeT >(range)))
Returns the end iterator to range using std::end and functions found through Argument-Dependent Looku...
Definition ADL.h:86
bool operator==(const AddressRangeValuePair &LHS, const AddressRangeValuePair &RHS)
auto map_range(ContainerTy &&C, FuncTy F)
Definition STLExtras.h:359
LLVM_ABI LLVM_ATTRIBUTE_RETURNS_NONNULL LLVM_ATTRIBUTE_RETURNS_NOALIAS void * allocate_buffer(size_t Size, size_t Alignment)
Allocate a buffer of memory with the given size and alignment.
Definition MemAlloc.cpp:15
auto reverse(ContainerTy &&C)
Definition STLExtras.h:401
LLVM_ABI void deallocate_buffer(void *Ptr, size_t Size, size_t Alignment)
Deallocate a buffer of memory with the given size and alignment.
Definition MemAlloc.cpp:27
constexpr bool shouldReverseIterate()
LLVM_ATTRIBUTE_VISIBILITY_DEFAULT AnalysisKey InnerAnalysisManagerProxy< AnalysisManagerT, IRUnitT, ExtraArgTs... >::Key
iterator_range(Container &&) -> iterator_range< llvm::detail::IterOfRange< Container > >
@ Default
The result values are uniform if and only if all operands are uniform.
Definition Uniformity.h:20
constexpr uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
Definition MathExtras.h:384
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:851
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
Definition BitVector.h:853
A suitably aligned and sized character array member which can hold elements of any type.
Definition AlignOf.h:22
std::conditional_t< std::is_pointer_v< T >, typename add_const_past_pointer< T >::type, const T & > type
Definition type_traits.h:54
const ValueT & getSecond() const
Definition DenseMap.h:51
const KeyT & getFirst() const
Definition DenseMap.h:49