From 5496a1fbbe3facc09dfc23be80707905eb844a62 Mon Sep 17 00:00:00 2001 From: Dylan MacKenzie Date: Tue, 17 Sep 2019 17:22:05 -0700 Subject: [PATCH] Document new dataflow analysis --- src/librustc_mir/dataflow/generic.rs | 50 ++++++++++++++++++++++++++++ 1 file changed, 50 insertions(+) diff --git a/src/librustc_mir/dataflow/generic.rs b/src/librustc_mir/dataflow/generic.rs index 7819fd11845..696b44ac2ef 100644 --- a/src/librustc_mir/dataflow/generic.rs +++ b/src/librustc_mir/dataflow/generic.rs @@ -8,15 +8,48 @@ use crate::dataflow::BottomValue; +/// A specific kind of dataflow analysis. +/// +/// To run a dataflow analysis, one must set the initial state of the `START_BLOCK` via +/// `initialize_start_block` and define a transfer function for each statement or terminator via +/// the various `effect` methods. The entry set for all other basic blocks is initialized to +/// `Self::BOTTOM_VALUE`. The dataflow `Engine` then iteratively updates the various entry sets for +/// each block with the cumulative effects of the transfer functions of all preceding blocks. +/// +/// You should use an `Engine` to actually run an analysis, and a `ResultsCursor` to inspect the +/// results of that analysis like so: +/// +/// ```ignore +/// fn do_my_analysis(body: &mir::Body<'tcx>, dead_unwinds: &BitSet) { +/// let analysis = MyAnalysis::new(); +/// let results = Engine::new(body, dead_unwinds, analysis).iterate_to_fixpoint(); +/// let mut cursor = dataflow::ResultsCursor::new(body, results); +/// +/// for statement_index in body.block_data[START_BLOCK].statements.iter() { +/// cursor.seek_after(Location { block: START_BLOCK, statement_index }); +/// let state = cursor.get(); +/// println!("{:?}", state); +/// } +/// } +/// ``` pub trait Analysis<'tcx>: BottomValue { + /// The index type used to access the dataflow state. type Idx: Idx; + /// A name describing the dataflow analysis being implemented. + /// + /// The name should be suitable as part of a filename, so avoid whitespace, slashes or periods + /// and try to keep it short. fn name() -> &'static str; + /// The size of each bitvector allocated for each block. fn bits_per_block(&self, body: &mir::Body<'tcx>) -> usize; + /// Mutates the entry set of the `START_BLOCK` to containthe initial state for dataflow + /// analysis. fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut BitSet); + /// Updates the current dataflow state with the effect of evaluating a statement. fn apply_statement_effect( &self, state: &mut BitSet, @@ -24,6 +57,11 @@ fn apply_statement_effect( location: Location, ); + /// Updates the current dataflow state with the effect of evaluating a statement. + /// + /// Note that the effect of a successful return from a `Call` terminator should **not** be + /// acounted for in this function. That should go in `apply_call_return_effect`. For example, + /// in the `InitializedPlaces` analyses, the return place is not marked as initialized here. fn apply_terminator_effect( &self, state: &mut BitSet, @@ -31,6 +69,11 @@ fn apply_terminator_effect( location: Location, ); + /// Updates the current dataflow state with the effect of a successful return from a `Call` + /// terminator. + /// + /// This is separated from `apply_terminator_effect` to properly track state across + /// unwind edges for `Call`s. fn apply_call_return_effect( &self, state: &mut BitSet, @@ -117,6 +160,11 @@ fn block(&self) -> BasicBlock { } } +/// Inspect the results of dataflow analysis. +/// +/// This cursor has linear performance when visiting statements in a block in order. Visiting +/// statements within a block in reverse order is `O(n^2)`, where `n` is the number of statements +/// in that block. pub struct ResultsCursor<'mir, 'tcx, A> where A: Analysis<'tcx>, @@ -267,6 +315,7 @@ pub fn get(&self) -> &BitSet { } } +/// A completed dataflow analysis. pub struct Results<'tcx, A> where A: Analysis<'tcx>, @@ -275,6 +324,7 @@ pub struct Results<'tcx, A> entry_sets: IndexVec>, } +/// All information required to iterate a dataflow analysis to fixpoint. pub struct Engine<'a, 'tcx, A> where A: Analysis<'tcx>,