14 #ifndef LLVM_ADT_DENSEMAP_H 15 #define LLVM_ADT_DENSEMAP_H 28 #include <initializer_list> 31 #include <type_traits> 40 template <
typename KeyT,
typename ValueT>
56 template <
typename AltKeyT,
typename AltValueT>
58 typename std::enable_if<
59 std::is_convertible<AltKeyT, KeyT>::value &&
60 std::is_convertible<AltValueT, ValueT>::value>::
type * = 0)
62 std::forward<AltValueT>(AltValue)) {}
64 template <
typename AltPairT>
66 typename std::enable_if<std::is_convertible<
67 AltPairT, std::pair<KeyT, ValueT>>::value>::
type * = 0)
68 :
std::pair<KeyT,
ValueT>(
std::forward<AltPairT>(AltPair)) {}
78 template <
typename KeyT,
typename ValueT,
84 template <
typename DerivedT,
typename KeyT,
typename ValueT,
typename KeyInfoT,
105 if (shouldReverseIterate<KeyT>())
106 return makeIterator(getBucketsEnd() - 1, getBuckets(), *
this);
107 return makeIterator(getBuckets(), getBucketsEnd(), *
this);
110 return makeIterator(getBucketsEnd(), getBucketsEnd(), *
this,
true);
115 if (shouldReverseIterate<KeyT>())
116 return makeConstIterator(getBucketsEnd() - 1, getBuckets(), *
this);
117 return makeConstIterator(getBuckets(), getBucketsEnd(), *
this);
120 return makeConstIterator(getBucketsEnd(), getBucketsEnd(), *
this,
true);
124 return getNumEntries() == 0;
126 unsigned size()
const {
return getNumEntries(); }
133 if (NumBuckets > getNumBuckets())
139 if (getNumEntries() == 0 && getNumTombstones() == 0)
return;
143 if (getNumEntries() * 4 < getNumBuckets() && getNumBuckets() > 64) {
148 const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
151 for (BucketT *
P = getBuckets(), *
E = getBucketsEnd();
P !=
E; ++
P)
152 P->getFirst() = EmptyKey;
154 unsigned NumEntries = getNumEntries();
155 for (BucketT *
P = getBuckets(), *
E = getBucketsEnd();
P !=
E; ++
P) {
158 P->getSecond().~ValueT();
161 P->getFirst() = EmptyKey;
164 assert(NumEntries == 0 &&
"Node count imbalance!");
172 const BucketT *TheBucket;
173 return LookupBucketFor(Val, TheBucket) ? 1 : 0;
178 if (LookupBucketFor(Val, TheBucket))
179 return makeIterator(TheBucket, getBucketsEnd(), *
this,
true);
183 const BucketT *TheBucket;
184 if (LookupBucketFor(Val, TheBucket))
185 return makeConstIterator(TheBucket, getBucketsEnd(), *
this,
true);
194 template<
class LookupKeyT>
197 if (LookupBucketFor(Val, TheBucket))
198 return makeIterator(TheBucket, getBucketsEnd(), *
this,
true);
201 template<
class LookupKeyT>
203 const BucketT *TheBucket;
204 if (LookupBucketFor(Val, TheBucket))
205 return makeConstIterator(TheBucket, getBucketsEnd(), *
this,
true);
211 ValueT
lookup(const_arg_type_t<KeyT> Val)
const {
212 const BucketT *TheBucket;
213 if (LookupBucketFor(Val, TheBucket))
214 return TheBucket->getSecond();
221 std::pair<iterator, bool>
insert(
const std::pair<KeyT, ValueT> &KV) {
222 return try_emplace(KV.first, KV.second);
228 std::pair<iterator, bool>
insert(std::pair<KeyT, ValueT> &&KV) {
229 return try_emplace(std::move(KV.first), std::move(KV.second));
235 template <
typename... Ts>
238 if (LookupBucketFor(
Key, TheBucket))
239 return std::make_pair(
240 makeIterator(TheBucket, getBucketsEnd(), *
this,
true),
245 InsertIntoBucket(TheBucket, std::move(
Key), std::forward<Ts>(
Args)...);
246 return std::make_pair(
247 makeIterator(TheBucket, getBucketsEnd(), *
this,
true),
254 template <
typename... Ts>
257 if (LookupBucketFor(Key, TheBucket))
258 return std::make_pair(
259 makeIterator(TheBucket, getBucketsEnd(), *
this,
true),
263 TheBucket = InsertIntoBucket(TheBucket, Key, std::forward<Ts>(
Args)...);
264 return std::make_pair(
265 makeIterator(TheBucket, getBucketsEnd(), *
this,
true),
274 template <
typename LookupKeyT>
275 std::pair<iterator, bool>
insert_as(std::pair<KeyT, ValueT> &&KV,
276 const LookupKeyT &Val) {
278 if (LookupBucketFor(Val, TheBucket))
279 return std::make_pair(
280 makeIterator(TheBucket, getBucketsEnd(), *
this,
true),
284 TheBucket = InsertIntoBucketWithLookup(TheBucket, std::move(KV.first),
285 std::move(KV.second), Val);
286 return std::make_pair(
287 makeIterator(TheBucket, getBucketsEnd(), *
this,
true),
292 template<
typename InputIt>
300 if (!LookupBucketFor(Val, TheBucket))
303 TheBucket->getSecond().~ValueT();
304 TheBucket->getFirst() = getTombstoneKey();
305 decrementNumEntries();
306 incrementNumTombstones();
310 BucketT *TheBucket = &*
I;
311 TheBucket->getSecond().~ValueT();
312 TheBucket->getFirst() = getTombstoneKey();
313 decrementNumEntries();
314 incrementNumTombstones();
319 if (LookupBucketFor(Key, TheBucket))
322 return *InsertIntoBucket(TheBucket, Key);
326 return FindAndConstruct(Key).second;
331 if (LookupBucketFor(
Key, TheBucket))
334 return *InsertIntoBucket(TheBucket, std::move(
Key));
338 return FindAndConstruct(std::move(
Key)).second;
345 return Ptr >= getBuckets() && Ptr < getBucketsEnd();
357 if (getNumBuckets() == 0)
360 const KeyT EmptyKey = getEmptyKey(), TombstoneKey = getTombstoneKey();
361 for (BucketT *
P = getBuckets(), *
E = getBucketsEnd();
P !=
E; ++
P) {
364 P->getSecond().~ValueT();
365 P->getFirst().~KeyT();
373 assert((getNumBuckets() & (getNumBuckets()-1)) == 0 &&
374 "# initial buckets must be a power of two!");
375 const KeyT EmptyKey = getEmptyKey();
376 for (BucketT *
B = getBuckets(), *
E = getBucketsEnd();
B !=
E; ++
B)
377 ::
new (&
B->getFirst()) KeyT(EmptyKey);
395 const KeyT EmptyKey = getEmptyKey();
396 const KeyT TombstoneKey = getTombstoneKey();
397 for (BucketT *
B = OldBucketsBegin, *
E = OldBucketsEnd;
B !=
E; ++
B) {
402 bool FoundVal = LookupBucketFor(
B->getFirst(), DestBucket);
404 assert(!FoundVal &&
"Key already in new map?");
405 DestBucket->getFirst() = std::move(
B->getFirst());
406 ::new (&DestBucket->getSecond()) ValueT(std::move(
B->getSecond()));
407 incrementNumEntries();
410 B->getSecond().~ValueT();
412 B->getFirst().~KeyT();
416 template <
typename OtherBaseT>
420 assert(getNumBuckets() == other.getNumBuckets());
422 setNumEntries(other.getNumEntries());
423 setNumTombstones(other.getNumTombstones());
426 memcpy(reinterpret_cast<void *>(getBuckets()), other.getBuckets(),
427 getNumBuckets() *
sizeof(BucketT));
429 for (
size_t i = 0; i < getNumBuckets(); ++i) {
431 KeyT(other.getBuckets()[i].getFirst());
434 ::
new (&getBuckets()[i].getSecond())
435 ValueT(other.getBuckets()[i].getSecond());
440 return KeyInfoT::getHashValue(Val);
443 template<
typename LookupKeyT>
445 return KeyInfoT::getHashValue(Val);
449 static_assert(std::is_base_of<DenseMapBase, DerivedT>::value,
450 "Must pass the derived type to this template!");
451 return KeyInfoT::getEmptyKey();
455 return KeyInfoT::getTombstoneKey();
461 bool NoAdvance=
false) {
462 if (shouldReverseIterate<KeyT>()) {
463 BucketT *
B = P == getBucketsEnd() ? getBuckets() : P + 1;
464 return iterator(B, E, Epoch, NoAdvance);
466 return iterator(P, E, Epoch, NoAdvance);
469 const_iterator makeConstIterator(
const BucketT *P,
const BucketT *E,
471 const bool NoAdvance=
false)
const {
472 if (shouldReverseIterate<KeyT>()) {
473 const BucketT *
B = P == getBucketsEnd() ? getBuckets() : P + 1;
479 unsigned getNumEntries()
const {
480 return static_cast<const DerivedT *
>(
this)->getNumEntries();
483 void setNumEntries(
unsigned Num) {
484 static_cast<DerivedT *
>(
this)->setNumEntries(Num);
487 void incrementNumEntries() {
488 setNumEntries(getNumEntries() + 1);
491 void decrementNumEntries() {
492 setNumEntries(getNumEntries() - 1);
495 unsigned getNumTombstones()
const {
496 return static_cast<const DerivedT *
>(
this)->getNumTombstones();
499 void setNumTombstones(
unsigned Num) {
500 static_cast<DerivedT *
>(
this)->setNumTombstones(Num);
503 void incrementNumTombstones() {
504 setNumTombstones(getNumTombstones() + 1);
507 void decrementNumTombstones() {
508 setNumTombstones(getNumTombstones() - 1);
511 const BucketT *getBuckets()
const {
512 return static_cast<const DerivedT *
>(
this)->getBuckets();
515 BucketT *getBuckets() {
516 return static_cast<DerivedT *
>(
this)->getBuckets();
519 unsigned getNumBuckets()
const {
520 return static_cast<const DerivedT *
>(
this)->getNumBuckets();
523 BucketT *getBucketsEnd() {
524 return getBuckets() + getNumBuckets();
527 const BucketT *getBucketsEnd()
const {
528 return getBuckets() + getNumBuckets();
531 void grow(
unsigned AtLeast) {
532 static_cast<DerivedT *
>(
this)->grow(AtLeast);
535 void shrink_and_clear() {
536 static_cast<DerivedT *
>(
this)->shrink_and_clear();
539 template <
typename KeyArg,
typename... ValueArgs>
540 BucketT *InsertIntoBucket(BucketT *TheBucket, KeyArg &&
Key,
541 ValueArgs &&... Values) {
542 TheBucket = InsertIntoBucketImpl(
Key,
Key, TheBucket);
544 TheBucket->getFirst() = std::forward<KeyArg>(
Key);
545 ::new (&TheBucket->getSecond()) ValueT(std::forward<ValueArgs>(Values)...);
549 template <
typename LookupKeyT>
550 BucketT *InsertIntoBucketWithLookup(BucketT *TheBucket, KeyT &&
Key,
552 TheBucket = InsertIntoBucketImpl(
Key, Lookup, TheBucket);
554 TheBucket->getFirst() = std::move(
Key);
555 ::new (&TheBucket->getSecond()) ValueT(std::move(
Value));
559 template <
typename LookupKeyT>
560 BucketT *InsertIntoBucketImpl(
const KeyT &
Key,
const LookupKeyT &Lookup,
561 BucketT *TheBucket) {
573 unsigned NewNumEntries = getNumEntries() + 1;
574 unsigned NumBuckets = getNumBuckets();
576 this->grow(NumBuckets * 2);
577 LookupBucketFor(Lookup, TheBucket);
578 NumBuckets = getNumBuckets();
579 }
else if (
LLVM_UNLIKELY(NumBuckets-(NewNumEntries+getNumTombstones()) <=
581 this->grow(NumBuckets);
582 LookupBucketFor(Lookup, TheBucket);
588 incrementNumEntries();
591 const KeyT EmptyKey = getEmptyKey();
593 decrementNumTombstones();
602 template<
typename LookupKeyT>
603 bool LookupBucketFor(
const LookupKeyT &Val,
604 const BucketT *&FoundBucket)
const {
605 const BucketT *BucketsPtr = getBuckets();
606 const unsigned NumBuckets = getNumBuckets();
608 if (NumBuckets == 0) {
609 FoundBucket =
nullptr;
614 const BucketT *FoundTombstone =
nullptr;
615 const KeyT EmptyKey = getEmptyKey();
616 const KeyT TombstoneKey = getTombstoneKey();
619 "Empty/Tombstone value shouldn't be inserted into map!");
621 unsigned BucketNo = getHashValue(Val) & (NumBuckets-1);
622 unsigned ProbeAmt = 1;
624 const BucketT *ThisBucket = BucketsPtr + BucketNo;
627 FoundBucket = ThisBucket;
636 FoundBucket = FoundTombstone ? FoundTombstone : ThisBucket;
644 FoundTombstone = ThisBucket;
648 BucketNo += ProbeAmt++;
649 BucketNo &= (NumBuckets-1);
653 template <
typename LookupKeyT>
654 bool LookupBucketFor(
const LookupKeyT &Val, BucketT *&FoundBucket) {
655 const BucketT *ConstFoundBucket;
657 ->LookupBucketFor(Val, ConstFoundBucket);
658 FoundBucket =
const_cast<BucketT *
>(ConstFoundBucket);
668 return getNumBuckets() *
sizeof(BucketT);
678 template <
typename DerivedT,
typename KeyT,
typename ValueT,
typename KeyInfoT,
686 for (
auto &KV : LHS) {
687 auto I = RHS.
find(KV.first);
688 if (
I == RHS.
end() ||
I->second != KV.second)
698 template <
typename DerivedT,
typename KeyT,
typename ValueT,
typename KeyInfoT,
703 return !(LHS == RHS);
706 template <
typename KeyT,
typename ValueT,
710 KeyT, ValueT, KeyInfoT, BucketT> {
719 unsigned NumTombstones;
725 explicit DenseMap(
unsigned InitialReserve = 0) {
init(InitialReserve); }
737 template<
typename InputIt>
739 init(std::distance(I, E));
743 DenseMap(std::initializer_list<typename BaseT::value_type> Vals) {
745 this->insert(Vals.begin(), Vals.end());
750 operator delete(Buckets);
754 this->incrementEpoch();
758 std::swap(NumTombstones, RHS.NumTombstones);
770 operator delete(Buckets);
778 operator delete(Buckets);
779 if (allocateBuckets(other.NumBuckets)) {
780 this->BaseT::copyFrom(other);
787 void init(
unsigned InitNumEntries) {
789 if (allocateBuckets(InitBuckets)) {
790 this->BaseT::initEmpty();
798 unsigned OldNumBuckets = NumBuckets;
799 BucketT *OldBuckets = Buckets;
801 allocateBuckets(std::max<unsigned>(64, static_cast<unsigned>(
NextPowerOf2(AtLeast-1))));
804 this->BaseT::initEmpty();
808 this->moveFromOldBuckets(OldBuckets, OldBuckets+OldNumBuckets);
811 operator delete(OldBuckets);
815 unsigned OldNumEntries = NumEntries;
819 unsigned NewNumBuckets = 0;
822 if (NewNumBuckets == NumBuckets) {
823 this->BaseT::initEmpty();
827 operator delete(Buckets);
832 unsigned getNumEntries()
const {
836 void setNumEntries(
unsigned Num) {
840 unsigned getNumTombstones()
const {
841 return NumTombstones;
844 void setNumTombstones(
unsigned Num) {
848 BucketT *getBuckets()
const {
852 unsigned getNumBuckets()
const {
856 bool allocateBuckets(
unsigned Num) {
858 if (NumBuckets == 0) {
863 Buckets =
static_cast<BucketT*
>(
operator new(
sizeof(BucketT) * NumBuckets));
868 template <
typename KeyT,
typename ValueT,
unsigned InlineBuckets = 4,
873 SmallDenseMap<KeyT, ValueT, InlineBuckets, KeyInfoT, BucketT>, KeyT,
874 ValueT, KeyInfoT, BucketT> {
882 "InlineBuckets must be a power of 2.");
885 unsigned NumEntries : 31;
886 unsigned NumTombstones;
899 init(NumInitBuckets);
912 template<
typename InputIt>
924 unsigned TmpNumEntries = RHS.NumEntries;
925 RHS.NumEntries = NumEntries;
926 NumEntries = TmpNumEntries;
927 std::swap(NumTombstones, RHS.NumTombstones);
929 const KeyT EmptyKey = this->getEmptyKey();
930 const KeyT TombstoneKey = this->getTombstoneKey();
931 if (
Small && RHS.Small) {
936 for (
unsigned i = 0, e = InlineBuckets; i != e; ++i) {
937 BucketT *LHSB = &getInlineBuckets()[i],
938 *RHSB = &RHS.getInlineBuckets()[i];
943 if (hasLHSValue && hasRHSValue) {
949 std::swap(LHSB->getFirst(), RHSB->getFirst());
951 ::new (&RHSB->getSecond()) ValueT(std::move(LHSB->getSecond()));
952 LHSB->getSecond().~ValueT();
953 }
else if (hasRHSValue) {
954 ::new (&LHSB->getSecond()) ValueT(std::move(RHSB->getSecond()));
955 RHSB->getSecond().~ValueT();
960 if (!
Small && !RHS.Small) {
961 std::swap(getLargeRep()->Buckets, RHS.getLargeRep()->Buckets);
962 std::swap(getLargeRep()->NumBuckets, RHS.getLargeRep()->NumBuckets);
970 LargeRep TmpRep = std::move(*LargeSide.getLargeRep());
971 LargeSide.getLargeRep()->~LargeRep();
972 LargeSide.Small =
true;
977 for (
unsigned i = 0, e = InlineBuckets; i != e; ++i) {
978 BucketT *NewB = &LargeSide.getInlineBuckets()[i],
979 *OldB = &SmallSide.getInlineBuckets()[i];
980 ::new (&NewB->getFirst()) KeyT(std::move(OldB->getFirst()));
981 OldB->getFirst().~KeyT();
984 ::new (&NewB->getSecond()) ValueT(std::move(OldB->getSecond()));
985 OldB->getSecond().~ValueT();
991 SmallSide.Small =
false;
992 new (SmallSide.getLargeRep()) LargeRep(std::move(TmpRep));
1003 deallocateBuckets();
1011 deallocateBuckets();
1013 if (other.getNumBuckets() > InlineBuckets) {
1015 new (getLargeRep()) LargeRep(allocateBuckets(other.getNumBuckets()));
1017 this->BaseT::copyFrom(other);
1022 if (InitBuckets > InlineBuckets) {
1024 new (getLargeRep()) LargeRep(allocateBuckets(InitBuckets));
1026 this->BaseT::initEmpty();
1030 if (AtLeast >= InlineBuckets)
1031 AtLeast = std::max<unsigned>(64,
NextPowerOf2(AtLeast-1));
1034 if (AtLeast < InlineBuckets)
1039 BucketT *TmpBegin =
reinterpret_cast<BucketT *
>(TmpStorage.
buffer);
1040 BucketT *TmpEnd = TmpBegin;
1044 const KeyT EmptyKey = this->getEmptyKey();
1045 const KeyT TombstoneKey = this->getTombstoneKey();
1046 for (BucketT *
P = getBuckets(), *
E =
P + InlineBuckets;
P !=
E; ++
P) {
1049 assert(
size_t(TmpEnd - TmpBegin) < InlineBuckets &&
1050 "Too many inline buckets!");
1051 ::new (&TmpEnd->getFirst()) KeyT(std::move(
P->getFirst()));
1052 ::new (&TmpEnd->getSecond()) ValueT(std::move(
P->getSecond()));
1054 P->getSecond().~ValueT();
1056 P->getFirst().~KeyT();
1062 new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
1063 this->moveFromOldBuckets(TmpBegin, TmpEnd);
1067 LargeRep OldRep = std::move(*getLargeRep());
1068 getLargeRep()->~LargeRep();
1069 if (AtLeast <= InlineBuckets) {
1072 new (getLargeRep()) LargeRep(allocateBuckets(AtLeast));
1075 this->moveFromOldBuckets(OldRep.Buckets, OldRep.Buckets+OldRep.NumBuckets);
1078 operator delete(OldRep.Buckets);
1082 unsigned OldSize = this->
size();
1086 unsigned NewNumBuckets = 0;
1089 if (NewNumBuckets > InlineBuckets && NewNumBuckets < 64u)
1092 if ((
Small && NewNumBuckets <= InlineBuckets) ||
1093 (!
Small && NewNumBuckets == getLargeRep()->NumBuckets)) {
1094 this->BaseT::initEmpty();
1098 deallocateBuckets();
1099 init(NewNumBuckets);
1103 unsigned getNumEntries()
const {
1107 void setNumEntries(
unsigned Num) {
1109 assert(Num < (1U << 31) &&
"Cannot support more than 1<<31 entries");
1113 unsigned getNumTombstones()
const {
1114 return NumTombstones;
1117 void setNumTombstones(
unsigned Num) {
1118 NumTombstones = Num;
1121 const BucketT *getInlineBuckets()
const {
1126 return reinterpret_cast<const BucketT *
>(storage.
buffer);
1129 BucketT *getInlineBuckets() {
1130 return const_cast<BucketT *
>(
1131 const_cast<const SmallDenseMap *
>(
this)->getInlineBuckets());
1134 const LargeRep *getLargeRep()
const {
1137 return reinterpret_cast<const LargeRep *
>(storage.
buffer);
1140 LargeRep *getLargeRep() {
1141 return const_cast<LargeRep *
>(
1145 const BucketT *getBuckets()
const {
1146 return Small ? getInlineBuckets() : getLargeRep()->Buckets;
1149 BucketT *getBuckets() {
1150 return const_cast<BucketT *
>(
1154 unsigned getNumBuckets()
const {
1155 return Small ? InlineBuckets : getLargeRep()->NumBuckets;
1158 void deallocateBuckets() {
1162 operator delete(getLargeRep()->Buckets);
1163 getLargeRep()->~LargeRep();
1166 LargeRep allocateBuckets(
unsigned Num) {
1167 assert(Num > InlineBuckets &&
"Must allocate more buckets than are inline");
1169 static_cast<BucketT*
>(
operator new(
sizeof(BucketT) * Num)), Num
1175 template <
typename KeyT,
typename ValueT,
typename KeyInfoT,
typename Bucket,
1186 typename std::conditional<IsConst, const Bucket, Bucket>::type;
1199 bool NoAdvance =
false)
1201 assert(isHandleInSync() &&
"invalid construction!");
1203 if (NoAdvance)
return;
1204 if (shouldReverseIterate<KeyT>()) {
1205 RetreatPastEmptyBuckets();
1208 AdvancePastEmptyBuckets();
1214 template <
bool IsConstSrc,
1215 typename =
typename std::enable_if<!IsConstSrc && IsConst>::type>
1221 assert(isHandleInSync() &&
"invalid iterator access!");
1222 if (shouldReverseIterate<KeyT>())
1227 assert(isHandleInSync() &&
"invalid iterator access!");
1228 if (shouldReverseIterate<KeyT>())
1234 assert((!Ptr || isHandleInSync()) &&
"handle not in sync!");
1237 "comparing incomparable iterators!");
1238 return Ptr == RHS.Ptr;
1241 assert((!Ptr || isHandleInSync()) &&
"handle not in sync!");
1244 "comparing incomparable iterators!");
1245 return Ptr != RHS.Ptr;
1249 assert(isHandleInSync() &&
"invalid iterator access!");
1250 if (shouldReverseIterate<KeyT>()) {
1252 RetreatPastEmptyBuckets();
1256 AdvancePastEmptyBuckets();
1260 assert(isHandleInSync() &&
"invalid iterator access!");
1265 void AdvancePastEmptyBuckets() {
1267 const KeyT
Empty = KeyInfoT::getEmptyKey();
1268 const KeyT Tombstone = KeyInfoT::getTombstoneKey();
1275 void RetreatPastEmptyBuckets() {
1277 const KeyT
Empty = KeyInfoT::getEmptyKey();
1278 const KeyT Tombstone = KeyInfoT::getTombstoneKey();
1286 template <
typename KeyT,
typename ValueT,
typename KeyInfoT>
1293 #endif // LLVM_ADT_DENSEMAP_H
unsigned Log2_32_Ceil(uint32_t Value)
Return the ceil log base 2 of the specified value, 32 if the value is zero.
const_iterator end(StringRef path)
Get end iterator over path.
DenseMapPair(KeyT &&Key, ValueT &&Value)
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
ValueT & operator[](const KeyT &Key)
void copyFrom(const DenseMap &other)
void moveFromOldBuckets(BucketT *OldBucketsBegin, BucketT *OldBucketsEnd)
GCNRegPressure max(const GCNRegPressure &P1, const GCNRegPressure &P2)
const KeyT & getFirst() const
This class represents lattice values for constants.
void init(unsigned InitNumEntries)
typename std::conditional< IsConst, const Bucket, Bucket >::type value_type
DenseMapPair(const KeyT &Key, const ValueT &Value)
void init(unsigned InitBuckets)
static const KeyT getTombstoneKey()
const void * getPointerIntoBucketsArray() const
getPointerIntoBucketsArray() - Return an opaque pointer into the buckets array.
block Block Frequency true
bool operator!=(const DenseSetImpl< ValueT, MapTy, ValueInfoT > &LHS, const DenseSetImpl< ValueT, MapTy, ValueInfoT > &RHS)
Inequality comparison for DenseSet.
const_iterator end() const
#define LLVM_UNLIKELY(EXPR)
DenseMap(unsigned InitialReserve=0)
Create a DenseMap wth an optional InitialReserve that guarantee that this number of elements can be i...
std::pair< iterator, bool > insert(const std::pair< KeyT, ValueT > &KV)
#define LLVM_NODISCARD
LLVM_NODISCARD - Warn if a type or return value is discarded.
reference operator*() const
A base class for data structure classes wishing to make iterators ("handles") pointing into themselve...
size_t capacity_in_bytes(const BitVector &X)
static unsigned getMinBucketToReserveForEntries(unsigned NumEntries)
Returns the number of buckets to allocate to ensure that the DenseMap can accommodate NumEntries with...
static int Lookup(ArrayRef< TableEntry > Table, unsigned Opcode)
void incrementEpoch()
Calling incrementEpoch invalidates all handles pointing into the calling instance.
DenseMapPair(AltPairT &&AltPair, typename std::enable_if< std::is_convertible< AltPairT, std::pair< KeyT, ValueT >>::value >::type *=0)
SmallDenseMap(SmallDenseMap &&other)
A base class for iterator classes ("handles") that wish to poll for iterator invalidating modificatio...
static bool isEqual(const Function &Caller, const Function &Callee)
unsigned getMinBucketToReserveForEntries(unsigned NumEntries)
Returns the number of buckets to allocate to ensure that the DenseMap can accommodate NumEntries with...
static const KeyT getEmptyKey()
void copyFrom(const DenseMapBase< OtherBaseT, KeyT, ValueT, KeyInfoT, BucketT > &other)
std::pair< iterator, bool > try_emplace(const KeyT &Key, Ts &&... Args)
SmallDenseMap(unsigned NumInitBuckets=0)
bool operator==(const DenseSetImpl< ValueT, MapTy, ValueInfoT > &LHS, const DenseSetImpl< ValueT, MapTy, ValueInfoT > &RHS)
Equality comparison for DenseSet.
void grow(unsigned AtLeast)
value_type & FindAndConstruct(const KeyT &Key)
iterator find(const_arg_type_t< KeyT > Val)
std::forward_iterator_tag iterator_category
initializer< Ty > init(const Ty &Val)
bool erase(const KeyT &Val)
const ValueT & getSecond() const
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
DenseMap(DenseMap &&other)
SmallDenseMap(const SmallDenseMap &other)
static unsigned getHashValue(const LookupKeyT &Val)
static GCRegistry::Add< CoreCLRGC > E("coreclr", "CoreCLR-compatible GC")
void grow(unsigned AtLeast)
constexpr bool isPowerOf2_64(uint64_t Value)
Return true if the argument is a power of two > 0 (64 bit edition.)
const void * getEpochAddress() const
Returns a pointer to the epoch word stored in the data structure this handle points into...
DenseMap(const DenseMap &other)
const_iterator begin() const
void reserve(size_type NumEntries)
Grow the densemap so that it can contain at least NumEntries items before resizing again...
llvm::AlignedCharArray< alignof(llvm::detail::AlignerImpl< T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >), sizeof(::llvm::detail::SizerImpl< T1, T2, T3, T4, T5, T6, T7, T8, T9, T10 >)>::buffer char buffer[Size]
DenseMapPair(AltKeyT &&AltKey, AltValueT &&AltValue, typename std::enable_if< std::is_convertible< AltKeyT, KeyT >::value &&std::is_convertible< AltValueT, ValueT >::value >::type *=0)
uint64_t NextPowerOf2(uint64_t A)
Returns the next power of two (in 64-bits) that is strictly greater than A.
void insert(InputIt I, InputIt E)
insert - Range insertion of pairs.
std::pair< iterator, bool > try_emplace(KeyT &&Key, Ts &&... Args)
SmallDenseMap & operator=(const SmallDenseMap &other)
constexpr bool empty(const T &RangeOrContainer)
Test whether RangeOrContainer is empty. Similar to C++17 std::empty.
bool operator==(const ConstIterator &RHS) const
size_t getMemorySize() const
Return the approximate size (in bytes) of the actual map.
isPodLike - This is a type trait that is used to determine whether a given type can be copied around ...
DenseMapIterator operator++(int)
auto size(R &&Range, typename std::enable_if< std::is_same< typename std::iterator_traits< decltype(Range.begin())>::iterator_category, std::random_access_iterator_tag >::value, void >::type *=nullptr) -> decltype(std::distance(Range.begin(), Range.end()))
Get the size of a range.
void swap(SmallDenseMap &RHS)
DenseMap & operator=(const DenseMap &other)
bool isPointerIntoBucketsArray(const void *Ptr) const
isPointerIntoBucketsArray - Return true if the specified pointer points somewhere into the DenseMap's...
const_iterator find(const_arg_type_t< KeyT > Val) const
void swap(llvm::BitVector &LHS, llvm::BitVector &RHS)
Implement std::swap in terms of BitVector swap.
SmallDenseMap & operator=(SmallDenseMap &&other)
void copyFrom(const SmallDenseMap &other)
DenseMapIterator & operator++()
ValueT & operator[](KeyT &&Key)
bool isHandleInSync() const
Returns true if the DebugEpochBase this Handle is linked to has not called incrementEpoch on itself s...
DenseMap(std::initializer_list< typename BaseT::value_type > Vals)
This class represents an analyzed expression in the program.
bool operator!=(const ConstIterator &RHS) const
constexpr char IsConst[]
Key for Kernel::Arg::Metadata::mIsConst.
std::pair< iterator, bool > insert(std::pair< KeyT, ValueT > &&KV)
size_type count(const_arg_type_t< KeyT > Val) const
Return 1 if the specified key is in the map, 0 otherwise.
LLVM_NODISCARD bool empty() const
ValueT lookup(const_arg_type_t< KeyT > Val) const
lookup - Return the entry for the specified key, or a default constructed value if no such entry exis...
iterator find_as(const LookupKeyT &Val)
Alternate version of find() which allows a different, and possibly less expensive, key type.
value_type & FindAndConstruct(KeyT &&Key)
SmallDenseMap(const InputIt &I, const InputIt &E)
assert(ImpDefSCC.getReg()==AMDGPU::SCC &&ImpDefSCC.isDef())
DenseMap(const InputIt &I, const InputIt &E)
LLVM Value Representation.
DenseMapIterator(const DenseMapIterator< KeyT, ValueT, KeyInfoT, Bucket, IsConstSrc > &I)
#define LLVM_LIKELY(EXPR)
DenseMap & operator=(DenseMap &&other)
pointer operator->() const
DenseMapIterator(pointer Pos, pointer E, const DebugEpochBase &Epoch, bool NoAdvance=false)
std::pair< iterator, bool > insert_as(std::pair< KeyT, ValueT > &&KV, const LookupKeyT &Val)
Alternate version of insert() which allows a different, and possibly less expensive, key type.
constexpr char Args[]
Key for Kernel::Metadata::mArgs.
static unsigned getHashValue(const KeyT &Val)
const_iterator find_as(const LookupKeyT &Val) const