1 //===- llvm/ADT/DenseMap.h - Dense probed hash table ------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
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/DenseMapInfo.h"
18 #include "llvm/ADT/EpochTracker.h"
19 #include "llvm/Support/AlignOf.h"
20 #include "llvm/Support/Compiler.h"
21 #include "llvm/Support/MathExtras.h"
22 #include "llvm/Support/type_traits.h"
23 #include <algorithm>
24 #include <cassert>
25 #include <cstddef>
26 #include <cstring>
27 #include <iterator>
28 #include <limits>
29 #include <new>
30 #include <utility>
31
32 namespace llvm {
33
34 namespace detail {
35
36 // We extend a pair to allow users to override the bucket type with their own
37 // implementation without requiring two members.
38 template <typename KeyT, typename ValueT>
39 struct DenseMapPair : public std::pair<KeyT, ValueT> {
getFirstDenseMapPair40 KeyT &getFirst() { return std::pair<KeyT, ValueT>::first; }
getFirstDenseMapPair41 const KeyT &getFirst() const { return std::pair<KeyT, ValueT>::first; }
getSecondDenseMapPair42 ValueT &getSecond() { return std::pair<KeyT, ValueT>::second; }
getSecondDenseMapPair43 const ValueT &getSecond() const { return std::pair<KeyT, ValueT>::second; }
44 };
45
46 } // end namespace detail
47
48 template <
49 typename KeyT, typename ValueT, typename KeyInfoT = DenseMapInfo<KeyT>,
50 typename Bucket = detail::DenseMapPair<KeyT, ValueT>, bool IsConst = false>
51 class DenseMapIterator;
52
53 template <typename DerivedT, typename KeyT, typename ValueT, typename KeyInfoT,
54 typename BucketT>
55 class DenseMapBase : public DebugEpochBase {
56 public:
57 typedef unsigned size_type;
58 typedef KeyT key_type;
59 typedef ValueT mapped_type;
60 typedef BucketT value_type;
61
62 typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT> iterator;
63 typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, BucketT, true>
64 const_iterator;
begin()65 inline iterator begin() {
66 // When the map is empty, avoid the overhead of AdvancePastEmptyBuckets().
67 return empty() ? end() : iterator(getBuckets(), getBucketsEnd(), *this);
68 }
end()69 inline iterator end() {
70 return iterator(getBucketsEnd(), getBucketsEnd(), *this, true);
71 }
begin()72 inline const_iterator begin() const {
73 return empty() ? end()
74 : const_iterator(getBuckets(), getBucketsEnd(), *this);
75 }
end()76 inline const_iterator end() const {
77 return const_iterator(getBucketsEnd(), getBucketsEnd(), *this, true);
78 }
79
empty()80 LLVM_NODISCARD bool empty() const {
81 return getNumEntries() == 0;
82 }
size()83 unsigned size() const { return getNumEntries(); }
84
85 /// Grow the densemap so that it can contain at least \p NumEntries items
86 /// before resizing again.
reserve(size_type NumEntries)87 void reserve(size_type NumEntries) {
88 auto NumBuckets = getMinBucketToReserveForEntries(NumEntries);
89 incrementEpoch();
90 if (NumBuckets > getNumBuckets())
91 grow(NumBuckets);
92 }
93
clear()94 void clear() {
95 incrementEpoch();
96 if (getNumEntries() == 0 && getNumTombstones() == 0) return;
97
98 // If the capacity of the array is huge, and the # elements used is small,
99 // shrink the array.
100 if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) {
101 shrink_and_clear();
102 return;
103 }
104
105 const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
106 unsigned NumEntries = getNumEntries();
107 for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
108 if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey)) {
109 if (!KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) {
110 P->getSecond().~ValueT();
111 --NumEntries;
112 }
113 P->getFirst() = EmptyKey;
114 }
115 }
116 (void) NumEntries;
117 assert(NumEntries == 0 && "Node count imbalance!");
118 setNumEntries(0);
119 setNumTombstones(0);
120 }
121
122 /// Return 1 if the specified key is in the map, 0 otherwise.
count(const KeyT & Val)123 size_type count(const KeyT &Val) const {
124 const BucketT *TheBucket;
125 return LookupBucketFor(Val, TheBucket) ? 1 : 0;
126 }
127
find(const KeyT & Val)128 iterator find(const KeyT &Val) {
129 BucketT *TheBucket;
130 if (LookupBucketFor(Val, TheBucket))
131 return iterator(TheBucket, getBucketsEnd(), *this, true);
132 return end();
133 }
find(const KeyT & Val)134 const_iterator find(const KeyT &Val) const {
135 const BucketT *TheBucket;
136 if (LookupBucketFor(Val, TheBucket))
137 return const_iterator(TheBucket, getBucketsEnd(), *this, true);
138 return end();
139 }
140
141 /// Alternate version of find() which allows a different, and possibly
142 /// less expensive, key type.
143 /// The DenseMapInfo is responsible for supplying methods
144 /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key
145 /// type used.
146 template<class LookupKeyT>
find_as(const LookupKeyT & Val)147 iterator find_as(const LookupKeyT &Val) {
148 BucketT *TheBucket;
149 if (LookupBucketFor(Val, TheBucket))
150 return iterator(TheBucket, getBucketsEnd(), *this, true);
151 return end();
152 }
153 template<class LookupKeyT>
find_as(const LookupKeyT & Val)154 const_iterator find_as(const LookupKeyT &Val) const {
155 const BucketT *TheBucket;
156 if (LookupBucketFor(Val, TheBucket))
157 return const_iterator(TheBucket, getBucketsEnd(), *this, true);
158 return end();
159 }
160
161 /// lookup - Return the entry for the specified key, or a default
162 /// constructed value if no such entry exists.
lookup(const KeyT & Val)163 ValueT lookup(const KeyT &Val) const {
164 const BucketT *TheBucket;
165 if (LookupBucketFor(Val, TheBucket))
166 return TheBucket->getSecond();
167 return ValueT();
168 }
169
170 // Inserts key,value pair into the map if the key isn't already in the map.
171 // If the key is already in the map, it returns false and doesn't update the
172 // value.
insert(const std::pair<KeyT,ValueT> & KV)173 std::pair<iterator, bool> insert(const std::pair<KeyT, ValueT> &KV) {
174 return try_emplace(KV.first, KV.second);
175 }
176
177 // Inserts key,value pair into the map if the key isn't already in the map.
178 // If the key is already in the map, it returns false and doesn't update the
179 // value.
insert(std::pair<KeyT,ValueT> && KV)180 std::pair<iterator, bool> insert(std::pair<KeyT, ValueT> &&KV) {
181 return try_emplace(std::move(KV.first), std::move(KV.second));
182 }
183
184 // Inserts key,value pair into the map if the key isn't already in the map.
185 // The value is constructed in-place if the key is not in the map, otherwise
186 // it is not moved.
187 template <typename... Ts>
try_emplace(KeyT && Key,Ts &&...Args)188 std::pair<iterator, bool> try_emplace(KeyT &&Key, Ts &&... Args) {
189 BucketT *TheBucket;
190 if (LookupBucketFor(Key, TheBucket))
191 return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
192 false); // Already in map.
193
194 // Otherwise, insert the new element.
195 TheBucket =
196 InsertIntoBucket(TheBucket, std::move(Key), std::forward<Ts>(Args)...);
197 return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
198 true);
199 }
200
201 // Inserts key,value pair into the map if the key isn't already in the map.
202 // The value is constructed in-place if the key is not in the map, otherwise
203 // it is not moved.
204 template <typename... Ts>
try_emplace(const KeyT & Key,Ts &&...Args)205 std::pair<iterator, bool> try_emplace(const KeyT &Key, Ts &&... Args) {
206 BucketT *TheBucket;
207 if (LookupBucketFor(Key, TheBucket))
208 return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
209 false); // Already in map.
210
211 // Otherwise, insert the new element.
212 TheBucket = InsertIntoBucket(TheBucket, Key, std::forward<Ts>(Args)...);
213 return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
214 true);
215 }
216
217 /// Alternate version of insert() which allows a different, and possibly
218 /// less expensive, key type.
219 /// The DenseMapInfo is responsible for supplying methods
220 /// getHashValue(LookupKeyT) and isEqual(LookupKeyT, KeyT) for each key
221 /// type used.
222 template <typename LookupKeyT>
insert_as(std::pair<KeyT,ValueT> && KV,const LookupKeyT & Val)223 std::pair<iterator, bool> insert_as(std::pair<KeyT, ValueT> &&KV,
224 const LookupKeyT &Val) {
225 BucketT *TheBucket;
226 if (LookupBucketFor(Val, TheBucket))
227 return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
228 false); // Already in map.
229
230 // Otherwise, insert the new element.
231 TheBucket = InsertIntoBucketWithLookup(TheBucket, std::move(KV.first),
232 std::move(KV.second), Val);
233 return std::make_pair(iterator(TheBucket, getBucketsEnd(), *this, true),
234 true);
235 }
236
237 /// insert - Range insertion of pairs.
238 template<typename InputIt>
insert(InputIt I,InputIt E)239 void insert(InputIt I, InputIt E) {
240 for (; I != E; ++I)
241 insert(*I);
242 }
243
erase(const KeyT & Val)244 bool erase(const KeyT &Val) {
245 BucketT *TheBucket;
246 if (!LookupBucketFor(Val, TheBucket))
247 return false; // not in map.
248
249 TheBucket->getSecond().~ValueT();
250 TheBucket->getFirst() = getTombstoneKey();
251 decrementNumEntries();
252 incrementNumTombstones();
253 return true;
254 }
erase(iterator I)255 void erase(iterator I) {
256 BucketT *TheBucket = &*I;
257 TheBucket->getSecond().~ValueT();
258 TheBucket->getFirst() = getTombstoneKey();
259 decrementNumEntries();
260 incrementNumTombstones();
261 }
262
FindAndConstruct(const KeyT & Key)263 value_type& FindAndConstruct(const KeyT &Key) {
264 BucketT *TheBucket;
265 if (LookupBucketFor(Key, TheBucket))
266 return *TheBucket;
267
268 return *InsertIntoBucket(TheBucket, Key);
269 }
270
271 ValueT &operator[](const KeyT &Key) {
272 return FindAndConstruct(Key).second;
273 }
274
FindAndConstruct(KeyT && Key)275 value_type& FindAndConstruct(KeyT &&Key) {
276 BucketT *TheBucket;
277 if (LookupBucketFor(Key, TheBucket))
278 return *TheBucket;
279
280 return *InsertIntoBucket(TheBucket, std::move(Key));
281 }
282
283 ValueT &operator[](KeyT &&Key) {
284 return FindAndConstruct(std::move(Key)).second;
285 }
286
287 /// isPointerIntoBucketsArray - Return true if the specified pointer points
288 /// somewhere into the DenseMap's array of buckets (i.e. either to a key or
289 /// value in the DenseMap).
isPointerIntoBucketsArray(const void * Ptr)290 bool isPointerIntoBucketsArray(const void *Ptr) const {
291 return Ptr >= getBuckets() && Ptr < getBucketsEnd();
292 }
293
294 /// getPointerIntoBucketsArray() - Return an opaque pointer into the buckets
295 /// array. In conjunction with the previous method, this can be used to
296 /// determine whether an insertion caused the DenseMap to reallocate.
getPointerIntoBucketsArray()297 const void *getPointerIntoBucketsArray() const { return getBuckets(); }
298
299 protected:
300 DenseMapBase() = default;
301
destroyAll()302 void destroyAll() {
303 if (getNumBuckets() == 0) // Nothing to do.
304 return;
305
306 const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
307 for (BucketT *P = getBuckets(), *E = getBucketsEnd(); P != E; ++P) {
308 if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey) &&
309 !KeyInfoT::isEqual(P->getFirst(), TombstoneKey))
310 P->getSecond().~ValueT();
311 P->getFirst().~KeyT();
312 }
313 }
314
initEmpty()315 void initEmpty() {
316 setNumEntries(0);
317 setNumTombstones(0);
318
319 assert((getNumBuckets() & (getNumBuckets()-1)) == 0 &&
320 "# initial buckets must be a power of two!");
321 const KeyT EmptyKey = getEmptyKey();
322 for (BucketT *B = getBuckets(), *E = getBucketsEnd(); B != E; ++B)
323 ::new (&B->getFirst()) KeyT(EmptyKey);
324 }
325
326 /// Returns the number of buckets to allocate to ensure that the DenseMap can
327 /// accommodate \p NumEntries without need to grow().
getMinBucketToReserveForEntries(unsigned NumEntries)328 unsigned getMinBucketToReserveForEntries(unsigned NumEntries) {
329 // Ensure that "NumEntries * 4 < NumBuckets * 3"
330 if (NumEntries == 0)
331 return 0;
332 // +1 is required because of the strict equality.
333 // For example if NumEntries is 48, we need to return 401.
334 return NextPowerOf2(NumEntries * 4 / 3 + 1);
335 }
336
moveFromOldBuckets(BucketT * OldBucketsBegin,BucketT * OldBucketsEnd)337 void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd) {
338 initEmpty();
339
340 // Insert all the old elements.
341 const KeyT EmptyKey = getEmptyKey();
342 const KeyT TombstoneKey = getTombstoneKey();
343 for (BucketT *B = OldBucketsBegin, *E = OldBucketsEnd; B != E; ++B) {
344 if (!KeyInfoT::isEqual(B->getFirst(), EmptyKey) &&
345 !KeyInfoT::isEqual(B->getFirst(), TombstoneKey)) {
346 // Insert the key/value into the new table.
347 BucketT *DestBucket;
348 bool FoundVal = LookupBucketFor(B->getFirst(), DestBucket);
349 (void)FoundVal; // silence warning.
350 assert(!FoundVal && "Key already in new map?");
351 DestBucket->getFirst() = std::move(B->getFirst());
352 ::new (&DestBucket->getSecond()) ValueT(std::move(B->getSecond()));
353 incrementNumEntries();
354
355 // Free the value.
356 B->getSecond().~ValueT();
357 }
358 B->getFirst().~KeyT();
359 }
360 }
361
362 template <typename OtherBaseT>
copyFrom(const DenseMapBase<OtherBaseT,KeyT,ValueT,KeyInfoT,BucketT> & other)363 void copyFrom(
364 const DenseMapBase<OtherBaseT, KeyT, ValueT, KeyInfoT, BucketT> &other) {
365 assert(&other != this);
366 assert(getNumBuckets() == other.getNumBuckets());
367
368 setNumEntries(other.getNumEntries());
369 setNumTombstones(other.getNumTombstones());
370
371 if (isPodLike<KeyT>::value && isPodLike<ValueT>::value)
372 memcpy(getBuckets(), other.getBuckets(),
373 getNumBuckets() * sizeof(BucketT));
374 else
375 for (size_t i = 0; i < getNumBuckets(); ++i) {
376 ::new (&getBuckets()[i].getFirst())
377 KeyT(other.getBuckets()[i].getFirst());
378 if (!KeyInfoT::isEqual(getBuckets()[i].getFirst(), getEmptyKey()) &&
379 !KeyInfoT::isEqual(getBuckets()[i].getFirst(), getTombstoneKey()))
380 ::new (&getBuckets()[i].getSecond())
381 ValueT(other.getBuckets()[i].getSecond());
382 }
383 }
384
getHashValue(const KeyT & Val)385 static unsigned getHashValue(const KeyT &Val) {
386 return KeyInfoT::getHashValue(Val);
387 }
388 template<typename LookupKeyT>
getHashValue(const LookupKeyT & Val)389 static unsigned getHashValue(const LookupKeyT &Val) {
390 return KeyInfoT::getHashValue(Val);
391 }
getEmptyKey()392 static const KeyT getEmptyKey() {
393 return KeyInfoT::getEmptyKey();
394 }
getTombstoneKey()395 static const KeyT getTombstoneKey() {
396 return KeyInfoT::getTombstoneKey();
397 }
398
399 private:
getNumEntries()400 unsigned getNumEntries() const {
401 return static_cast<const DerivedT *>(this)->getNumEntries();
402 }
setNumEntries(unsigned Num)403 void setNumEntries(unsigned Num) {
404 static_cast<DerivedT *>(this)->setNumEntries(Num);
405 }
incrementNumEntries()406 void incrementNumEntries() {
407 setNumEntries(getNumEntries() + 1);
408 }
decrementNumEntries()409 void decrementNumEntries() {
410 setNumEntries(getNumEntries() - 1);
411 }
getNumTombstones()412 unsigned getNumTombstones() const {
413 return static_cast<const DerivedT *>(this)->getNumTombstones();
414 }
setNumTombstones(unsigned Num)415 void setNumTombstones(unsigned Num) {
416 static_cast<DerivedT *>(this)->setNumTombstones(Num);
417 }
incrementNumTombstones()418 void incrementNumTombstones() {
419 setNumTombstones(getNumTombstones() + 1);
420 }
decrementNumTombstones()421 void decrementNumTombstones() {
422 setNumTombstones(getNumTombstones() - 1);
423 }
getBuckets()424 const BucketT *getBuckets() const {
425 return static_cast<const DerivedT *>(this)->getBuckets();
426 }
getBuckets()427 BucketT *getBuckets() {
428 return static_cast<DerivedT *>(this)->getBuckets();
429 }
getNumBuckets()430 unsigned getNumBuckets() const {
431 return static_cast<const DerivedT *>(this)->getNumBuckets();
432 }
getBucketsEnd()433 BucketT *getBucketsEnd() {
434 return getBuckets() + getNumBuckets();
435 }
getBucketsEnd()436 const BucketT *getBucketsEnd() const {
437 return getBuckets() + getNumBuckets();
438 }
439
grow(unsigned AtLeast)440 void grow(unsigned AtLeast) {
441 static_cast<DerivedT *>(this)->grow(AtLeast);
442 }
443
shrink_and_clear()444 void shrink_and_clear() {
445 static_cast<DerivedT *>(this)->shrink_and_clear();
446 }
447
448 template <typename KeyArg, typename... ValueArgs>
InsertIntoBucket(BucketT * TheBucket,KeyArg && Key,ValueArgs &&...Values)449 BucketT *InsertIntoBucket(BucketT *TheBucket, KeyArg &&Key,
450 ValueArgs &&... Values) {
451 TheBucket = InsertIntoBucketImpl(Key, Key, TheBucket);
452
453 TheBucket->getFirst() = std::forward<KeyArg>(Key);
454 ::new (&TheBucket->getSecond()) ValueT(std::forward<ValueArgs>(Values)...);
455 return TheBucket;
456 }
457
458 template <typename LookupKeyT>
InsertIntoBucketWithLookup(BucketT * TheBucket,KeyT && Key,ValueT && Value,LookupKeyT & Lookup)459 BucketT *InsertIntoBucketWithLookup(BucketT *TheBucket, KeyT &&Key,
460 ValueT &&Value, LookupKeyT &Lookup) {
461 TheBucket = InsertIntoBucketImpl(Key, Lookup, TheBucket);
462
463 TheBucket->getFirst() = std::move(Key);
464 ::new (&TheBucket->getSecond()) ValueT(std::move(Value));
465 return TheBucket;
466 }
467
468 template <typename LookupKeyT>
InsertIntoBucketImpl(const KeyT & Key,const LookupKeyT & Lookup,BucketT * TheBucket)469 BucketT *InsertIntoBucketImpl(const KeyT &Key, const LookupKeyT &Lookup,
470 BucketT *TheBucket) {
471 incrementEpoch();
472
473 // If the load of the hash table is more than 3/4, or if fewer than 1/8 of
474 // the buckets are empty (meaning that many are filled with tombstones),
475 // grow the table.
476 //
477 // The later case is tricky. For example, if we had one empty bucket with
478 // tons of tombstones, failing lookups (e.g. for insertion) would have to
479 // probe almost the entire table until it found the empty bucket. If the
480 // table completely filled with tombstones, no lookup would ever succeed,
481 // causing infinite loops in lookup.
482 unsigned NewNumEntries = getNumEntries() + 1;
483 unsigned NumBuckets = getNumBuckets();
484 if (LLVM_UNLIKELY(NewNumEntries * 4 >= NumBuckets * 3)) {
485 this->grow(NumBuckets * 2);
486 LookupBucketFor(Lookup, TheBucket);
487 NumBuckets = getNumBuckets();
488 } else if (LLVM_UNLIKELY(NumBuckets-(NewNumEntries+getNumTombstones()) <=
489 NumBuckets/8)) {
490 this->grow(NumBuckets);
491 LookupBucketFor(Lookup, TheBucket);
492 }
493 assert(TheBucket);
494
495 // Only update the state after we've grown our bucket space appropriately
496 // so that when growing buckets we have self-consistent entry count.
497 incrementNumEntries();
498
499 // If we are writing over a tombstone, remember this.
500 const KeyT EmptyKey = getEmptyKey();
501 if (!KeyInfoT::isEqual(TheBucket->getFirst(), EmptyKey))
502 decrementNumTombstones();
503
504 return TheBucket;
505 }
506
507 /// LookupBucketFor - Lookup the appropriate bucket for Val, returning it in
508 /// FoundBucket. If the bucket contains the key and a value, this returns
509 /// true, otherwise it returns a bucket with an empty marker or tombstone and
510 /// returns false.
511 template<typename LookupKeyT>
LookupBucketFor(const LookupKeyT & Val,const BucketT * & FoundBucket)512 bool LookupBucketFor(const LookupKeyT &Val,
513 const BucketT *&FoundBucket) const {
514 const BucketT *BucketsPtr = getBuckets();
515 const unsigned NumBuckets = getNumBuckets();
516
517 if (NumBuckets == 0) {
518 FoundBucket = nullptr;
519 return false;
520 }
521
522 // FoundTombstone - Keep track of whether we find a tombstone while probing.
523 const BucketT *FoundTombstone = nullptr;
524 const KeyT EmptyKey = getEmptyKey();
525 const KeyT TombstoneKey = getTombstoneKey();
526 assert(!KeyInfoT::isEqual(Val, EmptyKey) &&
527 !KeyInfoT::isEqual(Val, TombstoneKey) &&
528 "Empty/Tombstone value shouldn't be inserted into map!");
529
530 unsigned BucketNo = getHashValue(Val) & (NumBuckets-1);
531 unsigned ProbeAmt = 1;
532 while (true) {
533 const BucketT *ThisBucket = BucketsPtr + BucketNo;
534 // Found Val's bucket? If so, return it.
535 if (LLVM_LIKELY(KeyInfoT::isEqual(Val, ThisBucket->getFirst()))) {
536 FoundBucket = ThisBucket;
537 return true;
538 }
539
540 // If we found an empty bucket, the key doesn't exist in the set.
541 // Insert it and return the default value.
542 if (LLVM_LIKELY(KeyInfoT::isEqual(ThisBucket->getFirst(), EmptyKey))) {
543 // If we've already seen a tombstone while probing, fill it in instead
544 // of the empty bucket we eventually probed to.
545 FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
546 return false;
547 }
548
549 // If this is a tombstone, remember it. If Val ends up not in the map, we
550 // prefer to return it than something that would require more probing.
551 if (KeyInfoT::isEqual(ThisBucket->getFirst(), TombstoneKey) &&
552 !FoundTombstone)
553 FoundTombstone = ThisBucket; // Remember the first tombstone found.
554
555 // Otherwise, it's a hash collision or a tombstone, continue quadratic
556 // probing.
557 BucketNo += ProbeAmt++;
558 BucketNo &= (NumBuckets-1);
559 }
560 }
561
562 template <typename LookupKeyT>
LookupBucketFor(const LookupKeyT & Val,BucketT * & FoundBucket)563 bool LookupBucketFor(const LookupKeyT &Val, BucketT *&FoundBucket) {
564 const BucketT *ConstFoundBucket;
565 bool Result = const_cast<const DenseMapBase *>(this)
566 ->LookupBucketFor(Val, ConstFoundBucket);
567 FoundBucket = const_cast<BucketT *>(ConstFoundBucket);
568 return Result;
569 }
570
571 public:
572 /// Return the approximate size (in bytes) of the actual map.
573 /// This is just the raw memory used by DenseMap.
574 /// If entries are pointers to objects, the size of the referenced objects
575 /// are not included.
getMemorySize()576 size_t getMemorySize() const {
577 return getNumBuckets() * sizeof(BucketT);
578 }
579 };
580
581 template <typename KeyT, typename ValueT,
582 typename KeyInfoT = DenseMapInfo<KeyT>,
583 typename BucketT = detail::DenseMapPair<KeyT, ValueT>>
584 class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
585 KeyT, ValueT, KeyInfoT, BucketT> {
586 // Lift some types from the dependent base class into this class for
587 // simplicity of referring to them.
588 typedef DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT> BaseT;
589 friend class DenseMapBase<DenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
590
591 BucketT *Buckets;
592 unsigned NumEntries;
593 unsigned NumTombstones;
594 unsigned NumBuckets;
595
596 public:
597 /// Create a DenseMap wth an optional \p InitialReserve that guarantee that
598 /// this number of elements can be inserted in the map without grow()
599 explicit DenseMap(unsigned InitialReserve = 0) { init(InitialReserve); }
600
DenseMap(const DenseMap & other)601 DenseMap(const DenseMap &other) : BaseT() {
602 init(0);
603 copyFrom(other);
604 }
605
DenseMap(DenseMap && other)606 DenseMap(DenseMap &&other) : BaseT() {
607 init(0);
608 swap(other);
609 }
610
611 template<typename InputIt>
DenseMap(const InputIt & I,const InputIt & E)612 DenseMap(const InputIt &I, const InputIt &E) {
613 init(std::distance(I, E));
614 this->insert(I, E);
615 }
616
~DenseMap()617 ~DenseMap() {
618 this->destroyAll();
619 operator delete(Buckets);
620 }
621
swap(DenseMap & RHS)622 void swap(DenseMap& RHS) {
623 this->incrementEpoch();
624 RHS.incrementEpoch();
625 std::swap(Buckets, RHS.Buckets);
626 std::swap(NumEntries, RHS.NumEntries);
627 std::swap(NumTombstones, RHS.NumTombstones);
628 std::swap(NumBuckets, RHS.NumBuckets);
629 }
630
631 DenseMap& operator=(const DenseMap& other) {
632 if (&other != this)
633 copyFrom(other);
634 return *this;
635 }
636
637 DenseMap& operator=(DenseMap &&other) {
638 this->destroyAll();
639 operator delete(Buckets);
640 init(0);
641 swap(other);
642 return *this;
643 }
644
copyFrom(const DenseMap & other)645 void copyFrom(const DenseMap& other) {
646 this->destroyAll();
647 operator delete(Buckets);
648 if (allocateBuckets(other.NumBuckets)) {
649 this->BaseT::copyFrom(other);
650 } else {
651 NumEntries = 0;
652 NumTombstones = 0;
653 }
654 }
655
init(unsigned InitNumEntries)656 void init(unsigned InitNumEntries) {
657 auto InitBuckets = BaseT::getMinBucketToReserveForEntries(InitNumEntries);
658 if (allocateBuckets(InitBuckets)) {
659 this->BaseT::initEmpty();
660 } else {
661 NumEntries = 0;
662 NumTombstones = 0;
663 }
664 }
665
grow(unsigned AtLeast)666 void grow(unsigned AtLeast) {
667 unsigned OldNumBuckets = NumBuckets;
668 BucketT *OldBuckets = Buckets;
669
670 allocateBuckets(std::max<unsigned>(64, static_cast<unsigned>(NextPowerOf2(AtLeast-1))));
671 assert(Buckets);
672 if (!OldBuckets) {
673 this->BaseT::initEmpty();
674 return;
675 }
676
677 this->moveFromOldBuckets(OldBuckets, OldBuckets+OldNumBuckets);
678
679 // Free the old table.
680 operator delete(OldBuckets);
681 }
682
shrink_and_clear()683 void shrink_and_clear() {
684 unsigned OldNumEntries = NumEntries;
685 this->destroyAll();
686
687 // Reduce the number of buckets.
688 unsigned NewNumBuckets = 0;
689 if (OldNumEntries)
690 NewNumBuckets = std::max(64, 1 << (Log2_32_Ceil(OldNumEntries) + 1));
691 if (NewNumBuckets == NumBuckets) {
692 this->BaseT::initEmpty();
693 return;
694 }
695
696 operator delete(Buckets);
697 init(NewNumBuckets);
698 }
699
700 private:
getNumEntries()701 unsigned getNumEntries() const {
702 return NumEntries;
703 }
setNumEntries(unsigned Num)704 void setNumEntries(unsigned Num) {
705 NumEntries = Num;
706 }
707
getNumTombstones()708 unsigned getNumTombstones() const {
709 return NumTombstones;
710 }
setNumTombstones(unsigned Num)711 void setNumTombstones(unsigned Num) {
712 NumTombstones = Num;
713 }
714
getBuckets()715 BucketT *getBuckets() const {
716 return Buckets;
717 }
718
getNumBuckets()719 unsigned getNumBuckets() const {
720 return NumBuckets;
721 }
722
allocateBuckets(unsigned Num)723 bool allocateBuckets(unsigned Num) {
724 NumBuckets = Num;
725 if (NumBuckets == 0) {
726 Buckets = nullptr;
727 return false;
728 }
729
730 Buckets = static_cast<BucketT*>(operator new(sizeof(BucketT) * NumBuckets));
731 return true;
732 }
733 };
734
735 template <typename KeyT, typename ValueT, unsigned InlineBuckets = 4,
736 typename KeyInfoT = DenseMapInfo<KeyT>,
737 typename BucketT = detail::DenseMapPair<KeyT, ValueT>>
738 class SmallDenseMap
739 : public DenseMapBase<
740 SmallDenseMap<KeyT, ValueT, InlineBuckets, KeyInfoT, BucketT>, KeyT,
741 ValueT, KeyInfoT, BucketT> {
742 // Lift some types from the dependent base class into this class for
743 // simplicity of referring to them.
744 typedef DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT> BaseT;
745 friend class DenseMapBase<SmallDenseMap, KeyT, ValueT, KeyInfoT, BucketT>;
746 static_assert(isPowerOf2_64(InlineBuckets),
747 "InlineBuckets must be a power of 2.");
748
749 unsigned Small : 1;
750 unsigned NumEntries : 31;
751 unsigned NumTombstones;
752
753 struct LargeRep {
754 BucketT *Buckets;
755 unsigned NumBuckets;
756 };
757
758 /// A "union" of an inline bucket array and the struct representing
759 /// a large bucket. This union will be discriminated by the 'Small' bit.
760 AlignedCharArrayUnion<BucketT[InlineBuckets], LargeRep> storage;
761
762 public:
763 explicit SmallDenseMap(unsigned NumInitBuckets = 0) {
764 init(NumInitBuckets);
765 }
766
SmallDenseMap(const SmallDenseMap & other)767 SmallDenseMap(const SmallDenseMap &other) : BaseT() {
768 init(0);
769 copyFrom(other);
770 }
771
SmallDenseMap(SmallDenseMap && other)772 SmallDenseMap(SmallDenseMap &&other) : BaseT() {
773 init(0);
774 swap(other);
775 }
776
777 template<typename InputIt>
SmallDenseMap(const InputIt & I,const InputIt & E)778 SmallDenseMap(const InputIt &I, const InputIt &E) {
779 init(NextPowerOf2(std::distance(I, E)));
780 this->insert(I, E);
781 }
782
~SmallDenseMap()783 ~SmallDenseMap() {
784 this->destroyAll();
785 deallocateBuckets();
786 }
787
swap(SmallDenseMap & RHS)788 void swap(SmallDenseMap& RHS) {
789 unsigned TmpNumEntries = RHS.NumEntries;
790 RHS.NumEntries = NumEntries;
791 NumEntries = TmpNumEntries;
792 std::swap(NumTombstones, RHS.NumTombstones);
793
794 const KeyT EmptyKey = this->getEmptyKey();
795 const KeyT TombstoneKey = this->getTombstoneKey();
796 if (Small && RHS.Small) {
797 // If we're swapping inline bucket arrays, we have to cope with some of
798 // the tricky bits of DenseMap's storage system: the buckets are not
799 // fully initialized. Thus we swap every key, but we may have
800 // a one-directional move of the value.
801 for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
802 BucketT *LHSB = &getInlineBuckets()[i],
803 *RHSB = &RHS.getInlineBuckets()[i];
804 bool hasLHSValue = (!KeyInfoT::isEqual(LHSB->getFirst(), EmptyKey) &&
805 !KeyInfoT::isEqual(LHSB->getFirst(), TombstoneKey));
806 bool hasRHSValue = (!KeyInfoT::isEqual(RHSB->getFirst(), EmptyKey) &&
807 !KeyInfoT::isEqual(RHSB->getFirst(), TombstoneKey));
808 if (hasLHSValue && hasRHSValue) {
809 // Swap together if we can...
810 std::swap(*LHSB, *RHSB);
811 continue;
812 }
813 // Swap separately and handle any assymetry.
814 std::swap(LHSB->getFirst(), RHSB->getFirst());
815 if (hasLHSValue) {
816 ::new (&RHSB->getSecond()) ValueT(std::move(LHSB->getSecond()));
817 LHSB->getSecond().~ValueT();
818 } else if (hasRHSValue) {
819 ::new (&LHSB->getSecond()) ValueT(std::move(RHSB->getSecond()));
820 RHSB->getSecond().~ValueT();
821 }
822 }
823 return;
824 }
825 if (!Small && !RHS.Small) {
826 std::swap(getLargeRep()->Buckets, RHS.getLargeRep()->Buckets);
827 std::swap(getLargeRep()->NumBuckets, RHS.getLargeRep()->NumBuckets);
828 return;
829 }
830
831 SmallDenseMap &SmallSide = Small ? *this : RHS;
832 SmallDenseMap &LargeSide = Small ? RHS : *this;
833
834 // First stash the large side's rep and move the small side across.
835 LargeRep TmpRep = std::move(*LargeSide.getLargeRep());
836 LargeSide.getLargeRep()->~LargeRep();
837 LargeSide.Small = true;
838 // This is similar to the standard move-from-old-buckets, but the bucket
839 // count hasn't actually rotated in this case. So we have to carefully
840 // move construct the keys and values into their new locations, but there
841 // is no need to re-hash things.
842 for (unsigned i = 0, e = InlineBuckets; i != e; ++i) {
843 BucketT *NewB = &LargeSide.getInlineBuckets()[i],
844 *OldB = &SmallSide.getInlineBuckets()[i];
845 ::new (&NewB->getFirst()) KeyT(std::move(OldB->getFirst()));
846 OldB->getFirst().~KeyT();
847 if (!KeyInfoT::isEqual(NewB->getFirst(), EmptyKey) &&
848 !KeyInfoT::isEqual(NewB->getFirst(), TombstoneKey)) {
849 ::new (&NewB->getSecond()) ValueT(std::move(OldB->getSecond()));
850 OldB->getSecond().~ValueT();
851 }
852 }
853
854 // The hard part of moving the small buckets across is done, just move
855 // the TmpRep into its new home.
856 SmallSide.Small = false;
857 new (SmallSide.getLargeRep()) LargeRep(std::move(TmpRep));
858 }
859
860 SmallDenseMap& operator=(const SmallDenseMap& other) {
861 if (&other != this)
862 copyFrom(other);
863 return *this;
864 }
865
866 SmallDenseMap& operator=(SmallDenseMap &&other) {
867 this->destroyAll();
868 deallocateBuckets();
869 init(0);
870 swap(other);
871 return *this;
872 }
873
copyFrom(const SmallDenseMap & other)874 void copyFrom(const SmallDenseMap& other) {
875 this->destroyAll();
876 deallocateBuckets();
877 Small = true;
878 if (other.getNumBuckets() > InlineBuckets) {
879 Small = false;
880 new (getLargeRep()) LargeRep(allocateBuckets(other.getNumBuckets()));
881 }
882 this->BaseT::copyFrom(other);
883 }
884
init(unsigned InitBuckets)885 void init(unsigned InitBuckets) {
886 Small = true;
887 if (InitBuckets > InlineBuckets) {
888 Small = false;
889 new (getLargeRep()) LargeRep(allocateBuckets(InitBuckets));
890 }
891 this->BaseT::initEmpty();
892 }
893
grow(unsigned AtLeast)894 void grow(unsigned AtLeast) {
895 if (AtLeast >= InlineBuckets)
896 AtLeast = std::max<unsigned>(64, NextPowerOf2(AtLeast-1));
897
898 if (Small) {
899 if (AtLeast < InlineBuckets)
900 return; // Nothing to do.
901
902 // First move the inline buckets into a temporary storage.
903 AlignedCharArrayUnion<BucketT[InlineBuckets]> TmpStorage;
904 BucketT *TmpBegin = reinterpret_cast<BucketT *>(TmpStorage.buffer);
905 BucketT *TmpEnd = TmpBegin;
906
907 // Loop over the buckets, moving non-empty, non-tombstones into the
908 // temporary storage. Have the loop move the TmpEnd forward as it goes.
909 const KeyT EmptyKey = this->getEmptyKey();
910 const KeyT TombstoneKey = this->getTombstoneKey();
911 for (BucketT *P = getBuckets(), *E = P + InlineBuckets; P != E; ++P) {
912 if (!KeyInfoT::isEqual(P->getFirst(), EmptyKey) &&
913 !KeyInfoT::isEqual(P->getFirst(), TombstoneKey)) {
914 assert(size_t(TmpEnd - TmpBegin) < InlineBuckets &&
915 "Too many inline buckets!");
916 ::new (&TmpEnd->getFirst()) KeyT(std::move(P->getFirst()));
917 ::new (&TmpEnd->getSecond()) ValueT(std::move(P->getSecond()));
918 ++TmpEnd;
919 P->getSecond().~ValueT();
920 }
921 P->getFirst().~KeyT();
922 }
923
924 // Now make this map use the large rep, and move all the entries back
925 // into it.
926 Small = false;
927 new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
928 this->moveFromOldBuckets(TmpBegin, TmpEnd);
929 return;
930 }
931
932 LargeRep OldRep = std::move(*getLargeRep());
933 getLargeRep()->~LargeRep();
934 if (AtLeast <= InlineBuckets) {
935 Small = true;
936 } else {
937 new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
938 }
939
940 this->moveFromOldBuckets(OldRep.Buckets, OldRep.Buckets+OldRep.NumBuckets);
941
942 // Free the old table.
943 operator delete(OldRep.Buckets);
944 }
945
shrink_and_clear()946 void shrink_and_clear() {
947 unsigned OldSize = this->size();
948 this->destroyAll();
949
950 // Reduce the number of buckets.
951 unsigned NewNumBuckets = 0;
952 if (OldSize) {
953 NewNumBuckets = 1 << (Log2_32_Ceil(OldSize) + 1);
954 if (NewNumBuckets > InlineBuckets && NewNumBuckets < 64u)
955 NewNumBuckets = 64;
956 }
957 if ((Small && NewNumBuckets <= InlineBuckets) ||
958 (!Small && NewNumBuckets == getLargeRep()->NumBuckets)) {
959 this->BaseT::initEmpty();
960 return;
961 }
962
963 deallocateBuckets();
964 init(NewNumBuckets);
965 }
966
967 private:
getNumEntries()968 unsigned getNumEntries() const {
969 return NumEntries;
970 }
setNumEntries(unsigned Num)971 void setNumEntries(unsigned Num) {
972 // NumEntries is hardcoded to be 31 bits wide.
973 assert(Num < (1U << 31) && "Cannot support more than 1<<31 entries");
974 NumEntries = Num;
975 }
976
getNumTombstones()977 unsigned getNumTombstones() const {
978 return NumTombstones;
979 }
setNumTombstones(unsigned Num)980 void setNumTombstones(unsigned Num) {
981 NumTombstones = Num;
982 }
983
getInlineBuckets()984 const BucketT *getInlineBuckets() const {
985 assert(Small);
986 // Note that this cast does not violate aliasing rules as we assert that
987 // the memory's dynamic type is the small, inline bucket buffer, and the
988 // 'storage.buffer' static type is 'char *'.
989 return reinterpret_cast<const BucketT *>(storage.buffer);
990 }
getInlineBuckets()991 BucketT *getInlineBuckets() {
992 return const_cast<BucketT *>(
993 const_cast<const SmallDenseMap *>(this)->getInlineBuckets());
994 }
getLargeRep()995 const LargeRep *getLargeRep() const {
996 assert(!Small);
997 // Note, same rule about aliasing as with getInlineBuckets.
998 return reinterpret_cast<const LargeRep *>(storage.buffer);
999 }
getLargeRep()1000 LargeRep *getLargeRep() {
1001 return const_cast<LargeRep *>(
1002 const_cast<const SmallDenseMap *>(this)->getLargeRep());
1003 }
1004
getBuckets()1005 const BucketT *getBuckets() const {
1006 return Small ? getInlineBuckets() : getLargeRep()->Buckets;
1007 }
getBuckets()1008 BucketT *getBuckets() {
1009 return const_cast<BucketT *>(
1010 const_cast<const SmallDenseMap *>(this)->getBuckets());
1011 }
getNumBuckets()1012 unsigned getNumBuckets() const {
1013 return Small ? InlineBuckets : getLargeRep()->NumBuckets;
1014 }
1015
deallocateBuckets()1016 void deallocateBuckets() {
1017 if (Small)
1018 return;
1019
1020 operator delete(getLargeRep()->Buckets);
1021 getLargeRep()->~LargeRep();
1022 }
1023
allocateBuckets(unsigned Num)1024 LargeRep allocateBuckets(unsigned Num) {
1025 assert(Num > InlineBuckets && "Must allocate more buckets than are inline");
1026 LargeRep Rep = {
1027 static_cast<BucketT*>(operator new(sizeof(BucketT) * Num)), Num
1028 };
1029 return Rep;
1030 }
1031 };
1032
1033 template <typename KeyT, typename ValueT, typename KeyInfoT, typename Bucket,
1034 bool IsConst>
1035 class DenseMapIterator : DebugEpochBase::HandleBase {
1036 typedef DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true> ConstIterator;
1037 friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, true>;
1038 friend class DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, false>;
1039
1040 public:
1041 typedef ptrdiff_t difference_type;
1042 typedef typename std::conditional<IsConst, const Bucket, Bucket>::type
1043 value_type;
1044 typedef value_type *pointer;
1045 typedef value_type &reference;
1046 typedef std::forward_iterator_tag iterator_category;
1047
1048 private:
1049 pointer Ptr, End;
1050
1051 public:
DenseMapIterator()1052 DenseMapIterator() : Ptr(nullptr), End(nullptr) {}
1053
1054 DenseMapIterator(pointer Pos, pointer E, const DebugEpochBase &Epoch,
1055 bool NoAdvance = false)
1056 : DebugEpochBase::HandleBase(&Epoch), Ptr(Pos), End(E) {
1057 assert(isHandleInSync() && "invalid construction!");
1058 if (!NoAdvance) AdvancePastEmptyBuckets();
1059 }
1060
1061 // Converting ctor from non-const iterators to const iterators. SFINAE'd out
1062 // for const iterator destinations so it doesn't end up as a user defined copy
1063 // constructor.
1064 template <bool IsConstSrc,
1065 typename = typename std::enable_if<!IsConstSrc && IsConst>::type>
DenseMapIterator(const DenseMapIterator<KeyT,ValueT,KeyInfoT,Bucket,IsConstSrc> & I)1066 DenseMapIterator(
1067 const DenseMapIterator<KeyT, ValueT, KeyInfoT, Bucket, IsConstSrc> &I)
1068 : DebugEpochBase::HandleBase(I), Ptr(I.Ptr), End(I.End) {}
1069
1070 reference operator*() const {
1071 assert(isHandleInSync() && "invalid iterator access!");
1072 return *Ptr;
1073 }
1074 pointer operator->() const {
1075 assert(isHandleInSync() && "invalid iterator access!");
1076 return Ptr;
1077 }
1078
1079 bool operator==(const ConstIterator &RHS) const {
1080 assert((!Ptr || isHandleInSync()) && "handle not in sync!");
1081 assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!");
1082 assert(getEpochAddress() == RHS.getEpochAddress() &&
1083 "comparing incomparable iterators!");
1084 return Ptr == RHS.Ptr;
1085 }
1086 bool operator!=(const ConstIterator &RHS) const {
1087 assert((!Ptr || isHandleInSync()) && "handle not in sync!");
1088 assert((!RHS.Ptr || RHS.isHandleInSync()) && "handle not in sync!");
1089 assert(getEpochAddress() == RHS.getEpochAddress() &&
1090 "comparing incomparable iterators!");
1091 return Ptr != RHS.Ptr;
1092 }
1093
1094 inline DenseMapIterator& operator++() { // Preincrement
1095 assert(isHandleInSync() && "invalid iterator access!");
1096 ++Ptr;
1097 AdvancePastEmptyBuckets();
1098 return *this;
1099 }
1100 DenseMapIterator operator++(int) { // Postincrement
1101 assert(isHandleInSync() && "invalid iterator access!");
1102 DenseMapIterator tmp = *this; ++*this; return tmp;
1103 }
1104
1105 private:
AdvancePastEmptyBuckets()1106 void AdvancePastEmptyBuckets() {
1107 const KeyT Empty = KeyInfoT::getEmptyKey();
1108 const KeyT Tombstone = KeyInfoT::getTombstoneKey();
1109
1110 while (Ptr != End && (KeyInfoT::isEqual(Ptr->getFirst(), Empty) ||
1111 KeyInfoT::isEqual(Ptr->getFirst(), Tombstone)))
1112 ++Ptr;
1113 }
1114 };
1115
1116 template<typename KeyT, typename ValueT, typename KeyInfoT>
1117 static inline size_t
capacity_in_bytes(const DenseMap<KeyT,ValueT,KeyInfoT> & X)1118 capacity_in_bytes(const DenseMap<KeyT, ValueT, KeyInfoT> &X) {
1119 return X.getMemorySize();
1120 }
1121
1122 } // end namespace llvm
1123
1124 #endif // LLVM_ADT_DENSEMAP_H
1125