Skip to content

Commit 7eec37b

Browse files
committed
merge PointIndexMap and RegionValueElements
1 parent 1ab08ef commit 7eec37b

File tree

5 files changed

+88
-140
lines changed

5 files changed

+88
-140
lines changed

src/librustc_mir/borrow_check/nll/region_infer/values.rs

+73-41
Original file line numberDiff line numberDiff line change
@@ -20,13 +20,23 @@ use std::rc::Rc;
2020
crate struct RegionValueElements {
2121
/// For each basic block, how many points are contained within?
2222
statements_before_block: IndexVec<BasicBlock, usize>,
23+
24+
/// Map backward from each point into to one of two possible values:
25+
///
26+
/// - `None`: if this point index represents a Location with non-zero index
27+
/// - `Some(bb)`: if this point index represents a Location with zero index
28+
///
29+
/// NB. It may be better to just map back to a full `Location`. We
30+
/// should probably try that.
31+
basic_block_heads: IndexVec<PointIndex, Option<BasicBlock>>,
32+
2333
num_points: usize,
2434
}
2535

2636
impl RegionValueElements {
2737
crate fn new(mir: &Mir<'_>) -> Self {
2838
let mut num_points = 0;
29-
let statements_before_block = mir
39+
let statements_before_block: IndexVec<BasicBlock, usize> = mir
3040
.basic_blocks()
3141
.iter()
3242
.map(|block_data| {
@@ -41,8 +51,16 @@ impl RegionValueElements {
4151
);
4252
debug!("RegionValueElements: num_points={:#?}", num_points);
4353

54+
let mut basic_block_heads: IndexVec<PointIndex, Option<BasicBlock>> =
55+
(0..num_points).map(|_| None).collect();
56+
for (bb, &first_point) in statements_before_block.iter_enumerated() {
57+
let first_point = PointIndex::new(first_point);
58+
basic_block_heads[first_point] = Some(bb);
59+
}
60+
4461
Self {
4562
statements_before_block,
63+
basic_block_heads,
4664
num_points,
4765
}
4866
}
@@ -70,47 +88,55 @@ impl RegionValueElements {
7088

7189
/// Converts a `PointIndex` back to a location. O(N) where N is
7290
/// the number of blocks; could be faster if we ever cared.
73-
crate fn to_location(&self, i: PointIndex) -> Location {
74-
let point_index = i.index();
75-
76-
// Find the basic block. We have a vector with the
77-
// starting index of the statement in each block. Imagine
78-
// we have statement #22, and we have a vector like:
79-
//
80-
// [0, 10, 20]
81-
//
82-
// In that case, this represents point_index 2 of
83-
// basic block BB2. We know this because BB0 accounts for
84-
// 0..10, BB1 accounts for 11..20, and BB2 accounts for
85-
// 20...
86-
//
87-
// To compute this, we could do a binary search, but
88-
// because I am lazy we instead iterate through to find
89-
// the last point where the "first index" (0, 10, or 20)
90-
// was less than the statement index (22). In our case, this will
91-
// be (BB2, 20).
92-
//
93-
// Nit: we could do a binary search here but I'm too lazy.
94-
let (block, &first_index) = self
95-
.statements_before_block
96-
.iter_enumerated()
97-
.filter(|(_, first_index)| **first_index <= point_index)
98-
.last()
99-
.unwrap();
100-
101-
Location {
102-
block,
103-
statement_index: point_index - first_index,
91+
crate fn to_location(&self, index: PointIndex) -> Location {
92+
assert!(index.index() < self.num_points);
93+
94+
let mut statement_index = 0;
95+
96+
for opt_bb in self.basic_block_heads.raw[..= index.index()].iter().rev() {
97+
if let &Some(block) = opt_bb {
98+
return Location { block, statement_index };
99+
}
100+
101+
statement_index += 1;
104102
}
105-
}
106103

107-
/// Returns an iterator of each basic block and the first point
108-
/// index within the block; the point indices for all statements
109-
/// within the block follow afterwards.
110-
crate fn head_indices(&self) -> impl Iterator<Item = (BasicBlock, PointIndex)> + '_ {
111-
self.statements_before_block
112-
.iter_enumerated()
113-
.map(move |(bb, &first_index)| (bb, PointIndex::new(first_index)))
104+
bug!("did not find basic block as expected for index = {:?}", index)
105+
}
106+
107+
/// Sometimes we get point-indices back from bitsets that may be
108+
/// out of range (because they round up to the nearest 2^N number
109+
/// of bits). Use this function to filter such points out if you
110+
/// like.
111+
crate fn point_in_range(&self, index: PointIndex) -> bool {
112+
index.index() < self.num_points
113+
}
114+
115+
/// Pushes all predecessors of `index` onto `stack`.
116+
crate fn push_predecessors(
117+
&self,
118+
mir: &Mir<'_>,
119+
index: PointIndex,
120+
stack: &mut Vec<PointIndex>,
121+
) {
122+
match self.basic_block_heads[index] {
123+
// If this is a basic block head, then the predecessors are
124+
// the the terminators of other basic blocks
125+
Some(bb_head) => {
126+
stack.extend(
127+
mir
128+
.predecessors_for(bb_head)
129+
.iter()
130+
.map(|&pred_bb| mir.terminator_loc(pred_bb))
131+
.map(|pred_loc| self.point_from_location(pred_loc)),
132+
);
133+
}
134+
135+
// Otherwise, the pred is just the previous statement
136+
None => {
137+
stack.push(PointIndex::new(index.index() - 1));
138+
}
139+
}
114140
}
115141
}
116142

@@ -196,6 +222,7 @@ impl<N: Idx> LivenessValues<N> {
196222
.row(r)
197223
.into_iter()
198224
.flat_map(|set| set.iter())
225+
.take_while(|&p| self.elements.point_in_range(p))
199226
.map(|p| self.elements.to_location(p))
200227
.map(RegionElement::Location),
201228
)
@@ -304,7 +331,11 @@ impl<N: Idx> RegionValues<N> {
304331
self.points
305332
.row(r)
306333
.into_iter()
307-
.flat_map(move |set| set.iter().map(move |p| self.elements.to_location(p)))
334+
.flat_map(move |set| {
335+
set.iter()
336+
.take_while(move |&p| self.elements.point_in_range(p))
337+
.map(move |p| self.elements.to_location(p))
338+
})
308339
}
309340

310341
/// Returns just the universal regions that are contained in a given region's value.
@@ -400,6 +431,7 @@ crate fn location_set_str(
400431
region_value_str(
401432
points
402433
.into_iter()
434+
.take_while(|&p| elements.point_in_range(p))
403435
.map(|p| elements.to_location(p))
404436
.map(RegionElement::Location),
405437
)

src/librustc_mir/borrow_check/nll/type_check/liveness/mod.rs

-1
Original file line numberDiff line numberDiff line change
@@ -24,7 +24,6 @@ use super::TypeChecker;
2424

2525
crate mod liveness_map;
2626
mod local_use_map;
27-
mod point_index_map;
2827
mod trace;
2928

3029
/// Combines liveness analysis with initialization analysis to

src/librustc_mir/borrow_check/nll/type_check/liveness/point_index_map.rs

-78
This file was deleted.

src/librustc_mir/borrow_check/nll/type_check/liveness/trace.rs

+6-11
Original file line numberDiff line numberDiff line change
@@ -11,7 +11,6 @@
1111
use borrow_check::nll::region_infer::values::{self, PointIndex, RegionValueElements};
1212
use borrow_check::nll::type_check::liveness::liveness_map::{LiveVar, NllLivenessMap};
1313
use borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap;
14-
use borrow_check::nll::type_check::liveness::point_index_map::PointIndexMap;
1514
use borrow_check::nll::type_check::AtLocation;
1615
use borrow_check::nll::type_check::TypeChecker;
1716
use dataflow::move_paths::indexes::MovePathIndex;
@@ -57,7 +56,6 @@ pub(super) fn trace(
5756
}
5857

5958
let local_use_map = &LocalUseMap::build(liveness_map, elements, mir);
60-
let point_index_map = &PointIndexMap::new(elements, mir);
6159

6260
let cx = LivenessContext {
6361
typeck,
@@ -67,7 +65,6 @@ pub(super) fn trace(
6765
local_use_map,
6866
move_data,
6967
liveness_map,
70-
point_index_map,
7168
drop_data: FxHashMap::default(),
7269
};
7370

@@ -105,8 +102,6 @@ where
105102
/// dropped.
106103
local_use_map: &'me LocalUseMap<'me>,
107104

108-
point_index_map: &'me PointIndexMap<'me, 'tcx>,
109-
110105
/// Map tracking which variables need liveness computation.
111106
liveness_map: &'me NllLivenessMap,
112107
}
@@ -146,7 +141,7 @@ where
146141

147142
impl LivenessResults<'me, 'typeck, 'flow, 'gcx, 'tcx> {
148143
fn new(cx: LivenessContext<'me, 'typeck, 'flow, 'gcx, 'tcx>) -> Self {
149-
let num_points = cx.point_index_map.num_points();
144+
let num_points = cx.elements.num_points();
150145
LivenessResults {
151146
cx,
152147
defs: BitArray::new(num_points),
@@ -218,8 +213,8 @@ impl LivenessResults<'me, 'typeck, 'flow, 'gcx, 'tcx> {
218213

219214
if self.use_live_at.insert(p) {
220215
self.cx
221-
.point_index_map
222-
.push_predecessors(p, &mut self.stack)
216+
.elements
217+
.push_predecessors(self.cx.mir, p, &mut self.stack)
223218
}
224219
}
225220
}
@@ -242,7 +237,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'gcx, 'tcx> {
242237

243238
// Find the drops where `local` is initialized.
244239
for drop_point in self.cx.local_use_map.drops(live_local) {
245-
let location = self.cx.point_index_map.location_of(drop_point);
240+
let location = self.cx.elements.to_location(drop_point);
246241
debug_assert_eq!(self.cx.mir.terminator_loc(location.block), location,);
247242

248243
if self.cx.initialized_at_terminator(location.block, mpi) {
@@ -281,7 +276,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'gcx, 'tcx> {
281276
debug!(
282277
"compute_drop_live_points_for_block(mpi={:?}, term_point={:?})",
283278
self.cx.move_data.move_paths[mpi].place,
284-
self.cx.point_index_map.location_of(term_point),
279+
self.cx.elements.to_location(term_point),
285280
);
286281

287282
// We are only invoked with terminators where `mpi` is
@@ -301,7 +296,7 @@ impl LivenessResults<'me, 'typeck, 'flow, 'gcx, 'tcx> {
301296
for p in (entry_point..term_point).rev() {
302297
debug!(
303298
"compute_drop_live_points_for_block: p = {:?}",
304-
self.cx.point_index_map.location_of(p),
299+
self.cx.elements.to_location(p),
305300
);
306301

307302
if self.defs.contains(p) {

src/test/mir-opt/nll/named-lifetimes-basic.rs

+9-9
Original file line numberDiff line numberDiff line change
@@ -34,15 +34,15 @@ fn main() {
3434
// | '_#4r | Local | ['_#4r]
3535
// |
3636
// | Inferred Region Values
37-
// | '_#0r | U0 | {bb0[0..=127], '_#0r}
38-
// | '_#1r | U0 | {bb0[0..=127], '_#1r}
39-
// | '_#2r | U0 | {bb0[0..=127], '_#2r}
40-
// | '_#3r | U0 | {bb0[0..=127], '_#3r}
41-
// | '_#4r | U0 | {bb0[0..=127], '_#4r}
42-
// | '_#5r | U0 | {bb0[0..=127], '_#1r}
43-
// | '_#6r | U0 | {bb0[0..=127], '_#2r}
44-
// | '_#7r | U0 | {bb0[0..=127], '_#1r}
45-
// | '_#8r | U0 | {bb0[0..=127], '_#3r}
37+
// | '_#0r | U0 | {bb0[0..=1], '_#0r}
38+
// | '_#1r | U0 | {bb0[0..=1], '_#1r}
39+
// | '_#2r | U0 | {bb0[0..=1], '_#2r}
40+
// | '_#3r | U0 | {bb0[0..=1], '_#3r}
41+
// | '_#4r | U0 | {bb0[0..=1], '_#4r}
42+
// | '_#5r | U0 | {bb0[0..=1], '_#1r}
43+
// | '_#6r | U0 | {bb0[0..=1], '_#2r}
44+
// | '_#7r | U0 | {bb0[0..=1], '_#1r}
45+
// | '_#8r | U0 | {bb0[0..=1], '_#3r}
4646
// |
4747
// ...
4848
// fn use_x(_1: &'_#5r mut i32, _2: &'_#6r u32, _3: &'_#7r u32, _4: &'_#8r u32) -> bool {

0 commit comments

Comments
 (0)