[llvm] [DenseMap] memcpy buckets with trivial copy constructor and destructor. NFC (PR #224193)

Fangrui Song via llvm-commits llvm-commits at lists.llvm.org
Wed Sep 16 22:55:59 PDT 2026


https://github.com/MaskRay updated https://github.com/llvm/llvm-project/pull/224193

>From 16a2e516d39b9bbba40fb32703642c4c5303bdab Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 16 Sep 2026 21:37:34 -0700
Subject: [PATCH 1/2] [DenseMap] memcpy buckets with trivial copy constructor
 and destructor. NFC

std::pair has a user-provided copy assignment operator, so
std::is_trivially_copyable is false. Define is weaker
isRelocatableBucket instead.

This optimizes some DenseMap instantiations within lld (e.g.
lld/ELF/SyntheticSections.cpp)
---
 llvm/include/llvm/ADT/DenseMap.h    | 9 ++++++++-
 llvm/unittests/ADT/DenseMapTest.cpp | 4 ++++
 2 files changed, 12 insertions(+), 1 deletion(-)

diff --git a/llvm/include/llvm/ADT/DenseMap.h b/llvm/include/llvm/ADT/DenseMap.h
index 0126935ca3598..56c56c489915e 100644
--- a/llvm/include/llvm/ADT/DenseMap.h
+++ b/llvm/include/llvm/ADT/DenseMap.h
@@ -88,6 +88,13 @@ template <typename KeyT, typename ValueT> struct DenseMapPair {
 } // end namespace detail
 
 namespace densemap::detail {
+// Relocating copy-constructs and runs no destructor, so it does not need
+// trivial assignment, which a std::pair value type lacks.
+template <typename BucketT>
+inline constexpr bool isRelocatableBucket =
+    std::is_trivially_copy_constructible_v<BucketT> &&
+    std::is_trivially_destructible_v<BucketT>;
+
 using UsedT = uint32_t;
 
 // Number of used words backing N buckets where N is zero or a power of two.
@@ -596,7 +603,7 @@ class DenseMapBase : public DebugEpochBase {
     const UsedT *OtherU = other.getUsed();
     std::memcpy(U, OtherU,
                 llvm::densemap::detail::usedWords(NumBuckets) * sizeof(UsedT));
-    if constexpr (std::is_trivially_copyable_v<BucketT>) {
+    if constexpr (densemap::detail::isRelocatableBucket<BucketT>) {
       memcpy(reinterpret_cast<void *>(Buckets), OtherBuckets,
              NumBuckets * sizeof(BucketT));
     } else {
diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp
index 9ff486cbc2cff..abdd9657fecd9 100644
--- a/llvm/unittests/ADT/DenseMapTest.cpp
+++ b/llvm/unittests/ADT/DenseMapTest.cpp
@@ -475,10 +475,14 @@ TEST(DenseMapCustomTest, EqualityComparison) {
 }
 
 using IntBucket = detail::DenseMapPair<int, int>;
+using PairKeyBucket = detail::DenseMapPair<std::pair<int, int>, int>;
 
 static_assert(std::is_trivially_copyable_v<IntBucket>);
 static_assert(!std::is_trivially_default_constructible_v<IntBucket>);
 
+static_assert(!std::is_trivially_copyable_v<PairKeyBucket>);
+static_assert(densemap::detail::isRelocatableBucket<PairKeyBucket>);
+
 // A bucket converts to a std::pair, so code naming the pair type keeps working.
 static_assert(std::is_convertible_v<IntBucket, std::pair<int, int>>);
 static_assert(std::is_convertible_v<IntBucket, std::pair<const int, int>>);

>From 5d26ef34030d631f9c436a1294cf6a41a8a98434 Mon Sep 17 00:00:00 2001
From: Fangrui Song <i at maskray.me>
Date: Wed, 16 Sep 2026 22:55:47 -0700
Subject: [PATCH 2/2] Update llvm/unittests/ADT/DenseMapTest.cpp

Co-authored-by: Kazu Hirata <kazu at google.com>
---
 llvm/unittests/ADT/DenseMapTest.cpp | 3 +++
 1 file changed, 3 insertions(+)

diff --git a/llvm/unittests/ADT/DenseMapTest.cpp b/llvm/unittests/ADT/DenseMapTest.cpp
index abdd9657fecd9..f593db284963e 100644
--- a/llvm/unittests/ADT/DenseMapTest.cpp
+++ b/llvm/unittests/ADT/DenseMapTest.cpp
@@ -476,6 +476,9 @@ TEST(DenseMapCustomTest, EqualityComparison) {
 
 using IntBucket = detail::DenseMapPair<int, int>;
 using PairKeyBucket = detail::DenseMapPair<std::pair<int, int>, int>;
+using PairValueBucket = detail::DenseMapPair<int, std::pair<int, int>>;
+using PairPairBucket =
+    detail::DenseMapPair<std::pair<int, int>, std::pair<int, int>>;
 
 static_assert(std::is_trivially_copyable_v<IntBucket>);
 static_assert(!std::is_trivially_default_constructible_v<IntBucket>);



More information about the llvm-commits mailing list