diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index f7649c5f5c55e..0516134574386 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -160,7 +160,7 @@ impl DenseBitSet { /// 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`. @@ -789,7 +789,7 @@ impl BitRelations> for ChunkedBitSet { 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; @@ -817,10 +817,8 @@ impl BitRelations> for ChunkedBitSet { 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; } @@ -853,7 +851,7 @@ impl BitRelations> for ChunkedBitSet { match (&mut self_chunk, &other_chunk) { (Zeros, _) | (_, Zeros) => {} - (Ones | Mixed(_, _), Ones) => { + (Ones | Mixed(..), Ones) => { changed = true; *self_chunk = Zeros; } @@ -871,10 +869,7 @@ impl BitRelations> for ChunkedBitSet { 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)); } @@ -897,10 +892,8 @@ impl BitRelations> for ChunkedBitSet { 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; } @@ -956,10 +949,8 @@ impl BitRelations> for ChunkedBitSet { 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; } @@ -973,48 +964,6 @@ impl BitRelations> for ChunkedBitSet { } } -impl BitRelations> for DenseBitSet { - fn union(&mut self, other: &ChunkedBitSet) -> bool { - sequential_update(|elem| self.insert(elem), other.iter()) - } - - fn subtract(&mut self, _other: &ChunkedBitSet) -> bool { - unimplemented!("implement if/when necessary"); - } - - fn intersect(&mut self, other: &ChunkedBitSet) -> 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 Clone for ChunkedBitSet { fn clone(&self) -> Self { ChunkedBitSet { @@ -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::(), - 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::(), - 0 - ); + assert_eq!(count_ones(&words[num_words..]) as ChunkSize, 0); } } } @@ -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( - mut self_update: impl FnMut(T) -> bool, - it: impl Iterator, -) -> bool { - it.fold(false, |changed, elem| self_update(elem) | changed) -} - impl fmt::Debug for ChunkedBitSet { fn fmt(&self, w: &mut fmt::Formatter<'_>) -> fmt::Result { w.debug_list().entries(self.iter()).finish() @@ -1593,7 +1524,7 @@ impl BitMatrix { /// 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]) } } @@ -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 diff --git a/compiler/rustc_index/src/bit_set/tests.rs b/compiler/rustc_index/src/bit_set/tests.rs index deddc87261436..341e0622df75e 100644 --- a/compiler/rustc_index/src/bit_set/tests.rs +++ b/compiler/rustc_index/src/bit_set/tests.rs @@ -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 { - 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, vec: &Vec) {