Skip to content

Commit 2584216

Browse files
committed
represent LivenessValues with a specialized type
1 parent 2fda456 commit 2584216

File tree

4 files changed

+76
-42
lines changed

4 files changed

+76
-42
lines changed

src/librustc_mir/borrow_check/nll/constraint_generation.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -12,7 +12,7 @@ use borrow_check::borrow_set::BorrowSet;
1212
use borrow_check::location::LocationTable;
1313
use borrow_check::nll::ToRegionVid;
1414
use borrow_check::nll::facts::AllFacts;
15-
use borrow_check::nll::region_infer::values::RegionValues;
15+
use borrow_check::nll::region_infer::values::LivenessValues;
1616
use rustc::infer::InferCtxt;
1717
use rustc::mir::visit::TyContext;
1818
use rustc::mir::visit::Visitor;
@@ -24,7 +24,7 @@ use rustc::ty::{self, CanonicalTy, ClosureSubsts, GeneratorSubsts, RegionVid};
2424

2525
pub(super) fn generate_constraints<'cx, 'gcx, 'tcx>(
2626
infcx: &InferCtxt<'cx, 'gcx, 'tcx>,
27-
liveness_constraints: &mut RegionValues<RegionVid>,
27+
liveness_constraints: &mut LivenessValues<RegionVid>,
2828
all_facts: &mut Option<AllFacts>,
2929
location_table: &LocationTable,
3030
mir: &Mir<'tcx>,
@@ -48,7 +48,7 @@ struct ConstraintGeneration<'cg, 'cx: 'cg, 'gcx: 'tcx, 'tcx: 'cx> {
4848
infcx: &'cg InferCtxt<'cx, 'gcx, 'tcx>,
4949
all_facts: &'cg mut Option<AllFacts>,
5050
location_table: &'cg LocationTable,
51-
liveness_constraints: &'cg mut RegionValues<RegionVid>,
51+
liveness_constraints: &'cg mut LivenessValues<RegionVid>,
5252
borrow_set: &'cg BorrowSet<'tcx>,
5353
}
5454

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

Lines changed: 10 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ mod dump_mir;
3737
mod error_reporting;
3838
mod graphviz;
3939
pub mod values;
40-
use self::values::{RegionValueElements, RegionValues};
40+
use self::values::{RegionValueElements, RegionValues, LivenessValues};
4141

4242
use super::ToRegionVid;
4343

@@ -52,7 +52,7 @@ pub struct RegionInferenceContext<'tcx> {
5252
/// regions, these start out empty and steadily grow, though for
5353
/// each universally quantified region R they start out containing
5454
/// the entire CFG and `end(R)`.
55-
liveness_constraints: RegionValues<RegionVid>,
55+
liveness_constraints: LivenessValues<RegionVid>,
5656

5757
/// The outlives constraints computed by the type-check.
5858
constraints: Rc<ConstraintSet>,
@@ -199,7 +199,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
199199
_mir: &Mir<'tcx>,
200200
outlives_constraints: ConstraintSet,
201201
type_tests: Vec<TypeTest<'tcx>>,
202-
liveness_constraints: RegionValues<RegionVid>,
202+
liveness_constraints: LivenessValues<RegionVid>,
203203
elements: &Rc<RegionValueElements>,
204204
) -> Self {
205205
let universal_regions = Rc::new(universal_regions);
@@ -216,9 +216,9 @@ impl<'tcx> RegionInferenceContext<'tcx> {
216216

217217
let mut scc_values = RegionValues::new(elements);
218218

219-
for region in liveness_constraints.regions_with_points() {
219+
for region in liveness_constraints.rows() {
220220
let scc = constraint_sccs.scc(region);
221-
scc_values.merge_row(scc, region, &liveness_constraints);
221+
scc_values.merge_liveness(scc, region, &liveness_constraints);
222222
}
223223

224224
let mut result = Self {
@@ -283,7 +283,7 @@ impl<'tcx> RegionInferenceContext<'tcx> {
283283
self.scc_values.add_all_points(variable_scc);
284284

285285
// Add `end(X)` into the set for X.
286-
self.add_live_element(variable, variable);
286+
self.add_element_to_scc_of(variable, variable);
287287
}
288288
}
289289

@@ -314,27 +314,11 @@ impl<'tcx> RegionInferenceContext<'tcx> {
314314
self.scc_values.region_value_str(scc)
315315
}
316316

317-
/// Indicates that the region variable `v` is live at the point `point`.
318-
///
319-
/// Returns `true` if this constraint is new and `false` is the
320-
/// constraint was already present.
321-
pub(super) fn add_live_element(
322-
&mut self,
323-
v: RegionVid,
324-
elem: impl ToElementIndex,
325-
) -> bool {
317+
/// Adds `elem` to the value of the SCC in which `v` appears.
318+
fn add_element_to_scc_of(&mut self, v: RegionVid, elem: impl ToElementIndex) {
326319
debug!("add_live_element({:?}, {:?})", v, elem);
327-
328-
// Add to the liveness values for `v`...
329-
if self.liveness_constraints.add_element(v, elem) {
330-
// ...but also add to the SCC in which `v` appears.
331-
let scc = self.constraint_sccs.scc(v);
332-
self.scc_values.add_element(scc, elem);
333-
334-
true
335-
} else {
336-
false
337-
}
320+
let scc = self.constraint_sccs.scc(v);
321+
self.scc_values.add_element(scc, elem);
338322
}
339323

340324
/// Perform region inference and report errors if we see any

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

Lines changed: 60 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -117,6 +117,65 @@ crate enum RegionElement {
117117
RootUniversalRegion(RegionVid),
118118
}
119119

120+
/// When we initially compute liveness, we use a bit matrix storing
121+
/// points for each region-vid.
122+
crate struct LivenessValues<N: Idx> {
123+
elements: Rc<RegionValueElements>,
124+
points: SparseBitMatrix<N, PointIndex>,
125+
}
126+
127+
impl<N: Idx> LivenessValues<N> {
128+
/// Creates a new set of "region values" that tracks causal information.
129+
/// Each of the regions in num_region_variables will be initialized with an
130+
/// empty set of points and no causal information.
131+
crate fn new(elements: &Rc<RegionValueElements>) -> Self {
132+
Self {
133+
elements: elements.clone(),
134+
points: SparseBitMatrix::new(elements.num_points),
135+
}
136+
}
137+
138+
/// Iterate through each region that has a value in this set.
139+
crate fn rows<'a>(&'a self) -> impl Iterator<Item = N> {
140+
self.points.rows()
141+
}
142+
143+
/// Adds the given element to the value for the given region. Returns true if
144+
/// the element is newly added (i.e., was not already present).
145+
crate fn add_element(
146+
&mut self,
147+
row: N,
148+
location: Location,
149+
) -> bool {
150+
debug!("LivenessValues::add(r={:?}, location={:?})", row, location);
151+
let index = self.elements.point_from_location(location);
152+
self.points.add(row, index)
153+
}
154+
155+
/// Adds all the control-flow points to the values for `r`.
156+
crate fn add_all_points(&mut self, row: N) {
157+
self.points.add_all(row);
158+
}
159+
160+
/// True if the region `r` contains the given element.
161+
crate fn contains(&self, row: N, location: Location) -> bool {
162+
let index = self.elements.point_from_location(location);
163+
self.points.contains(row, index)
164+
}
165+
166+
/// Returns a "pretty" string value of the region. Meant for debugging.
167+
crate fn region_value_str(&self, r: N) -> String {
168+
region_value_str(
169+
self.points
170+
.row(r)
171+
.into_iter()
172+
.flat_map(|set| set.iter())
173+
.map(|p| self.elements.to_location(p))
174+
.map(RegionElement::Location)
175+
)
176+
}
177+
}
178+
120179
/// Stores the values for a set of regions. These are stored in a
121180
/// compact `SparseBitMatrix` representation, with one row per region
122181
/// variable. The columns consist of either universal regions or
@@ -172,22 +231,13 @@ impl<N: Idx> RegionValues<N> {
172231
elem.contained_in_row(self, r)
173232
}
174233

175-
/// Iterate through each region that has a value in this set.
176-
crate fn regions_with_points<'a>(&'a self) -> impl Iterator<Item = N> {
177-
self.points.rows()
178-
}
179-
180234
/// `self[to] |= values[from]`, essentially: that is, take all the
181235
/// elements for the region `from` from `values` and add them to
182236
/// the region `to` in `self`.
183-
crate fn merge_row<M: Idx>(&mut self, to: N, from: M, values: &RegionValues<M>) {
237+
crate fn merge_liveness<M: Idx>(&mut self, to: N, from: M, values: &LivenessValues<M>) {
184238
if let Some(set) = values.points.row(from) {
185239
self.points.merge_into(to, set);
186240
}
187-
188-
if let Some(set) = values.free_regions.row(from) {
189-
self.free_regions.merge_into(to, set);
190-
}
191241
}
192242

193243
/// True if `sup_region` contains all the CFG points that

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -15,8 +15,8 @@ use borrow_check::borrow_set::BorrowSet;
1515
use borrow_check::location::LocationTable;
1616
use borrow_check::nll::constraints::{ConstraintSet, OutlivesConstraint};
1717
use borrow_check::nll::facts::AllFacts;
18+
use borrow_check::nll::region_infer::values::{RegionValueElements, LivenessValues};
1819
use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest};
19-
use borrow_check::nll::region_infer::values::{RegionValues, RegionValueElements};
2020
use borrow_check::nll::universal_regions::UniversalRegions;
2121
use borrow_check::nll::ToRegionVid;
2222
use borrow_check::nll::LocalWithRegion;
@@ -121,7 +121,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
121121
) -> MirTypeckRegionConstraints<'tcx> {
122122
let implicit_region_bound = infcx.tcx.mk_region(ty::ReVar(universal_regions.fr_fn_body));
123123
let mut constraints = MirTypeckRegionConstraints {
124-
liveness_constraints: RegionValues::new(elements),
124+
liveness_constraints: LivenessValues::new(elements),
125125
outlives_constraints: ConstraintSet::default(),
126126
type_tests: Vec::default(),
127127
};
@@ -638,7 +638,7 @@ crate struct MirTypeckRegionConstraints<'tcx> {
638638
/// not otherwise appear in the MIR -- in particular, the
639639
/// late-bound regions that it instantiates at call-sites -- and
640640
/// hence it must report on their liveness constraints.
641-
crate liveness_constraints: RegionValues<RegionVid>,
641+
crate liveness_constraints: LivenessValues<RegionVid>,
642642

643643
crate outlives_constraints: ConstraintSet,
644644

0 commit comments

Comments
 (0)