Skip to content
Draft
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
100 changes: 18 additions & 82 deletions compiler/rustc_index/src/bit_set.rs
Original file line number Diff line number Diff line change
Expand Up @@ -160,7 +160,7 @@ impl<T: Idx> DenseBitSet<T> {

/// Count the number of set bits in the set.
pub fn count(&self) -> usize {
self.words.iter().map(|e| e.count_ones() as usize).sum()
count_ones(&self.words)
}

/// Returns `true` if `self` contains `elem`.
Expand Down Expand Up @@ -789,7 +789,7 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {

match (&mut self_chunk, &other_chunk) {
(_, Zeros) | (Ones, _) => {}
(Zeros, Ones) | (Mixed(..), Ones) | (Zeros, Mixed(..)) => {
(Zeros, _) | (Mixed(..), Ones) => {
// `other_chunk` fully overwrites `self_chunk`
*self_chunk = other_chunk.clone();
changed = true;
Expand Down Expand Up @@ -817,10 +817,8 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
op,
);
debug_assert!(has_changed);
*self_chunk_count = self_chunk_words[0..num_words]
.iter()
.map(|w| w.count_ones() as ChunkSize)
.sum();
*self_chunk_count =
count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
if *self_chunk_count == chunk_domain_size {
*self_chunk = Ones;
}
Expand Down Expand Up @@ -853,7 +851,7 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {

match (&mut self_chunk, &other_chunk) {
(Zeros, _) | (_, Zeros) => {}
(Ones | Mixed(_, _), Ones) => {
(Ones | Mixed(..), Ones) => {
changed = true;
*self_chunk = Zeros;
}
Expand All @@ -871,10 +869,7 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
let self_chunk_count = chunk_domain_size - *other_chunk_count;
debug_assert_eq!(
self_chunk_count,
self_chunk_words[0..num_words]
.iter()
.map(|w| w.count_ones() as ChunkSize)
.sum()
count_ones(&self_chunk_words[0..num_words]) as ChunkSize
);
*self_chunk = Mixed(self_chunk_count, Rc::new(self_chunk_words));
}
Expand All @@ -897,10 +892,8 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
op,
);
debug_assert!(has_changed);
*self_chunk_count = self_chunk_words[0..num_words]
.iter()
.map(|w| w.count_ones() as ChunkSize)
.sum();
*self_chunk_count =
count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
if *self_chunk_count == 0 {
*self_chunk = Zeros;
}
Expand Down Expand Up @@ -956,10 +949,8 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
op,
);
debug_assert!(has_changed);
*self_chunk_count = self_chunk_words[0..num_words]
.iter()
.map(|w| w.count_ones() as ChunkSize)
.sum();
*self_chunk_count =
count_ones(&self_chunk_words[0..num_words]) as ChunkSize;
if *self_chunk_count == 0 {
*self_chunk = Zeros;
}
Expand All @@ -973,48 +964,6 @@ impl<T: Idx> BitRelations<ChunkedBitSet<T>> for ChunkedBitSet<T> {
}
}

impl<T: Idx> BitRelations<ChunkedBitSet<T>> for DenseBitSet<T> {
fn union(&mut self, other: &ChunkedBitSet<T>) -> bool {
sequential_update(|elem| self.insert(elem), other.iter())
}

fn subtract(&mut self, _other: &ChunkedBitSet<T>) -> bool {
unimplemented!("implement if/when necessary");
}

fn intersect(&mut self, other: &ChunkedBitSet<T>) -> bool {
assert_eq!(self.domain_size(), other.domain_size);
let mut changed = false;
for (i, chunk) in other.chunks.iter().enumerate() {
let mut words = &mut self.words[i * CHUNK_WORDS..];
if words.len() > CHUNK_WORDS {
words = &mut words[..CHUNK_WORDS];
}
match chunk {
Zeros => {
for word in words {
if *word != 0 {
changed = true;
*word = 0;
}
}
}
Ones => (),
Mixed(_, data) => {
for (i, word) in words.iter_mut().enumerate() {
let new_val = *word & data[i];
if new_val != *word {
changed = true;
*word = new_val;
}
}
}
}
}
changed
}
}

impl<T> Clone for ChunkedBitSet<T> {
fn clone(&self) -> Self {
ChunkedBitSet {
Expand Down Expand Up @@ -1088,21 +1037,12 @@ impl Chunk {
assert!(0 < count && count < chunk_domain_size);

// Check the number of set bits matches `count`.
assert_eq!(
words.iter().map(|w| w.count_ones() as ChunkSize).sum::<ChunkSize>(),
count
);
assert_eq!(count_ones(&**words) as ChunkSize, count);

// Check the not-in-use words are all zeroed.
let num_words = num_words(chunk_domain_size as usize);
if num_words < CHUNK_WORDS {
assert_eq!(
words[num_words..]
.iter()
.map(|w| w.count_ones() as ChunkSize)
.sum::<ChunkSize>(),
0
);
assert_eq!(count_ones(&words[num_words..]) as ChunkSize, 0);
}
}
}
Expand All @@ -1125,15 +1065,6 @@ enum ChunkIter<'a> {
Finished,
}

// Applies a function to mutate a bitset, and returns true if any
// of the applications return true
fn sequential_update<T: Idx>(
mut self_update: impl FnMut(T) -> bool,
it: impl Iterator<Item = T>,
) -> bool {
it.fold(false, |changed, elem| self_update(elem) | changed)
}

impl<T: Idx> fmt::Debug for ChunkedBitSet<T> {
fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result {
w.debug_list().entries(self.iter()).finish()
Expand Down Expand Up @@ -1593,7 +1524,7 @@ impl<R: Idx, C: Idx> BitMatrix<R, C> {
/// Returns the number of elements in `row`.
pub fn count(&self, row: R) -> usize {
let (start, end) = self.range(row);
self.words[start..end].iter().map(|e| e.count_ones() as usize).sum()
count_ones(&self.words[start..end])
}
}

Expand Down Expand Up @@ -1804,6 +1735,11 @@ fn max_bit(word: Word) -> usize {
WORD_BITS - 1 - word.leading_zeros() as usize
}

#[inline]
fn count_ones(words: &[Word]) -> usize {
words.iter().map(|word| word.count_ones() as usize).sum()
}

/// Integral type used to represent the bit set.
pub trait FiniteBitSetTy:
BitAnd<Output = Self>
Expand Down
28 changes: 0 additions & 28 deletions compiler/rustc_index/src/bit_set/tests.rs
Original file line number Diff line number Diff line change
Expand Up @@ -306,34 +306,6 @@ fn with_elements_chunked(elements: &[usize], domain_size: usize) -> ChunkedBitSe
s
}

fn with_elements_standard(elements: &[usize], domain_size: usize) -> DenseBitSet<usize> {
let mut s = DenseBitSet::new_empty(domain_size);
for &e in elements {
assert!(s.insert(e));
}
s
}

#[test]
fn chunked_bitset_into_bitset_operations() {
let a = vec![1, 5, 7, 11, 15, 2000, 3000];
let b = vec![3, 4, 11, 3000, 4000];
let aub = vec![1, 3, 4, 5, 7, 11, 15, 2000, 3000, 4000];
let aib = vec![11, 3000];

let b = with_elements_chunked(&b, 9876);

let mut union = with_elements_standard(&a, 9876);
assert!(union.union(&b));
assert!(!union.union(&b));
assert!(union.iter().eq(aub.iter().copied()));

let mut intersection = with_elements_standard(&a, 9876);
assert!(intersection.intersect(&b));
assert!(!intersection.intersect(&b));
assert!(intersection.iter().eq(aib.iter().copied()));
}

#[test]
fn chunked_bitset_iter() {
fn check_iter(bit: &ChunkedBitSet<usize>, vec: &Vec<usize>) {
Expand Down
Loading