From 4a940b321534a1024078cce92fc69030bfd6c60d Mon Sep 17 00:00:00 2001 From: Niko Matsakis Date: Sun, 3 Dec 2017 12:49:08 -0500 Subject: [PATCH] move `flow_in_progress` into `dataflow` and document it --- src/librustc_mir/borrow_check/mod.rs | 4 +- .../borrow_check/nll/constraint_generation.rs | 2 +- src/librustc_mir/borrow_check/nll/mod.rs | 2 +- src/librustc_mir/dataflow/at_location.rs | 42 +++++++++++++++---- 4 files changed, 38 insertions(+), 12 deletions(-) diff --git a/src/librustc_mir/borrow_check/mod.rs b/src/librustc_mir/borrow_check/mod.rs index 39bcd2b6ae06..576d59857987 100644 --- a/src/librustc_mir/borrow_check/mod.rs +++ b/src/librustc_mir/borrow_check/mod.rs @@ -22,16 +22,16 @@ use rustc::mir::{Field, Statement, StatementKind, Terminator, TerminatorKind}; use rustc::mir::ClosureRegionRequirements; use rustc_data_structures::fx::FxHashSet; -use rustc_data_structures::indexed_set::{IdxSetBuf}; +use rustc_data_structures::indexed_set::IdxSetBuf; use rustc_data_structures::indexed_vec::Idx; use syntax::ast; use syntax_pos::Span; use dataflow::{do_dataflow, DebugFormatted}; +use dataflow::FlowAtLocation; use dataflow::MoveDataParamEnv; use dataflow::{DataflowAnalysis, DataflowResultsConsumer}; -use dataflow::{FlowAtLocation, FlowsAtLocation}; use dataflow::{MaybeInitializedLvals, MaybeUninitializedLvals}; use dataflow::{EverInitializedLvals, MovingOutStatements}; use dataflow::{Borrows, BorrowData, ReserveOrActivateIndex}; diff --git a/src/librustc_mir/borrow_check/nll/constraint_generation.rs b/src/librustc_mir/borrow_check/nll/constraint_generation.rs index 59e862a56af0..5564a0d98afa 100644 --- a/src/librustc_mir/borrow_check/nll/constraint_generation.rs +++ b/src/librustc_mir/borrow_check/nll/constraint_generation.rs @@ -22,7 +22,7 @@ use rustc::ty::fold::TypeFoldable; use rustc::util::common::ErrorReported; use rustc_data_structures::fx::FxHashSet; use syntax::codemap::DUMMY_SP; -use borrow_check::{FlowAtLocation, FlowsAtLocation}; +use dataflow::{FlowAtLocation, FlowsAtLocation}; use dataflow::MaybeInitializedLvals; use dataflow::move_paths::{HasMoveData, MoveData}; diff --git a/src/librustc_mir/borrow_check/nll/mod.rs b/src/librustc_mir/borrow_check/nll/mod.rs index 725694fd5b74..c616f027331b 100644 --- a/src/librustc_mir/borrow_check/nll/mod.rs +++ b/src/librustc_mir/borrow_check/nll/mod.rs @@ -17,7 +17,7 @@ use std::collections::BTreeSet; use std::io; use transform::MirSource; use util::liveness::{LivenessResults, LocalSet}; -use borrow_check::FlowAtLocation; +use dataflow::FlowAtLocation; use dataflow::MaybeInitializedLvals; use dataflow::move_paths::MoveData; diff --git a/src/librustc_mir/dataflow/at_location.rs b/src/librustc_mir/dataflow/at_location.rs index a6c3398489ad..7f243ad6e264 100644 --- a/src/librustc_mir/dataflow/at_location.rs +++ b/src/librustc_mir/dataflow/at_location.rs @@ -25,26 +25,43 @@ use std::iter; /// There's probably a way to auto-impl this, but I think /// it is cleaner to have manual visitor impls. pub trait FlowsAtLocation { - // reset the state bitvector to represent the entry to block `bb`. + /// Reset the state bitvector to represent the entry to block `bb`. fn reset_to_entry_of(&mut self, bb: BasicBlock); - // build gen + kill sets for statement at `loc`. + /// Build gen + kill sets for statement at `loc`. + /// + /// Note that invoking this method alone does not change the + /// `curr_state` -- you must invoke `apply_local_effect` + /// afterwards. fn reconstruct_statement_effect(&mut self, loc: Location); - // build gen + kill sets for terminator for `loc`. + /// Build gen + kill sets for terminator for `loc`. + /// + /// Note that invoking this method alone does not change the + /// `curr_state` -- you must invoke `apply_local_effect` + /// afterwards. fn reconstruct_terminator_effect(&mut self, loc: Location); - // apply current gen + kill sets to `flow_state`. - // - // (`bb` and `stmt_idx` parameters can be ignored if desired by - // client. For the terminator, the `stmt_idx` will be the number - // of statements in the block.) + /// Apply current gen + kill sets to `flow_state`. + /// + /// (`loc` parameters can be ignored if desired by + /// client. For the terminator, the `stmt_idx` will be the number + /// of statements in the block.) fn apply_local_effect(&mut self, loc: Location); } /// Represents the state of dataflow at a particular /// CFG location, both before and after it is /// executed. +/// +/// Data flow results are typically computed only as basic block +/// boundaries. A `FlowInProgress` allows you to reconstruct the +/// effects at any point in the control-flow graph by starting with +/// the state at the start of the basic block (`reset_to_entry_of`) +/// and then replaying the effects of statements and terminators +/// (e.g. via `reconstruct_statement_effect` and +/// `reconstruct_terminator_effect`; don't forget to call +/// `apply_local_effect`). pub struct FlowAtLocation where BD: BitDenotation, @@ -59,6 +76,7 @@ impl FlowAtLocation where BD: BitDenotation, { + /// Iterate over each bit set in the current state. pub fn each_state_bit(&self, f: F) where F: FnMut(BD::Idx), @@ -67,6 +85,9 @@ where .each_bit(self.base_results.operator().bits_per_block(), f) } + /// Iterate over each `gen` bit in the current effect (invoke + /// `reconstruct_statement_effect` or + /// `reconstruct_terminator_effect` first). pub fn each_gen_bit(&self, f: F) where F: FnMut(BD::Idx), @@ -88,6 +109,7 @@ where } } + /// Access the underlying operator. pub fn operator(&self) -> &BD { self.base_results.operator() } @@ -96,11 +118,15 @@ where self.curr_state.contains(x) } + /// Returns an iterator over the elements present in the current state. pub fn elems_incoming(&self) -> iter::Peekable> { let univ = self.base_results.sets().bits_per_block(); self.curr_state.elems(univ).peekable() } + /// Creates a clone of the current state and applies the local + /// effects to the clone (leaving the state of self intact). + /// Invokes `f` with an iterator over the resulting state. pub fn with_elems_outgoing(&self, f: F) where F: FnOnce(indexed_set::Elems),