[llvm] [ADT] Move the core logic of swapping to DenseMapBase::swap (NFC) (PR #168486)
Kazu Hirata via llvm-commits
llvm-commits at lists.llvm.org
Tue Nov 18 09:10:43 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();
----------------
kazutakahirata wrote:
The call to `deallocateBuckets` inside `kill` is a no-op here because this path is used in the small mode.
If `RHS` is in the large mode, we take the fast path:
```
if (derived().maybeMoveFast(std::move(RHS)))
return;
```
If `RHS` is in the small mode, we take the slow path ending with `kill()`.
`kill()` here puts `RHS` in a known good state that is safe for destruction. Without `kill()`, `RHS` would remain a move-from object, and that's not safe for destruction, which involves `destroyAll`.
https://github.com/llvm/llvm-project/pull/168486
More information about the llvm-commits
mailing list