[llvm-commits] [llvm] r40837 - in /llvm/trunk: include/llvm/ADT/DenseMap.h include/llvm/ADT/SmallPtrSet.h lib/Support/SmallPtrSet.cpp

Chris Lattner sabre at nondot.org
Sun Aug 5 00:32:16 PDT 2007


Author: lattner
Date: Sun Aug  5 02:32:14 2007
New Revision: 40837

URL: http://llvm.org/viewvc/llvm-project?rev=40837&view=rev
Log:
When clearing a SmallPtrSet, if the set had a huge capacity, but the
contents of the set were small, deallocate and shrink the set.  This
avoids having us to memset as much data, significantly speeding up
some pathological cases.  For example, this speeds up the verifier
from 0.3899s to 0.0763 (5.1x) on the testcase from PR1432 in a 
release build.

Modified:
    llvm/trunk/include/llvm/ADT/DenseMap.h
    llvm/trunk/include/llvm/ADT/SmallPtrSet.h
    llvm/trunk/lib/Support/SmallPtrSet.cpp

Modified: llvm/trunk/include/llvm/ADT/DenseMap.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/DenseMap.h?rev=40837&r1=40836&r2=40837&view=diff

==============================================================================
--- llvm/trunk/include/llvm/ADT/DenseMap.h (original)
+++ llvm/trunk/include/llvm/ADT/DenseMap.h Sun Aug  5 02:32:14 2007
@@ -91,6 +91,8 @@
   unsigned size() const { return NumEntries; }
   
   void clear() {
+    // If the capacity of the array is huge, and the # elements used is small,
+    // shrink the array.
     if (NumEntries * 4 < NumBuckets && NumBuckets > 64) {
       shrink_and_clear();
       return;

Modified: llvm/trunk/include/llvm/ADT/SmallPtrSet.h
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/ADT/SmallPtrSet.h?rev=40837&r1=40836&r2=40837&view=diff

==============================================================================
--- llvm/trunk/include/llvm/ADT/SmallPtrSet.h (original)
+++ llvm/trunk/include/llvm/ADT/SmallPtrSet.h Sun Aug  5 02:32:14 2007
@@ -80,6 +80,11 @@
   }
   
   void clear() {
+    // If the capacity of the array is huge, and the # elements used is small,
+    // shrink the array.
+    if (!isSmall() && NumElements*4 < CurArraySize && CurArraySize > 32)
+      return shrink_and_clear();
+    
     // Fill the array with empty markers.
     memset(CurArray, -1, CurArraySize*sizeof(void*));
     NumElements = 0;
@@ -103,8 +108,8 @@
   bool count(void * const Ptr) const {
     if (isSmall()) {
       // Linear search for the item.
-      for (const void *const *APtr = SmallArray, *const *E = SmallArray+NumElements;
-           APtr != E; ++APtr)
+      for (const void *const *APtr = SmallArray,
+                      *const *E = SmallArray+NumElements; APtr != E; ++APtr)
         if (*APtr == Ptr)
           return true;
       return false;
@@ -121,6 +126,7 @@
     return ((uintptr_t)Ptr >> 4) & (CurArraySize-1);
   }
   const void * const *FindBucketFor(const void *Ptr) const;
+  void shrink_and_clear();
   
   /// Grow - Allocate a larger backing store for the buckets and move it over.
   void Grow();

Modified: llvm/trunk/lib/Support/SmallPtrSet.cpp
URL: http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/Support/SmallPtrSet.cpp?rev=40837&r1=40836&r2=40837&view=diff

==============================================================================
--- llvm/trunk/lib/Support/SmallPtrSet.cpp (original)
+++ llvm/trunk/lib/Support/SmallPtrSet.cpp Sun Aug  5 02:32:14 2007
@@ -18,6 +18,24 @@
 
 using namespace llvm;
 
+void SmallPtrSetImpl::shrink_and_clear() {
+  assert(!isSmall() && "Can't shrink a small set!");
+  free(CurArray);
+
+  // Reduce the number of buckets.
+  CurArraySize = NumElements > 16 ? 1 << (Log2_32_Ceil(NumElements) + 1) : 32;
+  NumElements = NumTombstones = 0;
+
+  // Install the new array.  Clear all the buckets to empty.
+  CurArray = (const void**)malloc(sizeof(void*) * (CurArraySize+1));
+  assert(CurArray && "Failed to allocate memory?");
+  memset(CurArray, -1, CurArraySize*sizeof(void*));
+  
+  // The end pointer, always valid, is set to a valid element to help the
+  // iterator.
+  CurArray[CurArraySize] = 0;
+}
+
 bool SmallPtrSetImpl::insert(const void * Ptr) {
   if (isSmall()) {
     // Check to see if it is already in the set.





More information about the llvm-commits mailing list