[llvm] [mlir] [ADT] Reduce boilerplate in DenseSet (NFC) (PR #158456)

Kazu Hirata via llvm-commits llvm-commits at lists.llvm.org
Sat Sep 13 22:32:22 PDT 2025


https://github.com/kazutakahirata created https://github.com/llvm/llvm-project/pull/158456

The class definitions of DenseSet and SmallDenseSet contain a lot of
boilerplate code, repeating the lengthy base class name twice in each
definition.

This patch simplifies the two definitions by making them type aliases.
The patch adds an implicit default constructor.  Without the implicit
default constructor, the following wouldn't work:

  Index.exportToDot(OSDot, {});

One caveat is that with the type alias-based solution, forward
declarations like "class DenseSet;" are no longer valid. This patch
updates the forward declaration in MLIR.


>From fd0ccbb2d5e2d69d55761948c62fc9f7c687473a Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Sat, 6 Sep 2025 20:52:06 -0700
Subject: [PATCH] [ADT] Reduce boilerplate in DenseSet (NFC)

The class definitions of DenseSet and SmallDenseSet contain a lot of
boilerplate code, repeating the lengthy base class name twice in each
definition.

This patch simplifies the two definitions by making them type aliases.
The patch adds an implicit default constructor.  Without the implicit
default constructor, the following wouldn't work:

  Index.exportToDot(OSDot, {});

One caveat is that with the type alias-based solution, forward
declarations like "class DenseSet;" are no longer valid. This patch
updates the forward declaration in MLIR.
---
 llvm/include/llvm/ADT/DenseSet.h | 42 +++++++++-----------------------
 mlir/include/mlir/Support/LLVM.h | 15 +++++++++---
 2 files changed, 24 insertions(+), 33 deletions(-)

diff --git a/llvm/include/llvm/ADT/DenseSet.h b/llvm/include/llvm/ADT/DenseSet.h
index 281d4d1c78cc0..9668eb6640d1f 100644
--- a/llvm/include/llvm/ADT/DenseSet.h
+++ b/llvm/include/llvm/ADT/DenseSet.h
@@ -66,7 +66,8 @@ class DenseSetImpl {
   using value_type = ValueT;
   using size_type = unsigned;
 
-  explicit DenseSetImpl(unsigned InitialReserve = 0) : TheMap(InitialReserve) {}
+  DenseSetImpl() = default;
+  explicit DenseSetImpl(unsigned InitialReserve) : TheMap(InitialReserve) {}
 
   template <typename InputIt>
   DenseSetImpl(const InputIt &I, const InputIt &E)
@@ -254,40 +255,21 @@ bool operator!=(const DenseSetImpl<ValueT, MapTy, ValueInfoT> &LHS,
 
 /// Implements a dense probed hash-table based set.
 template <typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT>>
-class DenseSet : public detail::DenseSetImpl<
-                     ValueT,
-                     DenseMap<ValueT, detail::DenseSetEmpty, ValueInfoT,
-                              detail::DenseSetPair<ValueT>>,
-                     ValueInfoT> {
-  using BaseT =
-      detail::DenseSetImpl<ValueT,
-                           DenseMap<ValueT, detail::DenseSetEmpty, ValueInfoT,
-                                    detail::DenseSetPair<ValueT>>,
-                           ValueInfoT>;
-
-public:
-  using BaseT::BaseT;
-};
+using DenseSet =
+    detail::DenseSetImpl<ValueT,
+                         DenseMap<ValueT, detail::DenseSetEmpty, ValueInfoT,
+                                  detail::DenseSetPair<ValueT>>,
+                         ValueInfoT>;
 
 /// Implements a dense probed hash-table based set with some number of buckets
 /// stored inline.
 template <typename ValueT, unsigned InlineBuckets = 4,
           typename ValueInfoT = DenseMapInfo<ValueT>>
-class SmallDenseSet
-    : public detail::DenseSetImpl<
-          ValueT,
-          SmallDenseMap<ValueT, detail::DenseSetEmpty, InlineBuckets,
-                        ValueInfoT, detail::DenseSetPair<ValueT>>,
-          ValueInfoT> {
-  using BaseT = detail::DenseSetImpl<
-      ValueT,
-      SmallDenseMap<ValueT, detail::DenseSetEmpty, InlineBuckets, ValueInfoT,
-                    detail::DenseSetPair<ValueT>>,
-      ValueInfoT>;
-
-public:
-  using BaseT::BaseT;
-};
+using SmallDenseSet = detail::DenseSetImpl<
+    ValueT,
+    SmallDenseMap<ValueT, detail::DenseSetEmpty, InlineBuckets, ValueInfoT,
+                  detail::DenseSetPair<ValueT>>,
+    ValueInfoT>;
 
 } // end namespace llvm
 
diff --git a/mlir/include/mlir/Support/LLVM.h b/mlir/include/mlir/Support/LLVM.h
index 020c0fba726c8..8fd3b7c2f40f2 100644
--- a/mlir/include/mlir/Support/LLVM.h
+++ b/mlir/include/mlir/Support/LLVM.h
@@ -55,8 +55,13 @@ template <typename KeyT, typename ValueT, typename KeyInfoT, typename BucketT>
 class DenseMap;
 template <typename T, typename Enable>
 struct DenseMapInfo;
-template <typename ValueT, typename ValueInfoT>
-class DenseSet;
+namespace detail {
+template <typename ValueT, typename MapTy, typename ValueInfoT>
+class DenseSetImpl;
+struct DenseSetEmpty;
+template <typename KeyT>
+class DenseSetPair;
+} // namespace detail
 class MallocAllocator;
 template <typename T>
 class MutableArrayRef;
@@ -125,7 +130,11 @@ template <typename KeyT, typename ValueT,
           typename BucketT = llvm::detail::DenseMapPair<KeyT, ValueT>>
 using DenseMap = llvm::DenseMap<KeyT, ValueT, KeyInfoT, BucketT>;
 template <typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT>>
-using DenseSet = llvm::DenseSet<ValueT, ValueInfoT>;
+using DenseSet = llvm::detail::DenseSetImpl<
+    ValueT,
+    llvm::DenseMap<ValueT, llvm::detail::DenseSetEmpty, ValueInfoT,
+                   llvm::detail::DenseSetPair<ValueT>>,
+    ValueInfoT>;
 template <typename T, typename Vector = llvm::SmallVector<T, 0>,
           typename Set = DenseSet<T>, unsigned N = 0>
 using SetVector = llvm::SetVector<T, Vector, Set, N>;



More information about the llvm-commits mailing list