rustc_mir_dataflow/framework/
visitor.rs1use rustc_middle::mir::{self, BasicBlock, Location, traversal};
2
3use super::{Analysis, Direction, Results};
4
5pub fn visit_results<'mir, 'tcx, A>(
8 body: &'mir mir::Body<'tcx>,
9 blocks: impl IntoIterator<Item = BasicBlock>,
10 results: &Results<'tcx, A>,
11 vis: &mut impl ResultsVisitor<'tcx, A>,
12) where
13 A: Analysis<'tcx>,
14{
15 let mut state = results.analysis.bottom_value(body);
16
17 #[cfg(debug_assertions)]
18 let reachable_blocks = mir::traversal::reachable_as_bitset(body);
19
20 for block in blocks {
21 #[cfg(debug_assertions)]
22 assert!(reachable_blocks.contains(block));
23
24 let block_data = &body[block];
25 state.clone_from(&results.entry_states[block]);
26 A::Direction::visit_results_in_block(&results.analysis, &mut state, block, block_data, vis);
27 }
28}
29
30pub fn visit_reachable_results<'mir, 'tcx, A>(
32 body: &'mir mir::Body<'tcx>,
33 results: &Results<'tcx, A>,
34 vis: &mut impl ResultsVisitor<'tcx, A>,
35) where
36 A: Analysis<'tcx>,
37{
38 let blocks = traversal::reachable(body).map(|(bb, _)| bb);
39 visit_results(body, blocks, results, vis)
40}
41
42pub trait ResultsVisitor<'tcx, A>
46where
47 A: Analysis<'tcx>,
48{
49 fn visit_block_start(&mut self, _state: &A::Domain) {}
50
51 fn visit_after_early_statement_effect(
53 &mut self,
54 _analysis: &A,
55 _state: &A::Domain,
56 _statement: &mir::Statement<'tcx>,
57 _location: Location,
58 ) {
59 }
60
61 fn visit_after_primary_statement_effect(
63 &mut self,
64 _analysis: &A,
65 _state: &A::Domain,
66 _statement: &mir::Statement<'tcx>,
67 _location: Location,
68 ) {
69 }
70
71 fn visit_after_early_terminator_effect(
73 &mut self,
74 _analysis: &A,
75 _state: &A::Domain,
76 _terminator: &mir::Terminator<'tcx>,
77 _location: Location,
78 ) {
79 }
80
81 fn visit_after_primary_terminator_effect(
85 &mut self,
86 _analysis: &A,
87 _state: &A::Domain,
88 _terminator: &mir::Terminator<'tcx>,
89 _location: Location,
90 ) {
91 }
92
93 fn visit_block_end(&mut self, _state: &A::Domain) {}
94}