use LiveVariableMap as trait bound
This commit is contained in:
parent
f2b5583f60
commit
d25231f84a
2 changed files with 26 additions and 25 deletions
|
|
@ -22,7 +22,7 @@ use rustc::ty::{Ty, TypeFoldable};
|
|||
use rustc_data_structures::fx::FxHashMap;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use std::rc::Rc;
|
||||
use util::liveness::LivenessResults;
|
||||
use util::liveness::{LivenessResults, LiveVariableMap};
|
||||
|
||||
use super::TypeChecker;
|
||||
|
||||
|
|
@ -34,10 +34,10 @@ use super::TypeChecker;
|
|||
///
|
||||
/// NB. This computation requires normalization; therefore, it must be
|
||||
/// performed before
|
||||
pub(super) fn generate<'gcx, 'tcx>(
|
||||
pub(super) fn generate<'gcx, 'tcx, V: LiveVariableMap>(
|
||||
cx: &mut TypeChecker<'_, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
liveness: &LivenessResults<Local>,
|
||||
liveness: &LivenessResults<V>,
|
||||
flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
) {
|
||||
|
|
@ -55,16 +55,17 @@ pub(super) fn generate<'gcx, 'tcx>(
|
|||
}
|
||||
}
|
||||
|
||||
struct TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx>
|
||||
struct TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx, V: LiveVariableMap>
|
||||
where
|
||||
'typeck: 'gen,
|
||||
'flow: 'gen,
|
||||
'tcx: 'typeck + 'flow,
|
||||
'gcx: 'tcx,
|
||||
V: 'gen,
|
||||
{
|
||||
cx: &'gen mut TypeChecker<'typeck, 'gcx, 'tcx>,
|
||||
mir: &'gen Mir<'tcx>,
|
||||
liveness: &'gen LivenessResults<Local>,
|
||||
liveness: &'gen LivenessResults<V>,
|
||||
flow_inits: &'gen mut FlowAtLocation<MaybeInitializedPlaces<'flow, 'gcx, 'tcx>>,
|
||||
move_data: &'gen MoveData<'tcx>,
|
||||
drop_data: FxHashMap<Ty<'tcx>, DropData<'tcx>>,
|
||||
|
|
@ -75,7 +76,7 @@ struct DropData<'tcx> {
|
|||
region_constraint_data: Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>,
|
||||
}
|
||||
|
||||
impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx> {
|
||||
impl<'gen, 'typeck, 'flow, 'gcx, 'tcx, V:LiveVariableMap> TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx, V> {
|
||||
/// Liveness constraints:
|
||||
///
|
||||
/// > If a variable V is live at point P, then all regions R in the type of V
|
||||
|
|
@ -92,7 +93,7 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo
|
|||
}
|
||||
});
|
||||
|
||||
let mut all_live_locals: Vec<(Location, Vec<Local>)> = vec![];
|
||||
let mut all_live_locals: Vec<(Location, Vec<V::LiveVar>)> = vec![];
|
||||
self.liveness
|
||||
.drop
|
||||
.simulate_block(self.mir, bb, |location, live_locals| {
|
||||
|
|
|
|||
|
|
@ -48,21 +48,21 @@ use rustc::ty::TyCtxt;
|
|||
use std::io::{self, Write};
|
||||
use transform::MirSource;
|
||||
|
||||
pub type LocalSet<V: Idx> = IdxSetBuf<V>;
|
||||
pub type LocalSet<V: LiveVariableMap> = IdxSetBuf<V::LiveVar>;
|
||||
|
||||
/// This gives the result of the liveness analysis at the boundary of
|
||||
/// basic blocks. You can use `simulate_block` to obtain the
|
||||
/// intra-block results.
|
||||
pub struct LivenessResult<V: Idx> {
|
||||
pub struct LivenessResult<V: LiveVariableMap> {
|
||||
/// Liveness mode in use when these results were computed.
|
||||
pub mode: LivenessMode,
|
||||
|
||||
/// Live variables on exit to each basic block. This is equal to
|
||||
/// the union of the `ins` for each successor.
|
||||
pub outs: IndexVec<BasicBlock, LocalSet<V>>,
|
||||
pub outs: IndexVec<BasicBlock, LocalSet<V::LiveVar>>,
|
||||
}
|
||||
|
||||
trait LiveVariableMap {
|
||||
pub(crate) trait LiveVariableMap {
|
||||
type LiveVar;
|
||||
|
||||
fn from_local(&self, local: Local) -> Option<Self::LiveVar>;
|
||||
|
|
@ -103,18 +103,18 @@ pub struct LivenessMode {
|
|||
}
|
||||
|
||||
/// A combination of liveness results, used in NLL.
|
||||
pub struct LivenessResults<V: Idx> {
|
||||
pub struct LivenessResults<V: LiveVariableMap> {
|
||||
/// Liveness results where a regular use makes a variable X live,
|
||||
/// but not a drop.
|
||||
pub regular: LivenessResult<V>,
|
||||
pub regular: LivenessResult<V::LiveVar>,
|
||||
|
||||
/// Liveness results where a drop makes a variable X live,
|
||||
/// but not a regular use.
|
||||
pub drop: LivenessResult<V>,
|
||||
pub drop: LivenessResult<V::LiveVar>,
|
||||
}
|
||||
|
||||
impl<V: Idx> LivenessResults<V> {
|
||||
pub fn compute<'tcx>(mir: &Mir<'tcx>, map: &dyn LiveVariableMap<LiveVar = V>) -> LivenessResults<V> {
|
||||
impl<V: LiveVariableMap> LivenessResults<V> {
|
||||
pub fn compute<'tcx>(mir: &Mir<'tcx>, map: &dyn LiveVariableMap<LiveVar = V>) -> LivenessResults<V::LiveVar> {
|
||||
LivenessResults {
|
||||
regular: liveness_of_locals(
|
||||
&mir,
|
||||
|
|
@ -138,7 +138,7 @@ impl<V: Idx> LivenessResults<V> {
|
|||
/// Compute which local variables are live within the given function
|
||||
/// `mir`. The liveness mode `mode` determines what sorts of uses are
|
||||
/// considered to make a variable live (e.g., do drops count?).
|
||||
pub fn liveness_of_locals<'tcx, V: Idx>(mir: &Mir<'tcx>, mode: LivenessMode) -> LivenessResult<V> {
|
||||
pub fn liveness_of_locals<'tcx, V: LiveVariableMap>(mir: &Mir<'tcx>, mode: LivenessMode) -> LivenessResult<V::LiveVar> {
|
||||
let locals = mir.local_decls.len();
|
||||
let def_use: IndexVec<_, _> = mir.basic_blocks()
|
||||
.iter()
|
||||
|
|
@ -179,8 +179,7 @@ pub fn liveness_of_locals<'tcx, V: Idx>(mir: &Mir<'tcx>, mode: LivenessMode) ->
|
|||
LivenessResult { mode, outs }
|
||||
}
|
||||
|
||||
impl<V> LivenessResult<V>
|
||||
where V:Idx
|
||||
impl<V: LiveVariableMap> LivenessResult<V>
|
||||
{
|
||||
/// Walks backwards through the statements/terminator in the given
|
||||
/// basic block `block`. At each point within `block`, invokes
|
||||
|
|
@ -422,12 +421,13 @@ fn block<'tcx, 'lv>(mode: LivenessMode, b: &BasicBlockData<'tcx>, locals: usize)
|
|||
visitor.defs_uses
|
||||
}
|
||||
|
||||
pub fn dump_mir<'a, 'tcx, V: Idx>(
|
||||
pub fn dump_mir<'a, 'tcx, V: LiveVariableMap>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pass_name: &str,
|
||||
source: MirSource,
|
||||
mir: &Mir<'tcx>,
|
||||
result: &LivenessResult<Local>,
|
||||
map: &impl LiveVariableMap<LiveVar = V>
|
||||
) {
|
||||
if !dump_enabled(tcx, pass_name, source) {
|
||||
return;
|
||||
|
|
@ -439,13 +439,13 @@ pub fn dump_mir<'a, 'tcx, V: Idx>(
|
|||
dump_matched_mir_node(tcx, pass_name, &node_path, source, mir, result);
|
||||
}
|
||||
|
||||
fn dump_matched_mir_node<'a, 'tcx, V: Idx>(
|
||||
fn dump_matched_mir_node<'a, 'tcx, V: LiveVariableMap>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
pass_name: &str,
|
||||
node_path: &str,
|
||||
source: MirSource,
|
||||
mir: &Mir<'tcx>,
|
||||
result: &LivenessResult<V>,
|
||||
result: &LivenessResult<V::LiveVar>,
|
||||
) {
|
||||
let mut file_path = PathBuf::new();
|
||||
file_path.push(Path::new(&tcx.sess.opts.debugging_opts.dump_mir_dir));
|
||||
|
|
@ -462,16 +462,16 @@ fn dump_matched_mir_node<'a, 'tcx, V: Idx>(
|
|||
});
|
||||
}
|
||||
|
||||
pub fn write_mir_fn<'a, 'tcx, V :Idx>(
|
||||
pub fn write_mir_fn<'a, 'tcx, V: LiveVariableMap>(
|
||||
tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
src: MirSource,
|
||||
mir: &Mir<'tcx>,
|
||||
w: &mut dyn Write,
|
||||
result: &LivenessResult<V>,
|
||||
result: &LivenessResult<V::LiveVar>,
|
||||
) -> io::Result<()> {
|
||||
write_mir_intro(tcx, src, mir, w)?;
|
||||
for block in mir.basic_blocks().indices() {
|
||||
let print = |w: &mut dyn Write, prefix, result: &IndexVec<BasicBlock, LocalSet<V>>| {
|
||||
let print = |w: &mut dyn Write, prefix, result: &IndexVec<BasicBlock, LocalSet<Local>>| {
|
||||
let live: Vec<String> = mir.local_decls
|
||||
.indices()
|
||||
.filter(|i| result[block].contains(i))
|
||||
|
|
|
|||
Loading…
Add table
Add a link
Reference in a new issue