add LocalWithRegion NllLivenessMap
This commit is contained in:
parent
43b69c2777
commit
0d847ec1ab
8 changed files with 76 additions and 36 deletions
|
|
@ -52,7 +52,7 @@ pub mod traversal;
|
|||
pub mod visit;
|
||||
|
||||
/// Types for locals
|
||||
type LocalDecls<'tcx> = IndexVec<Local, LocalDecl<'tcx>>;
|
||||
type LocalDecls<'tcx> = IndexVec<LocalWithRegion, LocalDecl<'tcx>>;
|
||||
|
||||
pub trait HasLocalDecls<'tcx> {
|
||||
fn local_decls(&self) -> &LocalDecls<'tcx>;
|
||||
|
|
@ -141,7 +141,7 @@ impl<'tcx> Mir<'tcx> {
|
|||
source_scope_local_data: ClearCrossCrate<IndexVec<SourceScope, SourceScopeLocalData>>,
|
||||
promoted: IndexVec<Promoted, Mir<'tcx>>,
|
||||
yield_ty: Option<Ty<'tcx>>,
|
||||
local_decls: IndexVec<Local, LocalDecl<'tcx>>,
|
||||
local_decls: IndexVec<LocalWithRegion, LocalDecl<'tcx>>,
|
||||
arg_count: usize,
|
||||
upvar_decls: Vec<UpvarDecl>,
|
||||
span: Span,
|
||||
|
|
@ -209,7 +209,7 @@ impl<'tcx> Mir<'tcx> {
|
|||
}
|
||||
|
||||
#[inline]
|
||||
pub fn local_kind(&self, local: Local) -> LocalKind {
|
||||
pub fn local_kind(&self, local: LocalWithRegion) -> LocalKind {
|
||||
let index = local.0 as usize;
|
||||
if index == 0 {
|
||||
debug_assert!(
|
||||
|
|
@ -234,9 +234,9 @@ impl<'tcx> Mir<'tcx> {
|
|||
|
||||
/// Returns an iterator over all temporaries.
|
||||
#[inline]
|
||||
pub fn temps_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
|
||||
pub fn temps_iter<'a>(&'a self) -> impl Iterator<Item = LocalWithRegion> + 'a {
|
||||
(self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
|
||||
let local = Local::new(index);
|
||||
let local = LocalWithRegion::new(index);
|
||||
if self.local_decls[local].is_user_variable.is_some() {
|
||||
None
|
||||
} else {
|
||||
|
|
@ -247,9 +247,9 @@ impl<'tcx> Mir<'tcx> {
|
|||
|
||||
/// Returns an iterator over all user-declared locals.
|
||||
#[inline]
|
||||
pub fn vars_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
|
||||
pub fn vars_iter<'a>(&'a self) -> impl Iterator<Item = LocalWithRegion> + 'a {
|
||||
(self.arg_count + 1..self.local_decls.len()).filter_map(move |index| {
|
||||
let local = Local::new(index);
|
||||
let local = LocalWithRegion::new(index);
|
||||
if self.local_decls[local].is_user_variable.is_some() {
|
||||
Some(local)
|
||||
} else {
|
||||
|
|
@ -260,9 +260,9 @@ impl<'tcx> Mir<'tcx> {
|
|||
|
||||
/// Returns an iterator over all user-declared mutable arguments and locals.
|
||||
#[inline]
|
||||
pub fn mut_vars_and_args_iter<'a>(&'a self) -> impl Iterator<Item = Local> + 'a {
|
||||
pub fn mut_vars_and_args_iter<'a>(&'a self) -> impl Iterator<Item = LocalWithRegion> + 'a {
|
||||
(1..self.local_decls.len()).filter_map(move |index| {
|
||||
let local = Local::new(index);
|
||||
let local = LocalWithRegion::new(index);
|
||||
let decl = &self.local_decls[local];
|
||||
if (decl.is_user_variable.is_some() || index < self.arg_count + 1)
|
||||
&& decl.mutability == Mutability::Mut
|
||||
|
|
@ -2932,3 +2932,5 @@ impl<'tcx> TypeFoldable<'tcx> for Literal<'tcx> {
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
newtype_index!(LocalWithRegion);
|
||||
|
|
@ -146,7 +146,7 @@ macro_rules! make_mir_visitor {
|
|||
|
||||
fn visit_user_assert_ty(&mut self,
|
||||
c_ty: & $($mutability)* CanonicalTy<'tcx>,
|
||||
local: & $($mutability)* Local,
|
||||
local: & $($mutability)* LocalWithRegion,
|
||||
location: Location) {
|
||||
self.super_user_assert_ty(c_ty, local, location);
|
||||
}
|
||||
|
|
@ -250,13 +250,13 @@ macro_rules! make_mir_visitor {
|
|||
}
|
||||
|
||||
fn visit_local_decl(&mut self,
|
||||
local: Local,
|
||||
local: LocalWithRegion,
|
||||
local_decl: & $($mutability)* LocalDecl<'tcx>) {
|
||||
self.super_local_decl(local, local_decl);
|
||||
}
|
||||
|
||||
fn visit_local(&mut self,
|
||||
_local: & $($mutability)* Local,
|
||||
_local: & $($mutability)* LocalWithRegion,
|
||||
_context: PlaceContext<'tcx>,
|
||||
_location: Location) {
|
||||
}
|
||||
|
|
@ -632,7 +632,7 @@ macro_rules! make_mir_visitor {
|
|||
|
||||
fn super_user_assert_ty(&mut self,
|
||||
_c_ty: & $($mutability)* CanonicalTy<'tcx>,
|
||||
local: & $($mutability)* Local,
|
||||
local: & $($mutability)* LocalWithRegion,
|
||||
location: Location) {
|
||||
self.visit_local(local, PlaceContext::Validate, location);
|
||||
}
|
||||
|
|
@ -708,7 +708,7 @@ macro_rules! make_mir_visitor {
|
|||
}
|
||||
|
||||
fn super_local_decl(&mut self,
|
||||
local: Local,
|
||||
local: LocalWithRegion,
|
||||
local_decl: & $($mutability)* LocalDecl<'tcx>) {
|
||||
let LocalDecl {
|
||||
mutability: _,
|
||||
|
|
|
|||
|
|
@ -278,7 +278,7 @@ fn do_mir_borrowck<'a, 'gcx, 'tcx>(
|
|||
// Note that this set is expected to be small - only upvars from closures
|
||||
// would have a chance of erroneously adding non-user-defined mutable vars
|
||||
// to the set.
|
||||
let temporary_used_locals: FxHashSet<Local> = mbcx
|
||||
let temporary_used_locals: FxHashSet<LocalWithRegion> = mbcx
|
||||
.used_mut
|
||||
.iter()
|
||||
.filter(|&local| !mbcx.mir.local_decls[*local].is_user_variable.is_some())
|
||||
|
|
|
|||
|
|
@ -19,7 +19,7 @@ use dataflow::FlowAtLocation;
|
|||
use dataflow::MaybeInitializedPlaces;
|
||||
use rustc::hir::def_id::DefId;
|
||||
use rustc::infer::InferCtxt;
|
||||
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir, Local};
|
||||
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir, LocalWithRegion};
|
||||
use rustc::ty::{self, RegionKind, RegionVid};
|
||||
use rustc::util::nodemap::FxHashMap;
|
||||
use std::collections::BTreeSet;
|
||||
|
|
@ -30,7 +30,7 @@ use std::path::PathBuf;
|
|||
use std::rc::Rc;
|
||||
use std::str::FromStr;
|
||||
use transform::MirSource;
|
||||
use util::liveness::{IdentityMap, LivenessResults, LocalSet};
|
||||
use util::liveness::{IdentityMap, LivenessResults, LocalSet, NllLivenessMap};
|
||||
|
||||
use self::mir_util::PassWhere;
|
||||
use polonius_engine::{Algorithm, Output};
|
||||
|
|
@ -103,7 +103,8 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
|||
let elements = &Rc::new(RegionValueElements::new(mir, universal_regions.len()));
|
||||
|
||||
// Run the MIR type-checker.
|
||||
let liveness = &LivenessResults::compute(mir, &IdentityMap::new(mir));
|
||||
let liveness_map = NllLivenessMap::compute(&mir);
|
||||
let liveness = LivenessResults::compute(mir, &liveness_map);
|
||||
let constraint_sets = type_check::type_check(
|
||||
infcx,
|
||||
param_env,
|
||||
|
|
@ -193,7 +194,7 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
|||
// write unit-tests, as well as helping with debugging.
|
||||
dump_mir_results(
|
||||
infcx,
|
||||
liveness,
|
||||
&liveness,
|
||||
MirSource::item(def_id),
|
||||
&mir,
|
||||
®ioncx,
|
||||
|
|
@ -209,7 +210,7 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
|
|||
|
||||
fn dump_mir_results<'a, 'gcx, 'tcx>(
|
||||
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
|
||||
liveness: &LivenessResults<Local>,
|
||||
liveness: &LivenessResults<LocalWithRegion>,
|
||||
source: MirSource,
|
||||
mir: &Mir<'tcx>,
|
||||
regioncx: &RegionInferenceContext,
|
||||
|
|
@ -407,7 +408,7 @@ impl ToRegionVid for RegionVid {
|
|||
}
|
||||
}
|
||||
|
||||
fn live_variable_set(regular: &LocalSet<Local>, drops: &LocalSet<Local>) -> String {
|
||||
fn live_variable_set(regular: &LocalSet<LocalWithRegion>, drops: &LocalSet<LocalWithRegion>) -> String {
|
||||
// sort and deduplicate:
|
||||
let all_locals: BTreeSet<_> = regular.iter().chain(drops.iter()).collect();
|
||||
|
||||
|
|
|
|||
|
|
@ -13,7 +13,7 @@ use dataflow::move_paths::{HasMoveData, MoveData};
|
|||
use dataflow::MaybeInitializedPlaces;
|
||||
use dataflow::{FlowAtLocation, FlowsAtLocation};
|
||||
use rustc::infer::canonical::QueryRegionConstraint;
|
||||
use rustc::mir::Local;
|
||||
use rustc::mir::{Local, LocalWithRegion};
|
||||
use rustc::mir::{BasicBlock, Location, Mir};
|
||||
use rustc::traits::query::dropck_outlives::DropckOutlivesResult;
|
||||
use rustc::traits::query::type_op::outlives::DropckOutlives;
|
||||
|
|
@ -36,7 +36,7 @@ use super::TypeChecker;
|
|||
pub(super) fn generate<'gcx, 'tcx>(
|
||||
cx: &mut TypeChecker<'_, 'gcx, 'tcx>,
|
||||
mir: &Mir<'tcx>,
|
||||
liveness: &LivenessResults<Local>,
|
||||
liveness: &LivenessResults<LocalWithRegion>,
|
||||
flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
) {
|
||||
|
|
@ -64,7 +64,7 @@ where
|
|||
{
|
||||
cx: &'gen mut TypeChecker<'typeck, 'gcx, 'tcx>,
|
||||
mir: &'gen Mir<'tcx>,
|
||||
liveness: &'gen LivenessResults<Local>,
|
||||
liveness: &'gen LivenessResults<LocalWithRegion>,
|
||||
flow_inits: &'gen mut FlowAtLocation<MaybeInitializedPlaces<'flow, 'gcx, 'tcx>>,
|
||||
move_data: &'gen MoveData<'tcx>,
|
||||
drop_data: FxHashMap<Ty<'tcx>, DropData<'tcx>>,
|
||||
|
|
@ -93,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<LocalWithRegion>)> = vec![];
|
||||
self.liveness
|
||||
.drop
|
||||
.simulate_block(self.mir, bb, self.map, |location, live_locals| {
|
||||
|
|
|
|||
|
|
@ -108,8 +108,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
|
|||
mir_def_id: DefId,
|
||||
universal_regions: &UniversalRegions<'tcx>,
|
||||
location_table: &LocationTable,
|
||||
borrow_set: &BorrowSet<'tcx>,
|
||||
liveness: &LivenessResults,
|
||||
liveness: &LivenessResults<LocalWithRegion>,
|
||||
all_facts: &mut Option<AllFacts>,
|
||||
flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
|
||||
move_data: &MoveData<'tcx>,
|
||||
|
|
|
|||
|
|
@ -37,18 +37,18 @@ impl<'a, 'tcx: 'a> HaveBeenBorrowedLocals<'a, 'tcx> {
|
|||
}
|
||||
|
||||
impl<'a, 'tcx> BitDenotation for HaveBeenBorrowedLocals<'a, 'tcx> {
|
||||
type Idx = Local;
|
||||
type Idx = LocalWithRegion;
|
||||
fn name() -> &'static str { "has_been_borrowed_locals" }
|
||||
fn bits_per_block(&self) -> usize {
|
||||
self.mir.local_decls.len()
|
||||
}
|
||||
|
||||
fn start_block_effect(&self, _sets: &mut IdxSet<Local>) {
|
||||
fn start_block_effect(&self, _sets: &mut IdxSet<LocalWithRegion>) {
|
||||
// Nothing is borrowed on function entry
|
||||
}
|
||||
|
||||
fn statement_effect(&self,
|
||||
sets: &mut BlockSets<Local>,
|
||||
sets: &mut BlockSets<LocalWithRegion>,
|
||||
loc: Location) {
|
||||
BorrowedLocalsVisitor {
|
||||
sets,
|
||||
|
|
@ -56,7 +56,7 @@ impl<'a, 'tcx> BitDenotation for HaveBeenBorrowedLocals<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn terminator_effect(&self,
|
||||
sets: &mut BlockSets<Local>,
|
||||
sets: &mut BlockSets<LocalWithRegion>,
|
||||
loc: Location) {
|
||||
BorrowedLocalsVisitor {
|
||||
sets,
|
||||
|
|
@ -64,7 +64,7 @@ impl<'a, 'tcx> BitDenotation for HaveBeenBorrowedLocals<'a, 'tcx> {
|
|||
}
|
||||
|
||||
fn propagate_call_return(&self,
|
||||
_in_out: &mut IdxSet<Local>,
|
||||
_in_out: &mut IdxSet<LocalWithRegion>,
|
||||
_call_bb: mir::BasicBlock,
|
||||
_dest_bb: mir::BasicBlock,
|
||||
_dest_place: &mir::Place) {
|
||||
|
|
@ -87,10 +87,10 @@ impl<'a, 'tcx> InitialFlow for HaveBeenBorrowedLocals<'a, 'tcx> {
|
|||
}
|
||||
|
||||
struct BorrowedLocalsVisitor<'b, 'c: 'b> {
|
||||
sets: &'b mut BlockSets<'c, Local>,
|
||||
sets: &'b mut BlockSets<'c, LocalWithRegion>,
|
||||
}
|
||||
|
||||
fn find_local<'tcx>(place: &Place<'tcx>) -> Option<Local> {
|
||||
fn find_local<'tcx>(place: &Place<'tcx>) -> Option<LocalWithRegion> {
|
||||
match *place {
|
||||
Place::Local(l) => Some(l),
|
||||
Place::Static(..) => None,
|
||||
|
|
|
|||
|
|
@ -37,8 +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;
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::ty::{item_path, TyCtxt, TypeFoldable};
|
||||
use rustc_data_structures::indexed_set::IdxSetBuf;
|
||||
use rustc_data_structures::indexed_vec::{Idx, IndexVec};
|
||||
use rustc_data_structures::work_queue::WorkQueue;
|
||||
|
|
@ -545,3 +544,42 @@ pub fn write_mir_fn<'a, 'tcx, V: Idx>(
|
|||
writeln!(w, "}}")?;
|
||||
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<_,_> = 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…
Add table
Add a link
Reference in a new issue