From dd28c40c295778fc3c3cb945c443efc6ec86ee2e Mon Sep 17 00:00:00 2001 From: Nicholas Nethercote Date: Thu, 5 Dec 2024 12:49:04 +1100 Subject: [PATCH] Use `BitSet` in `SparseBitMatrix`. A `ChunkedBitSet` has to be at least 2048 bits for it to outperform a `BitSet`, because that's the chunk size. The largest `SparseBitMatrix` encountered when compiling the compiler and the entire rustc-perf benchmark suite is less than 600 bits. This change is a tiny perf win, but the motivation is more about avoiding uses of `ChunkedBitSet` outside of `MixedBitSet`. The test change is necessary to avoid hitting the ` as BitRelations>>::subtract` method that has `unimplemented!` in its body and isn't otherwise used. --- compiler/rustc_index/src/bit_set.rs | 20 ++++++++++---------- compiler/rustc_index/src/bit_set/tests.rs | 6 +++--- 2 files changed, 13 insertions(+), 13 deletions(-) diff --git a/compiler/rustc_index/src/bit_set.rs b/compiler/rustc_index/src/bit_set.rs index 41bd47ea6d06..aba1e9382969 100644 --- a/compiler/rustc_index/src/bit_set.rs +++ b/compiler/rustc_index/src/bit_set.rs @@ -1529,7 +1529,7 @@ fn fmt(&self, fmt: &mut fmt::Formatter<'_>) -> fmt::Result { /// sparse representation. /// /// Initially, every row has no explicit representation. If any bit within a -/// row is set, the entire row is instantiated as `Some()`. +/// row is set, the entire row is instantiated as `Some()`. /// Furthermore, any previously uninstantiated rows prior to it will be /// instantiated as `None`. Those prior rows may themselves become fully /// instantiated later on if any of their bits are set. @@ -1543,7 +1543,7 @@ pub struct SparseBitMatrix C: Idx, { num_columns: usize, - rows: IndexVec>>, + rows: IndexVec>>, } impl SparseBitMatrix { @@ -1552,10 +1552,10 @@ pub fn new(num_columns: usize) -> Self { Self { num_columns, rows: IndexVec::new() } } - fn ensure_row(&mut self, row: R) -> &mut ChunkedBitSet { - // Instantiate any missing rows up to and including row `row` with an empty ChunkedBitSet. - // Then replace row `row` with a full ChunkedBitSet if necessary. - self.rows.get_or_insert_with(row, || ChunkedBitSet::new_empty(self.num_columns)) + fn ensure_row(&mut self, row: R) -> &mut BitSet { + // Instantiate any missing rows up to and including row `row` with an empty `BitSet`. + // Then replace row `row` with a full `BitSet` if necessary. + self.rows.get_or_insert_with(row, || BitSet::new_empty(self.num_columns)) } /// Sets the cell at `(row, column)` to true. Put another way, insert @@ -1629,7 +1629,7 @@ pub fn iter(&self, row: R) -> impl Iterator + '_ { self.row(row).into_iter().flat_map(|r| r.iter()) } - pub fn row(&self, row: R) -> Option<&ChunkedBitSet> { + pub fn row(&self, row: R) -> Option<&BitSet> { self.rows.get(row)?.as_ref() } @@ -1639,7 +1639,7 @@ pub fn row(&self, row: R) -> Option<&ChunkedBitSet> { /// Returns true if the row was changed. pub fn intersect_row(&mut self, row: R, set: &Set) -> bool where - ChunkedBitSet: BitRelations, + BitSet: BitRelations, { match self.rows.get_mut(row) { Some(Some(row)) => row.intersect(set), @@ -1653,7 +1653,7 @@ pub fn intersect_row(&mut self, row: R, set: &Set) -> bool /// Returns true if the row was changed. pub fn subtract_row(&mut self, row: R, set: &Set) -> bool where - ChunkedBitSet: BitRelations, + BitSet: BitRelations, { match self.rows.get_mut(row) { Some(Some(row)) => row.subtract(set), @@ -1667,7 +1667,7 @@ pub fn subtract_row(&mut self, row: R, set: &Set) -> bool /// Returns true if the row was changed. pub fn union_row(&mut self, row: R, set: &Set) -> bool where - ChunkedBitSet: BitRelations, + BitSet: BitRelations, { self.ensure_row(row).union(set) } diff --git a/compiler/rustc_index/src/bit_set/tests.rs b/compiler/rustc_index/src/bit_set/tests.rs index 3f9198ce37f1..f61423239793 100644 --- a/compiler/rustc_index/src/bit_set/tests.rs +++ b/compiler/rustc_index/src/bit_set/tests.rs @@ -503,15 +503,15 @@ fn sparse_matrix_operations() { matrix.insert(2, 99); matrix.insert(4, 0); - let mut disjoint: ChunkedBitSet = ChunkedBitSet::new_empty(100); + let mut disjoint: BitSet = BitSet::new_empty(100); disjoint.insert(33); - let mut superset = ChunkedBitSet::new_empty(100); + let mut superset = BitSet::new_empty(100); superset.insert(22); superset.insert(75); superset.insert(33); - let mut subset = ChunkedBitSet::new_empty(100); + let mut subset = BitSet::new_empty(100); subset.insert(22); // SparseBitMatrix::remove