[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