[llvm] [ADT] Share relocateBucket across DenseMap.h (NFC) (PR #227970)
Kazu Hirata via llvm-commits
llvm-commits at lists.llvm.org
Wed Sep 30 23:14:33 PDT 2026
https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/227970
This patch moves relocateBucket from SmallDenseMapStorage into namespace
densemap::detail and uses it in DenseMapBase::moveFrom and
DenseMapBase::eraseFromFilledBucket as well.
Assisted-by: Antigravity
>From 497e4b7ade37d58a1528477a1d4256da4280829d Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Mon, 28 Sep 2026 12:32:35 -0700
Subject: [PATCH] [ADT] Share relocateBucket across DenseMap.h (NFC)
This patch moves relocateBucket from SmallDenseMapStorage into namespace
densemap::detail and uses it in DenseMapBase::moveFrom and
DenseMapBase::eraseFromFilledBucket as well.
Assisted-by: Antigravity
---
llvm/include/llvm/ADT/DenseMap.h | 34 +++++++++++---------------------
1 file changed, 12 insertions(+), 22 deletions(-)
diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
index 9c29fd8d0a9066..c4f6602fbbb022 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;
}
}
More information about the llvm-commits
mailing list