]> git.proxmox.com Git - rustc.git/blame - compiler/rustc_mir_dataflow/src/framework/visitor.rs
New upstream version 1.57.0+dfsg1
[rustc.git] / compiler / rustc_mir_dataflow / src / framework / visitor.rs
CommitLineData
ba9703b0 1use rustc_middle::mir::{self, BasicBlock, Location};
74b04a01 2
f9f354fc 3use super::{Analysis, Direction, Results};
74b04a01
XL
4
5/// Calls the corresponding method in `ResultsVisitor` for every location in a `mir::Body` with the
6/// dataflow state at that location.
f9f354fc 7pub fn visit_results<F, V>(
74b04a01
XL
8 body: &'mir mir::Body<'tcx>,
9 blocks: impl IntoIterator<Item = BasicBlock>,
f9f354fc 10 results: &V,
74b04a01 11 vis: &mut impl ResultsVisitor<'mir, 'tcx, FlowState = F>,
f9f354fc
XL
12) where
13 V: ResultsVisitable<'tcx, FlowState = F>,
14{
74b04a01
XL
15 let mut state = results.new_flow_state(body);
16
3dfed10e
XL
17 #[cfg(debug_assertions)]
18 let reachable_blocks = mir::traversal::reachable_as_bitset(body);
19
74b04a01 20 for block in blocks {
3dfed10e
XL
21 #[cfg(debug_assertions)]
22 assert!(reachable_blocks.contains(block));
23
74b04a01 24 let block_data = &body[block];
f9f354fc 25 V::Direction::visit_results_in_block(&mut state, block, block_data, results, vis);
74b04a01
XL
26 }
27}
28
29pub trait ResultsVisitor<'mir, 'tcx> {
30 type FlowState;
31
f9f354fc
XL
32 fn visit_block_start(
33 &mut self,
34 _state: &Self::FlowState,
35 _block_data: &'mir mir::BasicBlockData<'tcx>,
36 _block: BasicBlock,
37 ) {
38 }
39
74b04a01
XL
40 /// Called with the `before_statement_effect` of the given statement applied to `state` but not
41 /// its `statement_effect`.
f9f354fc 42 fn visit_statement_before_primary_effect(
74b04a01
XL
43 &mut self,
44 _state: &Self::FlowState,
45 _statement: &'mir mir::Statement<'tcx>,
46 _location: Location,
47 ) {
48 }
49
50 /// Called with both the `before_statement_effect` and the `statement_effect` of the given
51 /// statement applied to `state`.
f9f354fc 52 fn visit_statement_after_primary_effect(
74b04a01
XL
53 &mut self,
54 _state: &Self::FlowState,
55 _statement: &'mir mir::Statement<'tcx>,
56 _location: Location,
57 ) {
58 }
59
60 /// Called with the `before_terminator_effect` of the given terminator applied to `state` but not
61 /// its `terminator_effect`.
f9f354fc 62 fn visit_terminator_before_primary_effect(
74b04a01
XL
63 &mut self,
64 _state: &Self::FlowState,
65 _terminator: &'mir mir::Terminator<'tcx>,
66 _location: Location,
67 ) {
68 }
69
70 /// Called with both the `before_terminator_effect` and the `terminator_effect` of the given
71 /// terminator applied to `state`.
72 ///
73 /// The `call_return_effect` (if one exists) will *not* be applied to `state`.
f9f354fc 74 fn visit_terminator_after_primary_effect(
74b04a01
XL
75 &mut self,
76 _state: &Self::FlowState,
77 _terminator: &'mir mir::Terminator<'tcx>,
78 _location: Location,
79 ) {
80 }
f9f354fc
XL
81
82 fn visit_block_end(
83 &mut self,
84 _state: &Self::FlowState,
85 _block_data: &'mir mir::BasicBlockData<'tcx>,
86 _block: BasicBlock,
87 ) {
88 }
74b04a01
XL
89}
90
91/// Things that can be visited by a `ResultsVisitor`.
92///
93/// This trait exists so that we can visit the results of multiple dataflow analyses simultaneously.
94/// DO NOT IMPLEMENT MANUALLY. Instead, use the `impl_visitable` macro below.
95pub trait ResultsVisitable<'tcx> {
f9f354fc 96 type Direction: Direction;
74b04a01
XL
97 type FlowState;
98
99 /// Creates an empty `FlowState` to hold the transient state for these dataflow results.
100 ///
f9f354fc 101 /// The value of the newly created `FlowState` will be overwritten by `reset_to_block_entry`
74b04a01
XL
102 /// before it can be observed by a `ResultsVisitor`.
103 fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState;
104
f9f354fc 105 fn reset_to_block_entry(&self, state: &mut Self::FlowState, block: BasicBlock);
74b04a01
XL
106
107 fn reconstruct_before_statement_effect(
108 &self,
109 state: &mut Self::FlowState,
110 statement: &mir::Statement<'tcx>,
111 location: Location,
112 );
113
114 fn reconstruct_statement_effect(
115 &self,
116 state: &mut Self::FlowState,
117 statement: &mir::Statement<'tcx>,
118 location: Location,
119 );
120
121 fn reconstruct_before_terminator_effect(
122 &self,
123 state: &mut Self::FlowState,
124 terminator: &mir::Terminator<'tcx>,
125 location: Location,
126 );
127
128 fn reconstruct_terminator_effect(
129 &self,
130 state: &mut Self::FlowState,
131 terminator: &mir::Terminator<'tcx>,
132 location: Location,
133 );
134}
135
136impl<'tcx, A> ResultsVisitable<'tcx> for Results<'tcx, A>
137where
138 A: Analysis<'tcx>,
139{
1b1a35ee 140 type FlowState = A::Domain;
74b04a01 141
f9f354fc
XL
142 type Direction = A::Direction;
143
74b04a01 144 fn new_flow_state(&self, body: &mir::Body<'tcx>) -> Self::FlowState {
1b1a35ee 145 self.analysis.bottom_value(body)
74b04a01
XL
146 }
147
f9f354fc 148 fn reset_to_block_entry(&self, state: &mut Self::FlowState, block: BasicBlock) {
1b1a35ee 149 state.clone_from(&self.entry_set_for_block(block));
74b04a01
XL
150 }
151
152 fn reconstruct_before_statement_effect(
153 &self,
154 state: &mut Self::FlowState,
155 stmt: &mir::Statement<'tcx>,
156 loc: Location,
157 ) {
158 self.analysis.apply_before_statement_effect(state, stmt, loc);
159 }
160
161 fn reconstruct_statement_effect(
162 &self,
163 state: &mut Self::FlowState,
164 stmt: &mir::Statement<'tcx>,
165 loc: Location,
166 ) {
167 self.analysis.apply_statement_effect(state, stmt, loc);
168 }
169
170 fn reconstruct_before_terminator_effect(
171 &self,
172 state: &mut Self::FlowState,
173 term: &mir::Terminator<'tcx>,
174 loc: Location,
175 ) {
176 self.analysis.apply_before_terminator_effect(state, term, loc);
177 }
178
179 fn reconstruct_terminator_effect(
180 &self,
181 state: &mut Self::FlowState,
182 term: &mir::Terminator<'tcx>,
183 loc: Location,
184 ) {
185 self.analysis.apply_terminator_effect(state, term, loc);
186 }
187}