[Mlir-commits] [lld] [llvm] [mlir] [ADT] Tweak SmallSetVector to use SmallPtrSet (PR #231880)

Ramkumar Ramachandra llvmlistbot at llvm.org
Wed Oct 14 09:55:16 PDT 2026


https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/231880

>From bd16011c7826168a8aadc77a0867a8854b17545b Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Wed, 14 Oct 2026 11:21:44 +0100
Subject: [PATCH 1/3] [ADT] Tweak SmallSetVector to use SmallPtrSet

SmallPtrSet is more efficient than SmallDenseSet, and can be used in a
SmallSetVector when template type is of pointer type. The patch has
necessitated fixing a constness issue in SmallPtrSet.

This helps compile time.
---
 lld/ELF/Driver.cpp                               |  4 ++--
 llvm/include/llvm/ADT/SetVector.h                | 16 ++++++++++++++--
 llvm/include/llvm/ADT/SmallPtrSet.h              |  4 ++--
 .../mlir/Dialect/OpenACC/Transforms/Passes.h     |  2 +-
 .../SCF/Transforms/ParallelLoopFusion.cpp        |  2 +-
 offload/plugins-nextgen/common/include/RPC.h     |  6 +++---
 offload/plugins-nextgen/common/src/RPC.cpp       |  8 ++++----
 7 files changed, 27 insertions(+), 15 deletions(-)

diff --git a/lld/ELF/Driver.cpp b/lld/ELF/Driver.cpp
index 134aae9ef98ad5..65c527c3026222 100644
--- a/lld/ELF/Driver.cpp
+++ b/lld/ELF/Driver.cpp
@@ -1121,7 +1121,7 @@ template <class ELFT>
 static void ltoValidateAllVtablesHaveTypeInfos(Ctx &ctx,
                                                opt::InputArgList &args) {
   DenseSet<StringRef> typeInfoSymbols;
-  SmallSetVector<StringRef, 0> vtableSymbols;
+  SetVector<StringRef> vtableSymbols;
   auto processVtableAndTypeInfoSymbols = [&](StringRef name) {
     if (name.consume_front("_ZTI"))
       typeInfoSymbols.insert(name);
@@ -1150,7 +1150,7 @@ static void ltoValidateAllVtablesHaveTypeInfos(Ctx &ctx,
     }
   }
 
-  SmallSetVector<StringRef, 0> vtableSymbolsWithNoRTTI;
+  SetVector<StringRef> vtableSymbolsWithNoRTTI;
   for (StringRef s : vtableSymbols)
     if (!typeInfoSymbols.contains(s))
       vtableSymbolsWithNoRTTI.insert(s);
diff --git a/llvm/include/llvm/ADT/SetVector.h b/llvm/include/llvm/ADT/SetVector.h
index bc0ac2583327b3..cb3eb8360d9d39 100644
--- a/llvm/include/llvm/ADT/SetVector.h
+++ b/llvm/include/llvm/ADT/SetVector.h
@@ -25,6 +25,7 @@
 #include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/STLExtras.h"
 #include "llvm/ADT/STLForwardCompat.h"
+#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
 #include "llvm/Support/Compiler.h"
 #include <cassert>
@@ -342,9 +343,20 @@ class SetVector {
 /// A SetVector that performs no allocations if smaller than
 /// a certain size.
 template <typename T, unsigned N>
-class SmallSetVector : public SetVector<T, SmallVector<T, N>, DenseSet<T>, N> {
+class SmallSetVector
+    : public SetVector<
+          T, SmallVector<T, N>,
+          std::conditional_t<std::is_pointer_v<T>, SmallPtrSet<T, N>,
+                             SmallDenseSet<T, N>>,
+          N> {
+  static_assert(isPowerOf2_64(N) &&
+                "SmallSetVector is meant to be used with pow-of-2 size-hint");
+
 public:
-  using SetVector<T, SmallVector<T, N>, DenseSet<T>, N>::SetVector;
+  using SetVector<T, SmallVector<T, N>,
+                  std::conditional_t<std::is_pointer_v<T>, SmallPtrSet<T, N>,
+                                     SmallDenseSet<T, N>>,
+                  N>::SetVector;
 };
 
 } // end namespace llvm
diff --git a/llvm/include/llvm/ADT/SmallPtrSet.h b/llvm/include/llvm/ADT/SmallPtrSet.h
index 1a556d6a4145a2..1c59d06977326b 100644
--- a/llvm/include/llvm/ADT/SmallPtrSet.h
+++ b/llvm/include/llvm/ADT/SmallPtrSet.h
@@ -385,8 +385,8 @@ template <typename PtrType> class SmallPtrSetImpl : public SmallPtrSetImplBase {
   /// Returns whether the pointer was in the set. Invalidates iterators if
   /// true is returned. To remove elements while iterating over the set, use
   /// remove_if() instead.
-  bool erase(PtrType Ptr) {
-    return erase_imp(PtrTraits::getAsVoidPointer(Ptr));
+  bool erase(ConstPtrType Ptr) {
+    return erase_imp(ConstPtrTraits::getAsVoidPointer(Ptr));
   }
 
   /// Remove elements that match the given predicate.
diff --git a/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.h b/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.h
index 4751da91c60909..9cdb91a7d7befb 100644
--- a/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.h
+++ b/mlir/include/mlir/Dialect/OpenACC/Transforms/Passes.h
@@ -30,7 +30,7 @@ class OpenACCSupport;
 #include "mlir/Dialect/OpenACC/Transforms/Passes.h.inc"
 
 /// Holds information for which integers represent a device type in the runtime.
-using TypesForDevice = llvm::SmallSetVector<int64_t, 3>;
+using TypesForDevice = llvm::SmallSetVector<int64_t, 4>;
 
 //===----------------------------------------------------------------------===//
 // ACCSpecializeForDevice patterns
diff --git a/mlir/lib/Dialect/SCF/Transforms/ParallelLoopFusion.cpp b/mlir/lib/Dialect/SCF/Transforms/ParallelLoopFusion.cpp
index 17352933acc295..8c63ad3a25cbb9 100644
--- a/mlir/lib/Dialect/SCF/Transforms/ParallelLoopFusion.cpp
+++ b/mlir/lib/Dialect/SCF/Transforms/ParallelLoopFusion.cpp
@@ -839,7 +839,7 @@ computeCandidateInterchangePermutations(ParallelOp &firstPloop,
 
   SmallVector<LoopIV> firstIVs(firstPloop.getNumLoops());
   SmallVector<LoopIV> secondIVs(secondPloop.getNumLoops());
-  llvm::SmallSetVector<LoopIV, 6> unique;
+  llvm::SmallSetVector<LoopIV, 8> unique;
   for (unsigned index : llvm::seq(firstPloop.getNumLoops())) {
     firstIVs[index].lBound = firstPloop.getLowerBound()[index];
     firstIVs[index].uBound = firstPloop.getUpperBound()[index];
diff --git a/offload/plugins-nextgen/common/include/RPC.h b/offload/plugins-nextgen/common/include/RPC.h
index 3175d377705776..1769686f036b1f 100644
--- a/offload/plugins-nextgen/common/include/RPC.h
+++ b/offload/plugins-nextgen/common/include/RPC.h
@@ -90,7 +90,7 @@ struct RPCServerTy {
   std::mutex BufferMutex{};
 
   /// A list of callbacks the server will attempt to handle.
-  llvm::SmallSetVector<RPCServerCallbackTy, 0> Callbacks;
+  llvm::SetVector<RPCServerCallbackTy> Callbacks;
 
   /// A helper class for running the user thread that handles the RPC interface.
   /// Because we only need to check the RPC server while any kernels are
@@ -114,7 +114,7 @@ struct RPCServerTy {
     std::mutex &BufferMutex;
 
     /// A reference to the main server's callbacks.
-    llvm::SmallSetVector<RPCServerCallbackTy, 0> &Callbacks;
+    llvm::SetVector<RPCServerCallbackTy> &Callbacks;
 
     /// A reference to all the RPC interfaces that the server is handling.
     llvm::ArrayRef<void *> Buffers;
@@ -129,7 +129,7 @@ struct RPCServerTy {
     /// Initialize the worker thread to run in the background.
     ServerThread(void *Buffers[], plugin::GenericDeviceTy *Devices[],
                  size_t Length, std::mutex &BufferMutex,
-                 llvm::SmallSetVector<RPCServerCallbackTy, 0> &Callbacks)
+                 llvm::SetVector<RPCServerCallbackTy> &Callbacks)
         : Running(false), NumUsers(0), CV(), Mutex(), BufferMutex(BufferMutex),
           Callbacks(Callbacks), Buffers(Buffers, Length),
           Devices(Devices, Length), SleepFunction([]() {
diff --git a/offload/plugins-nextgen/common/src/RPC.cpp b/offload/plugins-nextgen/common/src/RPC.cpp
index ecb7cad412883a..c23b6dfe4710a0 100644
--- a/offload/plugins-nextgen/common/src/RPC.cpp
+++ b/offload/plugins-nextgen/common/src/RPC.cpp
@@ -85,7 +85,7 @@ static rpc::RPCStatus handleOffloadOpcodes(plugin::GenericDeviceTy &Device,
 
 static rpc::RPCStatus
 runServer(plugin::GenericDeviceTy &Device, void *Buffer,
-          llvm::SmallSetVector<RPCServerTy::RPCServerCallbackTy, 0> &Callbacks,
+          llvm::SetVector<RPCServerTy::RPCServerCallbackTy> &Callbacks,
           bool &ClientInUse) {
   const uint64_t NumPorts =
       std::min(Device.requestedRPCPortCount(), rpc::MAX_PORT_COUNT);
@@ -114,9 +114,9 @@ runServer(plugin::GenericDeviceTy &Device, void *Buffer,
   return Status;
 }
 
-static void flushServer(
-    plugin::GenericDeviceTy &Device, void *Buffer,
-    llvm::SmallSetVector<RPCServerTy::RPCServerCallbackTy, 0> Callbacks) {
+static void
+flushServer(plugin::GenericDeviceTy &Device, void *Buffer,
+            llvm::SetVector<RPCServerTy::RPCServerCallbackTy> Callbacks) {
   bool Pending = true;
   while (Pending) {
     Pending = false;

>From bdf34952770852afd5d505e804ed120b0d112002 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Wed, 14 Oct 2026 17:50:25 +0100
Subject: [PATCH 2/3] [SetVector] Introduce ConditionalSmallSet

---
 llvm/include/llvm/ADT/SetVector.h | 16 ++++++++--------
 1 file changed, 8 insertions(+), 8 deletions(-)

diff --git a/llvm/include/llvm/ADT/SetVector.h b/llvm/include/llvm/ADT/SetVector.h
index cb3eb8360d9d39..68c9083c4a4c0c 100644
--- a/llvm/include/llvm/ADT/SetVector.h
+++ b/llvm/include/llvm/ADT/SetVector.h
@@ -340,22 +340,22 @@ class SetVector {
   vector_type vector_;   ///< The vector.
 };
 
+/// SmallPtrSet beats SmallDenseSet on small sizes.
+template <typename T, unsigned N>
+using ConditionalSmallSet =
+    std::conditional_t<std::is_pointer_v<T> && N <= 8, SmallPtrSet<T, N>,
+                       SmallDenseSet<T, N>>;
+
 /// A SetVector that performs no allocations if smaller than
 /// a certain size.
 template <typename T, unsigned N>
 class SmallSetVector
-    : public SetVector<
-          T, SmallVector<T, N>,
-          std::conditional_t<std::is_pointer_v<T>, SmallPtrSet<T, N>,
-                             SmallDenseSet<T, N>>,
-          N> {
+    : public SetVector<T, SmallVector<T, N>, ConditionalSmallSet<T, N>, N> {
   static_assert(isPowerOf2_64(N) &&
                 "SmallSetVector is meant to be used with pow-of-2 size-hint");
 
 public:
-  using SetVector<T, SmallVector<T, N>,
-                  std::conditional_t<std::is_pointer_v<T>, SmallPtrSet<T, N>,
-                                     SmallDenseSet<T, N>>,
+  using SetVector<T, SmallVector<T, N>, ConditionalSmallSet<T, N>,
                   N>::SetVector;
 };
 

>From 1a8c57f44f660a9ef57bf9b05c6a986b5313dae3 Mon Sep 17 00:00:00 2001
From: Ramkumar Ramachandra <artagnon at tenstorrent.com>
Date: Wed, 14 Oct 2026 17:54:29 +0100
Subject: [PATCH 3/3] [SetVector] Tweak threshold to 16

---
 llvm/include/llvm/ADT/SetVector.h | 2 +-
 1 file changed, 1 insertion(+), 1 deletion(-)

diff --git a/llvm/include/llvm/ADT/SetVector.h b/llvm/include/llvm/ADT/SetVector.h
index 68c9083c4a4c0c..459eef4e370a5c 100644
--- a/llvm/include/llvm/ADT/SetVector.h
+++ b/llvm/include/llvm/ADT/SetVector.h
@@ -343,7 +343,7 @@ class SetVector {
 /// SmallPtrSet beats SmallDenseSet on small sizes.
 template <typename T, unsigned N>
 using ConditionalSmallSet =
-    std::conditional_t<std::is_pointer_v<T> && N <= 8, SmallPtrSet<T, N>,
+    std::conditional_t<std::is_pointer_v<T> && N <= 16, SmallPtrSet<T, N>,
                        SmallDenseSet<T, N>>;
 
 /// A SetVector that performs no allocations if smaller than



More information about the Mlir-commits mailing list