[llvm] b7dc8e3 - [ADT] Simplify FoldingSetIterator (NFC) (#219073)

via llvm-commits llvm-commits at lists.llvm.org
Wed Aug 26 20:47:24 PDT 2026


Author: Kazu Hirata
Date: 2026-08-26T20:47:18-07:00
New Revision: b7dc8e356b89a57b86f1571d52675327db52c506

URL: https://github.com/llvm/llvm-project/commit/b7dc8e356b89a57b86f1571d52675327db52c506
DIFF: https://github.com/llvm/llvm-project/commit/b7dc8e356b89a57b86f1571d52675327db52c506.diff

LOG: [ADT] Simplify FoldingSetIterator (NFC) (#219073)

This patch simplifies FoldingSetIterator by defining it entirely in the
header without the type-erased FoldingSetIteratorImpl.

Now that FoldingSet uses an open-addressing hash table, we just have to
march through the entire bucket array while skipping empty slots.  It
does not make sense to call out-of-line advance().

This also reduces the .text section size of a release build of bin/clang
by 647 bytes (from 185,968,635 to 185,967,988 bytes).

Assisted-by: Antigravity

Added: 
    

Modified: 
    llvm/include/llvm/ADT/FoldingSet.h
    llvm/lib/Support/FoldingSet.cpp

Removed: 
    


################################################################################
diff  --git a/llvm/include/llvm/ADT/FoldingSet.h b/llvm/include/llvm/ADT/FoldingSet.h
index bc3e5bcc8ad3e..48c2467754074 100644
--- a/llvm/include/llvm/ADT/FoldingSet.h
+++ b/llvm/include/llvm/ADT/FoldingSet.h
@@ -378,8 +378,6 @@ class FoldingSetBase : public DebugEpochBase {
   static bool nodeEquals(const FoldingSetInfo &Info, const FoldingSetBase *Self,
                          Node *N, const FoldingSetNodeID &ID, unsigned IDHash);
 
-  friend class FoldingSetIteratorImpl;
-
   /// Rehash into at least \p MinNumBuckets buckets, rounded up to a power of
   /// two and floored at the constructor's minimum.
   void grow(unsigned MinNumBuckets);
@@ -502,13 +500,19 @@ class FoldingSetImpl : public FoldingSetBase, public Trait::ContextStorage {
 public:
   using iterator = FoldingSetIterator<T>;
 
-  iterator begin() { return iterator(this, 0); }
-  iterator end() { return iterator(this, NumBuckets); }
+  iterator begin() { return iterator(Buckets, Buckets + NumBuckets, this); }
+  iterator end() {
+    return iterator(Buckets + NumBuckets, Buckets + NumBuckets, this);
+  }
 
   using const_iterator = FoldingSetIterator<const T>;
 
-  const_iterator begin() const { return const_iterator(this, 0); }
-  const_iterator end() const { return const_iterator(this, NumBuckets); }
+  const_iterator begin() const {
+    return const_iterator(Buckets, Buckets + NumBuckets, this);
+  }
+  const_iterator end() const {
+    return const_iterator(Buckets + NumBuckets, Buckets + NumBuckets, this);
+  }
 
   /// Remove a node from the folding set, returning true if one
   /// was removed or false if the node was not in the folding set.
@@ -634,40 +638,31 @@ template <class T, class VectorT = SmallVector<T *, 8>> class FoldingSetVector {
 };
 
 //===----------------------------------------------------------------------===//
-/// This is the common iterator support shared by all folding sets, which knows
-/// how to walk the folding set hash table.
-class FoldingSetIteratorImpl : DebugEpochBase::HandleBase {
-protected:
-  const FoldingSetBase *Set = nullptr;
-  unsigned Index = 0;
+/// Forward iterator for FoldingSet and ContextualFoldingSet.
+template <class T> class FoldingSetIterator : DebugEpochBase::HandleBase {
+  void **Bucket = nullptr;
+  void **End = nullptr;
 
-  LLVM_ABI FoldingSetIteratorImpl(const FoldingSetBase *Set, unsigned Index);
-
-  LLVM_ABI void advance();
-
-  FoldingSetNode *getNode() const {
+  void advance() {
     assert(isHandleInSync() && "invalid iterator access!");
-    return static_cast<FoldingSetNode *>(Set->Buckets[Index]);
+    do
+      ++Bucket;
+    while (Bucket != End && *Bucket == nullptr);
   }
 
 public:
-  bool operator==(const FoldingSetIteratorImpl &RHS) const {
-    assert(isHandleInSync() && RHS.isHandleInSync() && "handle not in sync!");
-    return Set == RHS.Set && Index == RHS.Index;
-  }
-  bool operator!=(const FoldingSetIteratorImpl &RHS) const {
-    return !(*this == RHS);
+  FoldingSetIterator(void **Bucket, void **End, const DebugEpochBase *Epoch)
+      : DebugEpochBase::HandleBase(Epoch), Bucket(Bucket), End(End) {
+    while (this->Bucket != this->End && *this->Bucket == nullptr)
+      ++this->Bucket;
   }
-};
-
-template <class T> class FoldingSetIterator : public FoldingSetIteratorImpl {
-public:
-  explicit FoldingSetIterator(const FoldingSetBase *Set, unsigned Index)
-      : FoldingSetIteratorImpl(Set, Index) {}
 
-  T &operator*() const { return *static_cast<T *>(getNode()); }
+  T &operator*() const {
+    assert(isHandleInSync() && "invalid iterator access!");
+    return *static_cast<T *>(*Bucket);
+  }
 
-  T *operator->() const { return static_cast<T *>(getNode()); }
+  T *operator->() const { return &operator*(); }
 
   inline FoldingSetIterator &operator++() { // Preincrement
     advance();
@@ -678,6 +673,14 @@ template <class T> class FoldingSetIterator : public FoldingSetIteratorImpl {
     ++*this;
     return tmp;
   }
+
+  bool operator==(const FoldingSetIterator &RHS) const {
+    assert(isHandleInSync() && RHS.isHandleInSync() && "handle not in sync!");
+    return Bucket == RHS.Bucket;
+  }
+  bool operator!=(const FoldingSetIterator &RHS) const {
+    return !(*this == RHS);
+  }
 };
 
 //===----------------------------------------------------------------------===//

diff  --git a/llvm/lib/Support/FoldingSet.cpp b/llvm/lib/Support/FoldingSet.cpp
index fc5da49c3ff47..4c1eac39ea7b6 100644
--- a/llvm/lib/Support/FoldingSet.cpp
+++ b/llvm/lib/Support/FoldingSet.cpp
@@ -287,20 +287,3 @@ FoldingSetBase::GetOrInsertNode(Node *N, const FoldingSetInfo &Info) {
   InsertNode(N, IP);
   return N;
 }
-
-//===----------------------------------------------------------------------===//
-// FoldingSetIteratorImpl Implementation
-
-FoldingSetIteratorImpl::FoldingSetIteratorImpl(const FoldingSetBase *Set,
-                                               unsigned Index)
-    : DebugEpochBase::HandleBase(Set), Set(Set), Index(Index) {
-  while (this->Index < Set->NumBuckets && !Set->Buckets[this->Index])
-    ++this->Index;
-}
-
-void FoldingSetIteratorImpl::advance() {
-  assert(isHandleInSync() && "invalid iterator access!");
-  do
-    ++Index;
-  while (Index < Set->NumBuckets && !Set->Buckets[Index]);
-}


        


More information about the llvm-commits mailing list