Skip to content

Commit f4ed01d

Browse files
committed
[DenseMap] Derive the used array instead of caching a pointer
The used array trails the bucket array in the shared allocation, so getUsed() computes Buckets + sizeof(BucketT)*NumBuckets instead of caching a pointer, dropping a word from every DenseMap (sizeof 24 -> 16 for a pointer key/value). The offset is aligned because NumBuckets is a power of two >= 64, asserted in allocateBuckets. Lookups are unaffected (the derived pointer folds away); insert costs a few extra instructions.
1 parent 99ed5a3 commit f4ed01d

1 file changed

Lines changed: 10 additions & 10 deletions

File tree

llvm/include/llvm/ADT/DenseMap.h

Lines changed: 10 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -838,7 +838,6 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
838838
using UsedT = llvm::densemap::detail::UsedT;
839839

840840
BucketT *Buckets = nullptr;
841-
UsedT *Used = nullptr;
842841
unsigned NumEntries = 0;
843842
unsigned NumBuckets = 0;
844843

@@ -891,7 +890,6 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
891890
private:
892891
void swapImpl(DenseMap &RHS) {
893892
std::swap(Buckets, RHS.Buckets);
894-
std::swap(Used, RHS.Used);
895893
std::swap(NumEntries, RHS.NumEntries);
896894
std::swap(NumBuckets, RHS.NumBuckets);
897895
}
@@ -902,9 +900,14 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
902900

903901
BucketT *getBuckets() const { return Buckets; }
904902

905-
typename BaseT::Rep getRep() const { return {Buckets, Used, NumBuckets}; }
903+
typename BaseT::Rep getRep() const {
904+
return {Buckets, getUsed(), NumBuckets};
905+
}
906906

907-
UsedT *getUsed() const { return Used; }
907+
UsedT *getUsed() const {
908+
return reinterpret_cast<UsedT *>(reinterpret_cast<char *>(Buckets) +
909+
sizeof(BucketT) * NumBuckets);
910+
}
908911

909912
unsigned getNumBuckets() const { return NumBuckets; }
910913

@@ -915,23 +918,20 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
915918
llvm::densemap::detail::allocBytes<BucketT>(NumBuckets),
916919
llvm::densemap::detail::allocAlign<BucketT>());
917920
Buckets = nullptr;
918-
Used = nullptr;
919921
NumBuckets = 0;
920922
}
921923

922924
bool allocateBuckets(unsigned Num) {
923925
NumBuckets = Num;
924926
if (NumBuckets == 0) {
925927
Buckets = nullptr;
926-
Used = nullptr;
927928
return false;
928929
}
929-
930-
auto *Storage = static_cast<char *>(
930+
assert(sizeof(BucketT) * NumBuckets % alignof(UsedT) == 0 &&
931+
"used array would be misaligned");
932+
Buckets = reinterpret_cast<BucketT *>(
931933
allocate_buffer(llvm::densemap::detail::allocBytes<BucketT>(NumBuckets),
932934
llvm::densemap::detail::allocAlign<BucketT>()));
933-
Buckets = reinterpret_cast<BucketT *>(Storage);
934-
Used = reinterpret_cast<UsedT *>(Storage + sizeof(BucketT) * NumBuckets);
935935
return true;
936936
}
937937

0 commit comments

Comments
 (0)