llvm.org GIT mirror llvm / 3a1c35a
Add range-based set()/reset() to BitVector. These allow fast setting/resetting of ranges of bits, particularly useful when dealing with very large BitVector's. git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@165984 91177308-0d34-0410-b5e6-96231b3b80d8 Owen Anderson 6 years ago
3 changed file(s) with 128 addition(s) and 0 deletion(s). Raw diff Collapse all Expand all
236236 return *this;
237237 }
238238
239 /// set - Efficiently set a range of bits in [I, E)
240 BitVector &set(unsigned I, unsigned E) {
241 assert(I <= E && "Attempted to set backwards range!");
242 assert(E <= size() && "Attempted to set out-of-bounds range!");
243
244 if (I == E) return *this;
245
246 if (I / BITWORD_SIZE == (E-1) / BITWORD_SIZE) {
247 BitWord EMask = 1 << (E % BITWORD_SIZE);
248 BitWord IMask = 1 << (I % BITWORD_SIZE);
249 BitWord Mask = EMask - IMask;
250 Bits[I / BITWORD_SIZE] |= Mask;
251 return *this;
252 }
253
254 BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
255 Bits[I / BITWORD_SIZE] |= PrefixMask;
256 I = RoundUpToAlignment(I, BITWORD_SIZE);
257
258 for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
259 Bits[I / BITWORD_SIZE] = ~0UL;
260
261 BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
262 Bits[I / BITWORD_SIZE] |= PostfixMask;
263
264 return *this;
265 }
266
239267 BitVector &reset() {
240268 init_words(Bits, Capacity, false);
241269 return *this;
243271
244272 BitVector &reset(unsigned Idx) {
245273 Bits[Idx / BITWORD_SIZE] &= ~(1L << (Idx % BITWORD_SIZE));
274 return *this;
275 }
276
277 /// reset - Efficiently reset a range of bits in [I, E)
278 BitVector &reset(unsigned I, unsigned E) {
279 assert(I <= E && "Attempted to reset backwards range!");
280 assert(E <= size() && "Attempted to reset out-of-bounds range!");
281
282 if (I == E) return *this;
283
284 if (I / BITWORD_SIZE == (E-1) / BITWORD_SIZE) {
285 BitWord EMask = 1 << (E % BITWORD_SIZE);
286 BitWord IMask = 1 << (I % BITWORD_SIZE);
287 BitWord Mask = EMask - IMask;
288 Bits[I / BITWORD_SIZE] &= ~Mask;
289 return *this;
290 }
291
292 BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
293 Bits[I / BITWORD_SIZE] &= ~PrefixMask;
294 I = RoundUpToAlignment(I, BITWORD_SIZE);
295
296 for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
297 Bits[I / BITWORD_SIZE] = 0UL;
298
299 BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
300 Bits[I / BITWORD_SIZE] &= ~PostfixMask;
301
246302 return *this;
247303 }
248304
299299 return *this;
300300 }
301301
302 /// set - Efficiently set a range of bits in [I, E)
303 SmallBitVector &set(unsigned I, unsigned E) {
304 assert(I <= E && "Attempted to set backwards range!");
305 assert(E <= size() && "Attempted to set out-of-bounds range!");
306 if (I == E) return *this;
307 if (isSmall()) {
308 uintptr_t EMask = 1 << E;
309 uintptr_t IMask = 1 << I;
310 uintptr_t Mask = EMask - IMask;
311 setSmallBits(getSmallBits() | Mask);
312 } else
313 getPointer()->set(I, E);
314 return *this;
315 }
316
302317 SmallBitVector &reset() {
303318 if (isSmall())
304319 setSmallBits(0);
312327 setSmallBits(getSmallBits() & ~(uintptr_t(1) << Idx));
313328 else
314329 getPointer()->reset(Idx);
330 return *this;
331 }
332
333 /// reset - Efficiently reset a range of bits in [I, E)
334 SmallBitVector &reset(unsigned I, unsigned E) {
335 assert(I <= E && "Attempted to reset backwards range!");
336 assert(E <= size() && "Attempted to reset out-of-bounds range!");
337 if (I == E) return *this;
338 if (isSmall()) {
339 uintptr_t EMask = 1 << E;
340 uintptr_t IMask = 1 << I;
341 uintptr_t Mask = EMask - IMask;
342 setSmallBits(getSmallBits() & ~Mask);
343 } else
344 getPointer()->reset(I, E);
315345 return *this;
316346 }
317347
280280 EXPECT_FALSE(A.anyCommon(B));
281281 EXPECT_FALSE(B.anyCommon(A));
282282 }
283
284 TYPED_TEST(BitVectorTest, RangeOps) {
285 TypeParam A;
286 A.resize(256);
287 A.reset();
288 A.set(1, 255);
289
290 EXPECT_FALSE(A.test(0));
291 EXPECT_TRUE( A.test(1));
292 EXPECT_TRUE( A.test(23));
293 EXPECT_TRUE( A.test(254));
294 EXPECT_FALSE(A.test(255));
295
296 TypeParam B;
297 B.resize(256);
298 B.set();
299 B.reset(1, 255);
300
301 EXPECT_TRUE( B.test(0));
302 EXPECT_FALSE(B.test(1));
303 EXPECT_FALSE(B.test(23));
304 EXPECT_FALSE(B.test(254));
305 EXPECT_TRUE( B.test(255));
306
307 TypeParam C;
308 C.resize(3);
309 C.reset();
310 C.set(0, 1);
311
312 EXPECT_TRUE(C.test(0));
313 EXPECT_FALSE( C.test(1));
314 EXPECT_FALSE( C.test(2));
315
316 TypeParam D;
317 D.resize(3);
318 D.set();
319 D.reset(0, 1);
320
321 EXPECT_FALSE(D.test(0));
322 EXPECT_TRUE( D.test(1));
323 EXPECT_TRUE( D.test(2));
324 }
283325 }
284326 #endif