llvm.org GIT mirror llvm / 0c01e44
[BitVector] Add find_last() and find_last_unset(). Differential Revision: https://reviews.llvm.org/D32302 git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@301014 91177308-0d34-0410-b5e6-96231b3b80d8 Zachary Turner 2 years ago
3 changed file(s) with 70 addition(s) and 4 deletion(s). Raw diff Collapse all Expand all
1414 #define LLVM_ADT_BITVECTOR_H
1515
1616 #include "llvm/ADT/ArrayRef.h"
17 #include "llvm/ADT/STLExtras.h"
1817 #include "llvm/Support/MathExtras.h"
1918 #include
2019 #include
160159 if (Bits[i] != 0)
161160 return i * BITWORD_SIZE + countTrailingZeros(Bits[i]);
162161 return -1;
162 }
163
164 /// find_last - Returns the index of the last set bit, -1 if none of the bits
165 /// are set.
166 int find_last() const {
167 if (Size == 0)
168 return -1;
169
170 unsigned N = NumBitWords(size());
171 assert(N > 0);
172
173 unsigned i = N - 1;
174 while (i > 0 && Bits[i] == BitWord(0))
175 --i;
176
177 return int((i + 1) * BITWORD_SIZE - countLeadingZeros(Bits[i])) - 1;
163178 }
164179
165180 /// find_first_unset - Returns the index of the first unset bit, -1 if all
171186 return Result < size() ? Result : -1;
172187 }
173188 return -1;
189 }
190
191 /// find_last_unset - Returns the index of the last unset bit, -1 if all of
192 /// the bits are set.
193 int find_last_unset() const {
194 if (Size == 0)
195 return -1;
196
197 const unsigned N = NumBitWords(size());
198 assert(N > 0);
199
200 unsigned i = N - 1;
201 BitWord W = Bits[i];
202
203 // The last word in the BitVector has some unused bits, so we need to set
204 // them all to 1 first. Set them all to 1 so they don't get treated as
205 // valid unset bits.
206 unsigned UnusedCount = BITWORD_SIZE - size() % BITWORD_SIZE;
207 W |= maskLeadingOnes(UnusedCount);
208
209 while (W == ~BitWord(0) && --i > 0)
210 W = Bits[i];
211
212 return int((i + 1) * BITWORD_SIZE - countLeadingOnes(W)) - 1;
174213 }
175214
176215 /// find_next - Returns the index of the next set bit following the
116116 }
117117
118118 // Return the size.
119 size_t getSmallSize() const {
120 return getSmallRawBits() >> SmallNumDataBits;
121 }
119 size_t getSmallSize() const { return getSmallRawBits() >> SmallNumDataBits; }
122120
123121 void setSmallSize(size_t Size) {
124122 setSmallRawBits(getSmallBits() | (Size << SmallNumDataBits));
215213 return getPointer()->find_first();
216214 }
217215
216 int find_last() const {
217 if (isSmall()) {
218 uintptr_t Bits = getSmallBits();
219 if (Bits == 0)
220 return -1;
221 return NumBaseBits - countLeadingZeros(Bits);
222 }
223 return getPointer()->find_last();
224 }
225
218226 /// Returns the index of the first unset bit, -1 if all of the bits are set.
219227 int find_first_unset() const {
220228 if (isSmall()) {
225233 return countTrailingOnes(Bits);
226234 }
227235 return getPointer()->find_first_unset();
236 }
237
238 int find_last_unset() const {
239 if (isSmall()) {
240 if (count() == getSmallSize())
241 return -1;
242
243 uintptr_t Bits = getSmallBits();
244 return NumBaseBits - countLeadingOnes(Bits);
245 }
246 return getPointer()->find_last_unset();
228247 }
229248
230249 /// Returns the index of the next set bit following the "Prev" bit.
185185 // Test finding in an empty BitVector.
186186 TypeParam A;
187187 EXPECT_EQ(-1, A.find_first());
188 EXPECT_EQ(-1, A.find_last());
188189 EXPECT_EQ(-1, A.find_first_unset());
190 EXPECT_EQ(-1, A.find_last_unset());
189191 EXPECT_EQ(-1, A.find_next(0));
190192 EXPECT_EQ(-1, A.find_next_unset(0));
191193
195197 A.set(13);
196198 A.set(75);
197199
200 EXPECT_EQ(75, A.find_last());
198201 EXPECT_EQ(12, A.find_first());
199202 EXPECT_EQ(13, A.find_next(12));
200203 EXPECT_EQ(75, A.find_next(13));
201204 EXPECT_EQ(-1, A.find_next(75));
202205
203206 EXPECT_EQ(0, A.find_first_unset());
207 EXPECT_EQ(99, A.find_last_unset());
204208 EXPECT_EQ(14, A.find_next_unset(11));
205209 EXPECT_EQ(14, A.find_next_unset(12));
206210 EXPECT_EQ(14, A.find_next_unset(13));
212216 A.set(0, 100);
213217 EXPECT_EQ(100U, A.count());
214218 EXPECT_EQ(0, A.find_first());
219 EXPECT_EQ(99, A.find_last());
215220 EXPECT_EQ(-1, A.find_first_unset());
221 EXPECT_EQ(-1, A.find_last_unset());
216222
217223 A.reset(0, 100);
218224 EXPECT_EQ(0U, A.count());
219225 EXPECT_EQ(-1, A.find_first());
226 EXPECT_EQ(-1, A.find_last());
220227 EXPECT_EQ(0, A.find_first_unset());
228 EXPECT_EQ(99, A.find_last_unset());
221229 }
222230
223231 TYPED_TEST(BitVectorTest, CompoundAssignment) {