From 31bda05073f642a595816e0b6712fe0ec03053eb Mon Sep 17 00:00:00 2001 From: Owen Anderson Date: Mon, 9 Jul 2007 22:27:20 +0000 Subject: [PATCH] Make the assignment operator for SmallPtrSet much faster for normal cases. llvm-svn: 38474 --- lib/Support/SmallPtrSet.cpp | 57 ++++++++++++++----------------------- 1 file changed, 21 insertions(+), 36 deletions(-) diff --git a/lib/Support/SmallPtrSet.cpp b/lib/Support/SmallPtrSet.cpp index e8e530fceed..e956cbcc9d3 100644 --- a/lib/Support/SmallPtrSet.cpp +++ b/lib/Support/SmallPtrSet.cpp @@ -177,42 +177,27 @@ SmallPtrSetImpl::SmallPtrSetImpl(const SmallPtrSetImpl& that) { /// CopyFrom - implement operator= from a smallptrset that has the same pointer /// type, but may have a different small size. void SmallPtrSetImpl::CopyFrom(const SmallPtrSetImpl &RHS) { - // Allocate space if needed or clear the current elements out of the array. - if (CurArraySize < RHS.size()*2) { - if (!isSmall()) - delete [] CurArray; - - NumElements = NumTombstones = 0; - - // Get a power of two larger than twice the RHS size. - CurArraySize = 1 << Log2_32(RHS.size()*4); - - // Install the new array. Clear all the buckets to empty. - CurArray = new void*[CurArraySize+1]; - memset(CurArray, -1, CurArraySize*sizeof(void*)); - - // The end pointer, always valid, is set to a valid element to help the - // iterator. - CurArray[CurArraySize] = 0; - - } else if (!empty()) { - clear(); - } + if (isSmall() && RHS.isSmall()) + assert(CurArraySize == RHS.CurArraySize && + "Cannot assign sets with different small sizes"); + NumElements = RHS.NumElements; + NumTombstones = RHS.NumTombstones; - // Now that we know we have enough space, and that the current array is empty, - // copy over all the elements from the RHS. - for (void **BucketPtr = RHS.CurArray, **E = RHS.CurArray+RHS.CurArraySize; - BucketPtr != E; ++BucketPtr) { - // Copy over the element if it is valid. - void *Elt = *BucketPtr; - if (Elt != getTombstoneMarker() && Elt != getEmptyMarker()) { - if (isSmall()) - SmallArray[NumElements++] = Elt; - else - *const_cast(FindBucketFor(Elt)) = Elt; - } - } + // If we're not currently small, and we don't have the same heap size, + // free our heap allocated storage + if (!isSmall() && CurArraySize != RHS.CurArraySize) + delete [] CurArray; - if (!isSmall()) - NumElements = RHS.NumElements; + // If we're becoming small, prepare to insert into our stack space + if (RHS.isSmall()) + CurArray = &SmallArray[0]; + // Otherwise, allocate new heap space (unless we were the same size) + else if (CurArraySize != RHS.CurArraySize) + CurArray = new void*[RHS.CurArraySize+1]; + + // Copy over the new array size + CurArraySize = RHS.CurArraySize; + + // Copy over the contents from the other set + memcpy(CurArray, RHS.CurArray, sizeof(void*)*(CurArraySize+1)); }