Skip to content

Commit 79f0820

Browse files
Use new dataflow interface for MaybeInitializedPlaces
1 parent b5e1b00 commit 79f0820

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

@@ -185,15 +185,11 @@ fn do_mir_borrowck<'a, 'tcx>(
185185
};
186186

187187
let dead_unwinds = BitSet::new_empty(body.basic_blocks().len());
188-
let mut flow_inits = FlowAtLocation::new(do_dataflow(
189-
tcx,
190-
&body,
191-
def_id,
192-
&attributes,
193-
&dead_unwinds,
194-
MaybeInitializedPlaces::new(tcx, &body, &mdpe),
195-
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
196-
));
188+
let flow_inits = MaybeInitializedPlaces::new(tcx, &body, &mdpe);
189+
let mut flow_inits =
190+
dataflow::generic::Engine::new_gen_kill(tcx, &body, def_id, &dead_unwinds, flow_inits)
191+
.iterate_to_fixpoint()
192+
.into_cursor(&body);
197193

198194
let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(id).is_fn_or_closure();
199195
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,8 +3,8 @@ use crate::borrow_check::location::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::move_paths::{InitLocation, MoveData, InitKind};
7-
use crate::dataflow::FlowAtLocation;
88
use crate::dataflow::MaybeInitializedPlaces;
99
use crate::transform::MirSource;
1010
use crate::borrow_check::Upvar;
@@ -165,7 +165,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
165165
upvars: &[Upvar],
166166
location_table: &LocationTable,
167167
param_env: ty::ParamEnv<'tcx>,
168-
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'cx, 'tcx>>,
168+
flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'cx, 'tcx>>,
169169
move_data: &MoveData<'tcx>,
170170
borrow_set: &BorrowSet<'tcx>,
171171
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, ReadOnlyBodyAndCache};
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: ReadOnlyBodyAndCache<'_, '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, ConstraintCategory, Local, Location, ReadOnlyBodyAndCache};
1112
use rustc::traits::query::dropck_outlives::DropckOutlivesResult;
@@ -34,7 +35,7 @@ pub(super) fn trace(
3435
typeck: &mut TypeChecker<'_, 'tcx>,
3536
body: ReadOnlyBodyAndCache<'_, '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.
@@ -390,23 +391,26 @@ impl LivenessResults<'me, 'typeck, 'flow, 'tcx> {
390391
}
391392

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

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

422426
/// 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
@@ -50,7 +50,7 @@ use crate::borrow_check::nll::type_check::free_region_relations::{
5050
CreateResult, UniversalRegionRelations,
5151
};
5252
use crate::borrow_check::nll::universal_regions::{DefiningTy, UniversalRegions};
53-
use crate::dataflow::FlowAtLocation;
53+
use crate::dataflow::generic::ResultsCursor;
5454
use crate::dataflow::MaybeInitializedPlaces;
5555
use crate::dataflow::move_paths::MoveData;
5656
use crate::transform::promote_consts::should_suggest_const_in_array_repeat_expressions_attribute;
@@ -114,7 +114,7 @@ mod relate_tys;
114114
/// constraints for the regions in the types of variables
115115
/// - `flow_inits` -- results of a maybe-init dataflow analysis
116116
/// - `move_data` -- move-data constructed when performing the maybe-init dataflow analysis
117-
pub(crate) fn type_check<'tcx>(
117+
pub(crate) fn type_check<'mir, 'tcx>(
118118
infcx: &InferCtxt<'_, 'tcx>,
119119
param_env: ty::ParamEnv<'tcx>,
120120
body: ReadOnlyBodyAndCache<'_, 'tcx>,
@@ -124,7 +124,7 @@ pub(crate) fn type_check<'tcx>(
124124
location_table: &LocationTable,
125125
borrow_set: &BorrowSet<'tcx>,
126126
all_facts: &mut Option<AllFacts>,
127-
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
127+
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
128128
move_data: &MoveData<'tcx>,
129129
elements: &Rc<RegionValueElements>,
130130
) -> 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)