Replaced (FoldingSet) profiling of ImutAVLTree with a hashing based scheme. The
authorTed Kremenek <kremenek@apple.com>
Mon, 21 Jan 2008 22:33:30 +0000 (22:33 +0000)
committerTed Kremenek <kremenek@apple.com>
Mon, 21 Jan 2008 22:33:30 +0000 (22:33 +0000)
problem was that we previously hashed based on the pointers of the left and
right children, but this is bogus: we can easily have different trees that
represent the same set. Now we use a hashing based scheme that compares the
*contents* of the trees, but not without having to do a full scan of a tree. The
only caveat is that with hashing is that we may have collisions, which result in
two different trees being falsely labeled as equivalent. If this becomes a
problem, we can add extra data to the profile to hopefully resolve most
collisions.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@46224 91177308-0d34-0410-b5e6-96231b3b80d8

include/llvm/ADT/ImmutableSet.h

index e77deeb51eb6f3a934975d3e551449d276d8da36..5118b0d33696a0c52d377ef5dc0c88b219ffa352 100644 (file)
@@ -198,6 +198,7 @@ private:
   ImutAVLTree*     Right;
   unsigned         Height;
   value_type       Value;
+  unsigned         Hash;
   
   //===----------------------------------------------------===//  
   // Profiling or FoldingSet.
@@ -205,22 +206,38 @@ private:
 
 private:
 
+  static inline
+  unsigned ComputeHash(ImutAVLTree* L, ImutAVLTree* R, value_type_ref V) {
+    FoldingSetNodeID ID;
+    
+    ID.AddInteger(L ? L->ComputeHash() : 0);
+    ImutInfo::Profile(ID,V);
+    ID.AddInteger(R ? R->ComputeHash() : 0);
+    
+    return ID.ComputeHash();    
+  }
+  
+  inline unsigned ComputeHash() {
+    if (!isMutable() && Hash) return Hash;
+    Hash = ComputeHash(getSafeLeft(), getRight(), getValue());
+    return Hash;
+  }    
+  
   /// Profile - Generates a FoldingSet profile for a tree node before it is
   ///   created.  This is used by the ImutAVLFactory when creating
   ///   trees.
   static inline
   void Profile(FoldingSetNodeID& ID, ImutAVLTree* L, ImutAVLTree* R,
-               value_type_ref V) {    
-    ID.AddPointer(L);
-    ID.AddPointer(R);
-    ImutInfo::Profile(ID,V);
+               value_type_ref V) {
+    
+    ID.AddInteger(ComputeHash(L, R, V));
   }
   
 public:
 
   /// Profile - Generates a FoldingSet profile for an existing tree node.
   void Profile(FoldingSetNodeID& ID) {
-    Profile(ID,getSafeLeft(),getRight(),getValue());    
+    ID.AddInteger(ComputeHash());
   }
   
   //===----------------------------------------------------===//    
@@ -235,7 +252,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) {}
+    Right(r), Height(height), Value(v), Hash(0) {}
   
   
   /// isMutable - Returns true if the left and right subtree references