DenseMap.h 43 KB

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