Index: include/llvm/ADT/SmallPtrSet.h =================================================================== --- include/llvm/ADT/SmallPtrSet.h +++ include/llvm/ADT/SmallPtrSet.h @@ -60,6 +60,7 @@ // If small, this is # elts allocated consecutively unsigned NumElements; + /// Uninitialized for small sets, otherwise the number of tombstones. unsigned NumTombstones; // Helpers to copy and move construct a SmallPtrSet. @@ -92,7 +93,6 @@ // Fill the array with empty markers. memset(CurArray, -1, CurArraySize*sizeof(void*)); NumElements = 0; - NumTombstones = 0; } protected: Index: lib/Support/SmallPtrSet.cpp =================================================================== --- lib/Support/SmallPtrSet.cpp +++ lib/Support/SmallPtrSet.cpp @@ -39,11 +39,14 @@ if (LLVM_UNLIKELY(NumElements * 4 >= CurArraySize * 3)) { // If more than 3/4 of the array is full, grow. Grow(CurArraySize < 64 ? 128 : CurArraySize*2); - } else if (LLVM_UNLIKELY(CurArraySize - (NumElements + NumTombstones) < + } else { + assert(!isSmall() && "NumTombstones is uninitialized if not small"); + if (LLVM_UNLIKELY(CurArraySize - (NumElements + NumTombstones) < CurArraySize / 8)) { - // If fewer of 1/8 of the array is empty (meaning that many are filled with - // tombstones), rehash. - Grow(CurArraySize); + // If fewer of 1/8 of the array is empty (meaning that many are filled + // with tombstones), rehash. + Grow(CurArraySize); + } } // Okay, we know we have space. Find a hash bucket. @@ -147,8 +150,8 @@ } free(OldBuckets); - NumTombstones = 0; } + NumTombstones = 0; } SmallPtrSetImplBase::SmallPtrSetImplBase(const void **SmallStorage, @@ -212,7 +215,8 @@ memcpy(CurArray, RHS.CurArray, sizeof(void*)*CurArraySize); NumElements = RHS.NumElements; - NumTombstones = RHS.NumTombstones; + if (!RHS.isSmall()) + NumTombstones = RHS.NumTombstones; } void SmallPtrSetImplBase::MoveFrom(unsigned SmallSize, @@ -233,18 +237,17 @@ } else { CurArray = RHS.CurArray; RHS.CurArray = RHS.SmallArray; + NumTombstones = RHS.NumTombstones; } // Copy the rest of the trivial members. CurArraySize = RHS.CurArraySize; NumElements = RHS.NumElements; - NumTombstones = RHS.NumTombstones; // Make the RHS small and empty. RHS.CurArraySize = SmallSize; assert(RHS.CurArray == RHS.SmallArray); RHS.NumElements = 0; - RHS.NumTombstones = 0; } void SmallPtrSetImplBase::swap(SmallPtrSetImplBase &RHS) { @@ -271,7 +274,6 @@ RHS.CurArray = this->CurArray; RHS.NumTombstones = this->NumTombstones; this->CurArray = this->SmallArray; - this->NumTombstones = 0; return; } @@ -283,7 +285,6 @@ std::swap(RHS.NumElements, this->NumElements); std::swap(RHS.CurArraySize, this->CurArraySize); this->CurArray = RHS.CurArray; - this->NumTombstones = RHS.NumTombstones; RHS.CurArray = RHS.SmallArray; RHS.NumTombstones = 0; return;