LLVM API Documentation

 All Classes Namespaces Files Functions Variables Typedefs Enumerations Enumerator Friends Macros Groups Pages
FoldingSet.h
Go to the documentation of this file.
1 //===-- llvm/ADT/FoldingSet.h - Uniquing Hash Set ---------------*- C++ -*-===//
2 //
3 // The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
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 set.
13 //
14 //===----------------------------------------------------------------------===//
15 
16 #ifndef LLVM_ADT_FOLDINGSET_H
17 #define LLVM_ADT_FOLDINGSET_H
18 
19 #include "llvm/ADT/SmallVector.h"
20 #include "llvm/ADT/StringRef.h"
21 #include "llvm/Support/DataTypes.h"
22 
23 namespace llvm {
24  class APFloat;
25  class APInt;
26  class BumpPtrAllocator;
27 
28 /// This folding set used for two purposes:
29 /// 1. Given information about a node we want to create, look up the unique
30 /// instance of the node in the set. If the node already exists, return
31 /// it, otherwise return the bucket it should be inserted into.
32 /// 2. Given a node that has already been created, remove it from the set.
33 ///
34 /// This class is implemented as a single-link chained hash table, where the
35 /// "buckets" are actually the nodes themselves (the next pointer is in the
36 /// node). The last node points back to the bucket to simplify node removal.
37 ///
38 /// Any node that is to be included in the folding set must be a subclass of
39 /// FoldingSetNode. The node class must also define a Profile method used to
40 /// establish the unique bits of data for the node. The Profile method is
41 /// passed a FoldingSetNodeID object which is used to gather the bits. Just
42 /// call one of the Add* functions defined in the FoldingSetImpl::NodeID class.
43 /// NOTE: That the folding set does not own the nodes and it is the
44 /// responsibility of the user to dispose of the nodes.
45 ///
46 /// Eg.
47 /// class MyNode : public FoldingSetNode {
48 /// private:
49 /// std::string Name;
50 /// unsigned Value;
51 /// public:
52 /// MyNode(const char *N, unsigned V) : Name(N), Value(V) {}
53 /// ...
54 /// void Profile(FoldingSetNodeID &ID) const {
55 /// ID.AddString(Name);
56 /// ID.AddInteger(Value);
57 /// }
58 /// ...
59 /// };
60 ///
61 /// To define the folding set itself use the FoldingSet template;
62 ///
63 /// Eg.
64 /// FoldingSet<MyNode> MyFoldingSet;
65 ///
66 /// Four public methods are available to manipulate the folding set;
67 ///
68 /// 1) If you have an existing node that you want add to the set but unsure
69 /// that the node might already exist then call;
70 ///
71 /// MyNode *M = MyFoldingSet.GetOrInsertNode(N);
72 ///
73 /// If The result is equal to the input then the node has been inserted.
74 /// Otherwise, the result is the node existing in the folding set, and the
75 /// input can be discarded (use the result instead.)
76 ///
77 /// 2) If you are ready to construct a node but want to check if it already
78 /// exists, then call FindNodeOrInsertPos with a FoldingSetNodeID of the bits to
79 /// check;
80 ///
81 /// FoldingSetNodeID ID;
82 /// ID.AddString(Name);
83 /// ID.AddInteger(Value);
84 /// void *InsertPoint;
85 ///
86 /// MyNode *M = MyFoldingSet.FindNodeOrInsertPos(ID, InsertPoint);
87 ///
88 /// If found then M with be non-NULL, else InsertPoint will point to where it
89 /// should be inserted using InsertNode.
90 ///
91 /// 3) If you get a NULL result from FindNodeOrInsertPos then you can as a new
92 /// node with FindNodeOrInsertPos;
93 ///
94 /// InsertNode(N, InsertPoint);
95 ///
96 /// 4) Finally, if you want to remove a node from the folding set call;
97 ///
98 /// bool WasRemoved = RemoveNode(N);
99 ///
100 /// The result indicates whether the node existed in the folding set.
101 
102 class FoldingSetNodeID;
103 
104 //===----------------------------------------------------------------------===//
105 /// FoldingSetImpl - Implements the folding set functionality. The main
106 /// structure is an array of buckets. Each bucket is indexed by the hash of
107 /// the nodes it contains. The bucket itself points to the nodes contained
108 /// in the bucket via a singly linked list. The last node in the list points
109 /// back to the bucket to facilitate node removal.
110 ///
112 protected:
113  /// Buckets - Array of bucket chains.
114  ///
115  void **Buckets;
116 
117  /// NumBuckets - Length of the Buckets array. Always a power of 2.
118  ///
119  unsigned NumBuckets;
120 
121  /// NumNodes - Number of nodes in the folding set. Growth occurs when NumNodes
122  /// is greater than twice the number of buckets.
123  unsigned NumNodes;
124 
125 public:
126  explicit FoldingSetImpl(unsigned Log2InitSize = 6);
127  virtual ~FoldingSetImpl();
128 
129  //===--------------------------------------------------------------------===//
130  /// Node - This class is used to maintain the singly linked bucket list in
131  /// a folding set.
132  ///
133  class Node {
134  private:
135  // NextInFoldingSetBucket - next link in the bucket list.
136  void *NextInFoldingSetBucket;
137 
138  public:
139 
140  Node() : NextInFoldingSetBucket(0) {}
141 
142  // Accessors
143  void *getNextInBucket() const { return NextInFoldingSetBucket; }
144  void SetNextInBucket(void *N) { NextInFoldingSetBucket = N; }
145  };
146 
147  /// clear - Remove all nodes from the folding set.
148  void clear();
149 
150  /// RemoveNode - Remove a node from the folding set, returning true if one
151  /// was removed or false if the node was not in the folding set.
152  bool RemoveNode(Node *N);
153 
154  /// GetOrInsertNode - If there is an existing simple Node exactly
155  /// equal to the specified node, return it. Otherwise, insert 'N' and return
156  /// it instead.
157  Node *GetOrInsertNode(Node *N);
158 
159  /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
160  /// return it. If not, return the insertion token that will make insertion
161  /// faster.
162  Node *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos);
163 
164  /// InsertNode - Insert the specified node into the folding set, knowing that
165  /// it is not already in the folding set. InsertPos must be obtained from
166  /// FindNodeOrInsertPos.
167  void InsertNode(Node *N, void *InsertPos);
168 
169  /// InsertNode - Insert the specified node into the folding set, knowing that
170  /// it is not already in the folding set.
171  void InsertNode(Node *N) {
172  Node *Inserted = GetOrInsertNode(N);
173  (void)Inserted;
174  assert(Inserted == N && "Node already inserted!");
175  }
176 
177  /// size - Returns the number of nodes in the folding set.
178  unsigned size() const { return NumNodes; }
179 
180  /// empty - Returns true if there are no nodes in the folding set.
181  bool empty() const { return NumNodes == 0; }
182 
183 private:
184 
185  /// GrowHashTable - Double the size of the hash table and rehash everything.
186  ///
187  void GrowHashTable();
188 
189 protected:
190 
191  /// GetNodeProfile - Instantiations of the FoldingSet template implement
192  /// this function to gather data bits for the given node.
193  virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const = 0;
194  /// NodeEquals - Instantiations of the FoldingSet template implement
195  /// this function to compare the given node with the given ID.
196  virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
197  FoldingSetNodeID &TempID) const=0;
198  /// ComputeNodeHash - Instantiations of the FoldingSet template implement
199  /// this function to compute a hash value for the given node.
200  virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const = 0;
201 };
202 
203 //===----------------------------------------------------------------------===//
204 
205 template<typename T> struct FoldingSetTrait;
206 
207 /// DefaultFoldingSetTrait - This class provides default implementations
208 /// for FoldingSetTrait implementations.
209 ///
210 template<typename T> struct DefaultFoldingSetTrait {
211  static void Profile(const T &X, FoldingSetNodeID &ID) {
212  X.Profile(ID);
213  }
214  static void Profile(T &X, FoldingSetNodeID &ID) {
215  X.Profile(ID);
216  }
217 
218  // Equals - Test if the profile for X would match ID, using TempID
219  // to compute a temporary ID if necessary. The default implementation
220  // just calls Profile and does a regular comparison. Implementations
221  // can override this to provide more efficient implementations.
222  static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash,
223  FoldingSetNodeID &TempID);
224 
225  // ComputeHash - Compute a hash value for X, using TempID to
226  // compute a temporary ID if necessary. The default implementation
227  // just calls Profile and does a regular hash computation.
228  // Implementations can override this to provide more efficient
229  // implementations.
230  static inline unsigned ComputeHash(T &X, FoldingSetNodeID &TempID);
231 };
232 
233 /// FoldingSetTrait - This trait class is used to define behavior of how
234 /// to "profile" (in the FoldingSet parlance) an object of a given type.
235 /// The default behavior is to invoke a 'Profile' method on an object, but
236 /// through template specialization the behavior can be tailored for specific
237 /// types. Combined with the FoldingSetNodeWrapper class, one can add objects
238 /// to FoldingSets that were not originally designed to have that behavior.
239 template<typename T> struct FoldingSetTrait
240  : public DefaultFoldingSetTrait<T> {};
241 
242 template<typename T, typename Ctx> struct ContextualFoldingSetTrait;
243 
244 /// DefaultContextualFoldingSetTrait - Like DefaultFoldingSetTrait, but
245 /// for ContextualFoldingSets.
246 template<typename T, typename Ctx>
248  static void Profile(T &X, FoldingSetNodeID &ID, Ctx Context) {
249  X.Profile(ID, Context);
250  }
251  static inline bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash,
252  FoldingSetNodeID &TempID, Ctx Context);
253  static inline unsigned ComputeHash(T &X, FoldingSetNodeID &TempID,
254  Ctx Context);
255 };
256 
257 /// ContextualFoldingSetTrait - Like FoldingSetTrait, but for
258 /// ContextualFoldingSets.
259 template<typename T, typename Ctx> struct ContextualFoldingSetTrait
260  : public DefaultContextualFoldingSetTrait<T, Ctx> {};
261 
262 //===--------------------------------------------------------------------===//
263 /// FoldingSetNodeIDRef - This class describes a reference to an interned
264 /// FoldingSetNodeID, which can be a useful to store node id data rather
265 /// than using plain FoldingSetNodeIDs, since the 32-element SmallVector
266 /// is often much larger than necessary, and the possibility of heap
267 /// allocation means it requires a non-trivial destructor call.
269  const unsigned *Data;
270  size_t Size;
271 public:
272  FoldingSetNodeIDRef() : Data(0), Size(0) {}
273  FoldingSetNodeIDRef(const unsigned *D, size_t S) : Data(D), Size(S) {}
274 
275  /// ComputeHash - Compute a strong hash value for this FoldingSetNodeIDRef,
276  /// used to lookup the node in the FoldingSetImpl.
277  unsigned ComputeHash() const;
278 
279  bool operator==(FoldingSetNodeIDRef) const;
280 
281  /// Used to compare the "ordering" of two nodes as defined by the
282  /// profiled bits and their ordering defined by memcmp().
283  bool operator<(FoldingSetNodeIDRef) const;
284 
285  const unsigned *getData() const { return Data; }
286  size_t getSize() const { return Size; }
287 };
288 
289 //===--------------------------------------------------------------------===//
290 /// FoldingSetNodeID - This class is used to gather all the unique data bits of
291 /// a node. When all the bits are gathered this class is used to produce a
292 /// hash value for the node.
293 ///
295  /// Bits - Vector of all the data bits that make the node unique.
296  /// Use a SmallVector to avoid a heap allocation in the common case.
298 
299 public:
301 
303  : Bits(Ref.getData(), Ref.getData() + Ref.getSize()) {}
304 
305  /// Add* - Add various data types to Bit data.
306  ///
307  void AddPointer(const void *Ptr);
308  void AddInteger(signed I);
309  void AddInteger(unsigned I);
310  void AddInteger(long I);
311  void AddInteger(unsigned long I);
312  void AddInteger(long long I);
313  void AddInteger(unsigned long long I);
314  void AddBoolean(bool B) { AddInteger(B ? 1U : 0U); }
315  void AddString(StringRef String);
316  void AddNodeID(const FoldingSetNodeID &ID);
317 
318  template <typename T>
319  inline void Add(const T &x) { FoldingSetTrait<T>::Profile(x, *this); }
320 
321  /// clear - Clear the accumulated profile, allowing this FoldingSetNodeID
322  /// object to be used to compute a new profile.
323  inline void clear() { Bits.clear(); }
324 
325  /// ComputeHash - Compute a strong hash value for this FoldingSetNodeID, used
326  /// to lookup the node in the FoldingSetImpl.
327  unsigned ComputeHash() const;
328 
329  /// operator== - Used to compare two nodes to each other.
330  ///
331  bool operator==(const FoldingSetNodeID &RHS) const;
332  bool operator==(const FoldingSetNodeIDRef RHS) const;
333 
334  /// Used to compare the "ordering" of two nodes as defined by the
335  /// profiled bits and their ordering defined by memcmp().
336  bool operator<(const FoldingSetNodeID &RHS) const;
337  bool operator<(const FoldingSetNodeIDRef RHS) const;
338 
339  /// Intern - Copy this node's data to a memory region allocated from the
340  /// given allocator and return a FoldingSetNodeIDRef describing the
341  /// interned data.
342  FoldingSetNodeIDRef Intern(BumpPtrAllocator &Allocator) const;
343 };
344 
345 // Convenience type to hide the implementation of the folding set.
347 template<class T> class FoldingSetIterator;
348 template<class T> class FoldingSetBucketIterator;
349 
350 // Definitions of FoldingSetTrait and ContextualFoldingSetTrait functions, which
351 // require the definition of FoldingSetNodeID.
352 template<typename T>
353 inline bool
355  unsigned /*IDHash*/,
356  FoldingSetNodeID &TempID) {
357  FoldingSetTrait<T>::Profile(X, TempID);
358  return TempID == ID;
359 }
360 template<typename T>
361 inline unsigned
363  FoldingSetTrait<T>::Profile(X, TempID);
364  return TempID.ComputeHash();
365 }
366 template<typename T, typename Ctx>
367 inline bool
369  const FoldingSetNodeID &ID,
370  unsigned /*IDHash*/,
371  FoldingSetNodeID &TempID,
372  Ctx Context) {
373  ContextualFoldingSetTrait<T, Ctx>::Profile(X, TempID, Context);
374  return TempID == ID;
375 }
376 template<typename T, typename Ctx>
377 inline unsigned
379  FoldingSetNodeID &TempID,
380  Ctx Context) {
381  ContextualFoldingSetTrait<T, Ctx>::Profile(X, TempID, Context);
382  return TempID.ComputeHash();
383 }
384 
385 //===----------------------------------------------------------------------===//
386 /// FoldingSet - This template class is used to instantiate a specialized
387 /// implementation of the folding set to the node class T. T must be a
388 /// subclass of FoldingSetNode and implement a Profile function.
389 ///
390 template<class T> class FoldingSet : public FoldingSetImpl {
391 private:
392  /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
393  /// way to convert nodes into a unique specifier.
394  virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const {
395  T *TN = static_cast<T *>(N);
397  }
398  /// NodeEquals - Instantiations may optionally provide a way to compare a
399  /// node with a specified ID.
400  virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash,
401  FoldingSetNodeID &TempID) const {
402  T *TN = static_cast<T *>(N);
403  return FoldingSetTrait<T>::Equals(*TN, ID, IDHash, TempID);
404  }
405  /// ComputeNodeHash - Instantiations may optionally provide a way to compute a
406  /// hash value directly from a node.
407  virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const {
408  T *TN = static_cast<T *>(N);
409  return FoldingSetTrait<T>::ComputeHash(*TN, TempID);
410  }
411 
412 public:
413  explicit FoldingSet(unsigned Log2InitSize = 6)
414  : FoldingSetImpl(Log2InitSize)
415  {}
416 
420 
424 
426 
428  return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
429  }
430 
432  return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
433  }
434 
435  /// GetOrInsertNode - If there is an existing simple Node exactly
436  /// equal to the specified node, return it. Otherwise, insert 'N' and
437  /// return it instead.
439  return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
440  }
441 
442  /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
443  /// return it. If not, return the insertion token that will make insertion
444  /// faster.
445  T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
446  return static_cast<T *>(FoldingSetImpl::FindNodeOrInsertPos(ID, InsertPos));
447  }
448 };
449 
450 //===----------------------------------------------------------------------===//
451 /// ContextualFoldingSet - This template class is a further refinement
452 /// of FoldingSet which provides a context argument when calling
453 /// Profile on its nodes. Currently, that argument is fixed at
454 /// initialization time.
455 ///
456 /// T must be a subclass of FoldingSetNode and implement a Profile
457 /// function with signature
458 /// void Profile(llvm::FoldingSetNodeID &, Ctx);
459 template <class T, class Ctx>
461  // Unfortunately, this can't derive from FoldingSet<T> because the
462  // construction vtable for FoldingSet<T> requires
463  // FoldingSet<T>::GetNodeProfile to be instantiated, which in turn
464  // requires a single-argument T::Profile().
465 
466 private:
467  Ctx Context;
468 
469  /// GetNodeProfile - Each instantiatation of the FoldingSet needs to provide a
470  /// way to convert nodes into a unique specifier.
471  virtual void GetNodeProfile(FoldingSetImpl::Node *N,
472  FoldingSetNodeID &ID) const {
473  T *TN = static_cast<T *>(N);
475  }
476  virtual bool NodeEquals(FoldingSetImpl::Node *N,
477  const FoldingSetNodeID &ID, unsigned IDHash,
478  FoldingSetNodeID &TempID) const {
479  T *TN = static_cast<T *>(N);
480  return ContextualFoldingSetTrait<T, Ctx>::Equals(*TN, ID, IDHash, TempID,
481  Context);
482  }
483  virtual unsigned ComputeNodeHash(FoldingSetImpl::Node *N,
484  FoldingSetNodeID &TempID) const {
485  T *TN = static_cast<T *>(N);
486  return ContextualFoldingSetTrait<T, Ctx>::ComputeHash(*TN, TempID, Context);
487  }
488 
489 public:
490  explicit ContextualFoldingSet(Ctx Context, unsigned Log2InitSize = 6)
491  : FoldingSetImpl(Log2InitSize), Context(Context)
492  {}
493 
494  Ctx getContext() const { return Context; }
495 
496 
500 
504 
506 
508  return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
509  }
510 
512  return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
513  }
514 
515  /// GetOrInsertNode - If there is an existing simple Node exactly
516  /// equal to the specified node, return it. Otherwise, insert 'N'
517  /// and return it instead.
519  return static_cast<T *>(FoldingSetImpl::GetOrInsertNode(N));
520  }
521 
522  /// FindNodeOrInsertPos - Look up the node specified by ID. If it
523  /// exists, return it. If not, return the insertion token that will
524  /// make insertion faster.
525  T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
526  return static_cast<T *>(FoldingSetImpl::FindNodeOrInsertPos(ID, InsertPos));
527  }
528 };
529 
530 //===----------------------------------------------------------------------===//
531 /// FoldingSetVectorIterator - This implements an iterator for
532 /// FoldingSetVector. It is only necessary because FoldingSetIterator provides
533 /// a value_type of T, while the vector in FoldingSetVector exposes
534 /// a value_type of T*. Fortunately, FoldingSetIterator doesn't expose very
535 /// much besides operator* and operator->, so we just wrap the inner vector
536 /// iterator and perform the extra dereference.
537 template <class T, class VectorIteratorT>
539  // Provide a typedef to workaround the lack of correct injected class name
540  // support in older GCCs.
542 
543  VectorIteratorT Iterator;
544 
545 public:
546  FoldingSetVectorIterator(VectorIteratorT I) : Iterator(I) {}
547 
548  bool operator==(const SelfT &RHS) const {
549  return Iterator == RHS.Iterator;
550  }
551  bool operator!=(const SelfT &RHS) const {
552  return Iterator != RHS.Iterator;
553  }
554 
555  T &operator*() const { return **Iterator; }
556 
557  T *operator->() const { return *Iterator; }
558 
559  inline SelfT &operator++() {
560  ++Iterator;
561  return *this;
562  }
564  SelfT tmp = *this;
565  ++*this;
566  return tmp;
567  }
568 };
569 
570 //===----------------------------------------------------------------------===//
571 /// FoldingSetVector - This template class combines a FoldingSet and a vector
572 /// to provide the interface of FoldingSet but with deterministic iteration
573 /// order based on the insertion order. T must be a subclass of FoldingSetNode
574 /// and implement a Profile function.
575 template <class T, class VectorT = SmallVector<T*, 8> >
577  FoldingSet<T> Set;
578  VectorT Vector;
579 
580 public:
581  explicit FoldingSetVector(unsigned Log2InitSize = 6)
582  : Set(Log2InitSize) {
583  }
584 
586  iterator begin() { return Vector.begin(); }
587  iterator end() { return Vector.end(); }
588 
591  const_iterator begin() const { return Vector.begin(); }
592  const_iterator end() const { return Vector.end(); }
593 
594  /// clear - Remove all nodes from the folding set.
595  void clear() { Set.clear(); Vector.clear(); }
596 
597  /// FindNodeOrInsertPos - Look up the node specified by ID. If it exists,
598  /// return it. If not, return the insertion token that will make insertion
599  /// faster.
600  T *FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos) {
601  return Set.FindNodeOrInsertPos(ID, InsertPos);
602  }
603 
604  /// GetOrInsertNode - If there is an existing simple Node exactly
605  /// equal to the specified node, return it. Otherwise, insert 'N' and
606  /// return it instead.
608  T *Result = Set.GetOrInsertNode(N);
609  if (Result == N) Vector.push_back(N);
610  return Result;
611  }
612 
613  /// InsertNode - Insert the specified node into the folding set, knowing that
614  /// it is not already in the folding set. InsertPos must be obtained from
615  /// FindNodeOrInsertPos.
616  void InsertNode(T *N, void *InsertPos) {
617  Set.InsertNode(N, InsertPos);
618  Vector.push_back(N);
619  }
620 
621  /// InsertNode - Insert the specified node into the folding set, knowing that
622  /// it is not already in the folding set.
623  void InsertNode(T *N) {
624  Set.InsertNode(N);
625  Vector.push_back(N);
626  }
627 
628  /// size - Returns the number of nodes in the folding set.
629  unsigned size() const { return Set.size(); }
630 
631  /// empty - Returns true if there are no nodes in the folding set.
632  bool empty() const { return Set.empty(); }
633 };
634 
635 //===----------------------------------------------------------------------===//
636 /// FoldingSetIteratorImpl - This is the common iterator support shared by all
637 /// folding sets, which knows how to walk the folding set hash table.
639 protected:
641  FoldingSetIteratorImpl(void **Bucket);
642  void advance();
643 
644 public:
645  bool operator==(const FoldingSetIteratorImpl &RHS) const {
646  return NodePtr == RHS.NodePtr;
647  }
648  bool operator!=(const FoldingSetIteratorImpl &RHS) const {
649  return NodePtr != RHS.NodePtr;
650  }
651 };
652 
653 
654 template<class T>
655 class FoldingSetIterator : public FoldingSetIteratorImpl {
656 public:
657  explicit FoldingSetIterator(void **Bucket) : FoldingSetIteratorImpl(Bucket) {}
658 
659  T &operator*() const {
660  return *static_cast<T*>(NodePtr);
661  }
662 
663  T *operator->() const {
664  return static_cast<T*>(NodePtr);
665  }
666 
667  inline FoldingSetIterator &operator++() { // Preincrement
668  advance();
669  return *this;
670  }
671  FoldingSetIterator operator++(int) { // Postincrement
672  FoldingSetIterator tmp = *this; ++*this; return tmp;
673  }
674 };
675 
676 //===----------------------------------------------------------------------===//
677 /// FoldingSetBucketIteratorImpl - This is the common bucket iterator support
678 /// shared by all folding sets, which knows how to walk a particular bucket
679 /// of a folding set hash table.
680 
682 protected:
683  void *Ptr;
684 
685  explicit FoldingSetBucketIteratorImpl(void **Bucket);
686 
687  FoldingSetBucketIteratorImpl(void **Bucket, bool)
688  : Ptr(Bucket) {}
689 
690  void advance() {
691  void *Probe = static_cast<FoldingSetNode*>(Ptr)->getNextInBucket();
692  uintptr_t x = reinterpret_cast<uintptr_t>(Probe) & ~0x1;
693  Ptr = reinterpret_cast<void*>(x);
694  }
695 
696 public:
697  bool operator==(const FoldingSetBucketIteratorImpl &RHS) const {
698  return Ptr == RHS.Ptr;
699  }
700  bool operator!=(const FoldingSetBucketIteratorImpl &RHS) const {
701  return Ptr != RHS.Ptr;
702  }
703 };
704 
705 
706 template<class T>
707 class FoldingSetBucketIterator : public FoldingSetBucketIteratorImpl {
708 public:
709  explicit FoldingSetBucketIterator(void **Bucket) :
711 
712  FoldingSetBucketIterator(void **Bucket, bool) :
714 
715  T &operator*() const { return *static_cast<T*>(Ptr); }
716  T *operator->() const { return static_cast<T*>(Ptr); }
717 
718  inline FoldingSetBucketIterator &operator++() { // Preincrement
719  advance();
720  return *this;
721  }
722  FoldingSetBucketIterator operator++(int) { // Postincrement
723  FoldingSetBucketIterator tmp = *this; ++*this; return tmp;
724  }
725 };
726 
727 //===----------------------------------------------------------------------===//
728 /// FoldingSetNodeWrapper - This template class is used to "wrap" arbitrary
729 /// types in an enclosing object so that they can be inserted into FoldingSets.
730 template <typename T>
732  T data;
733 public:
734  explicit FoldingSetNodeWrapper(const T &x) : data(x) {}
736 
737  template<typename A1>
738  explicit FoldingSetNodeWrapper(const A1 &a1)
739  : data(a1) {}
740 
741  template <typename A1, typename A2>
742  explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2)
743  : data(a1,a2) {}
744 
745  template <typename A1, typename A2, typename A3>
746  explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3)
747  : data(a1,a2,a3) {}
748 
749  template <typename A1, typename A2, typename A3, typename A4>
750  explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3,
751  const A4 &a4)
752  : data(a1,a2,a3,a4) {}
753 
754  template <typename A1, typename A2, typename A3, typename A4, typename A5>
755  explicit FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3,
756  const A4 &a4, const A5 &a5)
757  : data(a1,a2,a3,a4,a5) {}
758 
759 
761 
762  T &getValue() { return data; }
763  const T &getValue() const { return data; }
764 
765  operator T&() { return data; }
766  operator const T&() const { return data; }
767 };
768 
769 //===----------------------------------------------------------------------===//
770 /// FastFoldingSetNode - This is a subclass of FoldingSetNode which stores
771 /// a FoldingSetNodeID value rather than requiring the node to recompute it
772 /// each time it is needed. This trades space for speed (which can be
773 /// significant if the ID is long), and it also permits nodes to drop
774 /// information that would otherwise only be required for recomputing an ID.
776  FoldingSetNodeID FastID;
777 protected:
778  explicit FastFoldingSetNode(const FoldingSetNodeID &ID) : FastID(ID) {}
779 public:
780  void Profile(FoldingSetNodeID &ID) const {
781  ID.AddNodeID(FastID);
782  }
783 };
784 
785 //===----------------------------------------------------------------------===//
786 // Partial specializations of FoldingSetTrait.
787 
788 template<typename T> struct FoldingSetTrait<T*> {
789  static inline void Profile(T *X, FoldingSetNodeID &ID) {
790  ID.AddPointer(X);
791  }
792 };
793 } // End of namespace llvm.
794 
795 #endif
Node * GetOrInsertNode(Node *N)
Definition: FoldingSet.cpp:377
FoldingSetIterator< T > iterator
Definition: FoldingSet.h:417
void AddPointer(const void *Ptr)
Definition: FoldingSet.cpp:52
FoldingSetNodeIDRef(const unsigned *D, size_t S)
Definition: FoldingSet.h:273
FoldingSetBucketIterator< T > bucket_iterator
Definition: FoldingSet.h:425
ContextualFoldingSet(Ctx Context, unsigned Log2InitSize=6)
Definition: FoldingSet.h:490
FoldingSetIterator< const T > const_iterator
Definition: FoldingSet.h:501
iterator end()
Definition: FoldingSet.h:419
bucket_iterator bucket_begin(unsigned hash)
Definition: FoldingSet.h:427
FastFoldingSetNode(const FoldingSetNodeID &ID)
Definition: FoldingSet.h:778
void InsertNode(Node *N, void *InsertPos)
Definition: FoldingSet.cpp:307
FoldingSetNodeWrapper(const A1 &a1, const A2 &a2)
Definition: FoldingSet.h:742
static void Profile(const T &X, FoldingSetNodeID &ID)
Definition: FoldingSet.h:211
FoldingSet(unsigned Log2InitSize=6)
Definition: FoldingSet.h:413
void InsertNode(Node *N)
Definition: FoldingSet.h:171
bool operator==(const SelfT &RHS) const
Definition: FoldingSet.h:548
unsigned ComputeHash() const
Definition: FoldingSet.cpp:30
static void Profile(T *X, FoldingSetNodeID &ID)
Definition: FoldingSet.h:789
static unsigned ComputeHash(T &X, FoldingSetNodeID &TempID)
Definition: FoldingSet.h:362
virtual void GetNodeProfile(Node *N, FoldingSetNodeID &ID) const =0
T * GetOrInsertNode(Node *N)
Definition: FoldingSet.h:438
size_t getSize() const
Definition: FoldingSet.h:286
void AddInteger(signed I)
Definition: FoldingSet.cpp:60
ID
LLVM Calling Convention Representation.
Definition: CallingConv.h:26
const_iterator end() const
Definition: FoldingSet.h:423
bool operator==(const FoldingSetNodeID &RHS) const
Definition: FoldingSet.cpp:151
FoldingSetNodeWrapper(const T &x)
Definition: FoldingSet.h:734
const_iterator end() const
Definition: FoldingSet.h:503
const_iterator begin() const
Definition: FoldingSet.h:591
void Profile(FoldingSetNodeID &ID)
Definition: FoldingSet.h:760
void clear()
clear - Remove all nodes from the folding set.
Definition: FoldingSet.h:595
FoldingSetVectorIterator< const T, typename VectorT::const_iterator > const_iterator
Definition: FoldingSet.h:590
FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3)
Definition: FoldingSet.h:746
virtual unsigned ComputeNodeHash(Node *N, FoldingSetNodeID &TempID) const =0
#define true
Definition: ConvertUTF.c:65
void AddNodeID(const FoldingSetNodeID &ID)
Definition: FoldingSet.cpp:139
const T & getValue() const
Definition: FoldingSet.h:763
FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4, const A5 &a5)
Definition: FoldingSet.h:755
void * getNextInBucket() const
Definition: FoldingSet.h:143
void Profile(FoldingSetNodeID &ID) const
Definition: FoldingSet.h:780
static unsigned ComputeHash(T &X, FoldingSetNodeID &TempID, Ctx Context)
Definition: FoldingSet.h:378
FoldingSetNode * NodePtr
Definition: FoldingSet.h:640
bool operator<(FoldingSetNodeIDRef) const
Definition: FoldingSet.cpp:41
void AddBoolean(bool B)
Definition: FoldingSet.h:314
T * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)
Definition: FoldingSet.h:445
T * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)
Definition: FoldingSet.h:600
FoldingSetBucketIterator operator++(int)
Definition: FoldingSet.h:722
bool empty() const
empty - Returns true if there are no nodes in the folding set.
Definition: FoldingSet.h:181
Node * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)
Definition: FoldingSet.cpp:282
T * FindNodeOrInsertPos(const FoldingSetNodeID &ID, void *&InsertPos)
Definition: FoldingSet.h:525
FoldingSetIterator operator++(int)
Definition: FoldingSet.h:671
unsigned size() const
size - Returns the number of nodes in the folding set.
Definition: FoldingSet.h:629
FoldingSetBucketIterator & operator++()
Definition: FoldingSet.h:718
bucket_iterator bucket_end(unsigned hash)
Definition: FoldingSet.h:431
void InsertNode(T *N, void *InsertPos)
Definition: FoldingSet.h:616
FoldingSetImpl(unsigned Log2InitSize=6)
Definition: FoldingSet.cpp:225
FoldingSetIterator< T > iterator
Definition: FoldingSet.h:497
FoldingSetVector(unsigned Log2InitSize=6)
Definition: FoldingSet.h:581
bool RemoveNode(Node *N)
Definition: FoldingSet.cpp:336
static bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID)
Definition: FoldingSet.h:354
bool empty() const
empty - Returns true if there are no nodes in the folding set.
Definition: FoldingSet.h:632
void Add(const T &x)
Definition: FoldingSet.h:319
bool operator<(const FoldingSetNodeID &RHS) const
Definition: FoldingSet.cpp:163
iterator begin()
Definition: FoldingSet.h:418
unsigned size() const
size - Returns the number of nodes in the folding set.
Definition: FoldingSet.h:178
FoldingSetNodeID(FoldingSetNodeIDRef Ref)
Definition: FoldingSet.h:302
FoldingSetNodeWrapper(const A1 &a1, const A2 &a2, const A3 &a3, const A4 &a4)
Definition: FoldingSet.h:750
void SetNextInBucket(void *N)
Definition: FoldingSet.h:144
FoldingSetBucketIterator(void **Bucket)
Definition: FoldingSet.h:709
FoldingSetBucketIterator(void **Bucket, bool)
Definition: FoldingSet.h:712
virtual ~FoldingSetImpl()
Definition: FoldingSet.cpp:232
FoldingSetImpl::Node FoldingSetNode
Definition: FoldingSet.h:346
T & operator*() const
Definition: FoldingSet.h:659
T * GetOrInsertNode(Node *N)
Definition: FoldingSet.h:518
FoldingSetIterator & operator++()
Definition: FoldingSet.h:667
FoldingSetVectorIterator(VectorIteratorT I)
Definition: FoldingSet.h:546
FoldingSetNodeWrapper(const A1 &a1)
Definition: FoldingSet.h:738
static void Profile(T &X, FoldingSetNodeID &ID)
Definition: FoldingSet.h:214
bool operator!=(const SelfT &RHS) const
Definition: FoldingSet.h:551
const unsigned * getData() const
Definition: FoldingSet.h:285
T * GetOrInsertNode(T *N)
Definition: FoldingSet.h:607
FoldingSetIteratorImpl(void **Bucket)
Definition: FoldingSet.cpp:390
unsigned ComputeHash() const
Definition: FoldingSet.cpp:145
#define I(x, y, z)
Definition: MD5.cpp:54
#define N
const_iterator end() const
Definition: FoldingSet.h:592
bucket_iterator bucket_end(unsigned hash)
Definition: FoldingSet.h:511
void AddString(StringRef String)
Definition: FoldingSet.cpp:87
bool operator==(const FoldingSetIteratorImpl &RHS) const
Definition: FoldingSet.h:645
FoldingSetVectorIterator< T, typename VectorT::iterator > iterator
Definition: FoldingSet.h:585
const_iterator begin() const
Definition: FoldingSet.h:502
FoldingSetBucketIteratorImpl(void **Bucket)
Definition: FoldingSet.cpp:422
T * operator->() const
Definition: FoldingSet.h:663
FoldingSetIterator(void **Bucket)
Definition: FoldingSet.h:657
FoldingSetNodeIDRef Intern(BumpPtrAllocator &Allocator) const
Definition: FoldingSet.cpp:175
bucket_iterator bucket_begin(unsigned hash)
Definition: FoldingSet.h:507
virtual bool NodeEquals(Node *N, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID) const =0
const_iterator begin() const
Definition: FoldingSet.h:422
bool operator==(const FoldingSetBucketIteratorImpl &RHS) const
Definition: FoldingSet.h:697
void clear()
clear - Remove all nodes from the folding set.
Definition: FoldingSet.cpp:235
static RegisterPass< NVPTXAllocaHoisting > X("alloca-hoisting","Hoisting alloca instructions in non-entry ""blocks to the entry block")
FoldingSetBucketIteratorImpl(void **Bucket, bool)
Definition: FoldingSet.h:687
bool operator!=(const FoldingSetIteratorImpl &RHS) const
Definition: FoldingSet.h:648
FoldingSetBucketIterator< T > bucket_iterator
Definition: FoldingSet.h:505
bool operator!=(const FoldingSetBucketIteratorImpl &RHS) const
Definition: FoldingSet.h:700
bool operator==(FoldingSetNodeIDRef) const
Definition: FoldingSet.cpp:34
FoldingSetIterator< const T > const_iterator
Definition: FoldingSet.h:421
static void Profile(T &X, FoldingSetNodeID &ID, Ctx Context)
Definition: FoldingSet.h:248
static bool Equals(T &X, const FoldingSetNodeID &ID, unsigned IDHash, FoldingSetNodeID &TempID, Ctx Context)
Definition: FoldingSet.h:368