[llvm] [ADT] Move shrink_and_clear to DenseMapBase (NFC) (PR #165103)
via llvm-commits
llvm-commits at lists.llvm.org
Sat Oct 25 07:55:35 PDT 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-llvm-adt
Author: Kazu Hirata (kazutakahirata)
<details>
<summary>Changes</summary>
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.
---
Full diff: https://github.com/llvm/llvm-project/pull/165103.diff
1 Files Affected:
- (modified) llvm/include/llvm/ADT/DenseMap.h (+34-42)
``````````diff
diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
index baa91f3a5f533..b2e8224a83fa8 100644
--- a/llvm/include/llvm/ADT/DenseMap.h
+++ b/llvm/include/llvm/ADT/DenseMap.h
@@ -154,6 +154,17 @@ class DenseMapBase : public DebugEpochBase {
setNumTombstones(0);
}
+ void shrink_and_clear() {
+ auto [Reallocate, NewNumBuckets] = derived().planShrinkAndClear();
+ destroyAll();
+ if (!Reallocate) {
+ initEmpty();
+ return;
+ }
+ derived().deallocateBuckets();
+ derived().init(NewNumBuckets);
+ }
+
/// Return true if the specified key is in the map, false otherwise.
[[nodiscard]] bool contains(const_arg_type_t<KeyT> Val) const {
return doFind(Val) != nullptr;
@@ -532,8 +543,6 @@ class DenseMapBase : public DebugEpochBase {
void grow(unsigned AtLeast) { derived().grow(AtLeast); }
- void shrink_and_clear() { derived().shrink_and_clear(); }
-
template <typename LookupKeyT>
BucketT *findBucketForInsertion(const LookupKeyT &Lookup,
BucketT *TheBucket) {
@@ -773,25 +782,6 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
return *this;
}
- void shrink_and_clear() {
- unsigned OldNumBuckets = NumBuckets;
- unsigned OldNumEntries = NumEntries;
- this->destroyAll();
-
- // Reduce the number of buckets.
- unsigned NewNumBuckets = 0;
- if (OldNumEntries)
- NewNumBuckets = std::max(64, 1 << (Log2_32_Ceil(OldNumEntries) + 1));
- if (NewNumBuckets == NumBuckets) {
- this->BaseT::initEmpty();
- return;
- }
-
- deallocate_buffer(Buckets, sizeof(BucketT) * OldNumBuckets,
- alignof(BucketT));
- init(NewNumBuckets);
- }
-
private:
unsigned getNumEntries() const { return NumEntries; }
@@ -861,6 +851,15 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
deallocate_buffer(OldBuckets, sizeof(BucketT) * OldNumBuckets,
alignof(BucketT));
}
+
+ std::pair<bool, unsigned> planShrinkAndClear() const {
+ unsigned NewNumBuckets = 0;
+ if (NumEntries)
+ NewNumBuckets = std::max(64u, 1u << (Log2_32_Ceil(NumEntries) + 1));
+ if (NewNumBuckets == NumBuckets)
+ return {false, 0}; // Reuse
+ return {true, NewNumBuckets}; // Reallocate
+ }
};
template <typename KeyT, typename ValueT, unsigned InlineBuckets = 4,
@@ -1013,27 +1012,6 @@ class SmallDenseMap
return *this;
}
- void shrink_and_clear() {
- unsigned OldSize = this->size();
- this->destroyAll();
-
- // Reduce the number of buckets.
- unsigned NewNumBuckets = 0;
- if (OldSize) {
- NewNumBuckets = 1 << (Log2_32_Ceil(OldSize) + 1);
- if (NewNumBuckets > InlineBuckets && NewNumBuckets < 64u)
- NewNumBuckets = 64;
- }
- if ((Small && NewNumBuckets <= InlineBuckets) ||
- (!Small && NewNumBuckets == getLargeRep()->NumBuckets)) {
- this->BaseT::initEmpty();
- return;
- }
-
- deallocateBuckets();
- init(NewNumBuckets);
- }
-
private:
unsigned getNumEntries() const { return NumEntries; }
@@ -1168,6 +1146,20 @@ class SmallDenseMap
deallocate_buffer(OldRep.Buckets, sizeof(BucketT) * OldRep.NumBuckets,
alignof(BucketT));
}
+
+ std::pair<bool, unsigned> planShrinkAndClear() const {
+ unsigned NewNumBuckets = 0;
+ if (this->size()) {
+ NewNumBuckets = 1u << (Log2_32_Ceil(this->size()) + 1);
+ if (NewNumBuckets > InlineBuckets)
+ NewNumBuckets = std::max(64u, NewNumBuckets);
+ }
+ bool Reuse = Small ? NewNumBuckets <= InlineBuckets
+ : NewNumBuckets == getLargeRep()->NumBuckets;
+ if (Reuse)
+ return {false, 0}; // Reuse
+ return {true, NewNumBuckets}; // Reallocate
+ }
};
template <typename KeyT, typename ValueT, typename KeyInfoT, typename Bucket,
``````````
</details>
https://github.com/llvm/llvm-project/pull/165103
More information about the llvm-commits
mailing list