[Mlir-commits] [lld] [llvm] [mlir] [ADT] Tweak SmallSetVector to use SmallPtrSet (PR #231880)
Ramkumar Ramachandra
llvmlistbot at llvm.org
Wed Oct 14 10:57:41 PDT 2026
https://github.com/artagnon updated https://github.com/llvm/llvm-project/pull/231880
>From 408106576159d499dd0c850d073d13b7e722537c 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] [ADT] Tweak SmallSetVector to use SmallPtrSet
SmallPtrSet is more efficient than DenseSet, and can be used when
template type is of pointer type. While at it, tighten construction
checks to keep the usage idiomatic. 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 | 17 +++++++++++++++--
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, 28 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..fd64834e57ebed 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>
@@ -339,12 +340,24 @@ class SetVector {
vector_type vector_; ///< The vector.
};
+/// This set is only used when SmallSetVector grows large enough that linear
+/// scanning would be unprofitable. If we have a pointer, use SmallPtrSet, and
+/// fall back to a DenseSet, but don't inline any elements.
+template <typename T>
+using ConditionalSet =
+ std::conditional_t<std::is_pointer_v<T>, SmallPtrSet<T, 0>, DenseSet<T>>;
+
/// 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>, ConditionalSet<T>, 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>, ConditionalSet<T>,
+ 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;
More information about the Mlir-commits
mailing list