Use MachineBasicBlock::transferSuccessors.
[oota-llvm.git] / include / llvm / ADT / FoldingSet.h
index bfbf99c269b1aea8e1cd884bfad57943395677fc..c6696b30344421ddfb456b83591687d54404ed85 100644 (file)
@@ -22,6 +22,7 @@
 
 namespace llvm {
   class APFloat;
+  class APInt;
 
 /// This folding set used for two purposes:
 ///   1. Given information about a node we want to create, look up the unique
@@ -31,7 +32,7 @@ namespace llvm {
 /// 
 /// This class is implemented as a single-link chained hash table, where the
 /// "buckets" are actually the nodes themselves (the next pointer is in the
-/// node).  The last node points back to the bucket to simplified node removal.
+/// node).  The last node points back to the bucket to simplify node removal.
 ///
 /// Any node that is to be included in the folding set must be a subclass of
 /// FoldingSetNode.  The node class must also define a Profile method used to
@@ -177,6 +178,19 @@ protected:
   virtual void GetNodeProfile(FoldingSetNodeID &ID, Node *N) const = 0;
 };
 
+//===----------------------------------------------------------------------===//
+/// FoldingSetTrait - This trait class is used to define behavior of how
+///  to "profile" (in the FoldingSet parlance) an object of a given type.
+///  The default behavior is to invoke a 'Profile' method on an object, but
+///  through template specialization the behavior can be tailored for specific
+///  types.  Combined with the FoldingSetNodeWrapper classs, one can add objects
+///  to FoldingSets that were not originally designed to have that behavior.
+///
+template<typename T> struct FoldingSetTrait {
+  static inline void Profile(const T& X, FoldingSetNodeID& ID) { X.Profile(ID);}
+  static inline void Profile(T& X, FoldingSetNodeID& ID) { X.Profile(ID); }
+};
+  
 //===--------------------------------------------------------------------===//
 /// FoldingSetNodeID - This class is used to gather all the unique data bits of
 /// a node.  When all the bits are gathered this class is used to produce a
@@ -205,9 +219,11 @@ public:
   void AddInteger(uint64_t I);
   void AddFloat(float F);
   void AddDouble(double D);
-  void AddAPFloat(const APFloat& apf);
   void AddString(const std::string &String);
   
+  template <typename T>
+  inline void Add(const T& x) { FoldingSetTrait<T>::Profile(x, *this); }
+  
   /// clear - Clear the accumulated profile, allowing this FoldingSetNodeID
   ///  object to be used to compute a new profile.
   inline void clear() { Bits.clear(); }
@@ -224,19 +240,7 @@ public:
 // Convenience type to hide the implementation of the folding set.
 typedef FoldingSetImpl::Node FoldingSetNode;
 template<class T> class FoldingSetIterator;
-
-//===----------------------------------------------------------------------===//
-/// FoldingSetTrait - This trait class is used to define behavior of how
-///  to "profile" (in the FoldingSet parlance) an object of a given type.
-///  The default behavior is to invoke a 'Profile' method on an object, but
-///  through template specialization the behavior can be tailored for specific
-///  types.  Combined with the FoldingSetNodeWrapper classs, one can add objects
-///  to FoldingSets that were not originally designed to have that behavior.
-///
-template<typename T> struct FoldingSetTrait {
-  static inline void Profile(const T& X, FoldingSetNodeID& ID) { X.Profile(ID);}
-  static inline void Profile(T& X, FoldingSetNodeID& ID) { X.Profile(ID); }
-};
+template<class T> class FoldingSetBucketIterator;
   
 //===----------------------------------------------------------------------===//
 /// FoldingSet - This template class is used to instantiate a specialized
@@ -265,6 +269,16 @@ public:
   const_iterator begin() const { return const_iterator(Buckets); }
   const_iterator end() const { return const_iterator(Buckets+NumBuckets); }
 
+  typedef FoldingSetBucketIterator<T> bucket_iterator;  
+
+  bucket_iterator bucket_begin(unsigned hash) {
+    return bucket_iterator(Buckets + (hash & (NumBuckets-1)));
+  }
+  
+  bucket_iterator bucket_end(unsigned hash) {
+    return bucket_iterator(Buckets + (hash & (NumBuckets-1)), true);
+  }
+  
   /// GetOrInsertNode - If there is an existing simple Node exactly
   /// equal to the specified node, return it.  Otherwise, insert 'N' and
   /// return it instead.
@@ -321,6 +335,57 @@ public:
   }
 };
   
+//===----------------------------------------------------------------------===//
+/// FoldingSetBucketIteratorImpl - This is the common bucket iterator support
+///  shared by all folding sets, which knows how to walk a particular bucket
+///  of a folding set hash table.
+  
+class FoldingSetBucketIteratorImpl {
+protected:
+  void *Ptr;
+
+  FoldingSetBucketIteratorImpl(void **Bucket);
+  
+  FoldingSetBucketIteratorImpl(void **Bucket, bool)
+    : Ptr(reinterpret_cast<void*>(Bucket)) {}
+
+  void advance() {
+    void *Probe = static_cast<FoldingSetNode*>(Ptr)->getNextInBucket();
+    uintptr_t x = reinterpret_cast<uintptr_t>(Probe) & ~0x1;
+    Ptr = reinterpret_cast<void*>(x);
+  }
+  
+public:
+  bool operator==(const FoldingSetBucketIteratorImpl &RHS) const {
+    return Ptr == RHS.Ptr;
+  }
+  bool operator!=(const FoldingSetBucketIteratorImpl &RHS) const {
+    return Ptr != RHS.Ptr;
+  }
+};
+  
+  
+template<class T>
+class FoldingSetBucketIterator : public FoldingSetBucketIteratorImpl {
+public:
+  FoldingSetBucketIterator(void **Bucket) : 
+    FoldingSetBucketIteratorImpl(Bucket) {}
+  
+  FoldingSetBucketIterator(void **Bucket, bool) : 
+    FoldingSetBucketIteratorImpl(Bucket, true) {}
+  
+  T& operator*() const { return *static_cast<T*>(Ptr); }  
+  T* operator->() const { return static_cast<T*>(Ptr); }
+  
+  inline FoldingSetBucketIterator& operator++() { // Preincrement
+    advance();
+    return *this;
+  }          
+  FoldingSetBucketIterator operator++(int) {      // Postincrement
+    FoldingSetBucketIterator tmp = *this; ++*this; return tmp;
+  }
+};
+  
 //===----------------------------------------------------------------------===//
 /// FoldingSetNodeWrapper - This template class is used to "wrap" arbitrary
 /// types in an enclosing object so that they can be inserted into FoldingSets.