From 81d76eee138583b3f8e3d90c3c5e2e2e577b2b52 Mon Sep 17 00:00:00 2001 From: panstromek Date: Fri, 4 Sep 2026 09:15:53 +0200 Subject: [PATCH 1/2] replace SparseBitMatrix in region inference with BitMatrix --- .../rustc_borrowck/src/region_infer/mod.rs | 8 ++++++-- .../region_infer/opaque_types/region_ctxt.rs | 9 +++++++-- .../rustc_borrowck/src/region_infer/values.rs | 19 ++++++++----------- 3 files changed, 21 insertions(+), 15 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/mod.rs b/compiler/rustc_borrowck/src/region_infer/mod.rs index d3fc7152acc44..16b4a518df2d4 100644 --- a/compiler/rustc_borrowck/src/region_infer/mod.rs +++ b/compiler/rustc_borrowck/src/region_infer/mod.rs @@ -362,8 +362,12 @@ impl<'tcx> RegionInferenceContext<'tcx> { sccs_info(infcx, &constraint_sccs); } - let mut scc_values = - RegionValues::new(location_map, universal_regions.len(), placeholder_indices); + let mut scc_values = RegionValues::new( + location_map, + constraint_sccs.num_sccs(), + universal_regions.len(), + placeholder_indices, + ); // Initializes the region variables with their initial live points. for (region, definition) in definitions.iter_enumerated() { diff --git a/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs b/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs index ae5a213c5c37d..acc541951bc88 100644 --- a/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs +++ b/compiler/rustc_borrowck/src/region_infer/opaque_types/region_ctxt.rs @@ -76,8 +76,13 @@ impl<'a, 'tcx> RegionCtxt<'a, 'tcx> { // Unlike the `RegionInferenceContext`, we only care about free regions // and fully ignore liveness and placeholders. let placeholder_indices = Default::default(); - let mut scc_values = - RegionValues::new(location_map, universal_regions.len(), placeholder_indices); + let mut scc_values = RegionValues::new( + location_map, + constraint_sccs.num_sccs(), + universal_regions.len(), + placeholder_indices, + ); + for (variable, definition) in definitions.iter_enumerated() { let scc = constraint_sccs.scc(variable); match definition.origin { diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 841e5713751cd..8bf39b7840716 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_index::Idx; -use rustc_index::bit_set::SparseBitMatrix; +use rustc_index::bit_set::BitMatrix; use rustc_index::interval::{IntervalSet, SparseIntervalMatrix}; use rustc_middle::bug; use rustc_middle::mir::{BasicBlock, Location}; @@ -272,11 +272,11 @@ pub(crate) struct RegionValues<'tcx, N: Idx> { location_map: Rc, placeholder_indices: PlaceholderIndices<'tcx>, points: SparseIntervalMatrix, - free_regions: SparseBitMatrix, + free_regions: BitMatrix, /// Placeholders represent bound regions -- so something like `'a` /// in `for<'a> fn(&'a u32)`. - placeholders: SparseBitMatrix, + placeholders: BitMatrix, } impl<'tcx, N: Idx> RegionValues<'tcx, N> { @@ -285,6 +285,7 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> { /// empty set of points and no causal information. pub(crate) fn new( location_map: Rc, + num_constraint_sccs: usize, num_universal_regions: usize, placeholder_indices: PlaceholderIndices<'tcx>, ) -> Self { @@ -294,8 +295,8 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> { location_map, points: SparseIntervalMatrix::new(num_points), placeholder_indices, - free_regions: SparseBitMatrix::new(num_universal_regions), - placeholders: SparseBitMatrix::new(num_placeholders), + free_regions: BitMatrix::new(num_constraint_sccs, num_universal_regions), + placeholders: BitMatrix::new(num_constraint_sccs, num_placeholders), } } @@ -354,7 +355,7 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> { /// Returns just the universal regions that are contained in a given region's value. pub(crate) fn universal_regions_outlived_by(&self, r: N) -> impl Iterator { - self.free_regions.row(r).map(|set| set.iter()).into_flat_iter() + self.free_regions.iter(r) } /// Returns all the elements contained in a given region's value. @@ -362,11 +363,7 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> { &self, r: N, ) -> impl Iterator> { - self.placeholders - .row(r) - .map(|set| set.iter()) - .into_flat_iter() - .map(move |p| self.placeholder_indices.lookup_placeholder(p)) + self.placeholders.iter(r).map(move |p| self.placeholder_indices.lookup_placeholder(p)) } /// Returns all the elements contained in a given region's value. From 0c5bae04dd81c679c68ba2034f66f95b2f85048f Mon Sep 17 00:00:00 2001 From: panstromek Date: Fri, 4 Sep 2026 13:23:41 +0200 Subject: [PATCH 2/2] use sparse bit matrix again but in reverse the order of rows --- .../rustc_borrowck/src/region_infer/values.rs | 44 ++++++++++++++++--- 1 file changed, 39 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_borrowck/src/region_infer/values.rs b/compiler/rustc_borrowck/src/region_infer/values.rs index 8bf39b7840716..4c79eac71cfc3 100644 --- a/compiler/rustc_borrowck/src/region_infer/values.rs +++ b/compiler/rustc_borrowck/src/region_infer/values.rs @@ -3,7 +3,7 @@ use std::rc::Rc; use rustc_data_structures::fx::{FxHashSet, FxIndexSet}; use rustc_index::Idx; -use rustc_index::bit_set::BitMatrix; +use rustc_index::bit_set::SparseBitMatrix; use rustc_index::interval::{IntervalSet, SparseIntervalMatrix}; use rustc_middle::bug; use rustc_middle::mir::{BasicBlock, Location}; @@ -272,11 +272,45 @@ pub(crate) struct RegionValues<'tcx, N: Idx> { location_map: Rc, placeholder_indices: PlaceholderIndices<'tcx>, points: SparseIntervalMatrix, - free_regions: BitMatrix, + free_regions: ReversedSparseBitMatrix, /// Placeholders represent bound regions -- so something like `'a` /// in `for<'a> fn(&'a u32)`. - placeholders: BitMatrix, + placeholders: ReversedSparseBitMatrix, +} + +struct ReversedSparseBitMatrix { + num_rows: usize, + rows: SparseBitMatrix, +} + +impl ReversedSparseBitMatrix { + #[inline] + fn new(rows: usize, cols: usize) -> ReversedSparseBitMatrix { + Self { num_rows: rows, rows: SparseBitMatrix::new(cols) } + } + #[inline] + fn insert(&mut self, row: R, col: C) { + self.rows.insert(self.inner_row_index(row), col); + } + + #[inline] + fn inner_row_index(&self, row: R) -> R { + R::new(self.num_rows - 1 - row.index()) + } + + #[inline] + fn contains(&self, row: R, col: C) -> bool { + self.rows.contains(self.inner_row_index(row), col) + } + #[inline] + fn iter(&self, row: R) -> impl Iterator { + self.rows.iter(self.inner_row_index(row)) + } + #[inline] + fn union_rows(&mut self, read: R, write: R) -> bool { + self.rows.union_rows(self.inner_row_index(read), self.inner_row_index(write)) + } } impl<'tcx, N: Idx> RegionValues<'tcx, N> { @@ -295,8 +329,8 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> { location_map, points: SparseIntervalMatrix::new(num_points), placeholder_indices, - free_regions: BitMatrix::new(num_constraint_sccs, num_universal_regions), - placeholders: BitMatrix::new(num_constraint_sccs, num_placeholders), + free_regions: ReversedSparseBitMatrix::new(num_constraint_sccs, num_universal_regions), + placeholders: ReversedSparseBitMatrix::new(num_constraint_sccs, num_placeholders), } }