From af3056c97e56106af7c3b9a5c856d1dc1d21e358 Mon Sep 17 00:00:00 2001 From: Chris Lattner Date: Sat, 27 Jan 2007 07:52:27 +0000 Subject: [PATCH] Fix a limitation of SmallPtrSet. Before it would assert if the smallsize was not a power of two. Now it rounds up to the next power of two internally. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@33580 91177308-0d34-0410-b5e6-96231b3b80d8 --- include/llvm/ADT/SmallPtrSet.h | 32 ++++++++++++++++++++++++++++++-- 1 file changed, 30 insertions(+), 2 deletions(-) diff --git a/include/llvm/ADT/SmallPtrSet.h b/include/llvm/ADT/SmallPtrSet.h index d617d6b3b0b..d2a68ff90f3 100644 --- a/include/llvm/ADT/SmallPtrSet.h +++ b/include/llvm/ADT/SmallPtrSet.h @@ -161,13 +161,41 @@ public: } }; +/// NextPowerOfTwo - This is a helper template that rounds N up to the next +/// power of two. +template +struct NextPowerOfTwo; + +/// NextPowerOfTwoH - If N is not a power of two, increase it. This is a helper +/// template used to implement NextPowerOfTwo. +template +struct NextPowerOfTwoH { + enum { Val = N }; +}; +template +struct NextPowerOfTwoH { + enum { + // We could just use NextVal = N+1, but this converges faster. N|(N-1) sets + // the right-most zero bits to one all at once, e.g. 0b0011000 -> 0b0011111. + NextVal = (N|(N-1)) + 1, + Val = NextPowerOfTwo::Val + }; +}; + +template +struct NextPowerOfTwo { + enum { Val = NextPowerOfTwoH::Val }; +}; + /// SmallPtrSet - This class implements template class SmallPtrSet : public SmallPtrSetImpl { - void *SmallArray[SmallSize]; + // Make sure that SmallSize is a power of two, round up if not. + enum { SmallSizePowTwo = NextPowerOfTwo::Val }; + void *SmallArray[SmallSizePowTwo]; public: - SmallPtrSet() : SmallPtrSetImpl(SmallSize) {} + SmallPtrSet() : SmallPtrSetImpl(NextPowerOfTwo::Val) {} typedef SmallPtrSetIterator iterator; typedef SmallPtrSetIterator const_iterator;