LLVM API Documentation

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