[lld] 11e915f - [FoldingSet] Add typed lookup/insert/erase/getOrInsert (#219644)

via llvm-commits llvm-commits at lists.llvm.org
Sat Aug 29 22:06:00 PDT 2026


Author: Fangrui Song
Date: 2026-08-30T05:05:54Z
New Revision: 11e915f2b75dfa0d96541b737304fcff65e77e7e

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

LOG: [FoldingSet] Add typed lookup/insert/erase/getOrInsert (#219644)

FindNodeOrInsertPos hands the insertion state to InsertNode as a `void *`:
any pointer converts to it, only a comment says where it may come from,
and since the switch to linear probing the value is the node's hash, not
a position at all.

Carry it in FoldingSetInsertToken instead, the hash wrapped in a type
whose constructor and accessor are private to FoldingSetBase, with
NotAHash as the no-token state. The `void *` overloads remain,
forwarding to the typed ones, until their callers are migrated.

LLM-aided

Added: 
    

Modified: 
    lld/ELF/SyntheticSections.cpp
    llvm/include/llvm/ADT/FoldingSet.h
    llvm/lib/Support/FoldingSet.cpp
    llvm/lib/TableGen/Record.cpp
    llvm/unittests/ADT/FoldingSet.cpp

Removed: 
    


################################################################################
diff  --git a/lld/ELF/SyntheticSections.cpp b/lld/ELF/SyntheticSections.cpp
index e2b9bb7590e26..aa7a859a9da9a 100644
--- a/lld/ELF/SyntheticSections.cpp
+++ b/lld/ELF/SyntheticSections.cpp
@@ -2875,14 +2875,14 @@ void DebugNamesBaseSection::computeHdrAndAbbrevTable(
         FoldingSetNodeID id;
         abbrev.Profile(id);
         uint32_t newCode;
-        void *insertPos;
-        if (Abbrev *existing = abbrevSet.FindNodeOrInsertPos(id, insertPos)) {
+        FoldingSetInsertToken token;
+        if (Abbrev *existing = abbrevSet.lookup(id, token)) {
           // Found it; we've already seen an identical abbreviation.
           newCode = existing->code;
         } else {
           Abbrev *abbrev2 =
               new (abbrevAlloc.Allocate()) Abbrev(std::move(abbrev));
-          abbrevSet.InsertNode(abbrev2, insertPos);
+          abbrevSet.insert(abbrev2, token);
           abbrevTable.push_back(abbrev2);
           newCode = abbrevTable.size();
           abbrev2->code = newCode;

diff  --git a/llvm/include/llvm/ADT/FoldingSet.h b/llvm/include/llvm/ADT/FoldingSet.h
index 9499aa784b7a0..77818bc151a09 100644
--- a/llvm/include/llvm/ADT/FoldingSet.h
+++ b/llvm/include/llvm/ADT/FoldingSet.h
@@ -74,38 +74,37 @@ namespace llvm {
 /// 1) If you have an existing node that you want add to the set but unsure
 /// that the node might already exist then call;
 ///
-///    MyNode *M = MyFoldingSet.GetOrInsertNode(N);
+///    MyNode *M = MyFoldingSet.getOrInsert(N);
 ///
 /// If The result is equal to the input then the node has been inserted.
 /// Otherwise, the result is the node existing in the folding set, and the
 /// input can be discarded (use the result instead.)
 ///
 /// 2) If you are ready to construct a node but want to check if it already
-/// exists, then call FindNodeOrInsertPos with a FoldingSetNodeID of the bits to
-/// check;
+/// exists, then call lookup with a FoldingSetNodeID of the bits to check;
 ///
 ///   FoldingSetNodeID ID;
 ///   ID.AddString(Name);
 ///   ID.AddInteger(Value);
-///   void *InsertPoint;
+///   FoldingSetInsertToken Token;
 ///
-///    MyNode *M = MyFoldingSet.FindNodeOrInsertPos(ID, InsertPoint);
+///    MyNode *M = MyFoldingSet.lookup(ID, Token);
 ///
-/// If found then M will be non-NULL, else InsertPoint will point to where it
-/// should be inserted using InsertNode.
+/// If found then M will be non-NULL, else Token holds what insert needs to
+/// place the node.
 ///
-/// 3) If you get a NULL result from FindNodeOrInsertPos then you can insert a
-/// new node with InsertNode;
+/// 3) If you get a NULL result from lookup then you can insert a new node with
+/// insert;
 ///
 ///    MyNode *N = new MyNode(Name, Value);
-///    MyFoldingSet.InsertNode(N, InsertPoint);
+///    MyFoldingSet.insert(N, Token);
 ///
-/// InsertPoint survives intervening insertions, but N must profile identically
-/// to the ID that produced it, or N becomes unfindable.
+/// Token survives intervening insertions, but N must profile identically to
+/// the ID that produced it, or N becomes unfindable.
 ///
 /// 4) Finally, if you want to remove a node from the folding set call;
 ///
-///    bool WasRemoved = MyFoldingSet.RemoveNode(M);
+///    bool WasRemoved = MyFoldingSet.erase(M);
 ///
 /// The result indicates whether the node existed in the folding set.
 
@@ -177,8 +176,8 @@ class FoldingSetNodeIDRef {
 
   // Compute a strong hash value used to lookup the node in the FoldingSetBase.
   // The hash value is not guaranteed to be deterministic across processes.
-  // Never returns NotAHash: FoldingSetBase uses it to keep the InsertPos token
-  // non-null and to mark a node belonging to no set.
+  // Never returns NotAHash: FoldingSetBase reserves it for the empty insert
+  // token and for a node belonging to no set.
   unsigned ComputeHash() const {
     unsigned Hash =
         static_cast<unsigned>(hash_combine_range(Data, Data + Size));
@@ -288,6 +287,31 @@ class FoldingSetNodeID {
   LLVM_ABI FoldingSetNodeIDRef Intern(BumpPtrAllocator &Allocator) const;
 };
 
+/// Insertion token: a failed lookup fills it in, the matching insert consumes
+/// it.
+class FoldingSetInsertToken {
+  uint32_t Hash = FoldingSetNodeIDRef::NotAHash;
+
+  explicit FoldingSetInsertToken(uint32_t Hash) : Hash(Hash) {
+    assert(Hash != FoldingSetNodeIDRef::NotAHash && "Invalid insert token");
+  }
+
+  friend class FoldingSetBase;
+
+public:
+  FoldingSetInsertToken() = default;
+  explicit operator bool() const {
+    return Hash != FoldingSetNodeIDRef::NotAHash;
+  }
+
+  friend bool operator==(FoldingSetInsertToken A, FoldingSetInsertToken B) {
+    return A.Hash == B.Hash;
+  }
+  friend bool operator!=(FoldingSetInsertToken A, FoldingSetInsertToken B) {
+    return !(A == B);
+  }
+};
+
 //===----------------------------------------------------------------------===//
 /// Non-templated base class for FoldingSet and ContextualFoldingSet, holding
 /// the memory management and probing that does not depend on the node type.
@@ -379,15 +403,19 @@ class FoldingSetBase : public DebugEpochBase {
   /// return it.  Otherwise, insert \p N and return it instead.
   LLVM_ABI Node *GetOrInsertNode(Node *N, const FoldingSetInfo &Info);
 
-  /// Look up the node specified by ID.  If it exists, return it.  If not,
-  /// return the insertion token that will make insertion faster.
+  /// Look up the node specified by ID. If it exists, return it and clear
+  /// \p Token; otherwise return null and set \p Token for a subsequent insert.
+  LLVM_ABI Node *lookup(const FoldingSetNodeID &ID,
+                        FoldingSetInsertToken &Token,
+                        const FoldingSetInfo &Info);
   LLVM_ABI Node *FindNodeOrInsertPos(const FoldingSetNodeID &ID,
                                      void *&InsertPos,
                                      const FoldingSetInfo &Info);
 
-  /// Insert the specified node into the folding set, knowing that
-  /// it is not already in the folding set.  InsertPos must be obtained from
-  /// FindNodeOrInsertPos for an ID that \p N profiles identically to.
+  /// Insert the specified node into the folding set, knowing that it is not
+  /// already in the folding set.  \p Token must come from lookup for an ID that
+  /// \p N profiles identically to.
+  LLVM_ABI void insert(Node *N, FoldingSetInsertToken Token);
   LLVM_ABI void InsertNode(Node *N, void *InsertPos);
 };
 
@@ -476,36 +504,46 @@ class FoldingSetImpl : public FoldingSetBase, public Trait::ContextStorage {
 
   /// Remove a node from the folding set, returning true if one
   /// was removed or false if the node was not in the folding set.
-  bool RemoveNode(T *N) { return FoldingSetBase::RemoveNode(N); }
+  bool erase(T *N) { return FoldingSetBase::RemoveNode(N); }
+  bool RemoveNode(T *N) { return erase(N); }
 
   /// If there is an existing node exactly equal to the specified node,
   /// return it.  Otherwise, insert 'N' and return it instead.
-  T *GetOrInsertNode(T *N) {
+  T *getOrInsert(T *N) {
     return static_cast<T *>(
         FoldingSetBase::GetOrInsertNode(N, getFoldingSetInfo()));
   }
+  T *GetOrInsertNode(T *N) { return getOrInsert(N); }
 
-  /// Look up the node specified by ID.  If it exists, return it.  If not,
-  /// return the insertion token that will make insertion faster.
+  /// Look up the node specified by ID. If it exists, return it and clear
+  /// \p Token; otherwise return null and set \p Token for a subsequent insert.
+  T *lookup(const FoldingSetNodeID &ID, FoldingSetInsertToken &Token) {
+    return static_cast<T *>(
+        FoldingSetBase::lookup(ID, Token, getFoldingSetInfo()));
+  }
   T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
     return static_cast<T *>(FoldingSetBase::FindNodeOrInsertPos(
         ID, InsertPos, getFoldingSetInfo()));
   }
 
-  /// Insert the specified node into the folding set, knowing that
-  /// it is not already in the folding set.  InsertPos must be obtained from
-  /// FindNodeOrInsertPos.
+  /// Insert the specified node into the folding set, knowing that it is not
+  /// already in the folding set.  \p Token must come from lookup for an ID that
+  /// \p N profiles identically to.
+  void insert(T *N, FoldingSetInsertToken Token) {
+    FoldingSetBase::insert(N, Token);
+  }
   void InsertNode(T *N, void *InsertPos) {
     FoldingSetBase::InsertNode(N, InsertPos);
   }
 
   /// Insert the specified node into the folding set, knowing that it is not
   /// already in the folding set.
-  void InsertNode(T *N) {
-    T *Inserted = GetOrInsertNode(N);
+  void insert(T *N) {
+    T *Inserted = getOrInsert(N);
     (void)Inserted;
     assert(Inserted == N && "Node already inserted!");
   }
+  void InsertNode(T *N) { insert(N); }
 };
 
 //===----------------------------------------------------------------------===//
@@ -560,24 +598,32 @@ template <class T, class VectorT = SmallVector<T *, 8>> class FoldingSetVector {
     Vector.clear();
   }
 
-  /// Look up the node specified by ID.  If it exists, return it.  If not,
-  /// return the insertion token that will make insertion faster.
+  /// Look up the node specified by ID. If it exists, return it and clear
+  /// \p Token; otherwise return null and set \p Token for a subsequent insert.
+  T *lookup(const FoldingSetNodeID &ID, FoldingSetInsertToken &Token) {
+    return Set.lookup(ID, Token);
+  }
   T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
     return Set.FindNodeOrInsertPos(ID, InsertPos);
   }
 
   /// If there is an existing node exactly equal to the specified node,
   /// return it.  Otherwise, insert 'N' and return it instead.
-  T *GetOrInsertNode(T *N) {
-    T *Result = Set.GetOrInsertNode(N);
+  T *getOrInsert(T *N) {
+    T *Result = Set.getOrInsert(N);
     if (Result == N)
       Vector.push_back(N);
     return Result;
   }
+  T *GetOrInsertNode(T *N) { return getOrInsert(N); }
 
-  /// Insert the specified node into the folding set, knowing that
-  /// it is not already in the folding set.  InsertPos must be obtained from
-  /// FindNodeOrInsertPos.
+  /// Insert the specified node into the folding set, knowing that it is not
+  /// already in the folding set.  \p Token must come from lookup for an ID that
+  /// \p N profiles identically to.
+  void insert(T *N, FoldingSetInsertToken Token) {
+    Set.insert(N, Token);
+    Vector.push_back(N);
+  }
   void InsertNode(T *N, void *InsertPos) {
     Set.InsertNode(N, InsertPos);
     Vector.push_back(N);
@@ -585,10 +631,11 @@ template <class T, class VectorT = SmallVector<T *, 8>> class FoldingSetVector {
 
   /// Insert the specified node into the folding set, knowing that
   /// it is not already in the folding set.
-  void InsertNode(T *N) {
-    Set.InsertNode(N);
+  void insert(T *N) {
+    Set.insert(N);
     Vector.push_back(N);
   }
+  void InsertNode(T *N) { insert(N); }
 
   /// Returns the number of nodes in the folding set.
   unsigned size() const { return Set.size(); }

diff  --git a/llvm/lib/Support/FoldingSet.cpp b/llvm/lib/Support/FoldingSet.cpp
index 0083e77ad95e4..a201130e66cdd 100644
--- a/llvm/lib/Support/FoldingSet.cpp
+++ b/llvm/lib/Support/FoldingSet.cpp
@@ -219,33 +219,46 @@ FoldingSetBase::nodeEquals(const FoldingSetInfo &Info,
   return Info.NodeEquals(Self, N, ID, TempID);
 }
 
-FoldingSetBase::Node *FoldingSetBase::FindNodeOrInsertPos(
-    const FoldingSetNodeID &ID, void *&InsertPos, const FoldingSetInfo &Info) {
+FoldingSetBase::Node *FoldingSetBase::lookup(const FoldingSetNodeID &ID,
+                                             FoldingSetInsertToken &Token,
+                                             const FoldingSetInfo &Info) {
   unsigned IDHash = ID.ComputeHash();
   unsigned Mask = NumBuckets - 1;
   for (unsigned I = IDHash & Mask; Buckets[I]; I = (I + 1) & Mask) {
     Node *N = static_cast<Node *>(Buckets[I]);
     if (N->getFoldingSetHash() == IDHash && nodeEquals(Info, this, N, ID)) {
-      InsertPos = nullptr;
+      Token = {};
       return N;
     }
   }
 
-  InsertPos = encodeHash(IDHash);
+  Token = FoldingSetInsertToken(IDHash);
   return nullptr;
 }
 
-void FoldingSetBase::InsertNode(Node *N, void *InsertPos) {
+FoldingSetBase::Node *FoldingSetBase::FindNodeOrInsertPos(
+    const FoldingSetNodeID &ID, void *&InsertPos, const FoldingSetInfo &Info) {
+  FoldingSetInsertToken Token;
+  Node *N = lookup(ID, Token, Info);
+  InsertPos = Token ? encodeHash(Token.Hash) : nullptr;
+  return N;
+}
+
+void FoldingSetBase::insert(Node *N, FoldingSetInsertToken Token) {
   assert(N && "Cannot insert a null node");
-  assert(InsertPos && "Invalid InsertPos!");
+  assert(Token && "Invalid token!");
   incrementEpoch();
   if (LLVM_UNLIKELY((NumNodes + 1) * 4 > NumBuckets * 3))
     grow(NumBuckets * 2);
-  uint32_t Hash = decodeHash(InsertPos);
+  uint32_t Hash = Token.Hash;
   placeNode(N, Hash);
   N->setFoldingSetHash(Hash);
 }
 
+void FoldingSetBase::InsertNode(Node *N, void *InsertPos) {
+  insert(N, FoldingSetInsertToken(decodeHash(InsertPos)));
+}
+
 bool FoldingSetBase::RemoveNode(Node *N) {
   uint32_t Hash = N->getFoldingSetHash();
   if (Hash == FoldingSetNodeIDRef::NotAHash)
@@ -280,9 +293,9 @@ FoldingSetBase::Node *
 FoldingSetBase::GetOrInsertNode(Node *N, const FoldingSetInfo &Info) {
   FoldingSetNodeID ID;
   Info.GetNodeProfile(this, N, ID);
-  void *IP;
-  if (Node *E = FindNodeOrInsertPos(ID, IP, Info))
+  FoldingSetInsertToken Token;
+  if (Node *E = lookup(ID, Token, Info))
     return E;
-  InsertNode(N, IP);
+  insert(N, Token);
   return N;
 }

diff  --git a/llvm/lib/TableGen/Record.cpp b/llvm/lib/TableGen/Record.cpp
index ac62e2f5785ae..3aa2e5ce2b94a 100644
--- a/llvm/lib/TableGen/Record.cpp
+++ b/llvm/lib/TableGen/Record.cpp
@@ -254,8 +254,8 @@ const RecordRecTy *RecordRecTy::get(RecordKeeper &RK,
   FoldingSetNodeID ID;
   ProfileRecordRecTy(ID, Classes);
 
-  void *IP = nullptr;
-  if (RecordRecTy *Ty = ThePool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (RecordRecTy *Ty = ThePool.lookup(ID, Token))
     return Ty;
 
 #ifndef NDEBUG
@@ -271,7 +271,7 @@ const RecordRecTy *RecordRecTy::get(RecordKeeper &RK,
   void *Mem = RKImpl.Allocator.Allocate(
       totalSizeToAlloc<const Record *>(Classes.size()), alignof(RecordRecTy));
   RecordRecTy *Ty = new (Mem) RecordRecTy(RK, Classes);
-  ThePool.InsertNode(Ty, IP);
+  ThePool.insert(Ty, Token);
   return Ty;
 }
 
@@ -416,13 +416,12 @@ const ArgumentInit *ArgumentInit::get(const Init *Value, ArgAuxType Aux) {
 
   RecordKeeper &RK = Value->getRecordKeeper();
   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
-  void *IP = nullptr;
-  if (const ArgumentInit *I =
-          RKImpl.TheArgumentInitPool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (const ArgumentInit *I = RKImpl.TheArgumentInitPool.lookup(ID, Token))
     return I;
 
   ArgumentInit *I = new (RKImpl.Allocator) ArgumentInit(Value, Aux);
-  RKImpl.TheArgumentInitPool.InsertNode(I, IP);
+  RKImpl.TheArgumentInitPool.insert(I, Token);
   return I;
 }
 
@@ -473,14 +472,14 @@ BitsInit *BitsInit::get(RecordKeeper &RK, ArrayRef<const Init *> Bits) {
   ProfileBitsInit(ID, Bits);
 
   detail::RecordKeeperImpl &RKImpl = RK.getImpl();
-  void *IP = nullptr;
-  if (BitsInit *I = RKImpl.TheBitsInitPool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (BitsInit *I = RKImpl.TheBitsInitPool.lookup(ID, Token))
     return I;
 
   void *Mem = RKImpl.Allocator.Allocate(
       totalSizeToAlloc<const Init *>(Bits.size()), alignof(BitsInit));
   BitsInit *I = new (Mem) BitsInit(RK, Bits);
-  RKImpl.TheBitsInitPool.InsertNode(I, IP);
+  RKImpl.TheBitsInitPool.insert(I, Token);
   return I;
 }
 
@@ -716,8 +715,8 @@ const ListInit *ListInit::get(ArrayRef<const Init *> Elements,
   ProfileListInit(ID, Elements, EltTy);
 
   detail::RecordKeeperImpl &RK = EltTy->getRecordKeeper().getImpl();
-  void *IP = nullptr;
-  if (const ListInit *I = RK.TheListInitPool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (const ListInit *I = RK.TheListInitPool.lookup(ID, Token))
     return I;
 
   assert(Elements.empty() || !isa<TypedInit>(Elements[0]) ||
@@ -726,7 +725,7 @@ const ListInit *ListInit::get(ArrayRef<const Init *> Elements,
   void *Mem = RK.Allocator.Allocate(
       totalSizeToAlloc<const Init *>(Elements.size()), alignof(ListInit));
   ListInit *I = new (Mem) ListInit(Elements, EltTy);
-  RK.TheListInitPool.InsertNode(I, IP);
+  RK.TheListInitPool.insert(I, Token);
   return I;
 }
 
@@ -826,12 +825,12 @@ const UnOpInit *UnOpInit::get(UnaryOp Opc, const Init *LHS, const RecTy *Type) {
   ProfileUnOpInit(ID, Opc, LHS, Type);
 
   detail::RecordKeeperImpl &RK = Type->getRecordKeeper().getImpl();
-  void *IP = nullptr;
-  if (const UnOpInit *I = RK.TheUnOpInitPool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (const UnOpInit *I = RK.TheUnOpInitPool.lookup(ID, Token))
     return I;
 
   UnOpInit *I = new (RK.Allocator) UnOpInit(Opc, LHS, Type);
-  RK.TheUnOpInitPool.InsertNode(I, IP);
+  RK.TheUnOpInitPool.insert(I, Token);
   return I;
 }
 
@@ -1098,12 +1097,12 @@ const BinOpInit *BinOpInit::get(BinaryOp Opc, const Init *LHS, const Init *RHS,
   ProfileBinOpInit(ID, Opc, LHS, RHS, Type);
 
   detail::RecordKeeperImpl &RK = LHS->getRecordKeeper().getImpl();
-  void *IP = nullptr;
-  if (const BinOpInit *I = RK.TheBinOpInitPool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (const BinOpInit *I = RK.TheBinOpInitPool.lookup(ID, Token))
     return I;
 
   BinOpInit *I = new (RK.Allocator) BinOpInit(Opc, LHS, RHS, Type);
-  RK.TheBinOpInitPool.InsertNode(I, IP);
+  RK.TheBinOpInitPool.insert(I, Token);
   return I;
 }
 
@@ -1693,12 +1692,12 @@ const TernOpInit *TernOpInit::get(TernaryOp Opc, const Init *LHS,
   ProfileTernOpInit(ID, Opc, LHS, MHS, RHS, Type);
 
   detail::RecordKeeperImpl &RK = LHS->getRecordKeeper().getImpl();
-  void *IP = nullptr;
-  if (TernOpInit *I = RK.TheTernOpInitPool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (TernOpInit *I = RK.TheTernOpInitPool.lookup(ID, Token))
     return I;
 
   TernOpInit *I = new (RK.Allocator) TernOpInit(Opc, LHS, MHS, RHS, Type);
-  RK.TheTernOpInitPool.InsertNode(I, IP);
+  RK.TheTernOpInitPool.insert(I, Token);
   return I;
 }
 
@@ -2122,12 +2121,12 @@ const FoldOpInit *FoldOpInit::get(const Init *Start, const Init *List,
   ProfileFoldOpInit(ID, Start, List, A, B, Expr, Type);
 
   detail::RecordKeeperImpl &RK = Start->getRecordKeeper().getImpl();
-  void *IP = nullptr;
-  if (const FoldOpInit *I = RK.TheFoldOpInitPool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (const FoldOpInit *I = RK.TheFoldOpInitPool.lookup(ID, Token))
     return I;
 
   FoldOpInit *I = new (RK.Allocator) FoldOpInit(Start, List, A, B, Expr, Type);
-  RK.TheFoldOpInitPool.InsertNode(I, IP);
+  RK.TheFoldOpInitPool.insert(I, Token);
   return I;
 }
 
@@ -2189,12 +2188,12 @@ const IsAOpInit *IsAOpInit::get(const RecTy *CheckType, const Init *Expr) {
   ProfileIsAOpInit(ID, CheckType, Expr);
 
   detail::RecordKeeperImpl &RK = Expr->getRecordKeeper().getImpl();
-  void *IP = nullptr;
-  if (const IsAOpInit *I = RK.TheIsAOpInitPool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (const IsAOpInit *I = RK.TheIsAOpInitPool.lookup(ID, Token))
     return I;
 
   IsAOpInit *I = new (RK.Allocator) IsAOpInit(CheckType, Expr);
-  RK.TheIsAOpInitPool.InsertNode(I, IP);
+  RK.TheIsAOpInitPool.insert(I, Token);
   return I;
 }
 
@@ -2253,13 +2252,12 @@ const ExistsOpInit *ExistsOpInit::get(const RecTy *CheckType,
   ProfileExistsOpInit(ID, CheckType, Expr);
 
   detail::RecordKeeperImpl &RK = Expr->getRecordKeeper().getImpl();
-  void *IP = nullptr;
-  if (const ExistsOpInit *I =
-          RK.TheExistsOpInitPool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (const ExistsOpInit *I = RK.TheExistsOpInitPool.lookup(ID, Token))
     return I;
 
   ExistsOpInit *I = new (RK.Allocator) ExistsOpInit(CheckType, Expr);
-  RK.TheExistsOpInitPool.InsertNode(I, IP);
+  RK.TheExistsOpInitPool.insert(I, Token);
   return I;
 }
 
@@ -2328,13 +2326,12 @@ const InstancesOpInit *InstancesOpInit::get(const RecTy *Type,
   ProfileInstancesOpInit(ID, Type, Regex);
 
   detail::RecordKeeperImpl &RK = Regex->getRecordKeeper().getImpl();
-  void *IP = nullptr;
-  if (const InstancesOpInit *I =
-          RK.TheInstancesOpInitPool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (const InstancesOpInit *I = RK.TheInstancesOpInitPool.lookup(ID, Token))
     return I;
 
   InstancesOpInit *I = new (RK.Allocator) InstancesOpInit(Type, Regex);
-  RK.TheInstancesOpInitPool.InsertNode(I, IP);
+  RK.TheInstancesOpInitPool.insert(I, Token);
   return I;
 }
 
@@ -2521,14 +2518,14 @@ const VarDefInit *VarDefInit::get(SMLoc Loc, const Record *Class,
   ProfileVarDefInit(ID, Class, Args);
 
   detail::RecordKeeperImpl &RK = Class->getRecords().getImpl();
-  void *IP = nullptr;
-  if (const VarDefInit *I = RK.TheVarDefInitPool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (const VarDefInit *I = RK.TheVarDefInitPool.lookup(ID, Token))
     return I;
 
   void *Mem = RK.Allocator.Allocate(
       totalSizeToAlloc<const ArgumentInit *>(Args.size()), alignof(VarDefInit));
   VarDefInit *I = new (Mem) VarDefInit(Loc, Class, Args);
-  RK.TheVarDefInitPool.InsertNode(I, IP);
+  RK.TheVarDefInitPool.insert(I, Token);
   return I;
 }
 
@@ -2714,14 +2711,14 @@ const CondOpInit *CondOpInit::get(ArrayRef<const Init *> Conds,
   ProfileCondOpInit(ID, Conds, Values, Ty);
 
   detail::RecordKeeperImpl &RK = Ty->getRecordKeeper().getImpl();
-  void *IP = nullptr;
-  if (const CondOpInit *I = RK.TheCondOpInitPool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (const CondOpInit *I = RK.TheCondOpInitPool.lookup(ID, Token))
     return I;
 
   void *Mem = RK.Allocator.Allocate(
       totalSizeToAlloc<const Init *>(2 * Conds.size()), alignof(CondOpInit));
   CondOpInit *I = new (Mem) CondOpInit(Conds, Values, Ty);
-  RK.TheCondOpInitPool.InsertNode(I, IP);
+  RK.TheCondOpInitPool.insert(I, Token);
   return I;
 }
 
@@ -2836,8 +2833,8 @@ const DagInit *DagInit::get(const Init *V, const StringInit *VN,
   ProfileDagInit(ID, V, VN, Args, ArgNames);
 
   detail::RecordKeeperImpl &RK = V->getRecordKeeper().getImpl();
-  void *IP = nullptr;
-  if (const DagInit *I = RK.TheDagInitPool.FindNodeOrInsertPos(ID, IP))
+  FoldingSetInsertToken Token;
+  if (const DagInit *I = RK.TheDagInitPool.lookup(ID, Token))
     return I;
 
   void *Mem =
@@ -2845,7 +2842,7 @@ const DagInit *DagInit::get(const Init *V, const StringInit *VN,
                                 Args.size(), ArgNames.size()),
                             alignof(DagInit));
   DagInit *I = new (Mem) DagInit(V, VN, Args, ArgNames);
-  RK.TheDagInitPool.InsertNode(I, IP);
+  RK.TheDagInitPool.insert(I, Token);
   return I;
 }
 

diff  --git a/llvm/unittests/ADT/FoldingSet.cpp b/llvm/unittests/ADT/FoldingSet.cpp
index 1b694e84780d3..f110bfdc282a5 100644
--- a/llvm/unittests/ADT/FoldingSet.cpp
+++ b/llvm/unittests/ADT/FoldingSet.cpp
@@ -130,6 +130,23 @@ TEST(FoldingSetTest, RemoveNodeThatIsAbsent) {
   EXPECT_EQ(0U, Trivial.size());
 }
 
+TEST(FoldingSetTest, TypedApi) {
+  FoldingSet<TrivialPair> Set;
+  TrivialPair T(99, 42), TCopy(99, 42);
+  FoldingSetNodeID ID;
+  T.Profile(ID);
+
+  FoldingSetInsertToken Token;
+  EXPECT_EQ(nullptr, Set.lookup(ID, Token));
+  ASSERT_TRUE(Token);
+  Set.insert(&T, Token);
+  EXPECT_EQ(&T, Set.lookup(ID, Token));
+  EXPECT_FALSE(Token);
+  EXPECT_EQ(&T, Set.getOrInsert(&TCopy));
+  EXPECT_TRUE(Set.erase(&T));
+  EXPECT_FALSE(Set.erase(&T));
+}
+
 TEST(FoldingSetTest, GetOrInsertInserting) {
   FoldingSet<TrivialPair> Trivial;
 
@@ -197,7 +214,7 @@ TEST(FoldingSetTest, Reserve) {
     std::vector<std::unique_ptr<TrivialPair>> Nodes;
     for (unsigned I = 0; I != Size; ++I) {
       Nodes.push_back(std::make_unique<TrivialPair>(I, I));
-      Set.InsertNode(Nodes.back().get());
+      Set.insert(Nodes.back().get());
     }
     ASSERT_EQ(Size, Set.size());
 
@@ -299,20 +316,20 @@ TEST(FoldingSetTest, FoldingSetVectorBasic) {
   TrivialPair T2(20, 200);
   TrivialPair T3(30, 300);
 
-  EXPECT_EQ(&T1, Vec.GetOrInsertNode(&T1));
-  EXPECT_EQ(&T1, Vec.GetOrInsertNode(&T1Copy));
+  EXPECT_EQ(&T1, Vec.getOrInsert(&T1));
+  EXPECT_EQ(&T1, Vec.getOrInsert(&T1Copy));
   EXPECT_THAT(Vec, SizeIs(1));
 
   // Insert a new node using an insertion token.
   FoldingSetNodeID ID2;
   T2.Profile(ID2);
-  void *InsertPos = nullptr;
-  EXPECT_EQ(nullptr, Vec.FindNodeOrInsertPos(ID2, InsertPos));
-  ASSERT_NE(nullptr, InsertPos);
-  Vec.InsertNode(&T2, InsertPos);
+  FoldingSetInsertToken Token;
+  EXPECT_EQ(nullptr, Vec.lookup(ID2, Token));
+  ASSERT_TRUE(Token);
+  Vec.insert(&T2, Token);
   EXPECT_THAT(Vec, SizeIs(2));
 
-  Vec.InsertNode(&T3);
+  EXPECT_EQ(&T3, Vec.getOrInsert(&T3));
   EXPECT_THAT(Vec, SizeIs(3));
   EXPECT_THAT(Vec, testing::Not(IsEmpty()));
 
@@ -354,26 +371,26 @@ TEST(FoldingSetTest, ContextualFoldingSetBasic) {
   ContextualPair T1Copy(10, 100);
   ContextualPair T2(20, 200);
 
-  EXPECT_EQ(&T1, Set.GetOrInsertNode(&T1));
-  EXPECT_EQ(&T1, Set.GetOrInsertNode(&T1Copy));
+  EXPECT_EQ(&T1, Set.getOrInsert(&T1));
+  EXPECT_EQ(&T1, Set.getOrInsert(&T1Copy));
   EXPECT_THAT(Set, SizeIs(1));
 
   // Insert a new node using an insertion token.
-  void *InsertPos = nullptr;
+  FoldingSetInsertToken Token;
   FoldingSetNodeID ID2;
   T2.Profile(ID2, ContextVal);
-  EXPECT_EQ(nullptr, Set.FindNodeOrInsertPos(ID2, InsertPos));
-  ASSERT_NE(nullptr, InsertPos);
-  Set.InsertNode(&T2, InsertPos);
+  EXPECT_EQ(nullptr, Set.lookup(ID2, Token));
+  ASSERT_TRUE(Token);
+  Set.insert(&T2, Token);
   EXPECT_THAT(Set, SizeIs(2));
 
-  EXPECT_EQ(&T2, Set.FindNodeOrInsertPos(ID2, InsertPos));
+  EXPECT_EQ(&T2, Set.lookup(ID2, Token));
 
   EXPECT_THAT(Set, UnorderedElementsAre(T1, T2));
 
-  EXPECT_TRUE(Set.RemoveNode(&T1));
+  EXPECT_TRUE(Set.erase(&T1));
   EXPECT_THAT(Set, SizeIs(1));
-  EXPECT_FALSE(Set.RemoveNode(&T1));
+  EXPECT_FALSE(Set.erase(&T1));
 
   EXPECT_THAT(Set, UnorderedElementsAre(T2));
 
@@ -510,27 +527,27 @@ TEST(FoldingSetTest, InsertInvalidatesIteratorComparison) {
 }
 #endif
 
-// The InsertPos token is a hash, not a position, so a rehash cannot stale it.
-TEST(FoldingSetTest, InsertPosSurvivesGrowth) {
+// The insert token is a hash, not a position, so a rehash cannot stale it.
+TEST(FoldingSetTest, TokenSurvivesGrowth) {
   FoldingSet<TrivialPair> Set;
   TrivialPair Late(9999, 9999);
 
   FoldingSetNodeID ID;
   Late.Profile(ID);
-  void *InsertPos = nullptr;
-  ASSERT_EQ(nullptr, Set.FindNodeOrInsertPos(ID, InsertPos));
-  ASSERT_NE(nullptr, InsertPos);
+  FoldingSetInsertToken Token;
+  ASSERT_EQ(nullptr, Set.lookup(ID, Token));
+  ASSERT_TRUE(Token);
 
   // Force several rehashes while the token is held.
   std::vector<std::unique_ptr<TrivialPair>> Nodes;
   for (unsigned I = 0; I != 200; ++I) {
     Nodes.push_back(std::make_unique<TrivialPair>(I, I));
-    Set.InsertNode(Nodes.back().get());
+    Set.insert(Nodes.back().get());
   }
 
-  Set.InsertNode(&Late, InsertPos);
-  void *Unused = nullptr;
-  EXPECT_EQ(&Late, Set.FindNodeOrInsertPos(ID, Unused));
+  Set.insert(&Late, Token);
+  EXPECT_EQ(&Late, Set.lookup(ID, Token));
+  EXPECT_FALSE(Token);
   EXPECT_EQ(201u, Set.size());
 }
 


        


More information about the llvm-commits mailing list