LLVM 22.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
19#include "llvm/ADT/Hashing.h"
22#include "llvm/ADT/iterator.h"
25#include "llvm/Support/xxhash.h"
26#include <cassert>
27#include <cstddef>
28#include <cstdint>
29#include <type_traits>
30#include <utility>
31
32namespace llvm {
33
34/// This folding set used for two purposes:
35/// 1. Given information about a node we want to create, look up the unique
36/// instance of the node in the set. If the node already exists, return
37/// it, otherwise return the bucket it should be inserted into.
38/// 2. Given a node that has already been created, remove it from the set.
39///
40/// This class is implemented as a single-link chained hash table, where the
41/// "buckets" are actually the nodes themselves (the next pointer is in the
42/// node). The last node points back to the bucket to simplify node removal.
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 FoldingSetBase::NodeID 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/// MyFoldingSet.InsertNode(M, InsertPoint);
101///
102/// 4) Finally, if you want to remove a node from the folding set call;
103///
104/// bool WasRemoved = MyFoldingSet.RemoveNode(M);
105///
106/// The result indicates whether the node existed in the folding set.
107
108class FoldingSetNodeID;
109class StringRef;
110
111//===----------------------------------------------------------------------===//
112/// FoldingSetBase - Implements the folding set functionality. The main
113/// structure is an array of buckets. Each bucket is indexed by the hash of
114/// the nodes it contains. The bucket itself points to the nodes contained
115/// in the bucket via a singly linked list. The last node in the list points
116/// back to the bucket to facilitate node removal.
117///
119protected:
120 /// Buckets - Array of bucket chains.
121 void **Buckets;
122
123 /// NumBuckets - Length of the Buckets array. Always a power of 2.
124 unsigned NumBuckets;
125
126 /// NumNodes - Number of nodes in the folding set. Growth occurs when NumNodes
127 /// is greater than twice the number of buckets.
128 unsigned NumNodes;
129
130 LLVM_ABI explicit FoldingSetBase(unsigned Log2InitSize = 6);
134
135public:
136 //===--------------------------------------------------------------------===//
137 /// Node - This class is used to maintain the singly linked bucket list in
138 /// a folding set.
139 class Node {
140 private:
141 // NextInFoldingSetBucket - next link in the bucket list.
142 void *NextInFoldingSetBucket = nullptr;
143
144 public:
145 Node() = default;
146
147 // Accessors
148 void *getNextInBucket() const { return NextInFoldingSetBucket; }
149 void SetNextInBucket(void *N) { NextInFoldingSetBucket = N; }
150 };
151
152 /// clear - Remove all nodes from the folding set.
153 LLVM_ABI void clear();
154
155 /// size - Returns the number of nodes in the folding set.
156 unsigned size() const { return NumNodes; }
157
158 /// empty - Returns true if there are no nodes in the folding set.
159 bool empty() const { return NumNodes == 0; }
160
161 /// capacity - Returns the number of nodes permitted in the folding set
162 /// before a rebucket operation is performed.
163 unsigned capacity() {
164 // We allow a load factor of up to 2.0,
165 // so that means our capacity is NumBuckets * 2
166 return NumBuckets * 2;
167 }
168
169protected:
170 /// Functions provided by the derived class to compute folding properties.
171 /// This is effectively a vtable for FoldingSetBase, except that we don't
172 /// actually store a pointer to it in the object.
174 /// GetNodeProfile - Instantiations of the FoldingSet template implement
175 /// this function to gather data bits for the given node.
176 void (*GetNodeProfile)(const FoldingSetBase *Self, Node *N,
178
179 /// NodeEquals - Instantiations of the FoldingSet template implement
180 /// this function to compare the given node with the given ID.
182 const FoldingSetNodeID &ID, unsigned IDHash,
183 FoldingSetNodeID &TempID);
184
185 /// ComputeNodeHash - Instantiations of the FoldingSet template implement
186 /// this function to compute a hash value for the given node.
188 FoldingSetNodeID &TempID);
189 };
190
191private:
192 /// GrowHashTable - Double the size of the hash table and rehash everything.
193 void GrowHashTable(const FoldingSetInfo &Info);
194
195 /// GrowBucketCount - resize the hash table and rehash everything.
196 /// NewBucketCount must be a power of two, and must be greater than the old
197 /// bucket count.
198 void GrowBucketCount(unsigned NewBucketCount, const FoldingSetInfo &Info);
199
200protected:
201 // The below methods are protected to encourage subclasses to provide a more
202 // type-safe API.
203
204 /// reserve - Increase the number of buckets such that adding the
205 /// EltCount-th node won't cause a rebucket operation. reserve is permitted
206 /// to allocate more space than requested by EltCount.
207 LLVM_ABI void reserve(unsigned EltCount, const FoldingSetInfo &Info);
208
209 /// RemoveNode - Remove a node from the folding set, returning true if one
210 /// was removed or false if the node was not in the folding set.
211 LLVM_ABI bool RemoveNode(Node *N);
212
213 /// GetOrInsertNode - If there is an existing simple Node exactly
214 /// equal to the specified node, return it. Otherwise, insert 'N' and return
215 /// it instead.
217
218 /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
219 /// return it. If not, return the insertion token that will make insertion
220 /// faster.
222 void *&InsertPos,
223 const FoldingSetInfo &Info);
224
225 /// InsertNode - Insert the specified node into the folding set, knowing that
226 /// it is not already in the folding set. InsertPos must be obtained from
227 /// FindNodeOrInsertPos.
228 LLVM_ABI void InsertNode(Node *N, void *InsertPos,
229 const FoldingSetInfo &Info);
230};
231
232//===----------------------------------------------------------------------===//
233
234/// DefaultFoldingSetTrait - This class provides default implementations
235/// for FoldingSetTrait implementations.
236template<typename T> struct DefaultFoldingSetTrait {
237 static void Profile(const T &X, FoldingSetNodeID &ID) {
238 X.Profile(ID);
239 }
240 static void Profile(T &X, FoldingSetNodeID &ID) {
241 X.Profile(ID);
242 }
243
244 // Equals - Test if the profile for X would match ID, using TempID
245 // to compute a temporary ID if necessary. The default implementation
246 // just calls Profile and does a regular comparison. Implementations
247 // can override this to provide more efficient implementations.
248 static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash,
249 FoldingSetNodeID &TempID);
250
251 // ComputeHash - Compute a hash value for X, using TempID to
252 // compute a temporary ID if necessary. The default implementation
253 // just calls Profile and does a regular hash computation.
254 // Implementations can override this to provide more efficient
255 // implementations.
256 static inline unsigned ComputeHash(T &X, FoldingSetNodeID &TempID);
257};
258
259/// FoldingSetTrait - This trait class is used to define behavior of how
260/// to "profile" (in the FoldingSet parlance) an object of a given type.
261/// The default behavior is to invoke a 'Profile' method on an object, but
262/// through template specialization the behavior can be tailored for specific
263/// types. Combined with the FoldingSetNodeWrapper class, one can add objects
264/// to FoldingSets that were not originally designed to have that behavior.
265template <typename T, typename Enable = void>
267
268/// DefaultContextualFoldingSetTrait - Like DefaultFoldingSetTrait, but
269/// for ContextualFoldingSets.
270template<typename T, typename Ctx>
272 static void Profile(T &X, FoldingSetNodeID &ID, Ctx Context) {
273 X.Profile(ID, Context);
274 }
275
276 static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash,
277 FoldingSetNodeID &TempID, Ctx Context);
278 static inline unsigned ComputeHash(T &X, FoldingSetNodeID &TempID,
279 Ctx Context);
280};
281
282/// ContextualFoldingSetTrait - Like FoldingSetTrait, but for
283/// ContextualFoldingSets.
284template<typename T, typename Ctx> struct ContextualFoldingSetTrait
285 : public DefaultContextualFoldingSetTrait<T, Ctx> {};
286
287//===--------------------------------------------------------------------===//
288/// FoldingSetNodeIDRef - This class describes a reference to an interned
289/// FoldingSetNodeID, which can be a useful to store node id data rather
290/// than using plain FoldingSetNodeIDs, since the 32-element SmallVector
291/// is often much larger than necessary, and the possibility of heap
292/// allocation means it requires a non-trivial destructor call.
294 const unsigned *Data = nullptr;
295 size_t Size = 0;
296
297public:
299 FoldingSetNodeIDRef(const unsigned *D, size_t S) : Data(D), Size(S) {}
300
301 // Compute a strong hash value used to lookup the node in the FoldingSetBase.
302 // The hash value is not guaranteed to be deterministic across processes.
303 unsigned ComputeHash() const {
304 return static_cast<unsigned>(hash_combine_range(Data, Data + Size));
305 }
306
307 // Compute a deterministic hash value across processes that is suitable for
308 // on-disk serialization.
309 unsigned computeStableHash() const {
310 return static_cast<unsigned>(xxh3_64bits(ArrayRef(
311 reinterpret_cast<const uint8_t *>(Data), sizeof(unsigned) * Size)));
312 }
313
314 LLVM_ABI bool operator==(FoldingSetNodeIDRef) const;
315
316 bool operator!=(FoldingSetNodeIDRef RHS) const { return !(*this == RHS); }
317
318 /// Used to compare the "ordering" of two nodes as defined by the
319 /// profiled bits and their ordering defined by memcmp().
321
322 const unsigned *getData() const { return Data; }
323 size_t getSize() const { return Size; }
324};
325
326//===--------------------------------------------------------------------===//
327/// FoldingSetNodeID - This class is used to gather all the unique data bits of
328/// a node. When all the bits are gathered this class is used to produce a
329/// hash value for the node.
331 /// Bits - Vector of all the data bits that make the node unique.
332 /// Use a SmallVector to avoid a heap allocation in the common case.
334
335public:
336 FoldingSetNodeID() = default;
337
339 : Bits(Ref.getData(), Ref.getData() + Ref.getSize()) {}
340
341 /// Add* - Add various data types to Bit data.
342 void AddPointer(const void *Ptr) {
343 // Note: this adds pointers to the hash using sizes and endianness that
344 // depend on the host. It doesn't matter, however, because hashing on
345 // pointer values is inherently unstable. Nothing should depend on the
346 // ordering of nodes in the folding set.
347 static_assert(sizeof(uintptr_t) <= sizeof(unsigned long long),
348 "unexpected pointer size");
349 AddInteger(reinterpret_cast<uintptr_t>(Ptr));
350 }
351 void AddInteger(signed I) { Bits.push_back(I); }
352 void AddInteger(unsigned I) { Bits.push_back(I); }
353 void AddInteger(long I) { AddInteger((unsigned long)I); }
354 void AddInteger(unsigned long I) {
355 if (sizeof(long) == sizeof(int))
356 AddInteger(unsigned(I));
357 else if (sizeof(long) == sizeof(long long)) {
358 AddInteger((unsigned long long)I);
359 } else {
360 llvm_unreachable("unexpected sizeof(long)");
361 }
362 }
363 void AddInteger(long long I) { AddInteger((unsigned long long)I); }
364 void AddInteger(unsigned long long I) {
365 AddInteger(unsigned(I));
366 AddInteger(unsigned(I >> 32));
367 }
368
369 void AddBoolean(bool B) { AddInteger(B ? 1U : 0U); }
372
373 template <typename T>
374 inline void Add(const T &x) { FoldingSetTrait<T>::Profile(x, *this); }
375
376 /// clear - Clear the accumulated profile, allowing this FoldingSetNodeID
377 /// object to be used to compute a new profile.
378 inline void clear() { Bits.clear(); }
379
380 // Compute a strong hash value for this FoldingSetNodeID, used to lookup the
381 // node in the FoldingSetBase. The hash value is not guaranteed to be
382 // deterministic across processes.
383 unsigned ComputeHash() const {
384 return FoldingSetNodeIDRef(Bits.data(), Bits.size()).ComputeHash();
385 }
386
387 // Compute a deterministic hash value across processes that is suitable for
388 // on-disk serialization.
389 unsigned computeStableHash() const {
390 return FoldingSetNodeIDRef(Bits.data(), Bits.size()).computeStableHash();
391 }
392
393 /// operator== - Used to compare two nodes to each other.
394 LLVM_ABI bool operator==(const FoldingSetNodeID &RHS) const;
395 LLVM_ABI bool operator==(const FoldingSetNodeIDRef RHS) const;
396
397 bool operator!=(const FoldingSetNodeID &RHS) const { return !(*this == RHS); }
398 bool operator!=(const FoldingSetNodeIDRef RHS) const { return !(*this ==RHS);}
399
400 /// Used to compare the "ordering" of two nodes as defined by the
401 /// profiled bits and their ordering defined by memcmp().
402 LLVM_ABI bool operator<(const FoldingSetNodeID &RHS) const;
403 LLVM_ABI bool operator<(const FoldingSetNodeIDRef RHS) const;
404
405 /// Intern - Copy this node's data to a memory region allocated from the
406 /// given allocator and return a FoldingSetNodeIDRef describing the
407 /// interned data.
409};
410
411// Convenience type to hide the implementation of the folding set.
413template<class T> class FoldingSetIterator;
414template<class T> class FoldingSetBucketIterator;
415
416// Definitions of FoldingSetTrait and ContextualFoldingSetTrait functions, which
417// require the definition of FoldingSetNodeID.
418template<typename T>
419inline bool
421 unsigned /*IDHash*/,
422 FoldingSetNodeID &TempID) {
424 return TempID == ID;
425}
426template<typename T>
427inline unsigned
430 return TempID.ComputeHash();
431}
432template<typename T, typename Ctx>
433inline bool
435 const FoldingSetNodeID &ID,
436 unsigned /*IDHash*/,
437 FoldingSetNodeID &TempID,
438 Ctx Context) {
440 return TempID == ID;
441}
442template<typename T, typename Ctx>
443inline unsigned
445 FoldingSetNodeID &TempID,
446 Ctx Context) {
448 return TempID.ComputeHash();
449}
450
451//===----------------------------------------------------------------------===//
452/// FoldingSetImpl - An implementation detail that lets us share code between
453/// FoldingSet and ContextualFoldingSet.
454template <class Derived, class T> class FoldingSetImpl : public FoldingSetBase {
455protected:
456 explicit FoldingSetImpl(unsigned Log2InitSize)
457 : FoldingSetBase(Log2InitSize) {}
458
461 ~FoldingSetImpl() = default;
462
463public:
465
468
470
473
475
477 return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
478 }
479
481 return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
482 }
483
484 /// reserve - Increase the number of buckets such that adding the
485 /// EltCount-th node won't cause a rebucket operation. reserve is permitted
486 /// to allocate more space than requested by EltCount.
487 void reserve(unsigned EltCount) {
488 return FoldingSetBase::reserve(EltCount, Derived::getFoldingSetInfo());
489 }
490
491 /// RemoveNode - Remove a node from the folding set, returning true if one
492 /// was removed or false if the node was not in the folding set.
493 bool RemoveNode(T *N) {
495 }
496
497 /// GetOrInsertNode - If there is an existing simple Node exactly
498 /// equal to the specified node, return it. Otherwise, insert 'N' and
499 /// return it instead.
501 return static_cast<T *>(
502 FoldingSetBase::GetOrInsertNode(N, Derived::getFoldingSetInfo()));
503 }
504
505 /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
506 /// return it. If not, return the insertion token that will make insertion
507 /// faster.
508 T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
509 return static_cast<T *>(FoldingSetBase::FindNodeOrInsertPos(
510 ID, InsertPos, Derived::getFoldingSetInfo()));
511 }
512
513 /// InsertNode - Insert the specified node into the folding set, knowing that
514 /// it is not already in the folding set. InsertPos must be obtained from
515 /// FindNodeOrInsertPos.
516 void InsertNode(T *N, void *InsertPos) {
517 FoldingSetBase::InsertNode(N, InsertPos, Derived::getFoldingSetInfo());
518 }
519
520 /// InsertNode - Insert the specified node into the folding set, knowing that
521 /// it is not already in the folding set.
522 void InsertNode(T *N) {
523 T *Inserted = GetOrInsertNode(N);
524 (void)Inserted;
525 assert(Inserted == N && "Node already inserted!");
526 }
527};
528
529//===----------------------------------------------------------------------===//
530/// FoldingSet - This template class is used to instantiate a specialized
531/// implementation of the folding set to the node class T. T must be a
532/// subclass of FoldingSetNode and implement a Profile function.
533///
534/// Note that this set type is movable and move-assignable. However, its
535/// moved-from state is not a valid state for anything other than
536/// move-assigning and destroying. This is primarily to enable movable APIs
537/// that incorporate these objects.
538template <class T>
539class FoldingSet : public FoldingSetImpl<FoldingSet<T>, T> {
541 using Node = typename Super::Node;
542
543 /// GetNodeProfile - Each instantiation of the FoldingSet needs to provide a
544 /// way to convert nodes into a unique specifier.
545 static void GetNodeProfile(const FoldingSetBase *, Node *N,
547 T *TN = static_cast<T *>(N);
549 }
550
551 /// NodeEquals - Instantiations may optionally provide a way to compare a
552 /// node with a specified ID.
553 static bool NodeEquals(const FoldingSetBase *, Node *N,
554 const FoldingSetNodeID &ID, unsigned IDHash,
555 FoldingSetNodeID &TempID) {
556 T *TN = static_cast<T *>(N);
557 return FoldingSetTrait<T>::Equals(*TN, ID, IDHash, TempID);
558 }
559
560 /// ComputeNodeHash - Instantiations may optionally provide a way to compute a
561 /// hash value directly from a node.
562 static unsigned ComputeNodeHash(const FoldingSetBase *, Node *N,
563 FoldingSetNodeID &TempID) {
564 T *TN = static_cast<T *>(N);
565 return FoldingSetTrait<T>::ComputeHash(*TN, TempID);
566 }
567
568 static const FoldingSetBase::FoldingSetInfo &getFoldingSetInfo() {
569 static constexpr FoldingSetBase::FoldingSetInfo Info = {
570 GetNodeProfile, NodeEquals, ComputeNodeHash};
571 return Info;
572 }
573 friend Super;
574
575public:
576 explicit FoldingSet(unsigned Log2InitSize = 6) : Super(Log2InitSize) {}
577 FoldingSet(FoldingSet &&Arg) = default;
579};
580
581//===----------------------------------------------------------------------===//
582/// ContextualFoldingSet - This template class is a further refinement
583/// of FoldingSet which provides a context argument when calling
584/// Profile on its nodes. Currently, that argument is fixed at
585/// initialization time.
586///
587/// T must be a subclass of FoldingSetNode and implement a Profile
588/// function with signature
589/// void Profile(FoldingSetNodeID &, Ctx);
590template <class T, class Ctx>
592 : public FoldingSetImpl<ContextualFoldingSet<T, Ctx>, T> {
593 // Unfortunately, this can't derive from FoldingSet<T> because the
594 // construction of the vtable for FoldingSet<T> requires
595 // FoldingSet<T>::GetNodeProfile to be instantiated, which in turn
596 // requires a single-argument T::Profile().
597
599 using Node = typename Super::Node;
600
601 Ctx Context;
602
603 static const Ctx &getContext(const FoldingSetBase *Base) {
604 return static_cast<const ContextualFoldingSet*>(Base)->Context;
605 }
606
607 /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
608 /// way to convert nodes into a unique specifier.
609 static void GetNodeProfile(const FoldingSetBase *Base, Node *N,
611 T *TN = static_cast<T *>(N);
613 }
614
615 static bool NodeEquals(const FoldingSetBase *Base, Node *N,
616 const FoldingSetNodeID &ID, unsigned IDHash,
617 FoldingSetNodeID &TempID) {
618 T *TN = static_cast<T *>(N);
619 return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID,
621 }
622
623 static unsigned ComputeNodeHash(const FoldingSetBase *Base, Node *N,
624 FoldingSetNodeID &TempID) {
625 T *TN = static_cast<T *>(N);
628 }
629
630 static const FoldingSetBase::FoldingSetInfo &getFoldingSetInfo() {
631 static constexpr FoldingSetBase::FoldingSetInfo Info = {
632 GetNodeProfile, NodeEquals, ComputeNodeHash};
633 return Info;
634 }
635 friend Super;
636
637public:
638 explicit ContextualFoldingSet(Ctx Context, unsigned Log2InitSize = 6)
639 : Super(Log2InitSize), Context(Context) {}
640
641 Ctx getContext() const { return Context; }
642};
643
644//===----------------------------------------------------------------------===//
645/// FoldingSetVector - This template class combines a FoldingSet and a vector
646/// to provide the interface of FoldingSet but with deterministic iteration
647/// order based on the insertion order. T must be a subclass of FoldingSetNode
648/// and implement a Profile function.
649template <class T, class VectorT = SmallVector<T*, 8>>
651 FoldingSet<T> Set;
652 VectorT Vector;
653
654public:
655 explicit FoldingSetVector(unsigned Log2InitSize = 6) : Set(Log2InitSize) {}
656
658
659 iterator begin() { return Vector.begin(); }
660 iterator end() { return Vector.end(); }
661
663
664 const_iterator begin() const { return Vector.begin(); }
665 const_iterator end() const { return Vector.end(); }
666
667 /// clear - Remove all nodes from the folding set.
668 void clear() { Set.clear(); Vector.clear(); }
669
670 /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
671 /// return it. If not, return the insertion token that will make insertion
672 /// faster.
673 T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
674 return Set.FindNodeOrInsertPos(ID, InsertPos);
675 }
676
677 /// GetOrInsertNode - If there is an existing simple Node exactly
678 /// equal to the specified node, return it. Otherwise, insert 'N' and
679 /// return it instead.
681 T *Result = Set.GetOrInsertNode(N);
682 if (Result == N) Vector.push_back(N);
683 return Result;
684 }
685
686 /// InsertNode - Insert the specified node into the folding set, knowing that
687 /// it is not already in the folding set. InsertPos must be obtained from
688 /// FindNodeOrInsertPos.
689 void InsertNode(T *N, void *InsertPos) {
690 Set.InsertNode(N, InsertPos);
691 Vector.push_back(N);
692 }
693
694 /// InsertNode - Insert the specified node into the folding set, knowing that
695 /// it is not already in the folding set.
696 void InsertNode(T *N) {
697 Set.InsertNode(N);
698 Vector.push_back(N);
699 }
700
701 /// size - Returns the number of nodes in the folding set.
702 unsigned size() const { return Set.size(); }
703
704 /// empty - Returns true if there are no nodes in the folding set.
705 bool empty() const { return Set.empty(); }
706};
707
708//===----------------------------------------------------------------------===//
709/// FoldingSetIteratorImpl - This is the common iterator support shared by all
710/// folding sets, which knows how to walk the folding set hash table.
712protected:
714
715 LLVM_ABI FoldingSetIteratorImpl(void **Bucket);
716
717 LLVM_ABI void advance();
718
719public:
721 return NodePtr == RHS.NodePtr;
722 }
724 return NodePtr != RHS.NodePtr;
725 }
726};
727
728template <class T> class FoldingSetIterator : public FoldingSetIteratorImpl {
729public:
730 explicit FoldingSetIterator(void **Bucket) : FoldingSetIteratorImpl(Bucket) {}
731
732 T &operator*() const {
733 return *static_cast<T*>(NodePtr);
734 }
735
736 T *operator->() const {
737 return static_cast<T*>(NodePtr);
738 }
739
740 inline FoldingSetIterator &operator++() { // Preincrement
741 advance();
742 return *this;
743 }
744 FoldingSetIterator operator++(int) { // Postincrement
745 FoldingSetIterator tmp = *this; ++*this; return tmp;
746 }
747};
748
749//===----------------------------------------------------------------------===//
750/// FoldingSetBucketIteratorImpl - This is the common bucket iterator support
751/// shared by all folding sets, which knows how to walk a particular bucket
752/// of a folding set hash table.
754protected:
755 void *Ptr;
756
757 LLVM_ABI explicit FoldingSetBucketIteratorImpl(void **Bucket);
758
759 FoldingSetBucketIteratorImpl(void **Bucket, bool) : Ptr(Bucket) {}
760
761 void advance() {
762 void *Probe = static_cast<FoldingSetNode*>(Ptr)->getNextInBucket();
763 uintptr_t x = reinterpret_cast<uintptr_t>(Probe) & ~0x1;
764 Ptr = reinterpret_cast<void*>(x);
765 }
766
767public:
769 return Ptr == RHS.Ptr;
770 }
772 return Ptr != RHS.Ptr;
773 }
774};
775
776template <class T>
778public:
779 explicit FoldingSetBucketIterator(void **Bucket) :
781
782 FoldingSetBucketIterator(void **Bucket, bool) :
784
785 T &operator*() const { return *static_cast<T*>(Ptr); }
786 T *operator->() const { return static_cast<T*>(Ptr); }
787
788 inline FoldingSetBucketIterator &operator++() { // Preincrement
789 advance();
790 return *this;
791 }
792 FoldingSetBucketIterator operator++(int) { // Postincrement
793 FoldingSetBucketIterator tmp = *this; ++*this; return tmp;
794 }
795};
796
797//===----------------------------------------------------------------------===//
798/// FoldingSetNodeWrapper - This template class is used to "wrap" arbitrary
799/// types in an enclosing object so that they can be inserted into FoldingSets.
800template <typename T>
802 T data;
803
804public:
805 template <typename... Ts>
806 explicit FoldingSetNodeWrapper(Ts &&... Args)
807 : data(std::forward<Ts>(Args)...) {}
808
810
811 T &getValue() { return data; }
812 const T &getValue() const { return data; }
813
814 operator T&() { return data; }
815 operator const T&() const { return data; }
816};
817
818//===----------------------------------------------------------------------===//
819/// FastFoldingSetNode - This is a subclass of FoldingSetNode which stores
820/// a FoldingSetNodeID value rather than requiring the node to recompute it
821/// each time it is needed. This trades space for speed (which can be
822/// significant if the ID is long), and it also permits nodes to drop
823/// information that would otherwise only be required for recomputing an ID.
825 FoldingSetNodeID FastID;
826
827protected:
828 explicit FastFoldingSetNode(const FoldingSetNodeID &ID) : FastID(ID) {}
829
830public:
831 void Profile(FoldingSetNodeID &ID) const { ID.AddNodeID(FastID); }
832};
833
834//===----------------------------------------------------------------------===//
835// Partial specializations of FoldingSetTrait.
836
837template<typename T> struct FoldingSetTrait<T*> {
838 static inline void Profile(T *X, FoldingSetNodeID &ID) {
839 ID.AddPointer(X);
840 }
841};
842template <typename T1, typename T2>
843struct FoldingSetTrait<std::pair<T1, T2>> {
844 static inline void Profile(const std::pair<T1, T2> &P,
846 ID.Add(P.first);
847 ID.Add(P.second);
848 }
849};
850
851template <typename T>
852struct FoldingSetTrait<T, std::enable_if_t<std::is_enum<T>::value>> {
853 static void Profile(const T &X, FoldingSetNodeID &ID) {
854 ID.AddInteger(llvm::to_underlying(X));
855 }
856};
857
858} // end namespace llvm
859
860#endif // LLVM_ADT_FOLDINGSET_H
assert(UImm &&(UImm !=~static_cast< T >(0)) &&"Invalid immediate!")
This file defines the BumpPtrAllocator interface.
static GCRegistry::Add< OcamlGC > B("ocaml", "ocaml 3.10-compatible GC")
static GCRegistry::Add< StatepointGC > D("statepoint-example", "an example strategy for statepoint")
Analysis containing CSE Info
Definition: CSEInfo.cpp:27
#define LLVM_ABI
Definition: Compiler.h:213
static GCMetadataPrinterRegistry::Add< ErlangGCPrinter > X("erlang", "erlang-compatible garbage collector")
#define I(x, y, z)
Definition: MD5.cpp:58
#define P(N)
Basic Register Allocator
This file contains library features backported from future STL versions.
This file defines the SmallVector class.
Value * RHS
static unsigned getSize(unsigned Kind)
ArrayRef - Represent a constant reference to an array (0 or more elements consecutively in memory),...
Definition: ArrayRef.h:41
Allocate memory in an ever growing pool, as if by bump-pointer.
Definition: Allocator.h:67
ContextualFoldingSet - This template class is a further refinement of FoldingSet which provides a con...
Definition: FoldingSet.h:592
ContextualFoldingSet(Ctx Context, unsigned Log2InitSize=6)
Definition: FoldingSet.h:638
FastFoldingSetNode - This is a subclass of FoldingSetNode which stores a FoldingSetNodeID value rathe...
Definition: FoldingSet.h:824
FastFoldingSetNode(const FoldingSetNodeID &ID)
Definition: FoldingSet.h:828
void Profile(FoldingSetNodeID &ID) const
Definition: FoldingSet.h:831
Node - This class is used to maintain the singly linked bucket list in a folding set.
Definition: FoldingSet.h:139
void * getNextInBucket() const
Definition: FoldingSet.h:148
void SetNextInBucket(void *N)
Definition: FoldingSet.h:149
FoldingSetBase - Implements the folding set functionality.
Definition: FoldingSet.h:118
void ** Buckets
Buckets - Array of bucket chains.
Definition: FoldingSet.h:121
unsigned size() const
size - Returns the number of nodes in the folding set.
Definition: FoldingSet.h:156
LLVM_ABI void reserve(unsigned EltCount, const FoldingSetInfo &Info)
reserve - Increase the number of buckets such that adding the EltCount-th node won't cause a rebucket...
Definition: FoldingSet.cpp:266
LLVM_ABI bool RemoveNode(Node *N)
RemoveNode - Remove a node from the folding set, returning true if one was removed or false if the no...
Definition: FoldingSet.cpp:334
LLVM_ABI FoldingSetBase & operator=(FoldingSetBase &&RHS)
Definition: FoldingSet.cpp:198
LLVM_ABI ~FoldingSetBase()
Definition: FoldingSet.cpp:209
unsigned NumBuckets
NumBuckets - Length of the Buckets array. Always a power of 2.
Definition: FoldingSet.h:124
unsigned NumNodes
NumNodes - Number of nodes in the folding set.
Definition: FoldingSet.h:128
unsigned capacity()
capacity - Returns the number of nodes permitted in the folding set before a rebucket operation is pe...
Definition: FoldingSet.h:163
LLVM_ABI Node * GetOrInsertNode(Node *N, const FoldingSetInfo &Info)
GetOrInsertNode - If there is an existing simple Node exactly equal to the specified node,...
Definition: FoldingSet.cpp:376
bool empty() const
empty - Returns true if there are no nodes in the folding set.
Definition: FoldingSet.h:159
LLVM_ABI void InsertNode(Node *N, void *InsertPos, const FoldingSetInfo &Info)
InsertNode - Insert the specified node into the folding set, knowing that it is not already in the fo...
Definition: FoldingSet.cpp:303
LLVM_ABI void clear()
clear - Remove all nodes from the folding set.
Definition: FoldingSet.cpp:213
LLVM_ABI Node * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos, const FoldingSetInfo &Info)
FindNodeOrInsertPos - Look up the node specified by ID.
Definition: FoldingSet.cpp:278
FoldingSetBucketIteratorImpl - This is the common bucket iterator support shared by all folding sets,...
Definition: FoldingSet.h:753
FoldingSetBucketIteratorImpl(void **Bucket, bool)
Definition: FoldingSet.h:759
bool operator!=(const FoldingSetBucketIteratorImpl &RHS) const
Definition: FoldingSet.h:771
bool operator==(const FoldingSetBucketIteratorImpl &RHS) const
Definition: FoldingSet.h:768
FoldingSetBucketIterator(void **Bucket, bool)
Definition: FoldingSet.h:782
FoldingSetBucketIterator(void **Bucket)
Definition: FoldingSet.h:779
FoldingSetBucketIterator operator++(int)
Definition: FoldingSet.h:792
FoldingSetBucketIterator & operator++()
Definition: FoldingSet.h:788
FoldingSetImpl - An implementation detail that lets us share code between FoldingSet and ContextualFo...
Definition: FoldingSet.h:454
void reserve(unsigned EltCount)
reserve - Increase the number of buckets such that adding the EltCount-th node won't cause a rebucket...
Definition: FoldingSet.h:487
FoldingSetIterator< T > iterator
Definition: FoldingSet.h:464
const_iterator end() const
Definition: FoldingSet.h:472
bucket_iterator bucket_begin(unsigned hash)
Definition: FoldingSet.h:476
bool RemoveNode(T *N)
RemoveNode - Remove a node from the folding set, returning true if one was removed or false if the no...
Definition: FoldingSet.h:493
~FoldingSetImpl()=default
FoldingSetImpl(FoldingSetImpl &&Arg)=default
FoldingSetBucketIterator< T > bucket_iterator
Definition: FoldingSet.h:474
void InsertNode(T *N)
InsertNode - Insert the specified node into the folding set, knowing that it is not already in the fo...
Definition: FoldingSet.h:522
void InsertNode(T *N, void *InsertPos)
InsertNode - Insert the specified node into the folding set, knowing that it is not already in the fo...
Definition: FoldingSet.h:516
T * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)
FindNodeOrInsertPos - Look up the node specified by ID.
Definition: FoldingSet.h:508
const_iterator begin() const
Definition: FoldingSet.h:471
FoldingSetIterator< const T > const_iterator
Definition: FoldingSet.h:469
FoldingSetImpl & operator=(FoldingSetImpl &&RHS)=default
T * GetOrInsertNode(T *N)
GetOrInsertNode - If there is an existing simple Node exactly equal to the specified node,...
Definition: FoldingSet.h:500
FoldingSetImpl(unsigned Log2InitSize)
Definition: FoldingSet.h:456
bucket_iterator bucket_end(unsigned hash)
Definition: FoldingSet.h:480
FoldingSetIteratorImpl - This is the common iterator support shared by all folding sets,...
Definition: FoldingSet.h:711
FoldingSetNode * NodePtr
Definition: FoldingSet.h:713
bool operator==(const FoldingSetIteratorImpl &RHS) const
Definition: FoldingSet.h:720
bool operator!=(const FoldingSetIteratorImpl &RHS) const
Definition: FoldingSet.h:723
FoldingSetIterator(void **Bucket)
Definition: FoldingSet.h:730
FoldingSetIterator operator++(int)
Definition: FoldingSet.h:744
FoldingSetIterator & operator++()
Definition: FoldingSet.h:740
FoldingSetNodeIDRef - This class describes a reference to an interned FoldingSetNodeID,...
Definition: FoldingSet.h:293
unsigned computeStableHash() const
Definition: FoldingSet.h:309
FoldingSetNodeIDRef(const unsigned *D, size_t S)
Definition: FoldingSet.h:299
LLVM_ABI bool operator<(FoldingSetNodeIDRef) const
Used to compare the "ordering" of two nodes as defined by the profiled bits and their ordering define...
Definition: FoldingSet.cpp:34
bool operator!=(FoldingSetNodeIDRef RHS) const
Definition: FoldingSet.h:316
unsigned ComputeHash() const
Definition: FoldingSet.h:303
size_t getSize() const
Definition: FoldingSet.h:323
const unsigned * getData() const
Definition: FoldingSet.h:322
FoldingSetNodeID - This class is used to gather all the unique data bits of a node.
Definition: FoldingSet.h:330
LLVM_ABI FoldingSetNodeIDRef Intern(BumpPtrAllocator &Allocator) const
Intern - Copy this node's data to a memory region allocated from the given allocator and return a Fol...
Definition: FoldingSet.cpp:132
void AddInteger(signed I)
Definition: FoldingSet.h:351
void AddInteger(unsigned long I)
Definition: FoldingSet.h:354
FoldingSetNodeID(FoldingSetNodeIDRef Ref)
Definition: FoldingSet.h:338
unsigned computeStableHash() const
Definition: FoldingSet.h:389
void AddPointer(const void *Ptr)
Add* - Add various data types to Bit data.
Definition: FoldingSet.h:342
bool operator!=(const FoldingSetNodeIDRef RHS) const
Definition: FoldingSet.h:398
void clear()
clear - Clear the accumulated profile, allowing this FoldingSetNodeID object to be used to compute a ...
Definition: FoldingSet.h:378
void AddInteger(unsigned I)
Definition: FoldingSet.h:352
void AddInteger(long I)
Definition: FoldingSet.h:353
void AddBoolean(bool B)
Definition: FoldingSet.h:369
bool operator!=(const FoldingSetNodeID &RHS) const
Definition: FoldingSet.h:397
void AddInteger(unsigned long long I)
Definition: FoldingSet.h:364
void AddInteger(long long I)
Definition: FoldingSet.h:363
unsigned ComputeHash() const
Definition: FoldingSet.h:383
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...
Definition: FoldingSet.cpp:120
LLVM_ABI void AddNodeID(const FoldingSetNodeID &ID)
Definition: FoldingSet.cpp:102
void Add(const T &x)
Definition: FoldingSet.h:374
LLVM_ABI void AddString(StringRef String)
Add* - Add various data types to Bit data.
Definition: FoldingSet.cpp:45
FoldingSetNodeWrapper - This template class is used to "wrap" arbitrary types in an enclosing object ...
Definition: FoldingSet.h:801
FoldingSetNodeWrapper(Ts &&... Args)
Definition: FoldingSet.h:806
const T & getValue() const
Definition: FoldingSet.h:812
void Profile(FoldingSetNodeID &ID)
Definition: FoldingSet.h:809
FoldingSetVector - This template class combines a FoldingSet and a vector to provide the interface of...
Definition: FoldingSet.h:650
T * GetOrInsertNode(T *N)
GetOrInsertNode - If there is an existing simple Node exactly equal to the specified node,...
Definition: FoldingSet.h:680
const_iterator end() const
Definition: FoldingSet.h:665
void InsertNode(T *N)
InsertNode - Insert the specified node into the folding set, knowing that it is not already in the fo...
Definition: FoldingSet.h:696
T * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)
FindNodeOrInsertPos - Look up the node specified by ID.
Definition: FoldingSet.h:673
unsigned size() const
size - Returns the number of nodes in the folding set.
Definition: FoldingSet.h:702
void clear()
clear - Remove all nodes from the folding set.
Definition: FoldingSet.h:668
bool empty() const
empty - Returns true if there are no nodes in the folding set.
Definition: FoldingSet.h:705
FoldingSetVector(unsigned Log2InitSize=6)
Definition: FoldingSet.h:655
void InsertNode(T *N, void *InsertPos)
InsertNode - Insert the specified node into the folding set, knowing that it is not already in the fo...
Definition: FoldingSet.h:689
const_iterator begin() const
Definition: FoldingSet.h:664
FoldingSet - This template class is used to instantiate a specialized implementation of the folding s...
Definition: FoldingSet.h:539
FoldingSet(FoldingSet &&Arg)=default
FoldingSet(unsigned Log2InitSize=6)
Definition: FoldingSet.h:576
FoldingSet & operator=(FoldingSet &&RHS)=default
This is a 'vector' (really, a variable-sized array), optimized for the case when the array is small.
Definition: SmallVector.h:1197
StringRef - Represent a constant reference to a string, i.e.
Definition: StringRef.h:55
#define llvm_unreachable(msg)
Marks that the current location is not supposed to be reachable.
unsigned ID
LLVM IR allows to use arbitrary numbers as calling convention identifiers.
Definition: CallingConv.h:24
This is an optimization pass for GlobalISel generic memory operations.
Definition: AddressRanges.h:18
LLVM_ABI uint64_t xxh3_64bits(ArrayRef< uint8_t > data)
Definition: xxhash.cpp:553
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.
hash_code hash_combine_range(InputIteratorT first, InputIteratorT last)
Compute a hash_code for a sequence of values.
Definition: Hashing.h:469
Implement std::hash so that hash_code can be used in STL containers.
Definition: BitVector.h:856
#define N
ContextualFoldingSetTrait - Like FoldingSetTrait, but for ContextualFoldingSets.
Definition: FoldingSet.h:285
DefaultContextualFoldingSetTrait - Like DefaultFoldingSetTrait, but for ContextualFoldingSets.
Definition: FoldingSet.h:271
static bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID, Ctx Context)
Definition: FoldingSet.h:434
static void Profile(T &X, FoldingSetNodeID &ID, Ctx Context)
Definition: FoldingSet.h:272
static unsigned ComputeHash(T &X, FoldingSetNodeID &TempID, Ctx Context)
Definition: FoldingSet.h:444
DefaultFoldingSetTrait - This class provides default implementations for FoldingSetTrait implementati...
Definition: FoldingSet.h:236
static void Profile(const T &X, FoldingSetNodeID &ID)
Definition: FoldingSet.h:237
static unsigned ComputeHash(T &X, FoldingSetNodeID &TempID)
Definition: FoldingSet.h:428
static bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID)
Definition: FoldingSet.h:420
static void Profile(T &X, FoldingSetNodeID &ID)
Definition: FoldingSet.h:240
Functions provided by the derived class to compute folding properties.
Definition: FoldingSet.h:173
unsigned(* ComputeNodeHash)(const FoldingSetBase *Self, Node *N, FoldingSetNodeID &TempID)
ComputeNodeHash - Instantiations of the FoldingSet template implement this function to compute a hash...
Definition: FoldingSet.h:187
bool(* NodeEquals)(const FoldingSetBase *Self, Node *N, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID)
NodeEquals - Instantiations of the FoldingSet template implement this function to compare the given n...
Definition: FoldingSet.h:181
void(* GetNodeProfile)(const FoldingSetBase *Self, Node *N, FoldingSetNodeID &ID)
GetNodeProfile - Instantiations of the FoldingSet template implement this function to gather data bit...
Definition: FoldingSet.h:176
static void Profile(const T &X, FoldingSetNodeID &ID)
Definition: FoldingSet.h:853
static void Profile(T *X, FoldingSetNodeID &ID)
Definition: FoldingSet.h:838
static void Profile(const std::pair< T1, T2 > &P, FoldingSetNodeID &ID)
Definition: FoldingSet.h:844
FoldingSetTrait - This trait class is used to define behavior of how to "profile" (in the FoldingSet ...
Definition: FoldingSet.h:266
An iterator type that allows iterating over the pointees via some other iterator.
Definition: iterator.h:324