Tidy up #includes.
[oota-llvm.git] / include / llvm / ADT / ImmutableSet.h
index b0f99101bd16ef67dd4d1f6755e24937a09914b4..c351771c6da22413c9f4b88f0199ae6d2d6d8d6a 100644 (file)
@@ -16,7 +16,9 @@
 
 #include "llvm/Support/Allocator.h"
 #include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/DataTypes.h"
 #include <cassert>
+#include <functional>
 
 namespace llvm {
   
@@ -203,13 +205,10 @@ public:
     return getHeight();
   }
   
-  /// Profile - Profiling for ImutAVLTree.  This is not used by the
-  //    Factory object (which internally uses a FoldingSet), but can
-  //    be used by external clients that wish to insert an ImutAVLTree
-  //    object into a FoldingSet.
-  void Profile(llvm::FoldingSetNodeID& ID) const {
-    ID.AddPointer(this);
-  }   
+  /// Profile - Profiling for ImutAVLTree.
+  void Profile(llvm::FoldingSetNodeID& ID) {
+    ID.AddInteger(ComputeDigest());
+  }
   
   //===----------------------------------------------------===//  
   // Internal Values.
@@ -220,7 +219,7 @@ private:
   ImutAVLTree*     Right;
   unsigned         Height;
   value_type       Value;
-  unsigned         Hash;
+  unsigned         Digest;
   
   //===----------------------------------------------------===//    
   // Internal methods (node manipulation; used by Factory).
@@ -234,7 +233,7 @@ private:
   ///   ImutAVLFactory.
   ImutAVLTree(ImutAVLTree* l, ImutAVLTree* r, value_type_ref v, unsigned height)
   : Left(reinterpret_cast<uintptr_t>(l) | Mutable),
-    Right(r), Height(height), Value(v), Hash(0) {}
+    Right(r), Height(height), Value(v), Digest(0) {}
   
   
   /// isMutable - Returns true if the left and right subtree references
@@ -299,27 +298,27 @@ private:
   
   
   static inline
-  unsigned ComputeHash(ImutAVLTree* L, ImutAVLTree* R, value_type_ref V) {
-    unsigned hash = 0;
+  unsigned ComputeDigest(ImutAVLTree* L, ImutAVLTree* R, value_type_ref V) {
+    unsigned digest = 0;
     
-    if (L) hash += L->ComputeHash();
+    if (L) digest += L->ComputeDigest();
     
-    { // Compute hash of stored data.
+    { // Compute digest of stored data.
       FoldingSetNodeID ID;
       ImutInfo::Profile(ID,V);
-      hash += ID.ComputeHash();
+      digest += ID.ComputeHash();
     }
     
-    if (R) hash += R->ComputeHash();
+    if (R) digest += R->ComputeDigest();
     
-    return hash;
+    return digest;
   }
   
-  inline unsigned ComputeHash() {
-    if (Hash) return Hash;
+  inline unsigned ComputeDigest() {
+    if (Digest) return Digest;
     
-    unsigned X = ComputeHash(getSafeLeft(), getRight(), getValue());
-    if (!isMutable()) Hash = X;
+    unsigned X = ComputeDigest(getSafeLeft(), getRight(), getValue());
+    if (!isMutable()) Digest = X;
     
     return X;
   }
@@ -337,15 +336,31 @@ class ImutAVLFactory {
   
   typedef FoldingSet<TreeTy> CacheTy;
   
-  CacheTy Cache;  
-  BumpPtrAllocator Allocator;    
+  CacheTy Cache;
+  uintptr_t Allocator;
+  
+  bool ownsAllocator() const {
+    return Allocator & 0x1 ? false : true;
+  }
+
+  BumpPtrAllocator& getAllocator() const { 
+    return *reinterpret_cast<BumpPtrAllocator*>(Allocator & ~0x1);
+  }
   
   //===--------------------------------------------------===//    
   // Public interface.
   //===--------------------------------------------------===//
   
 public:
-  ImutAVLFactory() {}
+  ImutAVLFactory()
+    : Allocator(reinterpret_cast<uintptr_t>(new BumpPtrAllocator())) {}
+  
+  ImutAVLFactory(BumpPtrAllocator& Alloc)
+    : Allocator(reinterpret_cast<uintptr_t>(&Alloc) | 0x1) {}
+  
+  ~ImutAVLFactory() {
+    if (ownsAllocator()) delete &getAllocator();
+  }
   
   TreeTy* Add(TreeTy* T, value_type_ref V) {
     T = Add_internal(V,T);
@@ -361,8 +376,6 @@ public:
   
   TreeTy* GetEmptyTree() const { return NULL; }
   
-  BumpPtrAllocator& getAllocator() { return Allocator; }
-  
   //===--------------------------------------------------===//    
   // A bunch of quick helper functions used for reasoning
   // about the properties of trees and their children.
@@ -408,15 +421,19 @@ private:
   //===--------------------------------------------------===//
   
   TreeTy* CreateNode(TreeTy* L, value_type_ref V, TreeTy* R) {
-    // Search the FoldingSet bucket for a Tree with the same hash.
-    unsigned hash = TreeTy::ComputeHash(L, R, V);
+    // Search the FoldingSet bucket for a Tree with the same digest.
+    FoldingSetNodeID ID;
+    unsigned digest = TreeTy::ComputeDigest(L, R, V);
+    ID.AddInteger(digest);
+    unsigned hash = ID.ComputeHash();
+    
     typename CacheTy::bucket_iterator I = Cache.bucket_begin(hash);
     typename CacheTy::bucket_iterator E = Cache.bucket_end(hash);
     
     for (; I != E; ++I) {
       TreeTy* T = &*I;
 
-      if (T->ComputeHash() != hash)
+      if (T->ComputeDigest() != digest)
         continue;
       
       // We found a collision.  Perform a comparison of Contents('T')
@@ -449,12 +466,13 @@ private:
     // Create it.
 
     // Allocate the new tree node and insert it into the cache.
-    TreeTy* T = (TreeTy*) Allocator.Allocate<TreeTy>();    
+    BumpPtrAllocator& A = getAllocator();
+    TreeTy* T = (TreeTy*) A.Allocate<TreeTy>();
     new (T) TreeTy(L,R,V,IncrementHeight(L,R));
 
     // We do not insert 'T' into the FoldingSet here.  This is because
     // this tree is still mutable and things may get rebalanced.
-    // Because our hash is associative and based on the contents of
+    // Because our digest is associative and based on the contents of
     // the set, this should hopefully not cause any strange bugs.
     // 'T' is inserted by 'MarkImmutable'.
 
@@ -592,7 +610,9 @@ private:
         
     // Now that the node is immutable it can safely be inserted
     // into the node cache.
-    Cache.InsertNode(T, (void*) &*Cache.bucket_end(T->ComputeHash()));
+    llvm::FoldingSetNodeID ID;
+    ID.AddInteger(T->ComputeDigest());
+    Cache.InsertNode(T, (void*) &*Cache.bucket_end(ID.ComputeHash()));
   }
 };
   
@@ -927,6 +947,9 @@ public:
   public:
     Factory() {}
     
+    Factory(BumpPtrAllocator& Alloc)
+      : F(Alloc) {}
+    
     /// GetEmptySet - Returns an immutable set that contains no elements.
     ImmutableSet GetEmptySet() { return ImmutableSet(F.GetEmptyTree()); }
     
@@ -1008,12 +1031,25 @@ public:
   iterator begin() const { return iterator(Root); }
   iterator end() const { return iterator(); }  
   
+  //===--------------------------------------------------===//    
+  // Utility methods.
+  //===--------------------------------------------------===//  
+  
+  inline unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
+  
+  static inline void Profile(FoldingSetNodeID& ID, const ImmutableSet& S) {
+    ID.AddPointer(S.Root);
+  }
+  
+  inline void Profile(FoldingSetNodeID& ID) const {
+    return Profile(ID,*this);
+  }
+  
   //===--------------------------------------------------===//    
   // For testing.
   //===--------------------------------------------------===//  
   
   void verify() const { if (Root) Root->verify(); }
-  unsigned getHeight() const { return Root ? Root->getHeight() : 0; }
 };
 
 } // end namespace llvm