Skip to content

Commit 5496a1f

Browse files
Document new dataflow analysis
1 parent ceb72e4 commit 5496a1f

File tree

1 file changed

+50
-0
lines changed

1 file changed

+50
-0
lines changed

src/librustc_mir/dataflow/generic.rs

+50
Original file line numberDiff line numberDiff line change
@@ -8,29 +8,72 @@ use rustc_data_structures::work_queue::WorkQueue;
88

99
use crate::dataflow::BottomValue;
1010

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+
/// ```
1135
pub trait Analysis<'tcx>: BottomValue {
36+
/// The index type used to access the dataflow state.
1237
type Idx: Idx;
1338

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.
1443
fn name() -> &'static str;
1544

45+
/// The size of each bitvector allocated for each block.
1646
fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize;
1747

48+
/// Mutates the entry set of the `START_BLOCK` to containthe initial state for dataflow
49+
/// analysis.
1850
fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut BitSet<Self::Idx>);
1951

52+
/// Updates the current dataflow state with the effect of evaluating a statement.
2053
fn apply_statement_effect(
2154
&self,
2255
state: &mut BitSet<Self::Idx>,
2356
statement: &mir::Statement<'tcx>,
2457
location: Location,
2558
);
2659

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.
2765
fn apply_terminator_effect(
2866
&self,
2967
state: &mut BitSet<Self::Idx>,
3068
terminator: &mir::Terminator<'tcx>,
3169
location: Location,
3270
);
3371

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.
3477
fn apply_call_return_effect(
3578
&self,
3679
state: &mut BitSet<Self::Idx>,
@@ -117,6 +160,11 @@ impl CursorPosition {
117160
}
118161
}
119162

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.
120168
pub struct ResultsCursor<'mir, 'tcx, A>
121169
where
122170
A: Analysis<'tcx>,
@@ -267,6 +315,7 @@ where
267315
}
268316
}
269317

318+
/// A completed dataflow analysis.
270319
pub struct Results<'tcx, A>
271320
where
272321
A: Analysis<'tcx>,
@@ -275,6 +324,7 @@ where
275324
entry_sets: IndexVec<BasicBlock, BitSet<A::Idx>>,
276325
}
277326

327+
/// All information required to iterate a dataflow analysis to fixpoint.
278328
pub struct Engine<'a, 'tcx, A>
279329
where
280330
A: Analysis<'tcx>,

0 commit comments

Comments
 (0)