Skip to content

Commit dbf6d75

Browse files
committed
RegionValues: disable unnecessary range check
Currently, when adding liveness points to region values in the `RegionValues` struct, the locations of the points are checked for ranges. This is unnecessarily cautious because they always are in range by construction. This adds documentation (including debug assertions) to make this clearer and removes the checks, which should have a strictly positive impact on performance.
1 parent 98594f4 commit dbf6d75

2 files changed

Lines changed: 26 additions & 23 deletions

File tree

compiler/rustc_borrowck/src/region_infer/values.rs

Lines changed: 20 additions & 22 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ use rustc_middle::bug;
99
use rustc_middle::mir::{BasicBlock, Location};
1010
use rustc_middle::ty::{self, RegionVid};
1111
use rustc_mir_dataflow::points::{DenseLocationMap, PointIndex};
12-
use tracing::debug;
12+
use tracing::{debug, instrument};
1313

1414
use crate::BorrowIndex;
1515
use crate::polonius::LiveLoans;
@@ -116,37 +116,43 @@ impl LivenessValues {
116116
/// Records `region` as being live at the given `location`.
117117
pub(crate) fn add_location(&mut self, region: RegionVid, location: Location) {
118118
let point = self.location_map.point_from_location(location);
119+
// This is a debug assert despite being cheap because it drops
120+
// the current `point_in_range()` uses to 0 when debugging is off.
121+
debug_assert!(
122+
self.location_map.point_in_range(point),
123+
"Tried inserting region {region:?} whose location {location:?} does not belong to this body!"
124+
);
119125
debug!("LivenessValues::add_location(region={:?}, location={:?})", region, location);
120126
match &mut self.live_regions {
121127
LiveRegions::AtPoints(points) => {
122128
points.insert(region, point);
123129
}
124130

125-
LiveRegions::InBody(live_regions) if self.location_map.point_in_range(point) => {
131+
LiveRegions::InBody(live_regions) => {
126132
live_regions.insert(region);
127133
}
128-
129-
LiveRegions::InBody(_) => (),
130134
};
131135
}
132136

133137
/// Records `region` as being live at all the given `points`.
134138
pub(crate) fn add_points(&mut self, region: RegionVid, points: &IntervalSet<PointIndex>) {
139+
debug_assert!(
140+
points.iter().all(|point| self.location_map.point_in_range(point)),
141+
"Tried inserting region {region:?} with some points not belonging to this body!"
142+
);
135143
debug!("LivenessValues::add_points(region={:?}, points={:?})", region, points);
136144
match &mut self.live_regions {
137145
LiveRegions::AtPoints(these_points) => {
138146
these_points.union_row(region, points);
139147
}
140-
LiveRegions::InBody(live_regions)
141-
if points.iter().any(|point| self.location_map.point_in_range(point)) =>
142-
{
148+
LiveRegions::InBody(live_regions) => {
143149
live_regions.insert(region);
144150
}
145-
LiveRegions::InBody(_) => (),
146151
};
147152
}
148153

149154
/// Records `region` as being live at all the control-flow points.
155+
#[instrument(skip(self))]
150156
pub(crate) fn add_all_points(&mut self, region: RegionVid) {
151157
match &mut self.live_regions {
152158
LiveRegions::AtPoints(points) => points.insert_all_into_row(region),
@@ -172,10 +178,7 @@ impl LivenessValues {
172178

173179
/// Returns an iterator of all the points where `region` is live.
174180
fn live_points(&self, region: RegionVid) -> impl Iterator<Item = PointIndex> {
175-
self.point_liveness(region)
176-
.into_iter()
177-
.flat_map(|set| set.iter())
178-
.take_while(|&p| self.location_map.point_in_range(p))
181+
self.point_liveness(region).into_iter().flat_map(|set| set.iter())
179182
}
180183

181184
/// For debugging purposes, returns a pretty-printed string of the points where the `region` is
@@ -343,11 +346,10 @@ impl<'tcx, N: Idx> RegionValues<'tcx, N> {
343346

344347
/// Returns the locations contained within a given region `r`.
345348
pub(crate) fn locations_outlived_by(&self, r: N) -> impl Iterator<Item = Location> {
346-
self.points.row(r).into_iter().flat_map(move |set| {
347-
set.iter()
348-
.take_while(move |&p| self.location_map.point_in_range(p))
349-
.map(move |p| self.location_map.to_location(p))
350-
})
349+
self.points
350+
.row(r)
351+
.into_iter()
352+
.flat_map(move |set| set.iter().map(move |p| self.location_map.to_location(p)))
351353
}
352354

353355
/// Returns just the universal regions that are contained in a given region's value.
@@ -413,11 +415,7 @@ pub(crate) fn pretty_print_points(
413415
points: impl IntoIterator<Item = PointIndex>,
414416
) -> String {
415417
pretty_print_region_elements(
416-
points
417-
.into_iter()
418-
.take_while(|&p| location_map.point_in_range(p))
419-
.map(|p| location_map.to_location(p))
420-
.map(RegionElement::Location),
418+
points.into_iter().map(|p| location_map.to_location(p)).map(RegionElement::Location),
421419
)
422420
}
423421

compiler/rustc_mir_dataflow/src/points.rs

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -31,7 +31,8 @@ impl DenseLocationMap {
3131
for (bb, bb_data) in body.basic_blocks.iter_enumerated() {
3232
basic_blocks.extend((0..=bb_data.statements.len()).map(|_| bb));
3333
}
34-
34+
// Invariant: no block is preceded by more than all statements.
35+
debug_assert!(*statements_before_block.iter().max().unwrap() < num_points);
3536
Self { statements_before_block, basic_blocks, num_points }
3637
}
3738

@@ -42,10 +43,14 @@ impl DenseLocationMap {
4243
}
4344

4445
/// Converts a `Location` into a `PointIndex`. O(1).
46+
/// [[`Self::point_in_range()`]] guaranteed for the returned index.
4547
#[inline]
4648
pub fn point_from_location(&self, location: Location) -> PointIndex {
4749
let Location { block, statement_index } = location;
4850
let start_index = self.statements_before_block[block];
51+
// Note the invariant in [`Self::new()`]; if the indexing
52+
// operation above did not panic then this holds by construction.
53+
debug_assert!(start_index < self.num_points);
4954
PointIndex::new(start_index + statement_index)
5055
}
5156

0 commit comments

Comments
 (0)