LLVM 24.0.0git
FoldingSet.h
Go to the documentation of this file.
1//===- llvm/ADT/FoldingSet.h - Uniquing Hash Set ----------------*- C++ -*-===//
2//
3// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4// See https://llvm.org/LICENSE.txt for license information.
5// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6//
7//===----------------------------------------------------------------------===//
8///
9/// \file
10/// This file defines a hash set that can be used to remove duplication of nodes
11/// in a graph. This code was originally created by Chris Lattner for use with
12/// SelectionDAGCSEMap, but was isolated to provide use across the llvm code
13/// set.
14//===----------------------------------------------------------------------===//
15
16#ifndef LLVM_ADT_FOLDINGSET_H
17#define LLVM_ADT_FOLDINGSET_H
18
20#include "llvm/ADT/Hashing.h"
23#include "llvm/ADT/iterator.h"
26#include "llvm/Support/xxhash.h"
27#include <cassert>
28#include <cstddef>
29#include <cstdint>
30#include <type_traits>
31#include <utility>
32
33namespace llvm {
34
35/// This folding set is used for two purposes:
36/// 1. Given information about a node we want to create, look up the unique
37/// instance of the node in the set. If the node already exists, return
38/// it, otherwise return a token that makes the insertion cheap.
39/// 2. Given a node that has already been created, remove it from the set.
40///
41/// The hash table is linear-probing open addressing with tombstone-free
42/// deletion, power-of-two capacity, and a 0.75 maximum load factor.
43///
44/// Any node that is to be included in the folding set must be a subclass of
45/// FoldingSetNode. The node class must also define a Profile method used to
46/// establish the unique bits of data for the node. The Profile method is
47/// passed a FoldingSetNodeID object which is used to gather the bits. Just
48/// call one of the Add* functions defined in the FoldingSetNodeID class.
49/// NOTE: That the folding set does not own the nodes and it is the
50/// responsibility of the user to dispose of the nodes.
51///
52/// Eg.
53/// class MyNode : public FoldingSetNode {
54/// private:
55/// std::string Name;
56/// unsigned Value;
57/// public:
58/// MyNode(const char *N, unsigned V) : Name(N), Value(V) {}
59/// ...
60/// void Profile(FoldingSetNodeID &ID) const {
61/// ID.AddString(Name);
62/// ID.AddInteger(Value);
63/// }
64/// ...
65/// };
66///
67/// To define the folding set itself use the FoldingSet template;
68///
69/// Eg.
70/// FoldingSet<MyNode> MyFoldingSet;
71///
72/// Four public methods are available to manipulate the folding set;
73///
74/// 1) If you have an existing node that you want add to the set but unsure
75/// that the node might already exist then call;
76///
77/// MyNode *M = MyFoldingSet.GetOrInsertNode(N);
78///
79/// If The result is equal to the input then the node has been inserted.
80/// Otherwise, the result is the node existing in the folding set, and the
81/// input can be discarded (use the result instead.)
82///
83/// 2) If you are ready to construct a node but want to check if it already
84/// exists, then call FindNodeOrInsertPos with a FoldingSetNodeID of the bits to
85/// check;
86///
87/// FoldingSetNodeID ID;
88/// ID.AddString(Name);
89/// ID.AddInteger(Value);
90/// void *InsertPoint;
91///
92/// MyNode *M = MyFoldingSet.FindNodeOrInsertPos(ID, InsertPoint);
93///
94/// If found then M will be non-NULL, else InsertPoint will point to where it
95/// should be inserted using InsertNode.
96///
97/// 3) If you get a NULL result from FindNodeOrInsertPos then you can insert a
98/// new node with InsertNode;
99///
100/// MyNode *N = new MyNode(Name, Value);
101/// MyFoldingSet.InsertNode(N, InsertPoint);
102///
103/// InsertPoint survives intervening insertions, but N must profile identically
104/// to the ID that produced it, or N becomes unfindable.
105///
106/// 4) Finally, if you want to remove a node from the folding set call;
107///
108/// bool WasRemoved = MyFoldingSet.RemoveNode(M);
109///
110/// The result indicates whether the node existed in the folding set.
111
112class FoldingSetNodeID;
113class StringRef;
114
115//===----------------------------------------------------------------------===//
116
117/// This class provides default implementations for FoldingSetTrait
118/// implementations.
119template <typename T> struct DefaultFoldingSetTrait {
120 struct ContextStorage {};
121
122 static void Profile(const T &X, FoldingSetNodeID &ID) { X.Profile(ID); }
123 static void Profile(T &X, FoldingSetNodeID &ID) { X.Profile(ID); }
124
125 // Equals - Test if the profile for X would match ID, using TempID
126 // to compute a temporary ID if necessary. The default implementation
127 // just calls Profile and does a regular comparison. Implementations
128 // can override this to provide more efficient implementations.
129 static inline bool Equals(T &X, const FoldingSetNodeID &ID,
130 FoldingSetNodeID &TempID);
131};
132
133/// This trait class is used to define behavior of how to "profile" (in the
134/// FoldingSet parlance) an object of a given type.
135/// The default behavior is to invoke a 'Profile' method on an object, but
136/// through template specialization the behavior can be tailored for specific
137/// types. Combined with the FoldingSetNodeWrapper class, one can add objects
138/// to FoldingSets that were not originally designed to have that behavior.
139template <typename T, typename Enable = void>
141
142/// Like DefaultFoldingSetTrait, but for ContextualFoldingSets.
143template <typename T, typename Ctx> struct DefaultContextualFoldingSetTrait {
147 Ctx getContext() const { return Context; }
148 };
149
150 static void Profile(T &X, FoldingSetNodeID &ID, Ctx Context) {
151 X.Profile(ID, Context);
152 }
153
154 static inline bool Equals(T &X, const FoldingSetNodeID &ID,
155 FoldingSetNodeID &TempID, Ctx Context);
156};
157
158/// Like FoldingSetTrait, but for ContextualFoldingSets.
159template <typename T, typename Ctx>
161
162//===--------------------------------------------------------------------===//
163/// This class describes a reference to an interned FoldingSetNodeID, which can
164/// be a useful to store node id data rather than using plain FoldingSetNodeIDs,
165/// since the 32-element SmallVector is often much larger than necessary, and
166/// the possibility of heap allocation means it requires a non-trivial
167/// destructor call.
169 const unsigned *Data = nullptr;
170 size_t Size = 0;
171
172public:
174 FoldingSetNodeIDRef(const unsigned *D, size_t S) : Data(D), Size(S) {}
175
176 static constexpr unsigned NotAHash = 0;
177
178 // Compute a strong hash value used to lookup the node in the FoldingSetBase.
179 // The hash value is not guaranteed to be deterministic across processes.
180 // Never returns NotAHash: FoldingSetBase uses it to keep the InsertPos token
181 // non-null and to mark a node belonging to no set.
182 unsigned ComputeHash() const {
183 unsigned Hash =
184 static_cast<unsigned>(hash_combine_range(Data, Data + Size));
185 return Hash == NotAHash ? 1 : Hash;
186 }
187
188 // Compute a deterministic hash value across processes that is suitable for
189 // on-disk serialization.
190 unsigned computeStableHash() const {
191 return static_cast<unsigned>(xxh3_64bits(
192 reinterpret_cast<const uint8_t *>(Data), sizeof(unsigned) * Size));
193 }
194
196
197 bool operator!=(FoldingSetNodeIDRef RHS) const { return !(*this == RHS); }
198
199 /// Used to compare the "ordering" of two nodes as defined by the
200 /// profiled bits and their ordering defined by memcmp().
202
203 const unsigned *getData() const { return Data; }
204 size_t getSize() const { return Size; }
205};
206
207//===--------------------------------------------------------------------===//
208/// This class is used to gather all the unique data bits of a node. When all
209/// the bits are gathered this class is used to produce a hash value for the
210/// node.
212 /// Vector of all the data bits that make the node unique.
213 /// Use a SmallVector to avoid a heap allocation in the common case.
215
216 template <typename T> void AddIntegerImpl(T I) {
217 static_assert(std::is_integral_v<T> && sizeof(T) <= sizeof(unsigned) * 2,
218 "T must be an integer type no wider than 64 bits");
219 Bits.push_back(static_cast<unsigned>(I));
220 if constexpr (sizeof(unsigned) < sizeof(T))
221 Bits.push_back(static_cast<unsigned long long>(I) >> 32);
222 }
223
224public:
225 FoldingSetNodeID() = default;
226
228 : Bits(Ref.getData(), Ref.getData() + Ref.getSize()) {}
229
230 /// Add* - Add various data types to Bit data.
231 void AddPointer(const void *Ptr) {
232 // Note: this adds pointers to the hash using sizes and endianness that
233 // depend on the host. It doesn't matter, however, because hashing on
234 // pointer values is inherently unstable. Nothing should depend on the
235 // ordering of nodes in the folding set.
236 static_assert(sizeof(uintptr_t) <= sizeof(unsigned long long),
237 "unexpected pointer size");
238 AddInteger(reinterpret_cast<uintptr_t>(Ptr));
239 }
240 void AddInteger(signed I) { AddIntegerImpl(I); }
241 void AddInteger(unsigned I) { AddIntegerImpl(I); }
242 void AddInteger(long I) { AddIntegerImpl(I); }
243 void AddInteger(unsigned long I) { AddIntegerImpl(I); }
244 void AddInteger(long long I) { AddIntegerImpl(I); }
245 void AddInteger(unsigned long long I) { AddIntegerImpl(I); }
246 void AddBoolean(bool B) { AddInteger(B ? 1U : 0U); }
248 LLVM_ABI void AddNodeID(const FoldingSetNodeID &ID);
249
250 template <typename T> inline void Add(const T &x) {
252 }
253
254 /// Clear the accumulated profile, allowing this FoldingSetNodeID
255 /// object to be used to compute a new profile.
256 inline void clear() { Bits.clear(); }
257
258 // Compute a strong hash value for this FoldingSetNodeID, used to lookup the
259 // node in the FoldingSetBase. The hash value is not guaranteed to be
260 // deterministic across processes.
261 unsigned ComputeHash() const {
262 return FoldingSetNodeIDRef(Bits.data(), Bits.size()).ComputeHash();
263 }
264
265 // Compute a deterministic hash value across processes that is suitable for
266 // on-disk serialization.
267 unsigned computeStableHash() const {
268 return FoldingSetNodeIDRef(Bits.data(), Bits.size()).computeStableHash();
269 }
270
271 /// operator== - Used to compare two nodes to each other.
272 LLVM_ABI bool operator==(const FoldingSetNodeID &RHS) const;
273 LLVM_ABI bool operator==(const FoldingSetNodeIDRef RHS) const;
274
275 bool operator!=(const FoldingSetNodeID &RHS) const { return !(*this == RHS); }
277 return !(*this == RHS);
278 }
279
280 /// Used to compare the "ordering" of two nodes as defined by the
281 /// profiled bits and their ordering defined by memcmp().
282 LLVM_ABI bool operator<(const FoldingSetNodeID &RHS) const;
283 LLVM_ABI bool operator<(const FoldingSetNodeIDRef RHS) const;
284
285 /// Copy this node's data to a memory region allocated from the
286 /// given allocator and return a FoldingSetNodeIDRef describing the
287 /// interned data.
289};
290
291//===----------------------------------------------------------------------===//
292/// Non-templated base class for FoldingSet and ContextualFoldingSet, holding
293/// the memory management and probing that does not depend on the node type.
295protected:
296 /// Array of node pointers; a null entry marks an empty slot.
297 void **Buckets = nullptr;
298
299 /// Length of the Buckets array. Always a power of 2.
300 unsigned NumBuckets = 0;
301
302 /// Number of nodes in the folding set.
303 unsigned NumNodes = 0;
304
305 LLVM_ABI explicit FoldingSetBase(unsigned Log2InitSize);
309
310public:
311 //===--------------------------------------------------------------------===//
312 /// This class is used to maintain node state in a folding set.
313 class Node {
314 private:
315 // Hash of the node's profile, cached so that growth and removal never
316 // re-run Profile(). NotAHash while the node is in no folding set.
318
319 public:
320 Node() = default;
321
322 // Accessors
323 uint32_t getFoldingSetHash() const { return FoldingSetHash; }
324 void setFoldingSetHash(uint32_t Hash) { FoldingSetHash = Hash; }
325 };
326
327 /// Remove all nodes from the folding set.
328 LLVM_ABI void clear();
329
330 /// Returns the number of nodes in the folding set.
331 unsigned size() const { return NumNodes; }
332
333 /// Returns true if there are no nodes in the folding set.
334 [[nodiscard]] bool empty() const { return NumNodes == 0; }
335
336 /// Grow the number of buckets so that we can hold at least \p N nodes
337 /// before rebucketing. May allocate more space than requested.
338 LLVM_ABI void reserve(unsigned N);
339
340protected:
341 /// Functions provided by the derived class to compute folding properties.
342 /// This is effectively a vtable for FoldingSetBase, except that we don't
343 /// actually store a pointer to it in the object.
345 /// Instantiations of the FoldingSet template implement this function to
346 /// gather data bits for the given node.
347 void (*GetNodeProfile)(const FoldingSetBase *Self, Node *N,
348 FoldingSetNodeID &ID);
349
350 /// Instantiations of the FoldingSet template implement this function to
351 /// compare the given node with the given ID.
353 const FoldingSetNodeID &ID, FoldingSetNodeID &TempID);
354 };
355
356private:
357 /// Put \p N in the first empty slot following its home, without checking
358 /// capacity. Does not touch \p N, so a rehash need not dirty every node.
359 void placeNode(Node *N, uint32_t Hash);
360
361 /// Compare \p N against \p ID. Out of line to keep FoldingSetNodeID's inline
362 /// storage out of the probe loop's frame.
363 static bool nodeEquals(const FoldingSetInfo &Info, const FoldingSetBase *Self,
364 Node *N, const FoldingSetNodeID &ID);
365
366 /// Rehash into at least \p MinNumBuckets buckets, rounded up to a power of
367 /// two and floored at the constructor's minimum.
368 void grow(unsigned MinNumBuckets);
369
370protected:
371 // The below methods are protected to encourage subclasses to provide a more
372 // type-safe API.
373
374 /// Remove a node from the folding set, returning true if one
375 /// was removed or false if the node was not in the folding set.
376 LLVM_ABI bool RemoveNode(Node *N);
377
378 /// If there is an existing node exactly equal to the node \p N,
379 /// return it. Otherwise, insert \p N and return it instead.
381
382 /// Look up the node specified by ID. If it exists, return it. If not,
383 /// return the insertion token that will make insertion faster.
385 void *&InsertPos,
386 const FoldingSetInfo &Info);
387
388 /// Insert the specified node into the folding set, knowing that
389 /// it is not already in the folding set. InsertPos must be obtained from
390 /// FindNodeOrInsertPos for an ID that \p N profiles identically to.
391 LLVM_ABI void InsertNode(Node *N, void *InsertPos);
392};
393
394// Convenience type to hide the implementation of the folding set.
396template <class T> class FoldingSetIterator;
397
398// Definitions of FoldingSetTrait and ContextualFoldingSetTrait functions, which
399// require the definition of FoldingSetNodeID.
400template <typename T>
402 FoldingSetNodeID &TempID) {
404 return TempID == ID;
405}
406template <typename T, typename Ctx>
408 T &X, const FoldingSetNodeID &ID, FoldingSetNodeID &TempID, Ctx Context) {
410 return TempID == ID;
411}
412
413//===----------------------------------------------------------------------===//
414/// An implementation detail that lets us share code between FoldingSet and
415/// ContextualFoldingSet.
416template <class T, class Trait = FoldingSetTrait<T>>
417class FoldingSetImpl : public FoldingSetBase, public Trait::ContextStorage {
418 // We define Info inside a static member function rather than as a static
419 // constexpr member variable to avoid eager instantiation on MSVC when T is an
420 // incomplete type.
421 static const FoldingSetBase::FoldingSetInfo &getFoldingSetInfo() {
422 static constexpr FoldingSetBase::FoldingSetInfo Info = {
423 // GetNodeProfile
425 FoldingSetNodeID &ID) {
426 if constexpr (std::is_empty_v<typename Trait::ContextStorage>)
427 Trait::Profile(*static_cast<T *>(N), ID);
428 else
429 Trait::Profile(
430 *static_cast<T *>(N), ID,
431 static_cast<const FoldingSetImpl *>(Base)->getContext());
432 },
433 // NodeEquals
435 const FoldingSetNodeID &ID, FoldingSetNodeID &TempID) {
436 if constexpr (std::is_empty_v<typename Trait::ContextStorage>)
437 return Trait::Equals(*static_cast<T *>(N), ID, TempID);
438 else
439 return Trait::Equals(
440 *static_cast<T *>(N), ID, TempID,
441 static_cast<const FoldingSetImpl *>(Base)->getContext());
442 }};
443 return Info;
444 }
445
446public:
447 explicit FoldingSetImpl(unsigned Log2InitSize = 6)
448 : FoldingSetBase(Log2InitSize) {}
449
450 template <typename C, typename = std::enable_if_t<std::is_constructible_v<
451 typename Trait::ContextStorage, C>>>
452 explicit FoldingSetImpl(C &&Context, unsigned Log2InitSize = 6)
453 : FoldingSetBase(Log2InitSize),
454 Trait::ContextStorage(std::forward<C>(Context)) {}
455
458 ~FoldingSetImpl() = default;
459
460public:
462
465 return iterator(Buckets + NumBuckets, Buckets + NumBuckets, this);
466 }
467
469
471 return const_iterator(Buckets, Buckets + NumBuckets, this);
472 }
475 }
476
477 /// Remove a node from the folding set, returning true if one
478 /// was removed or false if the node was not in the folding set.
480
481 /// If there is an existing node exactly equal to the specified node,
482 /// return it. Otherwise, insert 'N' and return it instead.
484 return static_cast<T *>(
485 FoldingSetBase::GetOrInsertNode(N, getFoldingSetInfo()));
486 }
487
488 /// Look up the node specified by ID. If it exists, return it. If not,
489 /// return the insertion token that will make insertion faster.
490 T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
491 return static_cast<T *>(FoldingSetBase::FindNodeOrInsertPos(
492 ID, InsertPos, getFoldingSetInfo()));
493 }
494
495 /// Insert the specified node into the folding set, knowing that
496 /// it is not already in the folding set. InsertPos must be obtained from
497 /// FindNodeOrInsertPos.
498 void InsertNode(T *N, void *InsertPos) {
499 FoldingSetBase::InsertNode(N, InsertPos);
500 }
501
502 /// Insert the specified node into the folding set, knowing that it is not
503 /// already in the folding set.
504 void InsertNode(T *N) {
505 T *Inserted = GetOrInsertNode(N);
506 (void)Inserted;
507 assert(Inserted == N && "Node already inserted!");
508 }
509};
510
511//===----------------------------------------------------------------------===//
512/// This template class is used to instantiate a specialized
513/// implementation of the folding set to the node class T. T must be a
514/// subclass of FoldingSetNode and implement a Profile function.
515///
516/// Note that this set type is movable and move-assignable. However, its
517/// moved-from state is not a valid state for anything other than
518/// move-assigning and destroying. This is primarily to enable movable APIs
519/// that incorporate these objects.
520template <class T, class Trait = FoldingSetTrait<T>>
522
523//===----------------------------------------------------------------------===//
524/// This template class is a further refinement of FoldingSet which provides a
525/// context argument when calling Profile on its nodes. Currently, that
526/// argument is fixed at initialization time.
527///
528/// T must be a subclass of FoldingSetNode and implement a Profile
529/// function with signature
530/// void Profile(FoldingSetNodeID &, Ctx);
531template <class T, class Ctx>
534
535//===----------------------------------------------------------------------===//
536/// This template class combines a FoldingSet and a vector to provide the
537/// interface of FoldingSet but with deterministic iteration order based on the
538/// insertion order. T must be a subclass of FoldingSetNode and implement a
539/// Profile function.
540template <class T, class VectorT = SmallVector<T *, 8>> class FoldingSetVector {
541 FoldingSet<T> Set;
542 VectorT Vector;
543
544public:
545 explicit FoldingSetVector(unsigned Log2InitSize = 6) : Set(Log2InitSize) {}
546
548
549 iterator begin() { return Vector.begin(); }
550 iterator end() { return Vector.end(); }
551
553
554 const_iterator begin() const { return Vector.begin(); }
555 const_iterator end() const { return Vector.end(); }
556
557 /// Remove all nodes from the folding set.
558 void clear() {
559 Set.clear();
560 Vector.clear();
561 }
562
563 /// Look up the node specified by ID. If it exists, return it. If not,
564 /// return the insertion token that will make insertion faster.
565 T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
566 return Set.FindNodeOrInsertPos(ID, InsertPos);
567 }
568
569 /// If there is an existing node exactly equal to the specified node,
570 /// return it. Otherwise, insert 'N' and return it instead.
572 T *Result = Set.GetOrInsertNode(N);
573 if (Result == N)
574 Vector.push_back(N);
575 return Result;
576 }
577
578 /// Insert the specified node into the folding set, knowing that
579 /// it is not already in the folding set. InsertPos must be obtained from
580 /// FindNodeOrInsertPos.
581 void InsertNode(T *N, void *InsertPos) {
582 Set.InsertNode(N, InsertPos);
583 Vector.push_back(N);
584 }
585
586 /// Insert the specified node into the folding set, knowing that
587 /// it is not already in the folding set.
588 void InsertNode(T *N) {
589 Set.InsertNode(N);
590 Vector.push_back(N);
591 }
592
593 /// Returns the number of nodes in the folding set.
594 unsigned size() const { return Set.size(); }
595
596 /// Returns true if there are no nodes in the folding set.
597 [[nodiscard]] bool empty() const { return Set.empty(); }
598};
599
600//===----------------------------------------------------------------------===//
601/// Forward iterator for FoldingSet and ContextualFoldingSet.
603 void **Bucket = nullptr;
604 void **End = nullptr;
605
606 void advance() {
607 assert(isHandleInSync() && "invalid iterator access!");
608 do
609 ++Bucket;
610 while (Bucket != End && *Bucket == nullptr);
611 }
612
613public:
614 FoldingSetIterator(void **Bucket, void **End, const DebugEpochBase *Epoch)
615 : DebugEpochBase::HandleBase(Epoch), Bucket(Bucket), End(End) {
616 while (this->Bucket != this->End && *this->Bucket == nullptr)
617 ++this->Bucket;
618 }
619
620 T &operator*() const {
621 assert(isHandleInSync() && "invalid iterator access!");
622 return *static_cast<T *>(*Bucket);
623 }
624
625 T *operator->() const { return &operator*(); }
626
627 inline FoldingSetIterator &operator++() { // Preincrement
628 advance();
629 return *this;
630 }
631 FoldingSetIterator operator++(int) { // Postincrement
632 FoldingSetIterator tmp = *this;
633 ++*this;
634 return tmp;
635 }
636
637 bool operator==(const FoldingSetIterator &RHS) const {
638 assert(isHandleInSync() && RHS.isHandleInSync() && "handle not in sync!");
639 return Bucket == RHS.Bucket;
640 }
641 bool operator!=(const FoldingSetIterator &RHS) const {
642 return !(*this == RHS);
643 }
644};
645
646//===----------------------------------------------------------------------===//
647/// This template class is used to "wrap" arbitrary types in an enclosing object
648/// so that they can be inserted into FoldingSets.
649template <typename T> class FoldingSetNodeWrapper : public FoldingSetNode {
650 T data;
651
652public:
653 template <typename... Ts>
654 explicit FoldingSetNodeWrapper(Ts &&...Args)
655 : data(std::forward<Ts>(Args)...) {}
656
658
659 T &getValue() { return data; }
660 const T &getValue() const { return data; }
661
662 operator T &() { return data; }
663 operator const T &() const { return data; }
664};
665
666//===----------------------------------------------------------------------===//
667/// This is a subclass of FoldingSetNode which stores a FoldingSetNodeID value
668/// rather than requiring the node to recompute it each time it is needed. This
669/// trades space for speed (which can be significant if the ID is long), and it
670/// also permits nodes to drop information that would otherwise only be required
671/// for recomputing an ID.
673 FoldingSetNodeID FastID;
674
675protected:
676 explicit FastFoldingSetNode(const FoldingSetNodeID &ID) : FastID(ID) {}
677
678public:
679 void Profile(FoldingSetNodeID &ID) const { ID.AddNodeID(FastID); }
680};
681
682//===----------------------------------------------------------------------===//
683// Partial specializations of FoldingSetTrait.
684
685template <typename T> struct FoldingSetTrait<T *> {
686 static inline void Profile(T *X, FoldingSetNodeID &ID) { ID.AddPointer(X); }
687};
688template <typename T1, typename T2> struct FoldingSetTrait<std::pair<T1, T2>> {
689 static inline void Profile(const std::pair<T1, T2> &P, FoldingSetNodeID &ID) {
690 ID.Add(P.first);
691 ID.Add(P.second);
692 }
693};
694
695template <typename T>
696struct FoldingSetTrait<T, std::enable_if_t<std::is_enum<T>::value>> {
697 static void Profile(const T &X, FoldingSetNodeID &ID) {
698 ID.AddInteger(llvm::to_underlying(X));
699 }
700};
701
702} // namespace llvm
703
704#endif // LLVM_ADT_FOLDINGSET_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the BumpPtrAllocator interface.
#define X(NUM, ENUM, NAME)
Definition ELF.h:857
static GCRegistry::Add< ShadowStackGC > C("shadow-stack", "Very portable GC for uncooperative code generators")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
#define LLVM_ABI
Definition Compiler.h:215
This file defines the DebugEpochBase and DebugEpochBase::HandleBase classes.
#define I(x, y, z)
Definition MD5.cpp:57
#define T
#define P(N)
Basic Register Allocator
Func getContext().diagnose(DiagnosticInfoUnsupported(Func
This file contains library features backported from future STL versions.
This file defines the SmallVector class.
Value * RHS
static unsigned getSize(unsigned Kind)
FastFoldingSetNode(const FoldingSetNodeID &ID)
Definition FoldingSet.h:676
void Profile(FoldingSetNodeID &ID) const
Definition FoldingSet.h:679
This class is used to maintain node state in a folding set.
Definition FoldingSet.h:313
uint32_t getFoldingSetHash() const
Definition FoldingSet.h:323
void setFoldingSetHash(uint32_t Hash)
Definition FoldingSet.h:324
Non-templated base class for FoldingSet and ContextualFoldingSet, holding the memory management and p...
Definition FoldingSet.h:294
void ** Buckets
Array of node pointers; a null entry marks an empty slot.
Definition FoldingSet.h:297
unsigned size() const
Returns the number of nodes in the folding set.
Definition FoldingSet.h:331
LLVM_ABI bool RemoveNode(Node *N)
Remove a node from the folding set, returning true if one was removed or false if the node was not in...
LLVM_ABI FoldingSetBase & operator=(FoldingSetBase &&RHS)
LLVM_ABI ~FoldingSetBase()
unsigned NumBuckets
Length of the Buckets array. Always a power of 2.
Definition FoldingSet.h:300
unsigned NumNodes
Number of nodes in the folding set.
Definition FoldingSet.h:303
LLVM_ABI Node * GetOrInsertNode(Node *N, const FoldingSetInfo &Info)
If there is an existing node exactly equal to the node N, return it.
bool empty() const
Returns true if there are no nodes in the folding set.
Definition FoldingSet.h:334
LLVM_ABI void reserve(unsigned N)
Grow the number of buckets so that we can hold at least N nodes before rebucketing.
LLVM_ABI void InsertNode(Node *N, void *InsertPos)
Insert the specified node into the folding set, knowing that it is not already in the folding set.
LLVM_ABI void clear()
Remove all nodes from the folding set.
LLVM_ABI Node * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos, const FoldingSetInfo &Info)
Look up the node specified by ID.
LLVM_ABI FoldingSetBase(unsigned Log2InitSize)
An implementation detail that lets us share code between FoldingSet and ContextualFoldingSet.
Definition FoldingSet.h:417
FoldingSetImpl(FoldingSetImpl &&Arg)=default
FoldingSetImpl(C &&Context, unsigned Log2InitSize=6)
Definition FoldingSet.h:452
const_iterator begin() const
Definition FoldingSet.h:470
FoldingSetImpl & operator=(FoldingSetImpl &&RHS)=default
FoldingSetIterator< const T > const_iterator
Definition FoldingSet.h:468
const_iterator end() const
Definition FoldingSet.h:473
FoldingSetIterator< T > iterator
Definition FoldingSet.h:461
FoldingSetImpl(unsigned Log2InitSize=6)
Definition FoldingSet.h:447
T * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)
Definition FoldingSet.h:490
void InsertNode(T *N, void *InsertPos)
Definition FoldingSet.h:498
Forward iterator for FoldingSet and ContextualFoldingSet.
Definition FoldingSet.h:602
bool operator==(const FoldingSetIterator &RHS) const
Definition FoldingSet.h:637
FoldingSetIterator operator++(int)
Definition FoldingSet.h:631
bool operator!=(const FoldingSetIterator &RHS) const
Definition FoldingSet.h:641
FoldingSetIterator(void **Bucket, void **End, const DebugEpochBase *Epoch)
Definition FoldingSet.h:614
FoldingSetIterator & operator++()
Definition FoldingSet.h:627
This class describes a reference to an interned FoldingSetNodeID, which can be a useful to store node...
Definition FoldingSet.h:168
unsigned computeStableHash() const
Definition FoldingSet.h:190
LLVM_ABI bool operator==(FoldingSetNodeIDRef) const
FoldingSetNodeIDRef(const unsigned *D, size_t S)
Definition FoldingSet.h:174
LLVM_ABI bool operator<(FoldingSetNodeIDRef) const
Used to compare the "ordering" of two nodes as defined by the profiled bits and their ordering define...
bool operator!=(FoldingSetNodeIDRef RHS) const
Definition FoldingSet.h:197
unsigned ComputeHash() const
Definition FoldingSet.h:182
const unsigned * getData() const
Definition FoldingSet.h:203
static constexpr unsigned NotAHash
Definition FoldingSet.h:176
This class is used to gather all the unique data bits of a node.
Definition FoldingSet.h:211
LLVM_ABI FoldingSetNodeIDRef Intern(BumpPtrAllocator &Allocator) const
Copy this node's data to a memory region allocated from the given allocator and return a FoldingSetNo...
void AddInteger(signed I)
Definition FoldingSet.h:240
void AddInteger(unsigned long I)
Definition FoldingSet.h:243
FoldingSetNodeID(FoldingSetNodeIDRef Ref)
Definition FoldingSet.h:227
unsigned computeStableHash() const
Definition FoldingSet.h:267
void AddPointer(const void *Ptr)
Add* - Add various data types to Bit data.
Definition FoldingSet.h:231
bool operator!=(const FoldingSetNodeIDRef RHS) const
Definition FoldingSet.h:276
void clear()
Clear the accumulated profile, allowing this FoldingSetNodeID object to be used to compute a new prof...
Definition FoldingSet.h:256
void AddInteger(unsigned I)
Definition FoldingSet.h:241
void AddInteger(long I)
Definition FoldingSet.h:242
void AddBoolean(bool B)
Definition FoldingSet.h:246
LLVM_ABI bool operator==(const FoldingSetNodeID &RHS) const
operator== - Used to compare two nodes to each other.
bool operator!=(const FoldingSetNodeID &RHS) const
Definition FoldingSet.h:275
void AddInteger(unsigned long long I)
Definition FoldingSet.h:245
void AddInteger(long long I)
Definition FoldingSet.h:244
unsigned ComputeHash() const
Definition FoldingSet.h:261
LLVM_ABI bool operator<(const FoldingSetNodeID &RHS) const
Used to compare the "ordering" of two nodes as defined by the profiled bits and their ordering define...
LLVM_ABI void AddNodeID(const FoldingSetNodeID &ID)
void Add(const T &x)
Definition FoldingSet.h:250
LLVM_ABI void AddString(StringRef String)
const T & getValue() const
Definition FoldingSet.h:660
FoldingSetNodeWrapper(Ts &&...Args)
Definition FoldingSet.h:654
void Profile(FoldingSetNodeID &ID)
Definition FoldingSet.h:657
T * GetOrInsertNode(T *N)
If there is an existing node exactly equal to the specified node, return it.
Definition FoldingSet.h:571
const_iterator end() const
Definition FoldingSet.h:555
void InsertNode(T *N)
Insert the specified node into the folding set, knowing that it is not already in the folding set.
Definition FoldingSet.h:588
T * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)
Look up the node specified by ID.
Definition FoldingSet.h:565
unsigned size() const
Returns the number of nodes in the folding set.
Definition FoldingSet.h:594
pointee_iterator< typename VectorT::const_iterator > const_iterator
Definition FoldingSet.h:552
pointee_iterator< typename VectorT::iterator > iterator
Definition FoldingSet.h:547
void clear()
Remove all nodes from the folding set.
Definition FoldingSet.h:558
bool empty() const
Returns true if there are no nodes in the folding set.
Definition FoldingSet.h:597
FoldingSetVector(unsigned Log2InitSize=6)
Definition FoldingSet.h:545
void InsertNode(T *N, void *InsertPos)
Insert the specified node into the folding set, knowing that it is not already in the folding set.
Definition FoldingSet.h:581
const_iterator begin() const
Definition FoldingSet.h:554
void push_back(const T &Elt)
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Represent a constant reference to a string, i.e.
Definition StringRef.h:56
This is an optimization pass for GlobalISel generic memory operations.
uint64_t xxh3_64bits(ArrayRef< uint8_t > data)
Inline ArrayRef overloads of the xxhash entry points declared out-of-line in llvm/Support/xxhash....
Definition ArrayRef.h:558
FoldingSetBase::Node FoldingSetNode
Definition FoldingSet.h:395
constexpr std::underlying_type_t< Enum > to_underlying(Enum E)
Returns underlying integer value of an enum.
@ Ref
The access may reference the value stored in memory.
Definition ModRef.h:32
FoldingSetImpl< T, ContextualFoldingSetTrait< T, Ctx > > ContextualFoldingSet
This template class is a further refinement of FoldingSet which provides a context argument when call...
Definition FoldingSet.h:532
BumpPtrAllocatorImpl<> BumpPtrAllocator
The standard BumpPtrAllocator which just uses the default template parameters.
Definition Allocator.h:390
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition Hashing.h:285
FoldingSetImpl< T, Trait > FoldingSet
This template class is used to instantiate a specialized implementation of the folding set to the nod...
Definition FoldingSet.h:521
Implement std::hash so that hash_code can be used in STL containers.
Definition BitVector.h:878
#define N
Like FoldingSetTrait, but for ContextualFoldingSets.
Definition FoldingSet.h:160
Like DefaultFoldingSetTrait, but for ContextualFoldingSets.
Definition FoldingSet.h:143
static bool Equals(T &X, const FoldingSetNodeID &ID, FoldingSetNodeID &TempID, Ctx Context)
Definition FoldingSet.h:407
static void Profile(T &X, FoldingSetNodeID &ID, Ctx Context)
Definition FoldingSet.h:150
This class provides default implementations for FoldingSetTrait implementations.
Definition FoldingSet.h:119
static bool Equals(T &X, const FoldingSetNodeID &ID, FoldingSetNodeID &TempID)
Definition FoldingSet.h:401
static void Profile(const T &X, FoldingSetNodeID &ID)
Definition FoldingSet.h:122
static void Profile(T &X, FoldingSetNodeID &ID)
Definition FoldingSet.h:123
Functions provided by the derived class to compute folding properties.
Definition FoldingSet.h:344
void(* GetNodeProfile)(const FoldingSetBase *Self, Node *N, FoldingSetNodeID &ID)
Instantiations of the FoldingSet template implement this function to gather data bits for the given n...
Definition FoldingSet.h:347
bool(* NodeEquals)(const FoldingSetBase *Self, Node *N, const FoldingSetNodeID &ID, FoldingSetNodeID &TempID)
Instantiations of the FoldingSet template implement this function to compare the given node with the ...
Definition FoldingSet.h:352
static void Profile(T *X, FoldingSetNodeID &ID)
Definition FoldingSet.h:686
static void Profile(const std::pair< T1, T2 > &P, FoldingSetNodeID &ID)
Definition FoldingSet.h:689
This trait class is used to define behavior of how to "profile" (in the FoldingSet parlance) an objec...
Definition FoldingSet.h:140
An iterator type that allows iterating over the pointees via some other iterator.
Definition iterator.h:329