Skip to content

Commit c500b5d

Browse files
Use new dataflow interface for all "initialized locals" analyses
1 parent dd940c9 commit c500b5d

File tree

1 file changed

+110
-63
lines changed
  • src/librustc_mir/dataflow/impls

1 file changed

+110
-63
lines changed

src/librustc_mir/dataflow/impls/mod.rs

Lines changed: 110 additions & 63 deletions
Original file line numberDiff line numberDiff line change
@@ -11,9 +11,9 @@ use super::MoveDataParamEnv;
1111

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

14-
use super::generic::GenKill;
14+
use super::generic::{AnalysisDomain, GenKill, GenKillAnalysis};
1515
use super::move_paths::{HasMoveData, InitIndex, InitKind, MoveData, MovePathIndex};
16-
use super::{BitDenotation, BottomValue, GenKillSet};
16+
use super::{BottomValue, GenKillSet};
1717

1818
use super::drop_flag_effects_for_function_entry;
1919
use super::drop_flag_effects_for_location;
@@ -217,6 +217,7 @@ impl<'a, 'tcx> HasMoveData<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
217217
/// }
218218
/// ```
219219
pub struct EverInitializedPlaces<'a, 'tcx> {
220+
#[allow(dead_code)]
220221
tcx: TyCtxt<'tcx>,
221222
body: &'a Body<'tcx>,
222223
mdpe: &'a MoveDataParamEnv<'tcx>,
@@ -249,7 +250,7 @@ impl<'a, 'tcx> MaybeInitializedPlaces<'a, 'tcx> {
249250

250251
impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
251252
fn update_bits(
252-
trans: &mut GenKillSet<MovePathIndex>,
253+
trans: &mut impl GenKill<MovePathIndex>,
253254
path: MovePathIndex,
254255
state: DropFlagState,
255256
) {
@@ -262,7 +263,7 @@ impl<'a, 'tcx> MaybeUninitializedPlaces<'a, 'tcx> {
262263

263264
impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
264265
fn update_bits(
265-
trans: &mut GenKillSet<MovePathIndex>,
266+
trans: &mut impl GenKill<MovePathIndex>,
266267
path: MovePathIndex,
267268
state: DropFlagState,
268269
) {
@@ -273,7 +274,7 @@ impl<'a, 'tcx> DefinitelyInitializedPlaces<'a, 'tcx> {
273274
}
274275
}
275276

276-
impl<'tcx> super::generic::AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
277+
impl<'tcx> AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
277278
type Idx = MovePathIndex;
278279

279280
const NAME: &'static str = "maybe_init";
@@ -294,7 +295,7 @@ impl<'tcx> super::generic::AnalysisDomain<'tcx> for MaybeInitializedPlaces<'_, '
294295
}
295296
}
296297

297-
impl<'tcx> super::generic::GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
298+
impl<'tcx> GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_, 'tcx> {
298299
fn statement_effect(
299300
&self,
300301
trans: &mut impl GenKill<Self::Idx>,
@@ -339,44 +340,61 @@ impl<'tcx> super::generic::GenKillAnalysis<'tcx> for MaybeInitializedPlaces<'_,
339340
}
340341
}
341342

342-
impl<'a, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> {
343+
impl<'tcx> AnalysisDomain<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
343344
type Idx = MovePathIndex;
344-
fn name() -> &'static str {
345-
"maybe_uninit"
346-
}
347-
fn bits_per_block(&self) -> usize {
345+
346+
const NAME: &'static str = "maybe_uninit";
347+
348+
fn bits_per_block(&self, _: &mir::Body<'tcx>) -> usize {
348349
self.move_data().move_paths.len()
349350
}
350351

351352
// sets on_entry bits for Arg places
352-
fn start_block_effect(&self, entry_set: &mut BitSet<MovePathIndex>) {
353+
fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut BitSet<Self::Idx>) {
353354
// set all bits to 1 (uninit) before gathering counterevidence
354-
assert!(self.bits_per_block() == entry_set.domain_size());
355-
entry_set.insert_all();
355+
assert!(self.bits_per_block(body) == state.domain_size());
356+
state.insert_all();
356357

357358
drop_flag_effects_for_function_entry(self.tcx, self.body, self.mdpe, |path, s| {
358359
assert!(s == DropFlagState::Present);
359-
entry_set.remove(path);
360+
state.remove(path);
360361
});
361362
}
362363

363-
fn statement_effect(&self, trans: &mut GenKillSet<Self::Idx>, location: Location) {
364+
fn pretty_print_idx(&self, w: &mut impl std::io::Write, mpi: Self::Idx) -> std::io::Result<()> {
365+
write!(w, "{:?}", self.move_data().move_paths[mpi])
366+
}
367+
}
368+
369+
impl<'tcx> GenKillAnalysis<'tcx> for MaybeUninitializedPlaces<'_, 'tcx> {
370+
fn statement_effect(
371+
&self,
372+
trans: &mut impl GenKill<Self::Idx>,
373+
_statement: &mir::Statement<'tcx>,
374+
location: Location,
375+
) {
364376
drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| {
365377
Self::update_bits(trans, path, s)
366378
})
367379
}
368380

369-
fn terminator_effect(&self, trans: &mut GenKillSet<Self::Idx>, location: Location) {
381+
fn terminator_effect(
382+
&self,
383+
trans: &mut impl GenKill<Self::Idx>,
384+
_terminator: &mir::Terminator<'tcx>,
385+
location: Location,
386+
) {
370387
drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| {
371388
Self::update_bits(trans, path, s)
372389
})
373390
}
374391

375-
fn propagate_call_return(
392+
fn call_return_effect(
376393
&self,
377-
in_out: &mut BitSet<MovePathIndex>,
378-
_call_bb: mir::BasicBlock,
379-
_dest_bb: mir::BasicBlock,
394+
trans: &mut impl GenKill<Self::Idx>,
395+
_block: mir::BasicBlock,
396+
_func: &mir::Operand<'tcx>,
397+
_args: &[mir::Operand<'tcx>],
380398
dest_place: &mir::Place<'tcx>,
381399
) {
382400
// when a call returns successfully, that means we need to set
@@ -387,48 +405,65 @@ impl<'a, 'tcx> BitDenotation<'tcx> for MaybeUninitializedPlaces<'a, 'tcx> {
387405
self.move_data(),
388406
self.move_data().rev_lookup.find(dest_place.as_ref()),
389407
|mpi| {
390-
in_out.remove(mpi);
408+
trans.kill(mpi);
391409
},
392410
);
393411
}
394412
}
395413

396-
impl<'a, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
414+
impl<'a, 'tcx> AnalysisDomain<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
397415
type Idx = MovePathIndex;
398-
fn name() -> &'static str {
399-
"definite_init"
400-
}
401-
fn bits_per_block(&self) -> usize {
416+
417+
const NAME: &'static str = "definite_init";
418+
419+
fn bits_per_block(&self, _: &mir::Body<'tcx>) -> usize {
402420
self.move_data().move_paths.len()
403421
}
404422

405423
// sets on_entry bits for Arg places
406-
fn start_block_effect(&self, entry_set: &mut BitSet<MovePathIndex>) {
407-
entry_set.clear();
424+
fn initialize_start_block(&self, _: &mir::Body<'tcx>, state: &mut BitSet<Self::Idx>) {
425+
state.clear();
408426

409427
drop_flag_effects_for_function_entry(self.tcx, self.body, self.mdpe, |path, s| {
410428
assert!(s == DropFlagState::Present);
411-
entry_set.insert(path);
429+
state.insert(path);
412430
});
413431
}
414432

415-
fn statement_effect(&self, trans: &mut GenKillSet<Self::Idx>, location: Location) {
433+
fn pretty_print_idx(&self, w: &mut impl std::io::Write, mpi: Self::Idx) -> std::io::Result<()> {
434+
write!(w, "{:?}", self.move_data().move_paths[mpi])
435+
}
436+
}
437+
438+
impl<'tcx> GenKillAnalysis<'tcx> for DefinitelyInitializedPlaces<'_, 'tcx> {
439+
fn statement_effect(
440+
&self,
441+
trans: &mut impl GenKill<Self::Idx>,
442+
_statement: &mir::Statement<'tcx>,
443+
location: Location,
444+
) {
416445
drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| {
417446
Self::update_bits(trans, path, s)
418447
})
419448
}
420449

421-
fn terminator_effect(&self, trans: &mut GenKillSet<Self::Idx>, location: Location) {
450+
fn terminator_effect(
451+
&self,
452+
trans: &mut impl GenKill<Self::Idx>,
453+
_terminator: &mir::Terminator<'tcx>,
454+
location: Location,
455+
) {
422456
drop_flag_effects_for_location(self.tcx, self.body, self.mdpe, location, |path, s| {
423457
Self::update_bits(trans, path, s)
424458
})
425459
}
426460

427-
fn propagate_call_return(
461+
fn call_return_effect(
428462
&self,
429-
in_out: &mut BitSet<MovePathIndex>,
430-
_call_bb: mir::BasicBlock,
431-
_dest_bb: mir::BasicBlock,
463+
trans: &mut impl GenKill<Self::Idx>,
464+
_block: mir::BasicBlock,
465+
_func: &mir::Operand<'tcx>,
466+
_args: &[mir::Operand<'tcx>],
432467
dest_place: &mir::Place<'tcx>,
433468
) {
434469
// when a call returns successfully, that means we need to set
@@ -439,30 +474,36 @@ impl<'a, 'tcx> BitDenotation<'tcx> for DefinitelyInitializedPlaces<'a, 'tcx> {
439474
self.move_data(),
440475
self.move_data().rev_lookup.find(dest_place.as_ref()),
441476
|mpi| {
442-
in_out.insert(mpi);
477+
trans.gen(mpi);
443478
},
444479
);
445480
}
446481
}
447482

448-
impl<'a, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'tcx> {
483+
impl<'tcx> AnalysisDomain<'tcx> for EverInitializedPlaces<'_, 'tcx> {
449484
type Idx = InitIndex;
450-
fn name() -> &'static str {
451-
"ever_init"
452-
}
453-
fn bits_per_block(&self) -> usize {
485+
486+
const NAME: &'static str = "ever_init";
487+
488+
fn bits_per_block(&self, _: &mir::Body<'tcx>) -> usize {
454489
self.move_data().inits.len()
455490
}
456491

457-
fn start_block_effect(&self, entry_set: &mut BitSet<InitIndex>) {
458-
for arg_init in 0..self.body.arg_count {
459-
entry_set.insert(InitIndex::new(arg_init));
492+
fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut BitSet<Self::Idx>) {
493+
for arg_init in 0..body.arg_count {
494+
state.insert(InitIndex::new(arg_init));
460495
}
461496
}
497+
}
462498

463-
fn statement_effect(&self, trans: &mut GenKillSet<Self::Idx>, location: Location) {
464-
let (_, body, move_data) = (self.tcx, self.body, self.move_data());
465-
let stmt = &body[location.block].statements[location.statement_index];
499+
impl<'tcx> GenKillAnalysis<'tcx> for EverInitializedPlaces<'_, 'tcx> {
500+
fn statement_effect(
501+
&self,
502+
trans: &mut impl GenKill<Self::Idx>,
503+
stmt: &mir::Statement<'tcx>,
504+
location: Location,
505+
) {
506+
let move_data = self.move_data();
466507
let init_path_map = &move_data.init_path_map;
467508
let init_loc_map = &move_data.init_loc_map;
468509
let rev_lookup = &move_data.rev_lookup;
@@ -471,7 +512,7 @@ impl<'a, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'tcx> {
471512
"statement {:?} at loc {:?} initializes move_indexes {:?}",
472513
stmt, location, &init_loc_map[location]
473514
);
474-
trans.gen_all(&init_loc_map[location]);
515+
trans.gen_all(init_loc_map[location].iter().copied());
475516

476517
match stmt.kind {
477518
mir::StatementKind::StorageDead(local) => {
@@ -482,13 +523,18 @@ impl<'a, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'tcx> {
482523
"stmt {:?} at loc {:?} clears the ever initialized status of {:?}",
483524
stmt, location, &init_path_map[move_path_index]
484525
);
485-
trans.kill_all(&init_path_map[move_path_index]);
526+
trans.kill_all(init_path_map[move_path_index].iter().copied());
486527
}
487528
_ => {}
488529
}
489530
}
490531

491-
fn terminator_effect(&self, trans: &mut GenKillSet<Self::Idx>, location: Location) {
532+
fn terminator_effect(
533+
&self,
534+
trans: &mut impl GenKill<Self::Idx>,
535+
_terminator: &mir::Terminator<'tcx>,
536+
location: Location,
537+
) {
492538
let (body, move_data) = (self.body, self.move_data());
493539
let term = body[location.block].terminator();
494540
let init_loc_map = &move_data.init_loc_map;
@@ -497,28 +543,29 @@ impl<'a, 'tcx> BitDenotation<'tcx> for EverInitializedPlaces<'a, 'tcx> {
497543
term, location, &init_loc_map[location]
498544
);
499545
trans.gen_all(
500-
init_loc_map[location].iter().filter(|init_index| {
501-
move_data.inits[**init_index].kind != InitKind::NonPanicPathOnly
502-
}),
546+
init_loc_map[location]
547+
.iter()
548+
.filter(|init_index| {
549+
move_data.inits[**init_index].kind != InitKind::NonPanicPathOnly
550+
})
551+
.copied(),
503552
);
504553
}
505554

506-
fn propagate_call_return(
555+
fn call_return_effect(
507556
&self,
508-
in_out: &mut BitSet<InitIndex>,
509-
call_bb: mir::BasicBlock,
510-
_dest_bb: mir::BasicBlock,
557+
trans: &mut impl GenKill<Self::Idx>,
558+
block: mir::BasicBlock,
559+
_func: &mir::Operand<'tcx>,
560+
_args: &[mir::Operand<'tcx>],
511561
_dest_place: &mir::Place<'tcx>,
512562
) {
513563
let move_data = self.move_data();
514-
let bits_per_block = self.bits_per_block();
515564
let init_loc_map = &move_data.init_loc_map;
516565

517-
let call_loc =
518-
Location { block: call_bb, statement_index: self.body[call_bb].statements.len() };
566+
let call_loc = self.body.terminator_loc(block);
519567
for init_index in &init_loc_map[call_loc] {
520-
assert!(init_index.index() < bits_per_block);
521-
in_out.insert(*init_index);
568+
trans.gen(*init_index);
522569
}
523570
}
524571
}

0 commit comments

Comments
 (0)