@@ -8,29 +8,72 @@ use rustc_data_structures::work_queue::WorkQueue;
8
8
9
9
use crate :: dataflow:: BottomValue ;
10
10
11
+ /// A specific kind of dataflow analysis.
12
+ ///
13
+ /// To run a dataflow analysis, one must set the initial state of the `START_BLOCK` via
14
+ /// `initialize_start_block` and define a transfer function for each statement or terminator via
15
+ /// the various `effect` methods. The entry set for all other basic blocks is initialized to
16
+ /// `Self::BOTTOM_VALUE`. The dataflow `Engine` then iteratively updates the various entry sets for
17
+ /// each block with the cumulative effects of the transfer functions of all preceding blocks.
18
+ ///
19
+ /// You should use an `Engine` to actually run an analysis, and a `ResultsCursor` to inspect the
20
+ /// results of that analysis like so:
21
+ ///
22
+ /// ```ignore
23
+ /// fn do_my_analysis(body: &mir::Body<'tcx>, dead_unwinds: &BitSet<BasicBlock>) {
24
+ /// let analysis = MyAnalysis::new();
25
+ /// let results = Engine::new(body, dead_unwinds, analysis).iterate_to_fixpoint();
26
+ /// let mut cursor = dataflow::ResultsCursor::new(body, results);
27
+ ///
28
+ /// for statement_index in body.block_data[START_BLOCK].statements.iter() {
29
+ /// cursor.seek_after(Location { block: START_BLOCK, statement_index });
30
+ /// let state = cursor.get();
31
+ /// println!("{:?}", state);
32
+ /// }
33
+ /// }
34
+ /// ```
11
35
pub trait Analysis < ' tcx > : BottomValue {
36
+ /// The index type used to access the dataflow state.
12
37
type Idx : Idx ;
13
38
39
+ /// A name describing the dataflow analysis being implemented.
40
+ ///
41
+ /// The name should be suitable as part of a filename, so avoid whitespace, slashes or periods
42
+ /// and try to keep it short.
14
43
fn name ( ) -> & ' static str ;
15
44
45
+ /// The size of each bitvector allocated for each block.
16
46
fn bits_per_block ( & self , body : & mir:: Body < ' tcx > ) -> usize ;
17
47
48
+ /// Mutates the entry set of the `START_BLOCK` to containthe initial state for dataflow
49
+ /// analysis.
18
50
fn initialize_start_block ( & self , body : & mir:: Body < ' tcx > , state : & mut BitSet < Self :: Idx > ) ;
19
51
52
+ /// Updates the current dataflow state with the effect of evaluating a statement.
20
53
fn apply_statement_effect (
21
54
& self ,
22
55
state : & mut BitSet < Self :: Idx > ,
23
56
statement : & mir:: Statement < ' tcx > ,
24
57
location : Location ,
25
58
) ;
26
59
60
+ /// Updates the current dataflow state with the effect of evaluating a statement.
61
+ ///
62
+ /// Note that the effect of a successful return from a `Call` terminator should **not** be
63
+ /// acounted for in this function. That should go in `apply_call_return_effect`. For example,
64
+ /// in the `InitializedPlaces` analyses, the return place is not marked as initialized here.
27
65
fn apply_terminator_effect (
28
66
& self ,
29
67
state : & mut BitSet < Self :: Idx > ,
30
68
terminator : & mir:: Terminator < ' tcx > ,
31
69
location : Location ,
32
70
) ;
33
71
72
+ /// Updates the current dataflow state with the effect of a successful return from a `Call`
73
+ /// terminator.
74
+ ///
75
+ /// This is separated from `apply_terminator_effect` to properly track state across
76
+ /// unwind edges for `Call`s.
34
77
fn apply_call_return_effect (
35
78
& self ,
36
79
state : & mut BitSet < Self :: Idx > ,
@@ -117,6 +160,11 @@ impl CursorPosition {
117
160
}
118
161
}
119
162
163
+ /// Inspect the results of dataflow analysis.
164
+ ///
165
+ /// This cursor has linear performance when visiting statements in a block in order. Visiting
166
+ /// statements within a block in reverse order is `O(n^2)`, where `n` is the number of statements
167
+ /// in that block.
120
168
pub struct ResultsCursor < ' mir , ' tcx , A >
121
169
where
122
170
A : Analysis < ' tcx > ,
@@ -267,6 +315,7 @@ where
267
315
}
268
316
}
269
317
318
+ /// A completed dataflow analysis.
270
319
pub struct Results < ' tcx , A >
271
320
where
272
321
A : Analysis < ' tcx > ,
@@ -275,6 +324,7 @@ where
275
324
entry_sets : IndexVec < BasicBlock , BitSet < A :: Idx > > ,
276
325
}
277
326
327
+ /// All information required to iterate a dataflow analysis to fixpoint.
278
328
pub struct Engine < ' a , ' tcx , A >
279
329
where
280
330
A : Analysis < ' tcx > ,
0 commit comments