mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2024-11-01 15:11:24 +00:00
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
This commit is contained in:
parent
fb9ebbf236
commit
3a1c35afbd
@ -237,6 +237,34 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// set - Efficiently set a range of bits in [I, E)
|
||||
BitVector &set(unsigned I, unsigned E) {
|
||||
assert(I <= E && "Attempted to set backwards range!");
|
||||
assert(E <= size() && "Attempted to set out-of-bounds range!");
|
||||
|
||||
if (I == E) return *this;
|
||||
|
||||
if (I / BITWORD_SIZE == (E-1) / BITWORD_SIZE) {
|
||||
BitWord EMask = 1 << (E % BITWORD_SIZE);
|
||||
BitWord IMask = 1 << (I % BITWORD_SIZE);
|
||||
BitWord Mask = EMask - IMask;
|
||||
Bits[I / BITWORD_SIZE] |= Mask;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
|
||||
Bits[I / BITWORD_SIZE] |= PrefixMask;
|
||||
I = RoundUpToAlignment(I, BITWORD_SIZE);
|
||||
|
||||
for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
|
||||
Bits[I / BITWORD_SIZE] = ~0UL;
|
||||
|
||||
BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
|
||||
Bits[I / BITWORD_SIZE] |= PostfixMask;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVector &reset() {
|
||||
init_words(Bits, Capacity, false);
|
||||
return *this;
|
||||
@ -247,6 +275,34 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// reset - Efficiently reset a range of bits in [I, E)
|
||||
BitVector &reset(unsigned I, unsigned E) {
|
||||
assert(I <= E && "Attempted to reset backwards range!");
|
||||
assert(E <= size() && "Attempted to reset out-of-bounds range!");
|
||||
|
||||
if (I == E) return *this;
|
||||
|
||||
if (I / BITWORD_SIZE == (E-1) / BITWORD_SIZE) {
|
||||
BitWord EMask = 1 << (E % BITWORD_SIZE);
|
||||
BitWord IMask = 1 << (I % BITWORD_SIZE);
|
||||
BitWord Mask = EMask - IMask;
|
||||
Bits[I / BITWORD_SIZE] &= ~Mask;
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitWord PrefixMask = ~0UL << (I % BITWORD_SIZE);
|
||||
Bits[I / BITWORD_SIZE] &= ~PrefixMask;
|
||||
I = RoundUpToAlignment(I, BITWORD_SIZE);
|
||||
|
||||
for (; I + BITWORD_SIZE <= E; I += BITWORD_SIZE)
|
||||
Bits[I / BITWORD_SIZE] = 0UL;
|
||||
|
||||
BitWord PostfixMask = (1UL << (E % BITWORD_SIZE)) - 1;
|
||||
Bits[I / BITWORD_SIZE] &= ~PostfixMask;
|
||||
|
||||
return *this;
|
||||
}
|
||||
|
||||
BitVector &flip() {
|
||||
for (unsigned i = 0; i < NumBitWords(size()); ++i)
|
||||
Bits[i] = ~Bits[i];
|
||||
|
@ -300,6 +300,21 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// set - Efficiently set a range of bits in [I, E)
|
||||
SmallBitVector &set(unsigned I, unsigned E) {
|
||||
assert(I <= E && "Attempted to set backwards range!");
|
||||
assert(E <= size() && "Attempted to set out-of-bounds range!");
|
||||
if (I == E) return *this;
|
||||
if (isSmall()) {
|
||||
uintptr_t EMask = 1 << E;
|
||||
uintptr_t IMask = 1 << I;
|
||||
uintptr_t Mask = EMask - IMask;
|
||||
setSmallBits(getSmallBits() | Mask);
|
||||
} else
|
||||
getPointer()->set(I, E);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmallBitVector &reset() {
|
||||
if (isSmall())
|
||||
setSmallBits(0);
|
||||
@ -316,6 +331,21 @@ public:
|
||||
return *this;
|
||||
}
|
||||
|
||||
/// reset - Efficiently reset a range of bits in [I, E)
|
||||
SmallBitVector &reset(unsigned I, unsigned E) {
|
||||
assert(I <= E && "Attempted to reset backwards range!");
|
||||
assert(E <= size() && "Attempted to reset out-of-bounds range!");
|
||||
if (I == E) return *this;
|
||||
if (isSmall()) {
|
||||
uintptr_t EMask = 1 << E;
|
||||
uintptr_t IMask = 1 << I;
|
||||
uintptr_t Mask = EMask - IMask;
|
||||
setSmallBits(getSmallBits() & ~Mask);
|
||||
} else
|
||||
getPointer()->reset(I, E);
|
||||
return *this;
|
||||
}
|
||||
|
||||
SmallBitVector &flip() {
|
||||
if (isSmall())
|
||||
setSmallBits(~getSmallBits());
|
||||
|
@ -281,5 +281,47 @@ TYPED_TEST(BitVectorTest, BinOps) {
|
||||
EXPECT_FALSE(A.anyCommon(B));
|
||||
EXPECT_FALSE(B.anyCommon(A));
|
||||
}
|
||||
|
||||
TYPED_TEST(BitVectorTest, RangeOps) {
|
||||
TypeParam A;
|
||||
A.resize(256);
|
||||
A.reset();
|
||||
A.set(1, 255);
|
||||
|
||||
EXPECT_FALSE(A.test(0));
|
||||
EXPECT_TRUE( A.test(1));
|
||||
EXPECT_TRUE( A.test(23));
|
||||
EXPECT_TRUE( A.test(254));
|
||||
EXPECT_FALSE(A.test(255));
|
||||
|
||||
TypeParam B;
|
||||
B.resize(256);
|
||||
B.set();
|
||||
B.reset(1, 255);
|
||||
|
||||
EXPECT_TRUE( B.test(0));
|
||||
EXPECT_FALSE(B.test(1));
|
||||
EXPECT_FALSE(B.test(23));
|
||||
EXPECT_FALSE(B.test(254));
|
||||
EXPECT_TRUE( B.test(255));
|
||||
|
||||
TypeParam C;
|
||||
C.resize(3);
|
||||
C.reset();
|
||||
C.set(0, 1);
|
||||
|
||||
EXPECT_TRUE(C.test(0));
|
||||
EXPECT_FALSE( C.test(1));
|
||||
EXPECT_FALSE( C.test(2));
|
||||
|
||||
TypeParam D;
|
||||
D.resize(3);
|
||||
D.set();
|
||||
D.reset(0, 1);
|
||||
|
||||
EXPECT_FALSE(D.test(0));
|
||||
EXPECT_TRUE( D.test(1));
|
||||
EXPECT_TRUE( D.test(2));
|
||||
}
|
||||
}
|
||||
#endif
|
||||
|
Loading…
Reference in New Issue
Block a user