move NllLivenessMap and LocalWithRegion to liveness_map
This commit is contained in:
parent
67685dee3f
commit
4e3339efda
@ -2933,4 +2933,4 @@ impl<'tcx> TypeFoldable<'tcx> for Literal<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
newtype_index!(LocalWithRegion);
|
||||
|
||||
|
58
src/librustc_mir/borrow_check/nll/liveness_map.rs
Normal file
58
src/librustc_mir/borrow_check/nll/liveness_map.rs
Normal file
@ -0,0 +1,58 @@
|
||||
// Copyright 2018 The Rust Project Developers. See the COPYRIGHT
|
||||
// file at the top-level directory of this distribution and at
|
||||
// http://rust-lang.org/COPYRIGHT.
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 <LICENSE-APACHE or
|
||||
// http://www.apache.org/licenses/LICENSE-2.0> or the MIT license
|
||||
// <LICENSE-MIT or http://opensource.org/licenses/MIT>, at your
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use rustc_data_structures::indexed_vec::IndexVec;
|
||||
use rustc::mir::{Mir, Local};
|
||||
use util::liveness::LiveVariableMap;
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
use rustc::ty::TypeFoldable;
|
||||
|
||||
crate struct NllLivenessMap {
|
||||
pub from_local: IndexVec<Local, Option<LocalWithRegion>>,
|
||||
pub to_local: IndexVec<LocalWithRegion, Local>,
|
||||
|
||||
}
|
||||
|
||||
impl LiveVariableMap for NllLivenessMap {
|
||||
type LiveVar = LocalWithRegion;
|
||||
|
||||
fn from_local(&self, local: Local) -> Option<Self::LiveVar> {
|
||||
self.from_local[local]
|
||||
}
|
||||
|
||||
fn from_live_var(&self, local: Self::LiveVar) -> Local {
|
||||
self.to_local[local]
|
||||
}
|
||||
|
||||
fn num_variables(&self) -> usize {
|
||||
self.to_local.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl NllLivenessMap {
|
||||
pub fn compute(mir: &Mir) -> Self {
|
||||
let mut to_local = IndexVec::default();
|
||||
let from_local: IndexVec<Local,Option<_>> = mir
|
||||
.local_decls
|
||||
.iter_enumerated()
|
||||
.map(|(local, local_decl)| {
|
||||
if local_decl.ty.has_free_regions() {
|
||||
Some(to_local.push(local))
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}).collect();
|
||||
|
||||
Self { from_local, to_local }
|
||||
}
|
||||
}
|
||||
|
||||
newtype_index!(LocalWithRegion);
|
@ -13,13 +13,14 @@ use borrow_check::location::{LocationIndex, LocationTable};
|
||||
use borrow_check::nll::facts::AllFactsExt;
|
||||
use borrow_check::nll::type_check::MirTypeckRegionConstraints;
|
||||
use borrow_check::nll::region_infer::values::RegionValueElements;
|
||||
use borrow_check::nll::liveness_map::{NllLivenessMap, LocalWithRegion};
|
||||
use dataflow::indexes::BorrowIndex;
|
||||
use dataflow::move_paths::MoveData;
|
||||
use dataflow::FlowAtLocation;
|
||||
use dataflow::MaybeInitializedPlaces;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir, LocalWithRegion};
|
||||
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir};
|
||||
use rustc::ty::{self, RegionKind, RegionVid};
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use std::collections::BTreeSet;
|
||||
@ -30,7 +31,7 @@ use std::path::PathBuf;
|
||||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
use transform::MirSource;
|
||||
use util::liveness::{LivenessResults, LocalSet, NllLivenessMap};
|
||||
use util::liveness::{LivenessResults, LiveVarSet};
|
||||
|
||||
use self::mir_util::PassWhere;
|
||||
use polonius_engine::{Algorithm, Output};
|
||||
@ -45,6 +46,7 @@ crate mod region_infer;
|
||||
mod renumber;
|
||||
crate mod type_check;
|
||||
mod universal_regions;
|
||||
crate mod liveness_map;
|
||||
|
||||
mod constraints;
|
||||
|
||||
@ -409,8 +411,8 @@ impl ToRegionVid for RegionVid {
|
||||
}
|
||||
|
||||
fn live_variable_set(
|
||||
regular: &LocalSet<LocalWithRegion>,
|
||||
drops: &LocalSet<LocalWithRegion>
|
||||
regular: &LiveVarSet<LocalWithRegion>,
|
||||
drops: &LiveVarSet<LocalWithRegion>
|
||||
) -> String {
|
||||
// sort and deduplicate:
|
||||
let all_locals: BTreeSet<_> = regular.iter().chain(drops.iter()).collect();
|
||||
|
@ -8,12 +8,12 @@
|
||||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
use borrow_check::nll::{NllLivenessMap, LocalWithRegion};
|
||||
use borrow_check::nll::type_check::AtLocation;
|
||||
use dataflow::move_paths::{HasMoveData, MoveData};
|
||||
use dataflow::MaybeInitializedPlaces;
|
||||
use dataflow::{FlowAtLocation, FlowsAtLocation};
|
||||
use rustc::infer::canonical::QueryRegionConstraint;
|
||||
use rustc::mir::LocalWithRegion;
|
||||
use rustc::mir::{BasicBlock, Location, Mir};
|
||||
use rustc::traits::query::dropck_outlives::DropckOutlivesResult;
|
||||
use rustc::traits::query::type_op::outlives::DropckOutlives;
|
||||
@ -21,7 +21,7 @@ use rustc::traits::query::type_op::TypeOp;
|
||||
use rustc::ty::{Ty, TypeFoldable};
|
||||
use rustc_data_structures::fx::FxHashMap;
|
||||
use std::rc::Rc;
|
||||
use util::liveness::{NllLivenessMap, LivenessResults, LiveVariableMap };
|
||||
use util::liveness::{LivenessResults, LiveVariableMap };
|
||||
|
||||
use super::TypeChecker;
|
||||
|
||||
|
@ -19,6 +19,7 @@ use borrow_check::nll::region_infer::{ClosureRegionRequirementsExt, TypeTest};
|
||||
use borrow_check::nll::region_infer::values::{RegionValues, RegionValueElements};
|
||||
use borrow_check::nll::universal_regions::UniversalRegions;
|
||||
use borrow_check::nll::ToRegionVid;
|
||||
use borrow_check::nll::LocalWithRegion;
|
||||
use dataflow::move_paths::MoveData;
|
||||
use dataflow::FlowAtLocation;
|
||||
use dataflow::MaybeInitializedPlaces;
|
||||
|
@ -130,7 +130,7 @@ struct SuspensionPoint {
|
||||
state: u32,
|
||||
resume: BasicBlock,
|
||||
drop: Option<BasicBlock>,
|
||||
storage_liveness: liveness::LocalSet<Local>,
|
||||
storage_liveness: liveness::LiveVarSet<Local>,
|
||||
}
|
||||
|
||||
struct TransformVisitor<'a, 'tcx: 'a> {
|
||||
@ -145,7 +145,7 @@ struct TransformVisitor<'a, 'tcx: 'a> {
|
||||
remap: HashMap<Local, (Ty<'tcx>, usize)>,
|
||||
|
||||
// A map from a suspension point in a block to the locals which have live storage at that point
|
||||
storage_liveness: HashMap<BasicBlock, liveness::LocalSet<Local>>,
|
||||
storage_liveness: HashMap<BasicBlock, liveness::LiveVarSet<Local>>,
|
||||
|
||||
// A list of suspension points, generated during the transform
|
||||
suspension_points: Vec<SuspensionPoint>,
|
||||
@ -317,7 +317,7 @@ fn replace_result_variable<'tcx>(ret_ty: Ty<'tcx>,
|
||||
new_ret_local
|
||||
}
|
||||
|
||||
struct StorageIgnored(liveness::LocalSet<Local>);
|
||||
struct StorageIgnored(liveness::LiveVarSet<Local>);
|
||||
|
||||
impl<'tcx> Visitor<'tcx> for StorageIgnored {
|
||||
fn visit_statement(&mut self,
|
||||
@ -332,7 +332,7 @@ impl<'tcx> Visitor<'tcx> for StorageIgnored {
|
||||
}
|
||||
}
|
||||
|
||||
struct BorrowedLocals(liveness::LocalSet<Local>);
|
||||
struct BorrowedLocals(liveness::LiveVarSet<Local>);
|
||||
|
||||
fn mark_as_borrowed<'tcx>(place: &Place<'tcx>, locals: &mut BorrowedLocals) {
|
||||
match *place {
|
||||
@ -365,8 +365,8 @@ fn locals_live_across_suspend_points<'a, 'tcx,>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
source: MirSource,
|
||||
movable: bool) ->
|
||||
(liveness::LocalSet<Local>,
|
||||
HashMap<BasicBlock, liveness::LocalSet<Local>>) {
|
||||
(liveness::LiveVarSet<Local>,
|
||||
HashMap<BasicBlock, liveness::LiveVarSet<Local>>) {
|
||||
let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
|
||||
let node_id = tcx.hir.as_local_node_id(source.def_id).unwrap();
|
||||
|
||||
@ -396,7 +396,7 @@ fn locals_live_across_suspend_points<'a, 'tcx,>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
};
|
||||
|
||||
// Calculate the liveness of MIR locals ignoring borrows.
|
||||
let mut set = liveness::LocalSet::new_empty(mir.local_decls.len());
|
||||
let mut set = liveness::LiveVarSet::new_empty(mir.local_decls.len());
|
||||
let mut liveness = liveness::liveness_of_locals(
|
||||
mir,
|
||||
LivenessMode {
|
||||
@ -479,7 +479,7 @@ fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
|
||||
mir: &mut Mir<'tcx>)
|
||||
-> (HashMap<Local, (Ty<'tcx>, usize)>,
|
||||
GeneratorLayout<'tcx>,
|
||||
HashMap<BasicBlock, liveness::LocalSet<Local>>)
|
||||
HashMap<BasicBlock, liveness::LiveVarSet<Local>>)
|
||||
{
|
||||
// Use a liveness analysis to compute locals which are live across a suspension point
|
||||
let (live_locals, storage_liveness) = locals_live_across_suspend_points(tcx,
|
||||
|
@ -37,7 +37,7 @@ use rustc::mir::visit::MirVisitable;
|
||||
use rustc::mir::visit::{PlaceContext, Visitor};
|
||||
use rustc::mir::Local;
|
||||
use rustc::mir::*;
|
||||
use rustc::ty::{item_path, TyCtxt, TypeFoldable};
|
||||
use rustc::ty::{item_path, TyCtxt};
|
||||
use rustc_data_structures::indexed_set::IdxSetBuf;
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use rustc_data_structures::work_queue::WorkQueue;
|
||||
@ -47,7 +47,7 @@ use std::path::{Path, PathBuf};
|
||||
use transform::MirSource;
|
||||
use util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
|
||||
|
||||
pub type LocalSet<V> = IdxSetBuf<V>;
|
||||
pub type LiveVarSet<V> = IdxSetBuf<V>;
|
||||
|
||||
/// This gives the result of the liveness analysis at the boundary of
|
||||
/// basic blocks. You can use `simulate_block` to obtain the
|
||||
@ -63,7 +63,7 @@ pub struct LivenessResult<V: Idx> {
|
||||
|
||||
/// 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, LiveVarSet<V>>,
|
||||
}
|
||||
|
||||
/// Defines the mapping to/from the MIR local variables (`Local`) to
|
||||
@ -176,13 +176,13 @@ pub fn liveness_of_locals<'tcx, V: Idx>(
|
||||
.map(|b| block(mode, map, b, num_live_vars))
|
||||
.collect();
|
||||
|
||||
let mut outs: IndexVec<_, LocalSet<V>> = mir
|
||||
let mut outs: IndexVec<_, LiveVarSet<V>> = mir
|
||||
.basic_blocks()
|
||||
.indices()
|
||||
.map(|_| LocalSet::new_empty(num_live_vars))
|
||||
.map(|_| LiveVarSet::new_empty(num_live_vars))
|
||||
.collect();
|
||||
|
||||
let mut bits = LocalSet::new_empty(num_live_vars);
|
||||
let mut bits = LiveVarSet::new_empty(num_live_vars);
|
||||
|
||||
// queue of things that need to be re-processed, and a set containing
|
||||
// the things currently in the queue
|
||||
@ -223,7 +223,7 @@ impl<V: Idx> LivenessResult<V> {
|
||||
map: &impl LiveVariableMap<LiveVar = V>,
|
||||
mut callback: OP,
|
||||
) where
|
||||
OP: FnMut(Location, &LocalSet<V>),
|
||||
OP: FnMut(Location, &LiveVarSet<V>),
|
||||
{
|
||||
let data = &mir[block];
|
||||
|
||||
@ -244,8 +244,8 @@ impl<V: Idx> LivenessResult<V> {
|
||||
mode: self.mode,
|
||||
map,
|
||||
defs_uses: DefsUses {
|
||||
defs: LocalSet::new_empty(num_live_vars),
|
||||
uses: LocalSet::new_empty(num_live_vars),
|
||||
defs: LiveVarSet::new_empty(num_live_vars),
|
||||
uses: LiveVarSet::new_empty(num_live_vars),
|
||||
},
|
||||
};
|
||||
// Visit the various parts of the basic block in reverse. If we go
|
||||
@ -362,8 +362,8 @@ where
|
||||
|
||||
#[derive(Eq, PartialEq, Clone)]
|
||||
struct DefsUses<V: Idx> {
|
||||
defs: LocalSet<V>,
|
||||
uses: LocalSet<V>,
|
||||
defs: LiveVarSet<V>,
|
||||
uses: LiveVarSet<V>,
|
||||
}
|
||||
|
||||
impl<V: Idx> DefsUses<V> {
|
||||
@ -372,7 +372,7 @@ impl<V: Idx> DefsUses<V> {
|
||||
self.defs.clear();
|
||||
}
|
||||
|
||||
fn apply(&self, bits: &mut LocalSet<V>) -> bool {
|
||||
fn apply(&self, bits: &mut LiveVarSet<V>) -> bool {
|
||||
bits.subtract(&self.defs) | bits.union(&self.uses)
|
||||
}
|
||||
|
||||
@ -418,10 +418,10 @@ where
|
||||
&mut self,
|
||||
location: Location,
|
||||
value: &impl MirVisitable<'tcx>,
|
||||
bits: &mut LocalSet<V>,
|
||||
bits: &mut LiveVarSet<V>,
|
||||
callback: &mut OP,
|
||||
) where
|
||||
OP: FnMut(Location, &LocalSet<V>),
|
||||
OP: FnMut(Location, &LiveVarSet<V>),
|
||||
{
|
||||
value.apply(location, self);
|
||||
self.defs_uses.apply(bits);
|
||||
@ -455,8 +455,8 @@ fn block<'tcx, V: Idx>(
|
||||
mode,
|
||||
map,
|
||||
defs_uses: DefsUses {
|
||||
defs: LocalSet::new_empty(locals),
|
||||
uses: LocalSet::new_empty(locals),
|
||||
defs: LiveVarSet::new_empty(locals),
|
||||
uses: LiveVarSet::new_empty(locals),
|
||||
},
|
||||
};
|
||||
|
||||
@ -527,7 +527,7 @@ pub fn write_mir_fn<'a, 'tcx, V: Idx>(
|
||||
) -> 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, LiveVarSet<V>>| {
|
||||
let live: Vec<String> = result[block].iter()
|
||||
.map(|v| map.from_live_var(v))
|
||||
.map(|local| format!("{:?}", local))
|
||||
@ -545,43 +545,4 @@ pub fn write_mir_fn<'a, 'tcx, V: Idx>(
|
||||
Ok(())
|
||||
}
|
||||
|
||||
crate struct NllLivenessMap {
|
||||
pub from_local: IndexVec<Local, Option<LocalWithRegion>>,
|
||||
pub to_local: IndexVec<LocalWithRegion, Local>,
|
||||
|
||||
}
|
||||
|
||||
impl LiveVariableMap for NllLivenessMap {
|
||||
type LiveVar = LocalWithRegion;
|
||||
|
||||
fn from_local(&self, local: Local) -> Option<Self::LiveVar> {
|
||||
self.from_local[local]
|
||||
}
|
||||
|
||||
fn from_live_var(&self, local: Self::LiveVar) -> Local {
|
||||
self.to_local[local]
|
||||
}
|
||||
|
||||
fn num_variables(&self) -> usize {
|
||||
self.to_local.len()
|
||||
}
|
||||
}
|
||||
|
||||
impl NllLivenessMap {
|
||||
pub fn compute(mir: &Mir) -> Self {
|
||||
let mut to_local = IndexVec::default();
|
||||
let from_local: IndexVec<Local,Option<_>> = mir
|
||||
.local_decls
|
||||
.iter_enumerated()
|
||||
.map(|(local, local_decl)| {
|
||||
if local_decl.ty.has_free_regions() {
|
||||
Some(to_local.push(local))
|
||||
}
|
||||
else {
|
||||
None
|
||||
}
|
||||
}).collect();
|
||||
|
||||
Self { from_local, to_local }
|
||||
}
|
||||
}
|
||||
|
Loading…
x
Reference in New Issue
Block a user