Skip to content

Commit

Permalink
Add some useful comments.
Browse files Browse the repository at this point in the history
Describing some things that took me a long time to understand.
  • Loading branch information
nnethercote committed Nov 26, 2024
1 parent 0066acf commit 7e704af
Show file tree
Hide file tree
Showing 5 changed files with 24 additions and 12 deletions.
14 changes: 9 additions & 5 deletions compiler/rustc_mir_dataflow/src/framework/cursor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,12 +8,16 @@ use rustc_middle::mir::{self, BasicBlock, Location};

use super::{Analysis, Direction, Effect, EffectIndex, Results};

/// Allows random access inspection of the results of a dataflow analysis.
/// Allows random access inspection of the results of a dataflow analysis. Use this when you want
/// to inspect domain values only in certain locations; use `ResultsVisitor` if you want to inspect
/// domain values in many or all locations.
///
/// This cursor only has linear performance within a basic block when its statements are visited in
/// the same order as the `DIRECTION` of the analysis. In the worst case—when statements are
/// visited in *reverse* order—performance will be quadratic in the number of statements in the
/// block. The order in which basic blocks are inspected has no impact on performance.
/// Because `Results` only has domain values for the entry of each basic block, these inspections
/// involve some amount of domain value recomputations. This cursor only has linear performance
/// within a basic block when its statements are visited in the same order as the `DIRECTION` of
/// the analysis. In the worst case—when statements are visited in *reverse* order—performance will
/// be quadratic in the number of statements in the block. The order in which basic blocks are
/// inspected has no impact on performance.
pub struct ResultsCursor<'mir, 'tcx, A>
where
A: Analysis<'tcx>,
Expand Down
9 changes: 6 additions & 3 deletions compiler/rustc_mir_dataflow/src/framework/direction.rs
Original file line number Diff line number Diff line change
Expand Up @@ -9,9 +9,9 @@ use super::{Analysis, Effect, EffectIndex, Results, SwitchIntTarget};

pub trait Direction {
const IS_FORWARD: bool;

const IS_BACKWARD: bool = !Self::IS_FORWARD;

/// Called by `iterate_to_fixpoint` during initial analysis computation.
fn apply_effects_in_block<'mir, 'tcx, A>(
analysis: &mut A,
body: &mir::Body<'tcx>,
Expand All @@ -22,7 +22,8 @@ pub trait Direction {
) where
A: Analysis<'tcx>;

/// Applies all effects between the given `EffectIndex`s.
/// Called by `ResultsCursor` to recompute the domain value for a location
/// in a basic block. Applies all effects between the given `EffectIndex`s.
///
/// `effects.start()` must precede or equal `effects.end()` in this direction.
fn apply_effects_in_range<'tcx, A>(
Expand All @@ -34,6 +35,9 @@ pub trait Direction {
) where
A: Analysis<'tcx>;

/// Called by `ResultsVisitor` to recompute the analysis domain values for
/// all locations in a basic block (starting from the entry value stored
/// in `Results`) and to visit them with `vis`.
fn visit_results_in_block<'mir, 'tcx, A>(
state: &mut A::Domain,
block: BasicBlock,
Expand Down Expand Up @@ -222,7 +226,6 @@ impl Direction for Backward {

vis.visit_block_end(state);

// Terminator
let loc = Location { block, statement_index: block_data.statements.len() };
let term = block_data.terminator();
results.analysis.apply_before_terminator_effect(state, term, loc);
Expand Down
5 changes: 3 additions & 2 deletions compiler/rustc_mir_dataflow/src/framework/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -8,8 +8,9 @@
//! The `impls` module contains several examples of dataflow analyses.
//!
//! Then call `iterate_to_fixpoint` on your type that impls `Analysis` to get a `Results`. From
//! there, you can use a `ResultsCursor` to inspect the fixpoint solution to your dataflow problem,
//! or implement the `ResultsVisitor` interface and use `visit_results`. The following example uses
//! there, you can use a `ResultsCursor` to inspect the fixpoint solution to your dataflow problem
//! (good for inspecting a small number of locations), or implement the `ResultsVisitor` interface
//! and use `visit_results` (good for inspecting many or all locations). The following example uses
//! the `ResultsCursor` approach.
//!
//! ```ignore (cross-crate-imports)
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir_dataflow/src/framework/results.rs
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,9 @@ use crate::errors::{

pub type EntrySets<'tcx, A> = IndexVec<BasicBlock, <A as Analysis<'tcx>>::Domain>;

/// A dataflow analysis that has converged to fixpoint.
/// A dataflow analysis that has converged to fixpoint. It only holds the domain values at the
/// entry of each basic block. Domain values in other parts of the block are recomputed on the fly
/// by visitors (i.e. `ResultsCursor`, or `ResultsVisitor` impls).
#[derive(Clone)]
pub struct Results<'tcx, A>
where
Expand Down
4 changes: 3 additions & 1 deletion compiler/rustc_mir_dataflow/src/framework/visitor.rs
Original file line number Diff line number Diff line change
Expand Up @@ -26,7 +26,9 @@ pub fn visit_results<'mir, 'tcx, A>(
}
}

/// A visitor over the results of an `Analysis`.
/// A visitor over the results of an `Analysis`. Use this when you want to inspect domain values in
/// many or all locations; use `ResultsCursor` if you want to inspect domain values only in certain
/// locations.
pub trait ResultsVisitor<'mir, 'tcx, A>
where
A: Analysis<'tcx>,
Expand Down

0 comments on commit 7e704af

Please sign in to comment.