[llvm] [ADT] Share relocateBucket across DenseMap.h (NFC) (PR #227970)

via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 30 23:15:15 PDT 2026


llvmorg-github-actions[bot] wrote:


<!--LLVM PR SUMMARY COMMENT-->

@llvm/pr-subscribers-llvm-adt

Author: Kazu Hirata (kazutakahirata)

<details>
<summary>Changes</summary>

This patch moves relocateBucket from SmallDenseMapStorage into namespace
densemap::detail and uses it in DenseMapBase::moveFrom and
DenseMapBase::eraseFromFilledBucket as well.

Assisted-by: Antigravity


---
Full diff: https://github.com/llvm/llvm-project/pull/227970.diff


1 Files Affected:

- (modified) llvm/include/llvm/ADT/DenseMap.h (+12-22) 


``````````diff
diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
index 9c29fd8d0a906..c4f6602fbbb02 100644
--- a/llvm/include/llvm/ADT/DenseMap.h
+++ b/llvm/include/llvm/ADT/DenseMap.h
@@ -95,6 +95,16 @@ inline constexpr bool isRelocatableBucket =
     std::is_trivially_copy_constructible_v<BucketT> &&
     std::is_trivially_destructible_v<BucketT>;
 
+// Move-construct *Dst from *Src, then destroy *Src. Dst is raw storage.
+template <typename BucketT> void relocateBucket(BucketT *Dst, BucketT *Src) {
+  using KeyT = std::remove_reference_t<decltype(Dst->getFirst())>;
+  using ValueT = std::remove_reference_t<decltype(Dst->getSecond())>;
+  ::new (&Dst->getFirst()) KeyT(std::move(Src->getFirst()));
+  ::new (&Dst->getSecond()) ValueT(std::move(Src->getSecond()));
+  Src->getSecond().~ValueT();
+  Src->getFirst().~KeyT();
+}
+
 using UsedT = uint32_t;
 
 // Number of used words backing N buckets where N is zero or a power of two.
@@ -313,16 +323,6 @@ class SmallDenseMapStorage {
     LargeRep Large;
   } storage;
 
-  // Move-construct *Dst from *Src, then destroy *Src. Dst is raw storage.
-  static void relocateBucket(BucketT *Dst, BucketT *Src) {
-    using KeyT = std::remove_reference_t<decltype(Dst->getFirst())>;
-    using ValueT = std::remove_reference_t<decltype(Dst->getSecond())>;
-    ::new (&Dst->getFirst()) KeyT(std::move(Src->getFirst()));
-    ::new (&Dst->getSecond()) ValueT(std::move(Src->getSecond()));
-    Src->getSecond().~ValueT();
-    Src->getFirst().~KeyT();
-  }
-
   const BucketT *getInlineBuckets() const {
     assert(Small);
     // Note that this cast does not violate aliasing rules as we assert that
@@ -1132,14 +1132,8 @@ class DenseMapBase : public DebugEpochBase {
       unsigned BucketNo = KeyInfoT::getHashValue(OtherB[I].getFirst()) & Mask;
       while (llvm::densemap::detail::used(U, BucketNo))
         BucketNo = (BucketNo + 1) & Mask;
-      BucketT *DestBucket = B + BucketNo;
-      ::new (&DestBucket->getFirst()) KeyT(std::move(OtherB[I].getFirst()));
-      ::new (&DestBucket->getSecond()) ValueT(std::move(OtherB[I].getSecond()));
+      llvm::densemap::detail::relocateBucket(B + BucketNo, &OtherB[I]);
       llvm::densemap::detail::setUsed(U, BucketNo);
-
-      // Free the moved-out key/value.
-      OtherB[I].getSecond().~ValueT();
-      OtherB[I].getFirst().~KeyT();
     });
     setNumEntries(Other.getNumEntries());
     Other.Storage.kill();
@@ -1200,11 +1194,7 @@ class DenseMapBase : public DebugEpochBase {
       // If the hole (I) lies on the linear-probe chain from the home bucket
       // (Ideal) to J, shift J into the hole and make J the new hole.
       if (((I - Ideal) & Mask) < ((J - Ideal) & Mask)) {
-        BucketT &BI = BucketsPtr[I];
-        ::new (&BI.getFirst()) KeyT(std::move(BJ.getFirst()));
-        ::new (&BI.getSecond()) ValueT(std::move(BJ.getSecond()));
-        BJ.getSecond().~ValueT();
-        BJ.getFirst().~KeyT();
+        llvm::densemap::detail::relocateBucket(&BucketsPtr[I], &BJ);
         I = J;
       }
     }

``````````

</details>


https://github.com/llvm/llvm-project/pull/227970


More information about the llvm-commits mailing list