Skip to content

Commit e983077

Browse files
kazutakahiratagithub-actions[bot]
authored andcommitted
Automerge: [ADT] Move shrink_and_clear to DenseMapBase (NFC) (#165103)
Without this patch, DenseMap and SmallDenseMap have distinct implementations of shrink_and_clear. These implementations mix a common high-level algorithm with class-specific logic. This patch moves the common algorithm into DenseMapBase::shrink_and_clear. A new private helper, planShrinkAndClear, now handles the class-specific logic for deciding whether to shrink the buffer. The base class method now serves as the single public entry point.
2 parents ce11f36 + 9458ecd commit e983077

File tree

1 file changed

+40
-42
lines changed

1 file changed

+40
-42
lines changed

llvm/include/llvm/ADT/DenseMap.h

Lines changed: 40 additions & 42 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,17 @@ class DenseMapBase : public DebugEpochBase {
154154
setNumTombstones(0);
155155
}
156156

157+
void shrink_and_clear() {
158+
auto [Reallocate, NewNumBuckets] = derived().planShrinkAndClear();
159+
destroyAll();
160+
if (!Reallocate) {
161+
initEmpty();
162+
return;
163+
}
164+
derived().deallocateBuckets();
165+
derived().init(NewNumBuckets);
166+
}
167+
157168
/// Return true if the specified key is in the map, false otherwise.
158169
[[nodiscard]] bool contains(const_arg_type_t<KeyT> Val) const {
159170
return doFind(Val) != nullptr;
@@ -529,8 +540,6 @@ class DenseMapBase : public DebugEpochBase {
529540

530541
void grow(unsigned AtLeast) { derived().grow(AtLeast); }
531542

532-
void shrink_and_clear() { derived().shrink_and_clear(); }
533-
534543
template <typename LookupKeyT>
535544
BucketT *findBucketForInsertion(const LookupKeyT &Lookup,
536545
BucketT *TheBucket) {
@@ -770,25 +779,6 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
770779
return *this;
771780
}
772781

773-
void shrink_and_clear() {
774-
unsigned OldNumBuckets = NumBuckets;
775-
unsigned OldNumEntries = NumEntries;
776-
this->destroyAll();
777-
778-
// Reduce the number of buckets.
779-
unsigned NewNumBuckets = 0;
780-
if (OldNumEntries)
781-
NewNumBuckets = std::max(64, 1 << (Log2_32_Ceil(OldNumEntries) + 1));
782-
if (NewNumBuckets == NumBuckets) {
783-
this->BaseT::initEmpty();
784-
return;
785-
}
786-
787-
deallocate_buffer(Buckets, sizeof(BucketT) * OldNumBuckets,
788-
alignof(BucketT));
789-
init(NewNumBuckets);
790-
}
791-
792782
private:
793783
unsigned getNumEntries() const { return NumEntries; }
794784

@@ -847,6 +837,18 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
847837
deallocate_buffer(OldBuckets, sizeof(BucketT) * OldNumBuckets,
848838
alignof(BucketT));
849839
}
840+
841+
// Plan how to shrink the bucket table. Return:
842+
// - {false, 0} to reuse the existing bucket table
843+
// - {true, N} to reallocate a bucket table with N entries
844+
std::pair<bool, unsigned> planShrinkAndClear() const {
845+
unsigned NewNumBuckets = 0;
846+
if (NumEntries)
847+
NewNumBuckets = std::max(64u, 1u << (Log2_32_Ceil(NumEntries) + 1));
848+
if (NewNumBuckets == NumBuckets)
849+
return {false, 0}; // Reuse.
850+
return {true, NewNumBuckets}; // Reallocate.
851+
}
850852
};
851853

852854
template <typename KeyT, typename ValueT, unsigned InlineBuckets = 4,
@@ -999,27 +1001,6 @@ class SmallDenseMap
9991001
return *this;
10001002
}
10011003

1002-
void shrink_and_clear() {
1003-
unsigned OldSize = this->size();
1004-
this->destroyAll();
1005-
1006-
// Reduce the number of buckets.
1007-
unsigned NewNumBuckets = 0;
1008-
if (OldSize) {
1009-
NewNumBuckets = 1 << (Log2_32_Ceil(OldSize) + 1);
1010-
if (NewNumBuckets > InlineBuckets && NewNumBuckets < 64u)
1011-
NewNumBuckets = 64;
1012-
}
1013-
if ((Small && NewNumBuckets <= InlineBuckets) ||
1014-
(!Small && NewNumBuckets == getLargeRep()->NumBuckets)) {
1015-
this->BaseT::initEmpty();
1016-
return;
1017-
}
1018-
1019-
deallocateBuckets();
1020-
init(NewNumBuckets);
1021-
}
1022-
10231004
private:
10241005
unsigned getNumEntries() const { return NumEntries; }
10251006

@@ -1148,6 +1129,23 @@ class SmallDenseMap
11481129
deallocate_buffer(OldRep.Buckets, sizeof(BucketT) * OldRep.NumBuckets,
11491130
alignof(BucketT));
11501131
}
1132+
1133+
// Plan how to shrink the bucket table. Return:
1134+
// - {false, 0} to reuse the existing bucket table
1135+
// - {true, N} to reallocate a bucket table with N entries
1136+
std::pair<bool, unsigned> planShrinkAndClear() const {
1137+
unsigned NewNumBuckets = 0;
1138+
if (!this->empty()) {
1139+
NewNumBuckets = 1u << (Log2_32_Ceil(this->size()) + 1);
1140+
if (NewNumBuckets > InlineBuckets)
1141+
NewNumBuckets = std::max(64u, NewNumBuckets);
1142+
}
1143+
bool Reuse = Small ? NewNumBuckets <= InlineBuckets
1144+
: NewNumBuckets == getLargeRep()->NumBuckets;
1145+
if (Reuse)
1146+
return {false, 0}; // Reuse.
1147+
return {true, NewNumBuckets}; // Reallocate.
1148+
}
11511149
};
11521150

11531151
template <typename KeyT, typename ValueT, typename KeyInfoT, typename Bucket,

0 commit comments

Comments
 (0)