[llvm] 9458ecd - [ADT] Move shrink_and_clear to DenseMapBase (NFC) (#165103)

via llvm-commits llvm-commits at lists.llvm.org
Sat Oct 25 10:05:54 PDT 2025


Author: Kazu Hirata
Date: 2025-10-25T10:05:51-07:00
New Revision: 9458ecd298a6d445ade80e750cbbfb89da0e0d5f

URL: https://github.com/llvm/llvm-project/commit/9458ecd298a6d445ade80e750cbbfb89da0e0d5f
DIFF: https://github.com/llvm/llvm-project/commit/9458ecd298a6d445ade80e750cbbfb89da0e0d5f.diff

LOG: [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.

Added: 
    

Modified: 
    llvm/include/llvm/ADT/DenseMap.h

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
index 6d60d89be1c0f..22ef7ed64451e 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;
@@ -529,8 +540,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) {
@@ -770,25 +779,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; }
 
@@ -847,6 +837,18 @@ class DenseMap : public DenseMapBase<DenseMap<KeyT, ValueT, KeyInfoT, BucketT>,
     deallocate_buffer(OldBuckets, sizeof(BucketT) * OldNumBuckets,
                       alignof(BucketT));
   }
+
+  // Plan how to shrink the bucket table.  Return:
+  // - {false, 0} to reuse the existing bucket table
+  // - {true, N} to reallocate a bucket table with N entries
+  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,
@@ -999,27 +1001,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; }
 
@@ -1148,6 +1129,23 @@ class SmallDenseMap
     deallocate_buffer(OldRep.Buckets, sizeof(BucketT) * OldRep.NumBuckets,
                       alignof(BucketT));
   }
+
+  // Plan how to shrink the bucket table.  Return:
+  // - {false, 0} to reuse the existing bucket table
+  // - {true, N} to reallocate a bucket table with N entries
+  std::pair<bool, unsigned> planShrinkAndClear() const {
+    unsigned NewNumBuckets = 0;
+    if (!this->empty()) {
+      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,


        


More information about the llvm-commits mailing list