mirror of
https://github.com/c64scene-ar/llvm-6502.git
synced 2025-06-20 10:24:12 +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:
@ -237,6 +237,34 @@ public:
|
|||||||
return *this;
|
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() {
|
BitVector &reset() {
|
||||||
init_words(Bits, Capacity, false);
|
init_words(Bits, Capacity, false);
|
||||||
return *this;
|
return *this;
|
||||||
@ -247,6 +275,34 @@ public:
|
|||||||
return *this;
|
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() {
|
BitVector &flip() {
|
||||||
for (unsigned i = 0; i < NumBitWords(size()); ++i)
|
for (unsigned i = 0; i < NumBitWords(size()); ++i)
|
||||||
Bits[i] = ~Bits[i];
|
Bits[i] = ~Bits[i];
|
||||||
|
@ -300,6 +300,21 @@ public:
|
|||||||
return *this;
|
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() {
|
SmallBitVector &reset() {
|
||||||
if (isSmall())
|
if (isSmall())
|
||||||
setSmallBits(0);
|
setSmallBits(0);
|
||||||
@ -316,6 +331,21 @@ public:
|
|||||||
return *this;
|
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() {
|
SmallBitVector &flip() {
|
||||||
if (isSmall())
|
if (isSmall())
|
||||||
setSmallBits(~getSmallBits());
|
setSmallBits(~getSmallBits());
|
||||||
|
@ -281,5 +281,47 @@ TYPED_TEST(BitVectorTest, BinOps) {
|
|||||||
EXPECT_FALSE(A.anyCommon(B));
|
EXPECT_FALSE(A.anyCommon(B));
|
||||||
EXPECT_FALSE(B.anyCommon(A));
|
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
|
#endif
|
||||||
|
Reference in New Issue
Block a user