[llvm] [DenseMap] Share rehash and grow for relocatable bucket types. NFC (PR #225018)
Kazu Hirata via llvm-commits
llvm-commits at lists.llvm.org
Mon Sep 21 02:07:07 PDT 2026
kazutakahirata wrote:
Nice compile-time and binary-size wins!
Could we avoid the runtime `if (!Hasher)` and `switch (BucketSize)` in `DenseMap.cpp` by templating `growRelocatable` / `rehashRelocatable` (or a base class in the spirit of `SmallPtrSetImpl`) on `<FixedSize, InlinePtrHash>` and explicitly instantiating them in `DenseMap.cpp` for the 8 common sizes (`4, 8, 12, 16, 24, 32, 40, 48`)?
In `DenseMapBase::grow`, `if constexpr` already separates relocatable buckets from non-relocatable ones:
```cpp
if constexpr (isRelocatableBucket<BucketT> && isCommonBucketSize<sizeof(BucketT)>) {
// Calls growRelocatable<sizeof(BucketT), InlinePtrHash>(...) directly
derived().growShared(MinNumBuckets);
} else {
// Existing inline Tmp.moveFrom(...) path handles non-relocatable buckets
// and uncommon bucket sizes
...
}
```
- **No runtime `switch (BucketSize)` or `if (!Hasher)`**: Common relocatable buckets (95% of maps) jump directly to `growRelocatable<16, true>` at compile time without a runtime switch or jump table (avoiding the issue @aengelke noted).
- **Clean fallback**: Non-relocatable buckets and uncommon bucket sizes simply fall into the existing `else` branch (or uncommon relocatable sizes can map `FixedSize` to `0` at compile time and call `growRelocatable<0, InlinePtrHash>`).
- **Sharing beyond `grow`**: If we eventually move this into a `SmallPtrSetImpl`-style base class parameterized on `<BucketSize>` for pointer keys (`InlinePtrHash == true`), all 16-byte pointer-keyed maps (`DenseMap<Instruction *, unsigned>`, `DenseMap<BasicBlock *, int>`, `DenseMap<Value *, Value *>`, etc.) could also share `doFind`, `LookupBucketFor`, `findBucketForInsertion`, and `copyFrom` rather than instantiating them per `(KeyT, ValueT)` type.
https://github.com/llvm/llvm-project/pull/225018
More information about the llvm-commits
mailing list