Skip to content

Commit 77663a6

Browse files
committed
refactor region value bitmatrix
1 parent a30e225 commit 77663a6

File tree

4 files changed

+270
-110
lines changed

4 files changed

+270
-110
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -70,7 +70,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
7070
with_msg: &mut FnMut(&str) -> io::Result<()>,
7171
) -> io::Result<()> {
7272
for region in self.definitions.indices() {
73-
let value = self.region_value_str_from_matrix(&self.liveness_constraints, region);
73+
let value = self.liveness_constraints.region_value_str(region);
7474
if value != "{}" {
7575
with_msg(&format!("{:?} live at {}", region, value))?;
7676
}

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

Lines changed: 38 additions & 105 deletions
Original file line numberDiff line numberDiff line change
@@ -19,15 +19,15 @@ use rustc::mir::{ClosureOutlivesRequirement, ClosureRegionRequirements, Location
1919
use rustc::ty::{self, RegionVid};
2020
use rustc_data_structures::indexed_vec::IndexVec;
2121
use rustc_data_structures::fx::FxHashSet;
22-
use rustc_data_structures::bitvec::BitMatrix;
23-
use rustc_data_structures::indexed_vec::Idx;
24-
use std::collections::BTreeMap;
2522
use std::fmt;
23+
use std::rc::Rc;
2624
use syntax_pos::Span;
2725

2826
mod annotation;
2927
mod dump_mir;
3028
mod graphviz;
29+
mod values;
30+
use self::values::{RegionValueElements, RegionValues};
3131

3232
pub struct RegionInferenceContext<'tcx> {
3333
/// Contains the definition for every region variable. Region
@@ -36,27 +36,22 @@ pub struct RegionInferenceContext<'tcx> {
3636
/// from as well as its final inferred value.
3737
definitions: IndexVec<RegionVid, RegionDefinition<'tcx>>,
3838

39+
/// Maps from points/universal-regions to a `RegionElementIndex`.
40+
elements: Rc<RegionValueElements>,
41+
3942
/// The liveness constraints added to each region. For most
4043
/// regions, these start out empty and steadily grow, though for
4144
/// each universally quantified region R they start out containing
4245
/// the entire CFG and `end(R)`.
43-
///
44-
/// In this `BitMatrix` representation, the rows are the region
45-
/// variables and the columns are the free regions and MIR locations.
46-
liveness_constraints: BitMatrix,
46+
liveness_constraints: RegionValues,
4747

4848
/// The final inferred values of the inference variables; `None`
4949
/// until `solve` is invoked.
50-
inferred_values: Option<BitMatrix>,
50+
inferred_values: Option<RegionValues>,
5151

5252
/// The constraints we have accumulated and used during solving.
5353
constraints: Vec<Constraint>,
5454

55-
/// A map from each MIR Location to its column index in
56-
/// `liveness_constraints`/`inferred_values`. (The first N columns are
57-
/// the free regions.)
58-
point_indices: BTreeMap<Location, usize>,
59-
6055
/// Information about the universally quantified regions in scope
6156
/// on this function and their (known) relations to one another.
6257
universal_regions: UniversalRegions<'tcx>,
@@ -112,19 +107,16 @@ impl<'tcx> RegionInferenceContext<'tcx> {
112107
let num_region_variables = var_origins.len();
113108
let num_universal_regions = universal_regions.len();
114109

115-
let mut num_points = 0;
116-
let mut point_indices = BTreeMap::new();
117-
110+
let mut points = Vec::new();
118111
for (block, block_data) in mir.basic_blocks().iter_enumerated() {
119112
for statement_index in 0..block_data.statements.len() + 1 {
120-
let location = Location {
113+
points.push(Location {
121114
block,
122115
statement_index,
123-
};
124-
point_indices.insert(location, num_universal_regions + num_points);
125-
num_points += 1;
116+
});
126117
}
127118
}
119+
let elements = &Rc::new(RegionValueElements::new(points, num_universal_regions));
128120

129121
// Create a RegionDefinition for each inference variable.
130122
let definitions = var_origins
@@ -134,13 +126,10 @@ impl<'tcx> RegionInferenceContext<'tcx> {
134126

135127
let mut result = Self {
136128
definitions,
137-
liveness_constraints: BitMatrix::new(
138-
num_region_variables,
139-
num_universal_regions + num_points,
140-
),
129+
elements: elements.clone(),
130+
liveness_constraints: RegionValues::new(elements, num_region_variables),
141131
inferred_values: None,
142132
constraints: Vec::new(),
143-
point_indices,
144133
universal_regions,
145134
};
146135

@@ -186,14 +175,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
186175
self.definitions[variable].is_universal = true;
187176

188177
// Add all nodes in the CFG to liveness constraints
189-
for (_location, point_index) in &self.point_indices {
190-
self.liveness_constraints
191-
.add(variable.index(), *point_index);
178+
for point_index in self.elements.all_point_indices() {
179+
self.liveness_constraints.add(variable, point_index);
192180
}
193181

194182
// Add `end(X)` into the set for X.
195-
self.liveness_constraints
196-
.add(variable.index(), variable.index());
183+
self.liveness_constraints.add(variable, variable);
197184
}
198185
}
199186

@@ -217,32 +204,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
217204
let inferred_values = self.inferred_values
218205
.as_ref()
219206
.expect("region values not yet inferred");
220-
self.region_contains_point_in_matrix(inferred_values, r, p)
221-
}
222-
223-
/// True if given region `r` contains the point `p`, when
224-
/// evaluated in the set of region values `matrix`.
225-
fn region_contains_point_in_matrix(
226-
&self,
227-
matrix: &BitMatrix,
228-
r: RegionVid,
229-
p: Location,
230-
) -> bool {
231-
let point_index = self.point_indices
232-
.get(&p)
233-
.expect("point index should be known");
234-
matrix.contains(r.index(), *point_index)
235-
}
236-
237-
/// True if given region `r` contains the `end(s)`, when
238-
/// evaluated in the set of region values `matrix`.
239-
fn region_contains_region_in_matrix(
240-
&self,
241-
matrix: &BitMatrix,
242-
r: RegionVid,
243-
s: RegionVid,
244-
) -> bool {
245-
matrix.contains(r.index(), s.index())
207+
inferred_values.contains(r, p)
246208
}
247209

248210
/// Returns access to the value of `r` for debugging purposes.
@@ -251,43 +213,21 @@ impl<'tcx> RegionInferenceContext<'tcx> {
251213
.as_ref()
252214
.expect("region values not yet inferred");
253215

254-
self.region_value_str_from_matrix(inferred_values, r)
255-
}
256-
257-
fn region_value_str_from_matrix(&self,
258-
matrix: &BitMatrix,
259-
r: RegionVid) -> String {
260-
let mut result = String::new();
261-
result.push_str("{");
262-
let mut sep = "";
263-
264-
for &point in self.point_indices.keys() {
265-
if self.region_contains_point_in_matrix(matrix, r, point) {
266-
result.push_str(&format!("{}{:?}", sep, point));
267-
sep = ", ";
268-
}
269-
}
270-
271-
for fr in (0..self.universal_regions.len()).map(RegionVid::new) {
272-
if self.region_contains_region_in_matrix(matrix, r, fr) {
273-
result.push_str(&format!("{}{:?}", sep, fr));
274-
sep = ", ";
275-
}
276-
}
277-
278-
result.push_str("}");
279-
280-
result
216+
inferred_values.region_value_str(r)
281217
}
282218

283219
/// Indicates that the region variable `v` is live at the point `point`.
284220
pub(super) fn add_live_point(&mut self, v: RegionVid, point: Location) -> bool {
285221
debug!("add_live_point({:?}, {:?})", v, point);
286222
assert!(self.inferred_values.is_none(), "values already inferred");
287-
let point_index = self.point_indices
288-
.get(&point)
289-
.expect("point index should be known");
290-
self.liveness_constraints.add(v.index(), *point_index)
223+
debug!("add_live_point: @{:?}", point);
224+
225+
let element = self.elements.index(point);
226+
if self.liveness_constraints.add(v, element) {
227+
true
228+
} else {
229+
false
230+
}
291231
}
292232

293233
/// Indicates that the region variable `sup` must outlive `sub` is live at the point `point`.
@@ -386,16 +326,12 @@ impl<'tcx> RegionInferenceContext<'tcx> {
386326
outlives_requirements: &mut Vec<ClosureOutlivesRequirement>,
387327
) {
388328
let inferred_values = self.inferred_values.as_ref().unwrap();
389-
let longer_value = inferred_values.iter(longer_fr.index());
390329

391330
debug!("check_universal_region(fr={:?})", longer_fr);
392331

393332
// Find every region `o` such that `fr: o`
394333
// (because `fr` includes `end(o)`).
395-
let shorter_frs = longer_value
396-
.take_while(|&i| i < self.universal_regions.len())
397-
.map(RegionVid::new);
398-
for shorter_fr in shorter_frs {
334+
for shorter_fr in inferred_values.universal_regions_outlived_by(longer_fr) {
399335
// If it is known that `fr: o`, carry on.
400336
if self.universal_regions.outlives(longer_fr, shorter_fr) {
401337
continue;
@@ -512,20 +448,22 @@ impl<'tcx> RegionInferenceContext<'tcx> {
512448

513449
fn copy(
514450
&self,
515-
inferred_values: &mut BitMatrix,
451+
inferred_values: &mut RegionValues,
516452
mir: &Mir<'tcx>,
517453
from_region: RegionVid,
518454
to_region: RegionVid,
519-
start_point: Location,
455+
constraint_point: Location,
520456
) -> bool {
521457
let mut changed = false;
522458

523459
let mut stack = vec![];
524460
let mut visited = FxHashSet();
525461

526-
stack.push(start_point);
462+
stack.push(constraint_point);
527463
while let Some(p) = stack.pop() {
528-
if !self.region_contains_point_in_matrix(inferred_values, from_region, p) {
464+
let point_index = self.elements.index(p);
465+
466+
if !inferred_values.contains(from_region, point_index) {
529467
debug!(" not in from-region");
530468
continue;
531469
}
@@ -535,8 +473,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
535473
continue;
536474
}
537475

538-
let point_index = self.point_indices.get(&p).unwrap();
539-
changed |= inferred_values.add(to_region.index(), *point_index);
476+
let new = inferred_values.add(to_region, point_index);
477+
changed |= new;
540478

541479
let block_data = &mir[p.block];
542480
let successor_points = if p.statement_index < block_data.statements.len() {
@@ -564,13 +502,8 @@ impl<'tcx> RegionInferenceContext<'tcx> {
564502
// If we reach the END point in the graph, then copy
565503
// over any skolemized end points in the `from_region`
566504
// and make sure they are included in the `to_region`.
567-
let universal_region_indices = inferred_values
568-
.iter(from_region.index())
569-
.take_while(|&i| i < self.universal_regions.len())
570-
.collect::<Vec<_>>();
571-
for fr in &universal_region_indices {
572-
changed |= inferred_values.add(to_region.index(), *fr);
573-
}
505+
changed |=
506+
inferred_values.add_universal_regions_outlived_by(from_region, to_region);
574507
} else {
575508
stack.extend(successor_points);
576509
}

0 commit comments

Comments
 (0)