llvm.org GIT mirror llvm / e1e9366
SmallVector and SmallPtrSet allocations now power-of-two aligned. This time tested on both OSX and Linux. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@178377 91177308-0d34-0410-b5e6-96231b3b80d8 Jean-Luc Duprat 6 years ago
4 changed file(s) with 81 addition(s) and 33 deletion(s). Raw diff Collapse all Expand all
5353 /// then the set is in 'small mode'.
5454 const void **CurArray;
5555 /// CurArraySize - The allocated size of CurArray, always a power of two.
56 /// Note that CurArray points to an array that has CurArraySize+1 elements in
57 /// it, so that the end iterator actually points to valid memory.
5856 unsigned CurArraySize;
5957
6058 // If small, this is # elts allocated consecutively
6765 SmallArray(SmallStorage), CurArray(SmallStorage), CurArraySize(SmallSize) {
6866 assert(SmallSize && (SmallSize & (SmallSize-1)) == 0 &&
6967 "Initial size must be a power of two!");
70 // The end pointer, always valid, is set to a valid element to help the
71 // iterator.
72 CurArray[SmallSize] = 0;
7368 clear();
7469 }
7570 ~SmallPtrSetImpl();
146141 class SmallPtrSetIteratorImpl {
147142 protected:
148143 const void *const *Bucket;
144 const void *const *End;
149145 public:
150 explicit SmallPtrSetIteratorImpl(const void *const *BP) : Bucket(BP) {
151 AdvanceIfNotValid();
146 explicit SmallPtrSetIteratorImpl(const void *const *BP, const void*const *E)
147 : Bucket(BP), End(E) {
148 AdvanceIfNotValid();
152149 }
153150
154151 bool operator==(const SmallPtrSetIteratorImpl &RHS) const {
163160 /// that is. This is guaranteed to stop because the end() bucket is marked
164161 /// valid.
165162 void AdvanceIfNotValid() {
166 while (*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
167 *Bucket == SmallPtrSetImpl::getTombstoneMarker())
163 assert(Bucket <= End);
164 while (Bucket != End &&
165 (*Bucket == SmallPtrSetImpl::getEmptyMarker() ||
166 *Bucket == SmallPtrSetImpl::getTombstoneMarker()))
168167 ++Bucket;
169168 }
170169 };
181180 typedef std::ptrdiff_t difference_type;
182181 typedef std::forward_iterator_tag iterator_category;
183182
184 explicit SmallPtrSetIterator(const void *const *BP)
185 : SmallPtrSetIteratorImpl(BP) {}
183 explicit SmallPtrSetIterator(const void *const *BP, const void *const *E)
184 : SmallPtrSetIteratorImpl(BP, E) {}
186185
187186 // Most methods provided by baseclass.
188187
189188 const PtrTy operator*() const {
189 assert(Bucket < End);
190190 return PtrTraits::getFromVoidPointer(const_cast(*Bucket));
191191 }
192192
235235 class SmallPtrSet : public SmallPtrSetImpl {
236236 // Make sure that SmallSize is a power of two, round up if not.
237237 enum { SmallSizePowTwo = RoundUpToPowerOfTwo::Val };
238 /// SmallStorage - Fixed size storage used in 'small mode'. The extra element
239 /// ensures that the end iterator actually points to valid memory.
240 const void *SmallStorage[SmallSizePowTwo+1];
238 /// SmallStorage - Fixed size storage used in 'small mode'.
239 const void *SmallStorage[SmallSizePowTwo];
241240 typedef PointerLikeTypeTraits PtrTraits;
242241 public:
243242 SmallPtrSet() : SmallPtrSetImpl(SmallStorage, SmallSizePowTwo) {}
274273 typedef SmallPtrSetIterator iterator;
275274 typedef SmallPtrSetIterator const_iterator;
276275 inline iterator begin() const {
277 return iterator(CurArray);
276 return iterator(CurArray, CurArray+CurArraySize);
278277 }
279278 inline iterator end() const {
280 return iterator(CurArray+CurArraySize);
279 return iterator(CurArray+CurArraySize, CurArray+CurArraySize);
281280 }
282281
283282 // Allow assignment from any smallptrset with the same element type even if it
1515
1616 #include "llvm/Support/AlignOf.h"
1717 #include "llvm/Support/Compiler.h"
18 #include "llvm/Support/MathExtras.h"
1819 #include "llvm/Support/type_traits.h"
1920 #include
2021 #include
266267 void SmallVectorTemplateBase::grow(size_t MinSize) {
267268 size_t CurCapacity = this->capacity();
268269 size_t CurSize = this->size();
269 size_t NewCapacity = 2*CurCapacity + 1; // Always grow, even from zero.
270 // Always grow, even from zero.
271 size_t NewCapacity = size_t(NextPowerOf2(CurCapacity+2));
270272 if (NewCapacity < MinSize)
271273 NewCapacity = MinSize;
272274 T *NewElts = static_cast(malloc(NewCapacity*sizeof(T)));
2828 NumElements = NumTombstones = 0;
2929
3030 // Install the new array. Clear all the buckets to empty.
31 CurArray = (const void**)malloc(sizeof(void*) * (CurArraySize+1));
31 CurArray = (const void**)malloc(sizeof(void*) * CurArraySize);
3232 assert(CurArray && "Failed to allocate memory?");
3333 memset(CurArray, -1, CurArraySize*sizeof(void*));
34
35 // The end pointer, always valid, is set to a valid element to help the
36 // iterator.
37 CurArray[CurArraySize] = 0;
3834 }
3935
4036 bool SmallPtrSetImpl::insert_imp(const void * Ptr) {
138134 bool WasSmall = isSmall();
139135
140136 // Install the new array. Clear all the buckets to empty.
141 CurArray = (const void**)malloc(sizeof(void*) * (NewSize+1));
137 CurArray = (const void**)malloc(sizeof(void*) * NewSize);
142138 assert(CurArray && "Failed to allocate memory?");
143139 CurArraySize = NewSize;
144140 memset(CurArray, -1, NewSize*sizeof(void*));
145
146 // The end pointer, always valid, is set to a valid element to help the
147 // iterator.
148 CurArray[NewSize] = 0;
149141
150142 // Copy over all the elements.
151143 if (WasSmall) {
179171 CurArray = SmallArray;
180172 // Otherwise, allocate new heap space (unless we were the same size)
181173 } else {
182 CurArray = (const void**)malloc(sizeof(void*) * (that.CurArraySize+1));
174 CurArray = (const void**)malloc(sizeof(void*) * that.CurArraySize);
183175 assert(CurArray && "Failed to allocate memory?");
184176 }
185177
187179 CurArraySize = that.CurArraySize;
188180
189181 // Copy over the contents from the other set
190 memcpy(CurArray, that.CurArray, sizeof(void*)*(CurArraySize+1));
182 memcpy(CurArray, that.CurArray, sizeof(void*)*CurArraySize);
191183
192184 NumElements = that.NumElements;
193185 NumTombstones = that.NumTombstones;
199191 if (isSmall() && RHS.isSmall())
200192 assert(CurArraySize == RHS.CurArraySize &&
201193 "Cannot assign sets with different small sizes");
202
194
203195 // If we're becoming small, prepare to insert into our stack space
204196 if (RHS.isSmall()) {
205197 if (!isSmall())
208200 // Otherwise, allocate new heap space (unless we were the same size)
209201 } else if (CurArraySize != RHS.CurArraySize) {
210202 if (isSmall())
211 CurArray = (const void**)malloc(sizeof(void*) * (RHS.CurArraySize+1));
203 CurArray = (const void**)malloc(sizeof(void*) * RHS.CurArraySize);
212204 else
213 CurArray = (const void**)realloc(CurArray, sizeof(void*)*(RHS.CurArraySize+1));
205 CurArray = (const void**)realloc(CurArray, sizeof(void*)*RHS.CurArraySize);
214206 assert(CurArray && "Failed to allocate memory?");
215207 }
216208
218210 CurArraySize = RHS.CurArraySize;
219211
220212 // Copy over the contents from the other set
221 memcpy(CurArray, RHS.CurArray, sizeof(void*)*(CurArraySize+1));
213 memcpy(CurArray, RHS.CurArray, sizeof(void*)*CurArraySize);
222214
223215 NumElements = RHS.NumElements;
224216 NumTombstones = RHS.NumTombstones;
1616 using namespace llvm;
1717
1818 // SmallPtrSet swapping test.
19 TEST(SmallPtrSetTest, GrowthTest) {
20 int i;
21 int buf[8];
22 for(i=0; i<8; ++i) buf[i]=0;
23
24
25 SmallPtrSet s;
26 typedef SmallPtrSet::iterator iter;
27
28 s.insert(&buf[0]);
29 s.insert(&buf[1]);
30 s.insert(&buf[2]);
31 s.insert(&buf[3]);
32 EXPECT_EQ(4U, s.size());
33
34 i = 0;
35 for(iter I=s.begin(), E=s.end(); I!=E; ++I, ++i)
36 (**I)++;
37 EXPECT_EQ(4, i);
38 for(i=0; i<8; ++i)
39 EXPECT_EQ(i<4?1:0,buf[i]);
40
41 s.insert(&buf[4]);
42 s.insert(&buf[5]);
43 s.insert(&buf[6]);
44 s.insert(&buf[7]);
45
46 i = 0;
47 for(iter I=s.begin(), E=s.end(); I!=E; ++I, ++i)
48 (**I)++;
49 EXPECT_EQ(8, i);
50 s.erase(&buf[4]);
51 s.erase(&buf[5]);
52 s.erase(&buf[6]);
53 s.erase(&buf[7]);
54 EXPECT_EQ(4U, s.size());
55
56 i = 0;
57 for(iter I=s.begin(), E=s.end(); I!=E; ++I, ++i)
58 (**I)++;
59 EXPECT_EQ(4, i);
60 for(i=0; i<8; ++i)
61 EXPECT_EQ(i<4?3:1,buf[i]);
62
63 s.clear();
64 for(i=0; i<8; ++i) buf[i]=0;
65 for(i=0; i<128; ++i) s.insert(&buf[i%8]); // test repeated entires
66 EXPECT_EQ(8U, s.size());
67 for(iter I=s.begin(), E=s.end(); I!=E; ++I, ++i)
68 (**I)++;
69 for(i=0; i<8; ++i)
70 EXPECT_EQ(1,buf[i]);
71 }
72
73
1974 TEST(SmallPtrSetTest, SwapTest) {
2075 int buf[10];
2176