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

Kazu Hirata via llvm-commits llvm-commits at lists.llvm.org
Sun Sep 14 09:14:30 PDT 2025


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

>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 1/2] [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>;

>From ba7eb1d7fe18755d27776cd77f554fa0155e06c1 Mon Sep 17 00:00:00 2001
From: Kazu Hirata <kazu at google.com>
Date: Sun, 14 Sep 2025 07:23:35 -0700
Subject: [PATCH 2/2] Address a comment.

---
 llvm/include/llvm/ADT/DenseSet.h | 38 ++++++++++++++++++++++----------
 mlir/include/mlir/Support/LLVM.h | 15 +++----------
 2 files changed, 29 insertions(+), 24 deletions(-)

diff --git a/llvm/include/llvm/ADT/DenseSet.h b/llvm/include/llvm/ADT/DenseSet.h
index 9668eb6640d1f..60ad9b2eb7762 100644
--- a/llvm/include/llvm/ADT/DenseSet.h
+++ b/llvm/include/llvm/ADT/DenseSet.h
@@ -66,8 +66,7 @@ class DenseSetImpl {
   using value_type = ValueT;
   using size_type = unsigned;
 
-  DenseSetImpl() = default;
-  explicit DenseSetImpl(unsigned InitialReserve) : TheMap(InitialReserve) {}
+  explicit DenseSetImpl(unsigned InitialReserve = 0) : TheMap(InitialReserve) {}
 
   template <typename InputIt>
   DenseSetImpl(const InputIt &I, const InputIt &E)
@@ -251,25 +250,40 @@ bool operator!=(const DenseSetImpl<ValueT, MapTy, ValueInfoT> &LHS,
   return !(LHS == RHS);
 }
 
+template <typename ValueT, typename ValueInfoT>
+using DenseSet = DenseSetImpl<
+    ValueT, DenseMap<ValueT, DenseSetEmpty, ValueInfoT, DenseSetPair<ValueT>>,
+    ValueInfoT>;
+
+template <typename ValueT, unsigned InlineBuckets, typename ValueInfoT>
+using SmallDenseSet =
+    DenseSetImpl<ValueT,
+                 SmallDenseMap<ValueT, DenseSetEmpty, InlineBuckets, ValueInfoT,
+                               DenseSetPair<ValueT>>,
+                 ValueInfoT>;
+
 } // end namespace detail
 
 /// Implements a dense probed hash-table based set.
 template <typename ValueT, typename ValueInfoT = DenseMapInfo<ValueT>>
-using DenseSet =
-    detail::DenseSetImpl<ValueT,
-                         DenseMap<ValueT, detail::DenseSetEmpty, ValueInfoT,
-                                  detail::DenseSetPair<ValueT>>,
-                         ValueInfoT>;
+class DenseSet : public detail::DenseSet<ValueT, ValueInfoT> {
+  using BaseT = detail::DenseSet<ValueT, ValueInfoT>;
+
+public:
+  using BaseT::BaseT;
+};
 
 /// 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>>
-using SmallDenseSet = detail::DenseSetImpl<
-    ValueT,
-    SmallDenseMap<ValueT, detail::DenseSetEmpty, InlineBuckets, ValueInfoT,
-                  detail::DenseSetPair<ValueT>>,
-    ValueInfoT>;
+class SmallDenseSet
+    : public detail::SmallDenseSet<ValueT, InlineBuckets, ValueInfoT> {
+  using BaseT = detail::SmallDenseSet<ValueT, InlineBuckets, ValueInfoT>;
+
+public:
+  using BaseT::BaseT;
+};
 
 } // end namespace llvm
 
diff --git a/mlir/include/mlir/Support/LLVM.h b/mlir/include/mlir/Support/LLVM.h
index 8fd3b7c2f40f2..020c0fba726c8 100644
--- a/mlir/include/mlir/Support/LLVM.h
+++ b/mlir/include/mlir/Support/LLVM.h
@@ -55,13 +55,8 @@ template <typename KeyT, typename ValueT, typename KeyInfoT, typename BucketT>
 class DenseMap;
 template <typename T, typename Enable>
 struct DenseMapInfo;
-namespace detail {
-template <typename ValueT, typename MapTy, typename ValueInfoT>
-class DenseSetImpl;
-struct DenseSetEmpty;
-template <typename KeyT>
-class DenseSetPair;
-} // namespace detail
+template <typename ValueT, typename ValueInfoT>
+class DenseSet;
 class MallocAllocator;
 template <typename T>
 class MutableArrayRef;
@@ -130,11 +125,7 @@ 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::detail::DenseSetImpl<
-    ValueT,
-    llvm::DenseMap<ValueT, llvm::detail::DenseSetEmpty, ValueInfoT,
-                   llvm::detail::DenseSetPair<ValueT>>,
-    ValueInfoT>;
+using DenseSet = llvm::DenseSet<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