Skip to content

Commit e029378

Browse files
committed
extend liveness to distinguish "drop" and "non-drop" uses
1 parent cb56ff5 commit e029378

File tree

9 files changed

+307
-139
lines changed

9 files changed

+307
-139
lines changed

src/librustc_mir/transform/generator.rs

Lines changed: 5 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -68,7 +68,7 @@ use rustc::mir::visit::{LvalueContext, Visitor, MutVisitor};
6868
use rustc::ty::{self, TyCtxt, AdtDef, Ty, GeneratorInterior};
6969
use rustc::ty::subst::{Kind, Substs};
7070
use util::dump_mir;
71-
use util::liveness;
71+
use util::liveness::{self, LivenessMode};
7272
use rustc_const_math::ConstInt;
7373
use rustc_data_structures::indexed_vec::Idx;
7474
use rustc_data_structures::indexed_set::IdxSetBuf;
@@ -348,7 +348,10 @@ fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
348348
ignored.visit_mir(mir);
349349

350350
let mut set = liveness::LocalSet::new_empty(mir.local_decls.len());
351-
let liveness = liveness::liveness_of_locals(mir);
351+
let liveness = liveness::liveness_of_locals(mir, LivenessMode {
352+
include_regular_use: true,
353+
include_drops: true,
354+
});
352355
liveness::dump_mir(tcx, "generator_liveness", source, mir, &liveness);
353356

354357
let mut storage_liveness_map = HashMap::new();

src/librustc_mir/transform/nll/constraint_generation.rs

Lines changed: 30 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -10,24 +10,30 @@
1010

1111
use rustc::mir::Mir;
1212
use rustc::infer::InferCtxt;
13-
use util::liveness::LivenessResult;
1413

14+
use super::LivenessResults;
1515
use super::ToRegionIndex;
1616
use super::region_infer::RegionInferenceContext;
1717

18-
pub fn generate_constraints<'a, 'gcx, 'tcx>(infcx: &InferCtxt<'a, 'gcx, 'tcx>,
19-
regioncx: &mut RegionInferenceContext,
20-
mir: &Mir<'tcx>,
21-
liveness: &LivenessResult)
22-
{
23-
ConstraintGeneration { infcx, regioncx, mir, liveness }.add_constraints();
18+
pub(super) fn generate_constraints<'a, 'gcx, 'tcx>(
19+
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
20+
regioncx: &mut RegionInferenceContext,
21+
mir: &Mir<'tcx>,
22+
liveness: &LivenessResults,
23+
) {
24+
ConstraintGeneration {
25+
infcx,
26+
regioncx,
27+
mir,
28+
liveness,
29+
}.add_constraints();
2430
}
2531

2632
struct ConstraintGeneration<'constrain, 'gcx: 'tcx, 'tcx: 'constrain> {
2733
infcx: &'constrain InferCtxt<'constrain, 'gcx, 'tcx>,
2834
regioncx: &'constrain mut RegionInferenceContext,
2935
mir: &'constrain Mir<'tcx>,
30-
liveness: &'constrain LivenessResult,
36+
liveness: &'constrain LivenessResults,
3137
}
3238

3339
impl<'constrain, 'gcx, 'tcx> ConstraintGeneration<'constrain, 'gcx, 'tcx> {
@@ -47,18 +53,23 @@ impl<'constrain, 'gcx, 'tcx> ConstraintGeneration<'constrain, 'gcx, 'tcx> {
4753
for bb in self.mir.basic_blocks().indices() {
4854
debug!("add_liveness_constraints: bb={:?}", bb);
4955

50-
self.liveness.simulate_block(self.mir, bb, |location, live_locals| {
51-
debug!("add_liveness_constraints: location={:?} live_locals={:?}",
52-
location, live_locals);
56+
self.liveness
57+
.regular
58+
.simulate_block(self.mir, bb, |location, live_locals| {
59+
debug!(
60+
"add_liveness_constraints: location={:?} live_locals={:?}",
61+
location,
62+
live_locals
63+
);
5364

54-
for live_local in live_locals.iter() {
55-
let live_local_ty = self.mir.local_decls[live_local].ty;
56-
tcx.for_each_free_region(&live_local_ty, |live_region| {
57-
let vid = live_region.to_region_index();
58-
self.regioncx.add_live_point(vid, location);
59-
})
60-
}
61-
});
65+
for live_local in live_locals.iter() {
66+
let live_local_ty = self.mir.local_decls[live_local].ty;
67+
tcx.for_each_free_region(&live_local_ty, |live_region| {
68+
let vid = live_region.to_region_index();
69+
self.regioncx.add_live_point(vid, location);
70+
})
71+
}
72+
});
6273
}
6374
}
6475
}

src/librustc_mir/transform/nll/mod.rs

Lines changed: 39 additions & 12 deletions
Original file line numberDiff line numberDiff line change
@@ -16,7 +16,7 @@ use rustc::util::nodemap::FxHashMap;
1616
use rustc_data_structures::indexed_vec::Idx;
1717
use std::collections::BTreeSet;
1818
use std::fmt;
19-
use util::liveness::{self, LivenessResult};
19+
use util::liveness::{self, LivenessResult, LivenessMode};
2020

2121
use util as mir_util;
2222
use self::mir_util::PassWhere;
@@ -50,7 +50,17 @@ impl MirPass for NLL {
5050
let num_region_variables = renumber::renumber_mir(infcx, mir);
5151

5252
// Compute what is live where.
53-
let liveness = &liveness::liveness_of_locals(mir);
53+
let liveness = &LivenessResults {
54+
regular: liveness::liveness_of_locals(mir, LivenessMode {
55+
include_regular_use: true,
56+
include_drops: false,
57+
}),
58+
59+
drop: liveness::liveness_of_locals(mir, LivenessMode {
60+
include_regular_use: false,
61+
include_drops: true,
62+
})
63+
};
5464

5565
// Create the region inference context, generate the constraints,
5666
// and then solve them.
@@ -64,9 +74,14 @@ impl MirPass for NLL {
6474
}
6575
}
6676

77+
struct LivenessResults {
78+
regular: LivenessResult,
79+
drop: LivenessResult,
80+
}
81+
6782
fn dump_mir_results<'a, 'gcx, 'tcx>(
6883
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
69-
liveness: &LivenessResult,
84+
liveness: &LivenessResults,
7085
source: MirSource,
7186
regioncx: &RegionInferenceContext,
7287
mir: &Mir<'tcx>,
@@ -75,11 +90,22 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
7590
return;
7691
}
7792

78-
let liveness_per_location: FxHashMap<_, _> = mir.basic_blocks()
93+
let regular_liveness_per_location: FxHashMap<_, _> = mir.basic_blocks()
94+
.indices()
95+
.flat_map(|bb| {
96+
let mut results = vec![];
97+
liveness.regular.simulate_block(&mir, bb, |location, local_set| {
98+
results.push((location, local_set.clone()));
99+
});
100+
results
101+
})
102+
.collect();
103+
104+
let drop_liveness_per_location: FxHashMap<_, _> = mir.basic_blocks()
79105
.indices()
80106
.flat_map(|bb| {
81107
let mut results = vec![];
82-
liveness.simulate_block(&mir, bb, |location, local_set| {
108+
liveness.drop.simulate_block(&mir, bb, |location, local_set| {
83109
results.push((location, local_set.clone()));
84110
});
85111
results
@@ -96,16 +122,17 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
96122
// Before each basic block, dump out the values
97123
// that are live on entry to the basic block.
98124
PassWhere::BeforeBlock(bb) => {
99-
let local_set = &liveness.ins[bb];
100-
writeln!(out, " | Variables live on entry to the block {:?}:", bb)?;
101-
for local in local_set.iter() {
102-
writeln!(out, " | - {:?}", local)?;
103-
}
125+
writeln!(out, " | Variables regular-live on entry to the block {:?}: {:?}",
126+
bb, liveness.regular.ins[bb])?;
127+
writeln!(out, " | Variables drop-live on entry to the block {:?}: {:?}",
128+
bb, liveness.drop.ins[bb])?;
104129
}
105130

106131
PassWhere::InCFG(location) => {
107-
let local_set = &liveness_per_location[&location];
108-
writeln!(out, " | Live variables here: {:?}", local_set)?;
132+
let local_set = &regular_liveness_per_location[&location];
133+
writeln!(out, " | Regular-Live variables here: {:?}", local_set)?;
134+
let local_set = &drop_liveness_per_location[&location];
135+
writeln!(out, " | Drop-Live variables here: {:?}", local_set)?;
109136
}
110137

111138
PassWhere::AfterCFG => {}

0 commit comments

Comments
 (0)