Skip to content

Commit 4c6ea89

Browse files
Use new dataflow interface for MaybeInitializedPlaces
1 parent c8869f8 commit 4c6ea89

File tree

7 files changed

+81
-67
lines changed

7 files changed

+81
-67
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::DataflowResultsConsumer;
3737
use crate::dataflow::EverInitializedPlaces;
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::{MaybeInitializedPlaces, MaybeUninitializedPlaces};
4242
use crate::transform::MirSource;
4343

@@ -189,15 +189,11 @@ fn do_mir_borrowck<'a, 'tcx>(
189189
let mdpe = MoveDataParamEnv { move_data, param_env };
190190

191191
let dead_unwinds = BitSet::new_empty(body.basic_blocks().len());
192-
let mut flow_inits = FlowAtLocation::new(do_dataflow(
193-
tcx,
194-
&body,
195-
def_id,
196-
&attributes,
197-
&dead_unwinds,
198-
MaybeInitializedPlaces::new(tcx, &body, &mdpe),
199-
|bd, i| DebugFormatted::new(&bd.move_data().move_paths[i]),
200-
));
192+
let flow_inits = MaybeInitializedPlaces::new(tcx, &body, &mdpe);
193+
let mut flow_inits =
194+
dataflow::generic::Engine::new_gen_kill(tcx, &body, def_id, &dead_unwinds, flow_inits)
195+
.iterate_to_fixpoint()
196+
.into_cursor(&body);
201197

202198
let locals_are_invalidated_at_exit = tcx.hir().body_owner_kind(id).is_fn_or_closure();
203199
let borrow_set =

src/librustc_mir/borrow_check/nll.rs

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,8 @@ use std::str::FromStr;
2020
use self::mir_util::PassWhere;
2121
use polonius_engine::{Algorithm, Output};
2222

23+
use crate::dataflow::generic::ResultsCursor;
2324
use crate::dataflow::move_paths::{InitKind, InitLocation, MoveData};
24-
use crate::dataflow::FlowAtLocation;
2525
use crate::dataflow::MaybeInitializedPlaces;
2626
use crate::transform::MirSource;
2727
use crate::util as mir_util;
@@ -149,7 +149,7 @@ pub(in crate::borrow_check) fn compute_regions<'cx, 'tcx>(
149149
promoted: &IndexVec<Promoted, ReadOnlyBodyAndCache<'_, 'tcx>>,
150150
location_table: &LocationTable,
151151
param_env: ty::ParamEnv<'tcx>,
152-
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'cx, 'tcx>>,
152+
flow_inits: &mut ResultsCursor<'cx, 'tcx, MaybeInitializedPlaces<'cx, 'tcx>>,
153153
move_data: &MoveData<'tcx>,
154154
borrow_set: &BorrowSet<'tcx>,
155155
) -> NllOutput<'tcx> {

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

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -3,8 +3,8 @@ use rustc::ty::{RegionVid, TyCtxt};
33
use rustc_data_structures::fx::FxHashSet;
44
use std::rc::Rc;
55

6+
use crate::dataflow::generic::ResultsCursor;
67
use crate::dataflow::move_paths::MoveData;
7-
use crate::dataflow::FlowAtLocation;
88
use crate::dataflow::MaybeInitializedPlaces;
99

1010
use crate::borrow_check::{
@@ -30,11 +30,11 @@ mod trace;
3030
///
3131
/// N.B., this computation requires normalization; therefore, it must be
3232
/// performed before
33-
pub(super) fn generate<'tcx>(
33+
pub(super) fn generate<'mir, 'tcx>(
3434
typeck: &mut TypeChecker<'_, 'tcx>,
3535
body: ReadOnlyBodyAndCache<'_, 'tcx>,
3636
elements: &Rc<RegionValueElements>,
37-
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
37+
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
3838
move_data: &MoveData<'tcx>,
3939
location_table: &LocationTable,
4040
) {

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

Lines changed: 22 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -8,9 +8,10 @@ use rustc_data_structures::fx::{FxHashMap, FxHashSet};
88
use rustc_index::bit_set::HybridBitSet;
99
use std::rc::Rc;
1010

11+
use crate::dataflow::generic::ResultsCursor;
1112
use crate::dataflow::indexes::MovePathIndex;
12-
use crate::dataflow::move_paths::MoveData;
13-
use crate::dataflow::{FlowAtLocation, FlowsAtLocation, MaybeInitializedPlaces};
13+
use crate::dataflow::move_paths::{HasMoveData, MoveData};
14+
use crate::dataflow::MaybeInitializedPlaces;
1415

1516
use crate::borrow_check::{
1617
region_infer::values::{self, PointIndex, RegionValueElements},
@@ -38,7 +39,7 @@ pub(super) fn trace(
3839
typeck: &mut TypeChecker<'_, 'tcx>,
3940
body: ReadOnlyBodyAndCache<'_, 'tcx>,
4041
elements: &Rc<RegionValueElements>,
41-
flow_inits: &mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'_, 'tcx>>,
42+
flow_inits: &mut ResultsCursor<'mir, 'tcx, MaybeInitializedPlaces<'mir, 'tcx>>,
4243
move_data: &MoveData<'tcx>,
4344
live_locals: Vec<Local>,
4445
polonius_drop_used: Option<Vec<(Local, Location)>>,
@@ -85,7 +86,7 @@ struct LivenessContext<'me, 'typeck, 'flow, 'tcx> {
8586

8687
/// Results of dataflow tracking which variables (and paths) have been
8788
/// initialized.
88-
flow_inits: &'me mut FlowAtLocation<'tcx, MaybeInitializedPlaces<'flow, 'tcx>>,
89+
flow_inits: &'me mut ResultsCursor<'flow, 'tcx, MaybeInitializedPlaces<'flow, 'tcx>>,
8990

9091
/// Index indicating where each variable is assigned, used, or
9192
/// 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_descendant(&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/type_check/mod.rs

Lines changed: 3 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -34,8 +34,8 @@ use rustc_hir::def_id::DefId;
3434
use rustc_index::vec::{Idx, IndexVec};
3535
use rustc_span::{Span, DUMMY_SP};
3636

37+
use crate::dataflow::generic::ResultsCursor;
3738
use crate::dataflow::move_paths::MoveData;
38-
use crate::dataflow::FlowAtLocation;
3939
use crate::dataflow::MaybeInitializedPlaces;
4040
use crate::transform::promote_consts::should_suggest_const_in_array_repeat_expressions_attribute;
4141

@@ -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 & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ use super::MoveDataParamEnv;
1111

1212
use crate::util::elaborate_drops::DropFlagState;
1313

14+
use super::generic::GenKill;
1415
use super::move_paths::{HasMoveData, InitIndex, InitKind, MoveData, MovePathIndex};
1516
use super::{BitDenotation, BottomValue, GenKillSet};
1617

@@ -235,7 +236,7 @@ impl<'a, 'tcx> HasMoveData<'tcx> for EverInitializedPlaces<'a, 'tcx> {
235236

236237
impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
237238
fn update_bits(
238-
trans: &mut GenKillSet<MovePathIndex>,
239+
trans: &mut impl GenKill<MovePathIndex>,
239240
path: MovePathIndex,
240241
state: DropFlagState,
241242
) {
@@ -272,39 +273,56 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
272273
}
273274
}
274275

275-
impl<'a, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
276+
impl<'tcx> super::generic::AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
276277
type Idx = MovePathIndex;
277-
fn name() -> &'static str {
278-
"maybe_init"
279-
}
280-
fn bits_per_block(&self) -> usize {
278+
279+
const NAME: &'static str = "maybe_init";
280+
281+
fn bits_per_block(&self, _: &mir::Body<'tcx>) -> usize {
281282
self.move_data().move_paths.len()
282283
}
283284

284-
fn start_block_effect(&self, entry_set: &mut BitSet<MovePathIndex>) {
285+
fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut BitSet<Self::Idx>) {
285286
drop_flag_effects_for_function_entry(self.tcx, self.body, self.mdpe, |path, s| {
286287
assert!(s == DropFlagState::Present);
287-
entry_set.insert(path);
288+
state.insert(path);
288289
});
289290
}
290291

291-
fn statement_effect(&self, trans: &mut GenKillSet<Self::Idx>, location: Location) {
292+
fn pretty_print_idx(&self, w: &mut impl std::io::Write, mpi: Self::Idx) -> std::io::Result<()> {
293+
write!(w, "{:?}", self.move_data().move_paths[mpi])
294+
}
295+
}
296+
297+
impl<'tcx> super::generic::GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
298+
fn statement_effect(
299+
&self,
300+
trans: &mut impl GenKill<Self::Idx>,
301+
_statement: &mir::Statement<'tcx>,
302+
location: Location,
303+
) {
292304
drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| {
293305
Self::update_bits(trans, path, s)
294306
})
295307
}
296308

297-
fn terminator_effect(&self, trans: &mut GenKillSet<Self::Idx>, location: Location) {
309+
fn terminator_effect(
310+
&self,
311+
trans: &mut impl GenKill<Self::Idx>,
312+
_terminator: &mir::Terminator<'tcx>,
313+
location: Location,
314+
) {
298315
drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| {
299316
Self::update_bits(trans, path, s)
300317
})
301318
}
302319

303-
fn propagate_call_return(
320+
fn call_return_effect(
304321
&self,
305-
in_out: &mut BitSet<MovePathIndex>,
306-
_call_bb: mir::BasicBlock,
307-
_dest_bb: mir::BasicBlock,
322+
trans: &mut impl GenKill<Self::Idx>,
323+
_block: mir::BasicBlock,
324+
_func: &mir::Operand<'tcx>,
325+
_args: &[mir::Operand<'tcx>],
308326
dest_place: &mir::Place<'tcx>,
309327
) {
310328
// when a call returns successfully, that means we need to set
@@ -315,7 +333,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeInitializedPlaces<'a, 'tcx> {
315333
self.move_data(),
316334
self.move_data().rev_lookup.find(dest_place.as_ref()),
317335
|mpi| {
318-
in_out.insert(mpi);
336+
trans.gen(mpi);
319337
},
320338
);
321339
}

src/librustc_mir/transform/elaborate_drops.rs

Lines changed: 12 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -1,3 +1,4 @@
1+
use crate::dataflow::generic::Results;
12
use crate::dataflow::move_paths::{HasMoveData, LookupResult, MoveData, MovePathIndex};
23
use crate::dataflow::DataflowResults;
34
use crate::dataflow::MoveDataParamEnv;
@@ -40,15 +41,15 @@ impl<'tcx> MirPass<'tcx> for ElaborateDrops {
4041
let body = &*body;
4142
let env = MoveDataParamEnv { move_data, param_env };
4243
let dead_unwinds = find_dead_unwinds(tcx, body, def_id, &env);
43-
let flow_inits = do_dataflow(
44+
let flow_inits = dataflow::generic::Engine::new_gen_kill(
4445
tcx,
4546
body,
4647
def_id,
47-
&[],
4848
&dead_unwinds,
4949
MaybeInitializedPlaces::new(tcx, body, &env),
50-
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]),
51-
);
50+
)
51+
.iterate_to_fixpoint();
52+
5253
let flow_uninits = do_dataflow(
5354
tcx,
5455
body,
@@ -87,15 +88,10 @@ fn find_dead_unwinds<'tcx>(
8788
// We only need to do this pass once, because unwind edges can only
8889
// reach cleanup blocks, which can't have unwind edges themselves.
8990
let mut dead_unwinds = BitSet::new_empty(body.basic_blocks().len());
90-
let flow_inits = do_dataflow(
91-
tcx,
92-
body,
93-
def_id,
94-
&[],
95-
&dead_unwinds,
96-
MaybeInitializedPlaces::new(tcx, body, &env),
97-
|bd, p| DebugFormatted::new(&bd.move_data().move_paths[p]),
98-
);
91+
let flow_inits = MaybeInitializedPlaces::new(tcx, body, &env);
92+
let flow_inits =
93+
dataflow::generic::Engine::new_gen_kill(tcx, body, def_id, &dead_unwinds, flow_inits)
94+
.iterate_to_fixpoint();
9995
for (bb, bb_data) in body.basic_blocks().iter_enumerated() {
10096
let location = match bb_data.terminator().kind {
10197
TerminatorKind::Drop { ref location, unwind: Some(_), .. }
@@ -104,7 +100,7 @@ fn find_dead_unwinds<'tcx>(
104100
};
105101

106102
let mut init_data = InitializationData {
107-
live: flow_inits.sets().entry_set_for(bb.index()).to_owned(),
103+
live: flow_inits.on_block_entry(bb).clone(),
108104
dead: BitSet::new_empty(env.move_data.move_paths.len()),
109105
};
110106
debug!("find_dead_unwinds @ {:?}: {:?}; init_data={:?}", bb, bb_data, init_data.live);
@@ -283,7 +279,7 @@ struct ElaborateDropsCtxt<'a, 'tcx> {
283279
tcx: TyCtxt<'tcx>,
284280
body: &'a Body<'tcx>,
285281
env: &'a MoveDataParamEnv<'tcx>,
286-
flow_inits: DataflowResults<'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
282+
flow_inits: Results<'tcx, MaybeInitializedPlaces<'a, 'tcx>>,
287283
flow_uninits: DataflowResults<'tcx, MaybeUninitializedPlaces<'a, 'tcx>>,
288284
drop_flags: FxHashMap<MovePathIndex, Local>,
289285
patch: MirPatch<'tcx>,
@@ -300,7 +296,7 @@ impl<'b, 'tcx> ElaborateDropsCtxt<'b, 'tcx> {
300296

301297
fn initialization_data_at(&self, loc: Location) -> InitializationData {
302298
let mut data = InitializationData {
303-
live: self.flow_inits.sets().entry_set_for(loc.block.index()).to_owned(),
299+
live: self.flow_inits.on_block_entry(loc.block).to_owned(),
304300
dead: self.flow_uninits.sets().entry_set_for(loc.block.index()).to_owned(),
305301
};
306302
for stmt in 0..loc.statement_index {

0 commit comments

Comments
 (0)