Skip to content

Commit eb322a4

Browse files
Use new dataflow interface for MaybeInitializedPlaces
1 parent b18f639 commit eb322a4

File tree

7 files changed

+80
-66
lines changed

7 files changed

+80
-66
lines changed

src/librustc_mir/borrow_check/mod.rs

Lines changed: 6 additions & 10 deletions
Original file line numberDiff line numberDiff line change
@@ -37,7 +37,7 @@ use crate::dataflow::Borrows;
3737
use crate::dataflow::DataflowResultsConsumer;
3838
use crate::dataflow::FlowAtLocation;
3939
use crate::dataflow::MoveDataParamEnv;
40-
use crate::dataflow::{do_dataflow, DebugFormatted};
40+
use crate::dataflow::{self, do_dataflow, DebugFormatted};
4141
use crate::dataflow::EverInitializedPlaces;
4242
use crate::dataflow::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
4343

@@ -168,15 +168,11 @@ fn do_mir_borrowck<'a, 'tcx>(
168168
};
169169

170170
let dead_unwinds = BitSet::new_empty(body.basic_blocks().len());
171-
let mut flow_inits = FlowAtLocation::new(do_dataflow(
172-
tcx,
173-
body,
174-
def_id,
175-
&attributes,
176-
&dead_unwinds,
177-
MaybeInitializedPlaces::new(tcx, body, &mdpe),
178-
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
179-
));
171+
let flow_inits = MaybeInitializedPlaces::new(tcx, body, &mdpe);
172+
let mut flow_inits =
173+
dataflow::generic::Engine::new_gen_kill(tcx, body, def_id, &dead_unwinds, flow_inits)
174+
.iterate_to_fixpoint()
175+
.into_cursor(body);
180176

181177
let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(id).is_fn_or_closure();
182178
let borrow_set = Rc::new(BorrowSet::build(

src/librustc_mir/borrow_check/nll/mod.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,9 @@ use crate::borrow_check::location::{LocationIndex, LocationTable};
33
use crate::borrow_check::nll::facts::AllFactsExt;
44
use crate::borrow_check::nll::type_check::{MirTypeckResults, MirTypeckRegionConstraints};
55
use crate::borrow_check::nll::region_infer::values::RegionValueElements;
6+
use crate::dataflow::generic::ResultsCursor;
67
use crate::dataflow::indexes::BorrowIndex;
78
use crate::dataflow::move_paths::{InitLocation, MoveData, MovePathIndex, InitKind};
8-
use crate::dataflow::FlowAtLocation;
99
use crate::dataflow::MaybeInitializedPlaces;
1010
use crate::transform::MirSource;
1111
use crate::borrow_check::Upvar;
@@ -161,7 +161,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
161161
upvars: &[Upvar],
162162
location_table: &LocationTable,
163163
param_env: ty::ParamEnv<'tcx>,
164-
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'cx, 'tcx>>,
164+
flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'cx, 'tcx>>,
165165
move_data: &MoveData<'tcx>,
166166
borrow_set: &BorrowSet<'tcx>,
167167
errors_buffer: &mut Vec<Diagnostic>,

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -4,8 +4,8 @@ use crate::borrow_check::nll::facts::{AllFacts, AllFactsExt};
44
use crate::borrow_check::nll::region_infer::values::RegionValueElements;
55
use crate::borrow_check::nll::universal_regions::UniversalRegions;
66
use crate::borrow_check::nll::ToRegionVid;
7+
use crate::dataflow::generic::ResultsCursor;
78
use crate::dataflow::move_paths::MoveData;
8-
use crate::dataflow::FlowAtLocation;
99
use crate::dataflow::MaybeInitializedPlaces;
1010
use rustc::mir::{Body, Local};
1111
use rustc::ty::{RegionVid, TyCtxt};
@@ -26,11 +26,11 @@ mod trace;
2626
///
2727
/// N.B., this computation requires normalization; therefore, it must be
2828
/// performed before
29-
pub(super) fn generate<'tcx>(
29+
pub(super) fn generate<'mir, 'tcx>(
3030
typeck: &mut TypeChecker<'_, 'tcx>,
3131
body: &Body<'tcx>,
3232
elements: &Rc<RegionValueElements>,
33-
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
33+
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
3434
move_data: &MoveData<'tcx>,
3535
location_table: &LocationTable,
3636
) {

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

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -3,9 +3,10 @@ use crate::borrow_check::nll::type_check::liveness::local_use_map::LocalUseMap;
33
use crate::borrow_check::nll::type_check::liveness::polonius;
44
use crate::borrow_check::nll::type_check::NormalizeLocation;
55
use crate::borrow_check::nll::type_check::TypeChecker;
6+
use crate::dataflow::generic::ResultsCursor;
67
use crate::dataflow::indexes::MovePathIndex;
7-
use crate::dataflow::move_paths::MoveData;
8-
use crate::dataflow::{FlowAtLocation, FlowsAtLocation, MaybeInitializedPlaces};
8+
use crate::dataflow::move_paths::{HasMoveData, MoveData};
9+
use crate::dataflow::MaybeInitializedPlaces;
910
use rustc::infer::canonical::QueryRegionConstraints;
1011
use rustc::mir::{BasicBlock, Body, ConstraintCategory, Local, Location};
1112
use rustc::traits::query::dropck_outlives::DropckOutlivesResult;
@@ -34,7 +35,7 @@ pub(super) fn trace(
3435
typeck: &mut TypeChecker<'_, 'tcx>,
3536
body: &Body<'tcx>,
3637
elements: &Rc<RegionValueElements>,
37-
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
38+
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
3839
move_data: &MoveData<'tcx>,
3940
live_locals: Vec<Local>,
4041
polonius_drop_used: Option<Vec<(Local, Location)>>,
@@ -81,7 +82,7 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> {
8182

8283
/// Results of dataflow tracking which variables (and paths) have been
8384
/// initialized.
84-
flow_inits: &'me mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'flow, 'tcx>>,
85+
flow_inits: &'me mut ResultsCursor<'flow, 'tcx, MaybeInitializedPlaces<'flow, 'tcx>>,
8586

8687
/// Index indicating where each variable is assigned, used, or
8788
/// dropped.
@@ -389,23 +390,26 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
389390
}
390391

391392
impl LivenessContext<'_, '_, '_, 'tcx> {
393+
/// Returns `true` if the local variable (or some part of it) is initialized at the current
394+
/// cursor position. Callers should call one of the `seek` methods immediately before to point
395+
/// the cursor to the desired location.
396+
fn initialized_at_curr_loc(&self, mpi: MovePathIndex) -> bool {
397+
let state = self.flow_inits.get();
398+
if state.contains(mpi) {
399+
return true;
400+
}
401+
402+
let move_paths = &self.flow_inits.analysis().move_data().move_paths;
403+
move_paths[mpi].find_child(&move_paths, |mpi| state.contains(mpi)).is_some()
404+
}
405+
392406
/// Returns `true` if the local variable (or some part of it) is initialized in
393407
/// the terminator of `block`. We need to check this to determine if a
394408
/// DROP of some local variable will have an effect -- note that
395409
/// drops, as they may unwind, are always terminators.
396410
fn initialized_at_terminator(&mut self, block: BasicBlock, mpi: MovePathIndex) -> bool {
397-
// Compute the set of initialized paths at terminator of block
398-
// by resetting to the start of the block and then applying
399-
// the effects of all statements. This is the only way to get
400-
// "just ahead" of a terminator.
401-
self.flow_inits.reset_to_entry_of(block);
402-
for statement_index in 0..self.body[block].statements.len() {
403-
let location = Location { block, statement_index };
404-
self.flow_inits.reconstruct_statement_effect(location);
405-
self.flow_inits.apply_local_effect(location);
406-
}
407-
408-
self.flow_inits.has_any_child_of(mpi).is_some()
411+
self.flow_inits.seek_before(self.body.terminator_loc(block));
412+
self.initialized_at_curr_loc(mpi)
409413
}
410414

411415
/// Returns `true` if the path `mpi` (or some part of it) is initialized at
@@ -414,8 +418,8 @@ impl LivenessContext<'_, '_, '_, 'tcx> {
414418
/// **Warning:** Does not account for the result of `Call`
415419
/// instructions.
416420
fn initialized_at_exit(&mut self, block: BasicBlock, mpi: MovePathIndex) -> bool {
417-
self.flow_inits.reset_to_exit_of(block);
418-
self.flow_inits.has_any_child_of(mpi).is_some()
421+
self.flow_inits.seek_after(self.body.terminator_loc(block));
422+
self.initialized_at_curr_loc(mpi)
419423
}
420424

421425
/// Stores the result that all regions in `value` are live for the

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -17,8 +17,8 @@ use crate::borrow_check::nll::type_check::free_region_relations::{
1717
use crate::borrow_check::nll::universal_regions::{DefiningTy, UniversalRegions};
1818
use crate::borrow_check::nll::ToRegionVid;
1919
use crate::transform::promote_consts::should_suggest_const_in_array_repeat_expressions_attribute;
20+
use crate::dataflow::generic::ResultsCursor;
2021
use crate::dataflow::move_paths::MoveData;
21-
use crate::dataflow::FlowAtLocation;
2222
use crate::dataflow::MaybeInitializedPlaces;
2323
use either::Either;
2424
use rustc::hir;
@@ -110,7 +110,7 @@ mod relate_tys;
110110
/// constraints for the regions in the types of variables
111111
/// - `flow_inits` -- results of a maybe-init dataflow analysis
112112
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
113-
pub(crate) fn type_check<'tcx>(
113+
pub(crate) fn type_check<'mir, 'tcx>(
114114
infcx: &InferCtxt<'_, 'tcx>,
115115
param_env: ty::ParamEnv<'tcx>,
116116
body: &Body<'tcx>,
@@ -120,7 +120,7 @@ pub(crate) fn type_check<'tcx>(
120120
location_table: &LocationTable,
121121
borrow_set: &BorrowSet<'tcx>,
122122
all_facts: &mut Option<AllFacts>,
123-
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
123+
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
124124
move_data: &MoveData<'tcx>,
125125
elements: &Rc<RegionValueElements>,
126126
) -> MirTypeckResults<'tcx> {

src/librustc_mir/dataflow/impls/mod.rs

Lines changed: 33 additions & 19 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,7 @@ use crate::util::elaborate_drops::DropFlagState;
1313

1414
use super::move_paths::{HasMoveData, MoveData, MovePathIndex, InitIndex, InitKind};
1515
use super::{BitDenotation, BottomValue, GenKillSet};
16+
use super::generic::GenKill;
1617

1718
use super::drop_flag_effects_for_function_entry;
1819
use super::drop_flag_effects_for_location;
@@ -226,7 +227,7 @@ impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, 'tcx> {
226227
}
227228

228229
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
229-
fn update_bits(trans: &mut GenKillSet<MovePathIndex>,
230+
fn update_bits(trans: &mut impl GenKill<MovePathIndex>,
230231
path: MovePathIndex,
231232
state: DropFlagState)
232233
{
@@ -261,56 +262,69 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
261262
}
262263
}
263264

264-
impl<'a, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
265+
impl<'tcx> super::generic::AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
265266
type Idx = MovePathIndex;
266-
fn name() -> &'static str { "maybe_init" }
267-
fn bits_per_block(&self) -> usize {
267+
268+
const NAME: &'static str = "maybe_init";
269+
270+
fn bits_per_block(&self, _: &mir::Body<'tcx>) -> usize {
268271
self.move_data().move_paths.len()
269272
}
270273

271-
fn start_block_effect(&self, entry_set: &mut BitSet<MovePathIndex>) {
274+
fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut BitSet<Self::Idx>) {
272275
drop_flag_effects_for_function_entry(
273276
self.tcx, self.body, self.mdpe,
274277
|path, s| {
275278
assert!(s == DropFlagState::Present);
276-
entry_set.insert(path);
279+
state.insert(path);
277280
});
278281
}
279282

280-
fn statement_effect(&self,
281-
trans: &mut GenKillSet<Self::Idx>,
282-
location: Location)
283-
{
283+
fn pretty_print_idx(&self, w: &mut impl std::io::Write, mpi: Self::Idx) -> std::io::Result<()> {
284+
write!(w, "{:?}", self.move_data().move_paths[mpi])
285+
}
286+
}
287+
288+
impl<'tcx> super::generic::GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
289+
fn statement_effect(
290+
&self,
291+
trans: &mut impl GenKill<Self::Idx>,
292+
_statement: &mir::Statement<'tcx>,
293+
location: Location,
294+
) {
284295
drop_flag_effects_for_location(
285296
self.tcx, self.body, self.mdpe,
286297
location,
287298
|path, s| Self::update_bits(trans, path, s)
288299
)
289300
}
290301

291-
fn terminator_effect(&self,
292-
trans: &mut GenKillSet<Self::Idx>,
293-
location: Location)
294-
{
302+
fn terminator_effect(
303+
&self,
304+
trans: &mut impl GenKill<Self::Idx>,
305+
_terminator: &mir::Terminator<'tcx>,
306+
location: Location,
307+
) {
295308
drop_flag_effects_for_location(
296309
self.tcx, self.body, self.mdpe,
297310
location,
298311
|path, s| Self::update_bits(trans, path, s)
299312
)
300313
}
301314

302-
fn propagate_call_return(
315+
fn call_return_effect(
303316
&self,
304-
in_out: &mut BitSet<MovePathIndex>,
305-
_call_bb: mir::BasicBlock,
306-
_dest_bb: mir::BasicBlock,
317+
trans: &mut impl GenKill<Self::Idx>,
318+
_block: mir::BasicBlock,
319+
_func: &mir::Operand<'tcx>,
320+
_args: &[mir::Operand<'tcx>],
307321
dest_place: &mir::Place<'tcx>,
308322
) {
309323
// when a call returns successfully, that means we need to set
310324
// the bits for that dest_place to 1 (initialized).
311325
on_lookup_result_bits(self.tcx, self.body, self.move_data(),
312326
self.move_data().rev_lookup.find(dest_place.as_ref()),
313-
|mpi| { in_out.insert(mpi); });
327+
|mpi| { trans.gen(mpi); });
314328
}
315329
}
316330

src/librustc_mir/transform/elaborate_drops.rs

Lines changed: 11 additions & 11 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ use crate::dataflow::{on_all_children_bits, on_all_drop_children_bits};
55
use crate::dataflow::{drop_flag_effects_for_location, on_lookup_result_bits};
66
use crate::dataflow::MoveDataParamEnv;
77
use crate::dataflow::{self, do_dataflow, DebugFormatted};
8+
use crate::dataflow::generic::Results;
89
use crate::transform::{MirPass, MirSource};
910
use crate::util::patch::MirPatch;
1011
use crate::util::elaborate_drops::{DropFlagState, Unwind, elaborate_drop};
@@ -37,10 +38,10 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
3738
param_env,
3839
};
3940
let dead_unwinds = find_dead_unwinds(tcx, body, def_id, &env);
40-
let flow_inits =
41-
do_dataflow(tcx, body, def_id, &[], &dead_unwinds,
42-
MaybeInitializedPlaces::new(tcx, body, &env),
43-
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
41+
let flow_inits = dataflow::generic::Engine::new_gen_kill(
42+
tcx, body, def_id, &dead_unwinds,
43+
MaybeInitializedPlaces::new(tcx, body, &env),
44+
).iterate_to_fixpoint();
4445
let flow_uninits =
4546
do_dataflow(tcx, body, def_id, &[], &dead_unwinds,
4647
MaybeUninitializedPlaces::new(tcx, body, &env),
@@ -73,10 +74,10 @@ fn find_dead_unwinds<'tcx>(
7374
// We only need to do this pass once, because unwind edges can only
7475
// reach cleanup blocks, which can't have unwind edges themselves.
7576
let mut dead_unwinds = BitSet::new_empty(body.basic_blocks().len());
77+
let flow_inits = MaybeInitializedPlaces::new(tcx, body, &env);
7678
let flow_inits =
77-
do_dataflow(tcx, body, def_id, &[], &dead_unwinds,
78-
MaybeInitializedPlaces::new(tcx, body, &env),
79-
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]));
79+
dataflow::generic::Engine::new_gen_kill(tcx, body, def_id, &dead_unwinds, flow_inits)
80+
.iterate_to_fixpoint();
8081
for (bb, bb_data) in body.basic_blocks().iter_enumerated() {
8182
let location = match bb_data.terminator().kind {
8283
TerminatorKind::Drop { ref location, unwind: Some(_), .. } |
@@ -85,7 +86,7 @@ fn find_dead_unwinds<'tcx>(
8586
};
8687

8788
let mut init_data = InitializationData {
88-
live: flow_inits.sets().entry_set_for(bb.index()).to_owned(),
89+
live: flow_inits.on_block_entry(bb).clone(),
8990
dead: BitSet::new_empty(env.move_data.move_paths.len()),
9091
};
9192
debug!("find_dead_unwinds @ {:?}: {:?}; init_data={:?}",
@@ -266,7 +267,7 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
266267
tcx: TyCtxt<'tcx>,
267268
body: &'a Body<'tcx>,
268269
env: &'a MoveDataParamEnv<'tcx>,
269-
flow_inits: DataflowResults<'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
270+
flow_inits: Results<'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
270271
flow_uninits: DataflowResults<'tcx, MaybeUninitializedPlaces<'a, 'tcx>>,
271272
drop_flags: FxHashMap<MovePathIndex, Local>,
272273
patch: MirPatch<'tcx>,
@@ -281,8 +282,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
281282

282283
fn initialization_data_at(&self, loc: Location) -> InitializationData {
283284
let mut data = InitializationData {
284-
live: self.flow_inits.sets().entry_set_for(loc.block.index())
285-
.to_owned(),
285+
live: self.flow_inits.on_block_entry(loc.block).to_owned(),
286286
dead: self.flow_uninits.sets().entry_set_for(loc.block.index())
287287
.to_owned(),
288288
};

0 commit comments

Comments
 (0)