Rollup merge of #133938 - nnethercote:rustc_mir_dataflow-renamings, r=oli-obk

`rustc_mir_dataflow` cleanups, including some renamings

Some opinionated commits in this collection, let's see how we go.

r? `@cjgillot`
This commit is contained in:
Matthias Krüger
2024-12-13 17:25:29 +01:00
committed by GitHub
23 changed files with 362 additions and 424 deletions

View File

@@ -179,15 +179,15 @@ where
/// Advances the cursor to hold the dataflow state at `target` before its "primary" effect is
/// applied.
///
/// The "before" effect at the target location *will be* applied.
/// The "early" effect at the target location *will be* applied.
pub fn seek_before_primary_effect(&mut self, target: Location) {
self.seek_after(target, Effect::Before)
self.seek_after(target, Effect::Early)
}
/// Advances the cursor to hold the dataflow state at `target` after its "primary" effect is
/// applied.
///
/// The "before" effect at the target location will be applied as well.
/// The "early" effect at the target location will be applied as well.
pub fn seek_after_primary_effect(&mut self, target: Location) {
self.seek_after(target, Effect::Primary)
}
@@ -222,12 +222,12 @@ where
#[rustfmt::skip]
let next_effect = if A::Direction::IS_FORWARD {
self.pos.curr_effect_index.map_or_else(
|| Effect::Before.at_index(0),
|| Effect::Early.at_index(0),
EffectIndex::next_in_forward_order,
)
} else {
self.pos.curr_effect_index.map_or_else(
|| Effect::Before.at_index(block_data.statements.len()),
|| Effect::Early.at_index(block_data.statements.len()),
EffectIndex::next_in_backward_order,
)
};

View File

@@ -66,12 +66,12 @@ impl Direction for Backward {
{
let terminator = block_data.terminator();
let location = Location { block, statement_index: block_data.statements.len() };
analysis.apply_before_terminator_effect(state, terminator, location);
analysis.apply_terminator_effect(state, terminator, location);
analysis.apply_early_terminator_effect(state, terminator, location);
analysis.apply_primary_terminator_effect(state, terminator, location);
for (statement_index, statement) in block_data.statements.iter().enumerate().rev() {
let location = Location { block, statement_index };
analysis.apply_before_statement_effect(state, statement, location);
analysis.apply_statement_effect(state, statement, location);
analysis.apply_early_statement_effect(state, statement, location);
analysis.apply_primary_statement_effect(state, statement, location);
}
let exit_state = state;
@@ -159,14 +159,14 @@ impl Direction for Backward {
let location = Location { block, statement_index: from.statement_index };
let terminator = block_data.terminator();
if from.effect == Effect::Before {
analysis.apply_before_terminator_effect(state, terminator, location);
if to == Effect::Before.at_index(terminator_index) {
if from.effect == Effect::Early {
analysis.apply_early_terminator_effect(state, terminator, location);
if to == Effect::Early.at_index(terminator_index) {
return;
}
}
analysis.apply_terminator_effect(state, terminator, location);
analysis.apply_primary_terminator_effect(state, terminator, location);
if to == Effect::Primary.at_index(terminator_index) {
return;
}
@@ -180,7 +180,7 @@ impl Direction for Backward {
let location = Location { block, statement_index: from.statement_index };
let statement = &block_data.statements[from.statement_index];
analysis.apply_statement_effect(state, statement, location);
analysis.apply_primary_statement_effect(state, statement, location);
if to == Effect::Primary.at_index(from.statement_index) {
return;
}
@@ -188,7 +188,7 @@ impl Direction for Backward {
from.statement_index - 1
}
Effect::Before => from.statement_index,
Effect::Early => from.statement_index,
};
// Handle all statements between `first_unapplied_idx` and `to.statement_index`.
@@ -196,21 +196,21 @@ impl Direction for Backward {
for statement_index in (to.statement_index..next_effect).rev().map(|i| i + 1) {
let location = Location { block, statement_index };
let statement = &block_data.statements[statement_index];
analysis.apply_before_statement_effect(state, statement, location);
analysis.apply_statement_effect(state, statement, location);
analysis.apply_early_statement_effect(state, statement, location);
analysis.apply_primary_statement_effect(state, statement, location);
}
// Handle the statement at `to`.
let location = Location { block, statement_index: to.statement_index };
let statement = &block_data.statements[to.statement_index];
analysis.apply_before_statement_effect(state, statement, location);
analysis.apply_early_statement_effect(state, statement, location);
if to.effect == Effect::Before {
if to.effect == Effect::Early {
return;
}
analysis.apply_statement_effect(state, statement, location);
analysis.apply_primary_statement_effect(state, statement, location);
}
fn visit_results_in_block<'mir, 'tcx, A>(
@@ -228,17 +228,17 @@ impl Direction for Backward {
let loc = Location { block, statement_index: block_data.statements.len() };
let term = block_data.terminator();
results.analysis.apply_before_terminator_effect(state, term, loc);
vis.visit_terminator_before_primary_effect(results, state, term, loc);
results.analysis.apply_terminator_effect(state, term, loc);
vis.visit_terminator_after_primary_effect(results, state, term, loc);
results.analysis.apply_early_terminator_effect(state, term, loc);
vis.visit_after_early_terminator_effect(results, state, term, loc);
results.analysis.apply_primary_terminator_effect(state, term, loc);
vis.visit_after_primary_terminator_effect(results, state, term, loc);
for (statement_index, stmt) in block_data.statements.iter().enumerate().rev() {
let loc = Location { block, statement_index };
results.analysis.apply_before_statement_effect(state, stmt, loc);
vis.visit_statement_before_primary_effect(results, state, stmt, loc);
results.analysis.apply_statement_effect(state, stmt, loc);
vis.visit_statement_after_primary_effect(results, state, stmt, loc);
results.analysis.apply_early_statement_effect(state, stmt, loc);
vis.visit_after_early_statement_effect(results, state, stmt, loc);
results.analysis.apply_primary_statement_effect(state, stmt, loc);
vis.visit_after_primary_statement_effect(results, state, stmt, loc);
}
vis.visit_block_start(state);
@@ -294,13 +294,13 @@ impl Direction for Forward {
{
for (statement_index, statement) in block_data.statements.iter().enumerate() {
let location = Location { block, statement_index };
analysis.apply_before_statement_effect(state, statement, location);
analysis.apply_statement_effect(state, statement, location);
analysis.apply_early_statement_effect(state, statement, location);
analysis.apply_primary_statement_effect(state, statement, location);
}
let terminator = block_data.terminator();
let location = Location { block, statement_index: block_data.statements.len() };
analysis.apply_before_terminator_effect(state, terminator, location);
let edges = analysis.apply_terminator_effect(state, terminator, location);
analysis.apply_early_terminator_effect(state, terminator, location);
let edges = analysis.apply_primary_terminator_effect(state, terminator, location);
let exit_state = state;
match edges {
@@ -368,21 +368,21 @@ impl Direction for Forward {
// after effect, do so now and start the loop below from the next statement.
let first_unapplied_index = match from.effect {
Effect::Before => from.statement_index,
Effect::Early => from.statement_index,
Effect::Primary if from.statement_index == terminator_index => {
debug_assert_eq!(from, to);
let location = Location { block, statement_index: terminator_index };
let terminator = block_data.terminator();
analysis.apply_terminator_effect(state, terminator, location);
analysis.apply_primary_terminator_effect(state, terminator, location);
return;
}
Effect::Primary => {
let location = Location { block, statement_index: from.statement_index };
let statement = &block_data.statements[from.statement_index];
analysis.apply_statement_effect(state, statement, location);
analysis.apply_primary_statement_effect(state, statement, location);
// If we only needed to apply the after effect of the statement at `idx`, we are
// done.
@@ -399,8 +399,8 @@ impl Direction for Forward {
for statement_index in first_unapplied_index..to.statement_index {
let location = Location { block, statement_index };
let statement = &block_data.statements[statement_index];
analysis.apply_before_statement_effect(state, statement, location);
analysis.apply_statement_effect(state, statement, location);
analysis.apply_early_statement_effect(state, statement, location);
analysis.apply_primary_statement_effect(state, statement, location);
}
// Handle the statement or terminator at `to`.
@@ -408,17 +408,17 @@ impl Direction for Forward {
let location = Location { block, statement_index: to.statement_index };
if to.statement_index == terminator_index {
let terminator = block_data.terminator();
analysis.apply_before_terminator_effect(state, terminator, location);
analysis.apply_early_terminator_effect(state, terminator, location);
if to.effect == Effect::Primary {
analysis.apply_terminator_effect(state, terminator, location);
analysis.apply_primary_terminator_effect(state, terminator, location);
}
} else {
let statement = &block_data.statements[to.statement_index];
analysis.apply_before_statement_effect(state, statement, location);
analysis.apply_early_statement_effect(state, statement, location);
if to.effect == Effect::Primary {
analysis.apply_statement_effect(state, statement, location);
analysis.apply_primary_statement_effect(state, statement, location);
}
}
}
@@ -438,18 +438,18 @@ impl Direction for Forward {
for (statement_index, stmt) in block_data.statements.iter().enumerate() {
let loc = Location { block, statement_index };
results.analysis.apply_before_statement_effect(state, stmt, loc);
vis.visit_statement_before_primary_effect(results, state, stmt, loc);
results.analysis.apply_statement_effect(state, stmt, loc);
vis.visit_statement_after_primary_effect(results, state, stmt, loc);
results.analysis.apply_early_statement_effect(state, stmt, loc);
vis.visit_after_early_statement_effect(results, state, stmt, loc);
results.analysis.apply_primary_statement_effect(state, stmt, loc);
vis.visit_after_primary_statement_effect(results, state, stmt, loc);
}
let loc = Location { block, statement_index: block_data.statements.len() };
let term = block_data.terminator();
results.analysis.apply_before_terminator_effect(state, term, loc);
vis.visit_terminator_before_primary_effect(results, state, term, loc);
results.analysis.apply_terminator_effect(state, term, loc);
vis.visit_terminator_after_primary_effect(results, state, term, loc);
results.analysis.apply_early_terminator_effect(state, term, loc);
vis.visit_after_early_terminator_effect(results, state, term, loc);
results.analysis.apply_primary_terminator_effect(state, term, loc);
vis.visit_after_primary_terminator_effect(results, state, term, loc);
vis.visit_block_end(state);
}

View File

@@ -724,7 +724,7 @@ where
}
}
fn visit_statement_before_primary_effect(
fn visit_after_early_statement_effect(
&mut self,
results: &mut Results<'tcx, A>,
state: &A::Domain,
@@ -737,7 +737,7 @@ where
}
}
fn visit_statement_after_primary_effect(
fn visit_after_primary_statement_effect(
&mut self,
results: &mut Results<'tcx, A>,
state: &A::Domain,
@@ -748,7 +748,7 @@ where
self.prev_state.clone_from(state)
}
fn visit_terminator_before_primary_effect(
fn visit_after_early_terminator_effect(
&mut self,
results: &mut Results<'tcx, A>,
state: &A::Domain,
@@ -761,7 +761,7 @@ where
}
}
fn visit_terminator_after_primary_effect(
fn visit_after_primary_terminator_effect(
&mut self,
results: &mut Results<'tcx, A>,
state: &A::Domain,

View File

@@ -38,10 +38,8 @@
//! [Hasse diagram]: https://en.wikipedia.org/wiki/Hasse_diagram
//! [poset]: https://en.wikipedia.org/wiki/Partially_ordered_set
use std::iter;
use rustc_index::Idx;
use rustc_index::bit_set::{BitSet, MixedBitSet};
use rustc_index::{Idx, IndexVec};
use crate::framework::BitSetExt;
@@ -70,53 +68,6 @@ pub trait HasTop {
const TOP: Self;
}
/// A `bool` is a "two-point" lattice with `true` as the top element and `false` as the bottom:
///
/// ```text
/// true
/// |
/// false
/// ```
impl JoinSemiLattice for bool {
fn join(&mut self, other: &Self) -> bool {
if let (false, true) = (*self, *other) {
*self = true;
return true;
}
false
}
}
impl HasBottom for bool {
const BOTTOM: Self = false;
fn is_bottom(&self) -> bool {
!self
}
}
impl HasTop for bool {
const TOP: Self = true;
}
/// A tuple (or list) of lattices is itself a lattice whose least upper bound is the concatenation
/// of the least upper bounds of each element of the tuple (or list).
///
/// In other words:
/// (A₀, A₁, ..., Aₙ) (B₀, B₁, ..., Bₙ) = (A₀B₀, A₁B₁, ..., AₙBₙ)
impl<I: Idx, T: JoinSemiLattice> JoinSemiLattice for IndexVec<I, T> {
fn join(&mut self, other: &Self) -> bool {
assert_eq!(self.len(), other.len());
let mut changed = false;
for (a, b) in iter::zip(self, other) {
changed |= a.join(b);
}
changed
}
}
/// A `BitSet` represents the lattice formed by the powerset of all possible values of
/// the index type `T` ordered by inclusion. Equivalently, it is a tuple of "two-point" lattices,
/// one for each possible value of `T`.
@@ -197,18 +148,6 @@ impl<T> MaybeReachable<T> {
}
}
impl<T> HasBottom for MaybeReachable<T> {
const BOTTOM: Self = MaybeReachable::Unreachable;
fn is_bottom(&self) -> bool {
matches!(self, Self::Unreachable)
}
}
impl<T: HasTop> HasTop for MaybeReachable<T> {
const TOP: Self = MaybeReachable::Reachable(T::TOP);
}
impl<S> MaybeReachable<S> {
/// Return whether the current state contains the given element. If the state is unreachable,
/// it does no contain anything.

View File

@@ -56,7 +56,7 @@ mod visitor;
pub use self::cursor::ResultsCursor;
pub use self::direction::{Backward, Direction, Forward};
pub use self::lattice::{JoinSemiLattice, MaybeReachable};
pub use self::results::{EntrySets, Results};
pub use self::results::{EntryStates, Results};
pub use self::visitor::{ResultsVisitor, visit_results};
/// Analysis domains are all bitsets of various kinds. This trait holds
@@ -122,8 +122,23 @@ pub trait Analysis<'tcx> {
// `resume`). It's not obvious how to handle `yield` points in coroutines, however.
fn initialize_start_block(&self, body: &mir::Body<'tcx>, state: &mut Self::Domain);
/// Updates the current dataflow state with an "early" effect, i.e. one
/// that occurs immediately before the given statement.
///
/// This method is useful if the consumer of the results of this analysis only needs to observe
/// *part* of the effect of a statement (e.g. for two-phase borrows). As a general rule,
/// analyses should not implement this without also implementing
/// `apply_primary_statement_effect`.
fn apply_early_statement_effect(
&mut self,
_state: &mut Self::Domain,
_statement: &mir::Statement<'tcx>,
_location: Location,
) {
}
/// Updates the current dataflow state with the effect of evaluating a statement.
fn apply_statement_effect(
fn apply_primary_statement_effect(
&mut self,
state: &mut Self::Domain,
statement: &mir::Statement<'tcx>,
@@ -131,15 +146,16 @@ pub trait Analysis<'tcx> {
);
/// Updates the current dataflow state with an effect that occurs immediately *before* the
/// given statement.
/// given terminator.
///
/// This method is useful if the consumer of the results of this analysis only needs to observe
/// *part* of the effect of a statement (e.g. for two-phase borrows). As a general rule,
/// analyses should not implement this without also implementing `apply_statement_effect`.
fn apply_before_statement_effect(
/// This method is useful if the consumer of the results of this analysis needs only to observe
/// *part* of the effect of a terminator (e.g. for two-phase borrows). As a general rule,
/// analyses should not implement this without also implementing
/// `apply_primary_terminator_effect`.
fn apply_early_terminator_effect(
&mut self,
_state: &mut Self::Domain,
_statement: &mir::Statement<'tcx>,
_terminator: &mir::Terminator<'tcx>,
_location: Location,
) {
}
@@ -150,7 +166,7 @@ pub trait Analysis<'tcx> {
/// in this function. That should go in `apply_call_return_effect`. For example, in the
/// `InitializedPlaces` analyses, the return place for a function call is not marked as
/// initialized here.
fn apply_terminator_effect<'mir>(
fn apply_primary_terminator_effect<'mir>(
&mut self,
_state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
@@ -159,27 +175,13 @@ pub trait Analysis<'tcx> {
terminator.edges()
}
/// Updates the current dataflow state with an effect that occurs immediately *before* the
/// given terminator.
///
/// This method is useful if the consumer of the results of this analysis needs only to observe
/// *part* of the effect of a terminator (e.g. for two-phase borrows). As a general rule,
/// analyses should not implement this without also implementing `apply_terminator_effect`.
fn apply_before_terminator_effect(
&mut self,
_state: &mut Self::Domain,
_terminator: &mir::Terminator<'tcx>,
_location: Location,
) {
}
/* Edge-specific effects */
/// Updates the current dataflow state with the effect of a successful return from a `Call`
/// terminator.
///
/// This is separate from `apply_terminator_effect` to properly track state across unwind
/// edges.
/// This is separate from `apply_primary_terminator_effect` to properly track state across
/// unwind edges.
fn apply_call_return_effect(
&mut self,
_state: &mut Self::Domain,
@@ -234,11 +236,12 @@ pub trait Analysis<'tcx> {
Self: Sized,
Self::Domain: DebugWithContext<Self>,
{
let mut entry_sets =
let mut entry_states =
IndexVec::from_fn_n(|_| self.bottom_value(body), body.basic_blocks.len());
self.initialize_start_block(body, &mut entry_sets[mir::START_BLOCK]);
self.initialize_start_block(body, &mut entry_states[mir::START_BLOCK]);
if Self::Direction::IS_BACKWARD && entry_sets[mir::START_BLOCK] != self.bottom_value(body) {
if Self::Direction::IS_BACKWARD && entry_states[mir::START_BLOCK] != self.bottom_value(body)
{
bug!("`initialize_start_block` is not yet supported for backward dataflow analyses");
}
@@ -262,9 +265,9 @@ pub trait Analysis<'tcx> {
let mut state = self.bottom_value(body);
while let Some(bb) = dirty_queue.pop() {
// Set the state to the entry state of the block.
// This is equivalent to `state = entry_sets[bb].clone()`,
// This is equivalent to `state = entry_states[bb].clone()`,
// but it saves an allocation, thus improving compile times.
state.clone_from(&entry_sets[bb]);
state.clone_from(&entry_states[bb]);
Self::Direction::apply_effects_in_block(
&mut self,
@@ -273,7 +276,7 @@ pub trait Analysis<'tcx> {
bb,
&body[bb],
|target: BasicBlock, state: &Self::Domain| {
let set_changed = entry_sets[target].join(state);
let set_changed = entry_states[target].join(state);
if set_changed {
dirty_queue.insert(target);
}
@@ -281,7 +284,7 @@ pub trait Analysis<'tcx> {
);
}
let mut results = Results { analysis: self, entry_sets };
let mut results = Results { analysis: self, entry_states };
if tcx.sess.opts.unstable_opts.dump_mir_dataflow {
let res = write_graphviz_results(tcx, body, &mut results, pass_name);
@@ -358,11 +361,10 @@ impl<T, S: GenKill<T>> GenKill<T> for MaybeReachable<S> {
// NOTE: DO NOT CHANGE VARIANT ORDER. The derived `Ord` impls rely on the current order.
#[derive(Clone, Copy, Debug, PartialEq, Eq, PartialOrd, Ord)]
enum Effect {
/// The "before" effect (e.g., `apply_before_statement_effect`) for a statement (or
/// terminator).
Before,
/// The "early" effect (e.g., `apply_early_statement_effect`) for a statement/terminator.
Early,
/// The "primary" effect (e.g., `apply_statement_effect`) for a statement (or terminator).
/// The "primary" effect (e.g., `apply_primary_statement_effect`) for a statement/terminator.
Primary,
}
@@ -381,15 +383,15 @@ pub struct EffectIndex {
impl EffectIndex {
fn next_in_forward_order(self) -> Self {
match self.effect {
Effect::Before => Effect::Primary.at_index(self.statement_index),
Effect::Primary => Effect::Before.at_index(self.statement_index + 1),
Effect::Early => Effect::Primary.at_index(self.statement_index),
Effect::Primary => Effect::Early.at_index(self.statement_index + 1),
}
}
fn next_in_backward_order(self) -> Self {
match self.effect {
Effect::Before => Effect::Primary.at_index(self.statement_index),
Effect::Primary => Effect::Before.at_index(self.statement_index - 1),
Effect::Early => Effect::Primary.at_index(self.statement_index),
Effect::Primary => Effect::Early.at_index(self.statement_index - 1),
}
}

View File

@@ -6,7 +6,7 @@ use rustc_middle::mir::{BasicBlock, Body, traversal};
use super::{Analysis, ResultsCursor, ResultsVisitor, visit_results};
use crate::framework::cursor::ResultsHandle;
pub type EntrySets<'tcx, A> = IndexVec<BasicBlock, <A as Analysis<'tcx>>::Domain>;
pub type EntryStates<'tcx, A> = IndexVec<BasicBlock, <A as Analysis<'tcx>>::Domain>;
/// 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
@@ -17,7 +17,7 @@ where
A: Analysis<'tcx>,
{
pub analysis: A,
pub entry_sets: EntrySets<'tcx, A>,
pub entry_states: EntryStates<'tcx, A>,
}
impl<'tcx, A> Results<'tcx, A>
@@ -40,7 +40,7 @@ where
/// Gets the dataflow state for the given block.
pub fn entry_set_for_block(&self, block: BasicBlock) -> &A::Domain {
&self.entry_sets[block]
&self.entry_states[block]
}
pub fn visit_with<'mir>(

View File

@@ -73,7 +73,7 @@ fn mock_body<'tcx>() -> mir::Body<'tcx> {
///
/// The `102` in the block's entry set is derived from the basic block index and ensures that the
/// expected state is unique across all basic blocks. Remember, it is generated by
/// `mock_entry_sets`, not from actually running `MockAnalysis` to fixpoint.
/// `mock_entry_states`, not from actually running `MockAnalysis` to fixpoint.
struct MockAnalysis<'tcx, D> {
body: &'tcx mir::Body<'tcx>,
dir: PhantomData<D>,
@@ -90,7 +90,7 @@ impl<D: Direction> MockAnalysis<'_, D> {
ret
}
fn mock_entry_sets(&self) -> IndexVec<BasicBlock, BitSet<usize>> {
fn mock_entry_states(&self) -> IndexVec<BasicBlock, BitSet<usize>> {
let empty = self.bottom_value(self.body);
let mut ret = IndexVec::from_elem(empty, &self.body.basic_blocks);
@@ -104,7 +104,7 @@ impl<D: Direction> MockAnalysis<'_, D> {
/// Returns the index that should be added to the dataflow state at the given target.
fn effect(&self, loc: EffectIndex) -> usize {
let idx = match loc.effect {
Effect::Before => loc.statement_index * 2,
Effect::Early => loc.statement_index * 2,
Effect::Primary => loc.statement_index * 2 + 1,
};
@@ -128,14 +128,14 @@ impl<D: Direction> MockAnalysis<'_, D> {
let target = match target {
SeekTarget::BlockEntry { .. } => return ret,
SeekTarget::Before(loc) => Effect::Before.at_index(loc.statement_index),
SeekTarget::Early(loc) => Effect::Early.at_index(loc.statement_index),
SeekTarget::After(loc) => Effect::Primary.at_index(loc.statement_index),
};
let mut pos = if D::IS_FORWARD {
Effect::Before.at_index(0)
Effect::Early.at_index(0)
} else {
Effect::Before.at_index(self.body[block].statements.len())
Effect::Early.at_index(self.body[block].statements.len())
};
loop {
@@ -168,7 +168,17 @@ impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> {
unimplemented!("This is never called since `MockAnalysis` is never iterated to fixpoint");
}
fn apply_statement_effect(
fn apply_early_statement_effect(
&mut self,
state: &mut Self::Domain,
_statement: &mir::Statement<'tcx>,
location: Location,
) {
let idx = self.effect(Effect::Early.at_index(location.statement_index));
assert!(state.insert(idx));
}
fn apply_primary_statement_effect(
&mut self,
state: &mut Self::Domain,
_statement: &mir::Statement<'tcx>,
@@ -178,17 +188,17 @@ impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> {
assert!(state.insert(idx));
}
fn apply_before_statement_effect(
fn apply_early_terminator_effect(
&mut self,
state: &mut Self::Domain,
_statement: &mir::Statement<'tcx>,
_terminator: &mir::Terminator<'tcx>,
location: Location,
) {
let idx = self.effect(Effect::Before.at_index(location.statement_index));
let idx = self.effect(Effect::Early.at_index(location.statement_index));
assert!(state.insert(idx));
}
fn apply_terminator_effect<'mir>(
fn apply_primary_terminator_effect<'mir>(
&mut self,
state: &mut Self::Domain,
terminator: &'mir mir::Terminator<'tcx>,
@@ -198,22 +208,12 @@ impl<'tcx, D: Direction> Analysis<'tcx> for MockAnalysis<'tcx, D> {
assert!(state.insert(idx));
terminator.edges()
}
fn apply_before_terminator_effect(
&mut self,
state: &mut Self::Domain,
_terminator: &mir::Terminator<'tcx>,
location: Location,
) {
let idx = self.effect(Effect::Before.at_index(location.statement_index));
assert!(state.insert(idx));
}
}
#[derive(Clone, Copy, Debug, PartialEq, Eq)]
enum SeekTarget {
BlockEntry(BasicBlock),
Before(Location),
Early(Location),
After(Location),
}
@@ -223,7 +223,7 @@ impl SeekTarget {
match *self {
BlockEntry(block) => block,
Before(loc) | After(loc) => loc.block,
Early(loc) | After(loc) => loc.block,
}
}
@@ -235,7 +235,7 @@ impl SeekTarget {
.map(move |(i, kind)| {
let loc = Location { block, statement_index: i };
match kind {
0 => SeekTarget::Before(loc),
0 => SeekTarget::Early(loc),
1 => SeekTarget::After(loc),
_ => unreachable!(),
}
@@ -249,7 +249,7 @@ fn test_cursor<D: Direction>(analysis: MockAnalysis<'_, D>) {
let body = analysis.body;
let mut cursor =
Results { entry_sets: analysis.mock_entry_sets(), analysis }.into_results_cursor(body);
Results { entry_states: analysis.mock_entry_states(), analysis }.into_results_cursor(body);
cursor.allow_unreachable();
@@ -262,7 +262,7 @@ fn test_cursor<D: Direction>(analysis: MockAnalysis<'_, D>) {
match targ {
BlockEntry(block) => cursor.seek_to_block_entry(block),
Before(loc) => cursor.seek_before_primary_effect(loc),
Early(loc) => cursor.seek_before_primary_effect(loc),
After(loc) => cursor.seek_after_primary_effect(loc),
}

View File

@@ -35,9 +35,9 @@ where
{
fn visit_block_start(&mut self, _state: &A::Domain) {}
/// Called with the `before_statement_effect` of the given statement applied to `state` but not
/// its `statement_effect`.
fn visit_statement_before_primary_effect(
/// // njn: grep for "before", "primary", etc.
/// Called after the "early" effect of the given statement is applied to `state`.
fn visit_after_early_statement_effect(
&mut self,
_results: &mut Results<'tcx, A>,
_state: &A::Domain,
@@ -46,9 +46,8 @@ where
) {
}
/// Called with both the `before_statement_effect` and the `statement_effect` of the given
/// statement applied to `state`.
fn visit_statement_after_primary_effect(
/// Called after the "primary" effect of the given statement is applied to `state`.
fn visit_after_primary_statement_effect(
&mut self,
_results: &mut Results<'tcx, A>,
_state: &A::Domain,
@@ -57,9 +56,8 @@ where
) {
}
/// Called with the `before_terminator_effect` of the given terminator applied to `state` but
/// not its `terminator_effect`.
fn visit_terminator_before_primary_effect(
/// Called after the "early" effect of the given terminator is applied to `state`.
fn visit_after_early_terminator_effect(
&mut self,
_results: &mut Results<'tcx, A>,
_state: &A::Domain,
@@ -68,11 +66,10 @@ where
) {
}
/// Called with both the `before_terminator_effect` and the `terminator_effect` of the given
/// terminator applied to `state`.
/// Called after the "primary" effect of the given terminator is applied to `state`.
///
/// The `call_return_effect` (if one exists) will *not* be applied to `state`.
fn visit_terminator_after_primary_effect(
fn visit_after_primary_terminator_effect(
&mut self,
_results: &mut Results<'tcx, A>,
_state: &A::Domain,