[llvm] [ADT] Move the core logic of swapping to DenseMapBase::swap (NFC) (PR #168486)
Sergei Barannikov via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 18 03:24:52 PST 2025
================
@@ -424,6 +433,43 @@ class DenseMapBase : public DebugEpochBase {
return NextPowerOf2(NumEntries * 4 / 3 + 1);
}
+ // Move buckets without rehash.
+ //
+ // Preconditions:
+ // - *this is killed.
+ // - RHS is valid.
+ //
+ // Post conditions:
+ // - *this is valid.
+ // - RHS is valid or killed (but not uninitialized).
+ void moveWithoutRehash(DerivedT &&RHS) {
+ if (derived().maybeMoveFast(std::move(RHS.derived())))
+ return;
+
+ derived().allocateBuckets(RHS.getNumBuckets());
+ setNumEntries(RHS.getNumEntries());
+ setNumTombstones(RHS.getNumTombstones());
+ DerivedT &LHS = derived();
+ iterator_range<BucketT *> LHSBuckets = LHS.buckets();
+ iterator_range<BucketT *> RHSBuckets = RHS.buckets();
+ assert(std::distance(LHSBuckets.begin(), LHSBuckets.end()) ==
+ std::distance(RHSBuckets.begin(), RHSBuckets.end()));
+ const KeyT EmptyKey = KeyInfoT::getEmptyKey();
+ const KeyT TombstoneKey = KeyInfoT::getTombstoneKey();
+ for (BucketT *L = LHSBuckets.begin(), *R = RHSBuckets.begin(),
+ *E = LHSBuckets.end();
+ L != E; ++L, ++R) {
+ ::new (&L->getFirst()) KeyT(std::move(R->getFirst()));
+ R->getFirst().~KeyT();
+ if (!KeyInfoT::isEqual(L->getFirst(), EmptyKey) &&
+ !KeyInfoT::isEqual(L->getFirst(), TombstoneKey)) {
+ ::new (&L->getSecond()) ValueT(std::move(R->getSecond()));
+ R->getSecond().~ValueT();
+ }
+ }
+ RHS.derived().kill();
----------------
s-barannikov wrote:
Doesn't kill have a side effect of deallocating buckets? That's not what was happening before this patch.
`RHS` is already `DerivedT`, no need for `derived()`.
https://github.com/llvm/llvm-project/pull/168486
More information about the llvm-commits
mailing list