Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

only compute liveness for variables whose types include regions #52115

Merged
merged 16 commits into from
Jul 21, 2018
Merged
Show file tree
Hide file tree
Changes from 11 commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions src/librustc/mir/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -2932,3 +2932,5 @@ impl<'tcx> TypeFoldable<'tcx> for Literal<'tcx> {
}
}
}

newtype_index!(LocalWithRegion);
22 changes: 14 additions & 8 deletions src/librustc_mir/borrow_check/nll/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -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};
use rustc::mir::{ClosureOutlivesSubject, ClosureRegionRequirements, Mir, LocalWithRegion};
use rustc::ty::{self, RegionKind, RegionVid};
use rustc::util::nodemap::FxHashMap;
use std::collections::BTreeSet;
Expand All @@ -30,7 +30,7 @@ use std::path::PathBuf;
use std::rc::Rc;
use std::str::FromStr;
use transform::MirSource;
use util::liveness::{LivenessResults, LocalSet};
use util::liveness::{LivenessResults, LocalSet, NllLivenessMap};

use self::mir_util::PassWhere;
use polonius_engine::{Algorithm, Output};
Expand Down Expand Up @@ -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);
let liveness_map = NllLivenessMap::compute(&mir);
let liveness = LivenessResults::compute(mir, &liveness_map);
let constraint_sets = type_check::type_check(
infcx,
param_env,
Expand Down Expand Up @@ -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,
&regioncx,
Expand All @@ -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,
liveness: &LivenessResults<LocalWithRegion>,
source: MirSource,
mir: &Mir<'tcx>,
regioncx: &RegionInferenceContext,
Expand All @@ -219,14 +220,16 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
return;
}

let map = &NllLivenessMap::compute(mir);

let regular_liveness_per_location: FxHashMap<_, _> = mir
.basic_blocks()
.indices()
.flat_map(|bb| {
let mut results = vec![];
liveness
.regular
.simulate_block(&mir, bb, |location, local_set| {
.simulate_block(&mir, bb, map, |location, local_set| {
results.push((location, local_set.clone()));
});
results
Expand All @@ -240,7 +243,7 @@ fn dump_mir_results<'a, 'gcx, 'tcx>(
let mut results = vec![];
liveness
.drop
.simulate_block(&mir, bb, |location, local_set| {
.simulate_block(&mir, bb, map, |location, local_set| {
results.push((location, local_set.clone()));
});
results
Expand Down Expand Up @@ -405,7 +408,10 @@ impl ToRegionVid for RegionVid {
}
}

fn live_variable_set(regular: &LocalSet, drops: &LocalSet) -> 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();

Expand Down
27 changes: 16 additions & 11 deletions src/librustc_mir/borrow_check/nll/type_check/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -13,15 +13,15 @@ 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::LocalWithRegion;
use rustc::mir::{BasicBlock, Location, Mir};
use rustc::traits::query::dropck_outlives::DropckOutlivesResult;
use rustc::traits::query::type_op::outlives::DropckOutlives;
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::LivenessResults;
use util::liveness::{NllLivenessMap, LivenessResults, LiveVariableMap };

use super::TypeChecker;

Expand All @@ -36,7 +36,7 @@ use super::TypeChecker;
pub(super) fn generate<'gcx, 'tcx>(
cx: &mut TypeChecker<'_, 'gcx, 'tcx>,
mir: &Mir<'tcx>,
liveness: &LivenessResults,
liveness: &LivenessResults<LocalWithRegion>,
flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
move_data: &MoveData<'tcx>,
) {
Expand All @@ -47,6 +47,7 @@ pub(super) fn generate<'gcx, 'tcx>(
flow_inits,
move_data,
drop_data: FxHashMap(),
map: &NllLivenessMap::compute(mir),
};

for bb in mir.basic_blocks().indices() {
Expand All @@ -63,10 +64,11 @@ where
{
cx: &'gen mut TypeChecker<'typeck, 'gcx, 'tcx>,
mir: &'gen Mir<'tcx>,
liveness: &'gen LivenessResults,
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>>,
map: &'gen NllLivenessMap,
}

struct DropData<'tcx> {
Expand All @@ -84,17 +86,18 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo

self.liveness
.regular
.simulate_block(self.mir, bb, |location, live_locals| {
.simulate_block(self.mir, bb, self.map, |location, live_locals| {
for live_local in live_locals.iter() {
let live_local_ty = self.mir.local_decls[live_local].ty;
let local = self.map.from_live_var(live_local);
let live_local_ty = self.mir.local_decls[local].ty;
Self::push_type_live_constraint(&mut self.cx, live_local_ty, location);
}
});

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, |location, live_locals| {
.simulate_block(self.mir, bb, self.map, |location, live_locals| {
all_live_locals.push((location, live_locals.iter().collect()));
});
debug!(
Expand All @@ -121,15 +124,17 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo
});
}

let mpi = self.move_data.rev_lookup.find_local(live_local);
let local = self.map.from_live_var(live_local);
let mpi = self.move_data.rev_lookup.find_local(local);
if let Some(initialized_child) = self.flow_inits.has_any_child_of(mpi) {
debug!(
"add_liveness_constraints: mpi={:?} has initialized child {:?}",
self.move_data.move_paths[mpi],
self.move_data.move_paths[initialized_child]
);

let live_local_ty = self.mir.local_decls[live_local].ty;
let local = self.map.from_live_var(live_local);
let live_local_ty = self.mir.local_decls[local].ty;
self.add_drop_live_constraint(live_local, live_local_ty, location);
}
}
Expand Down Expand Up @@ -190,7 +195,7 @@ impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flo
/// particular this takes `#[may_dangle]` into account.
fn add_drop_live_constraint(
&mut self,
dropped_local: Local,
dropped_local: LocalWithRegion,
dropped_ty: Ty<'tcx>,
location: Location,
) {
Expand Down
2 changes: 1 addition & 1 deletion src/librustc_mir/borrow_check/nll/type_check/mod.rs
Original file line number Diff line number Diff line change
Expand Up @@ -109,7 +109,7 @@ pub(crate) fn type_check<'gcx, 'tcx>(
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>,
Expand Down
39 changes: 25 additions & 14 deletions src/librustc_mir/transform/generator.rs
Original file line number Diff line number Diff line change
Expand Up @@ -66,7 +66,7 @@ use rustc::mir::visit::{PlaceContext, Visitor, MutVisitor};
use rustc::ty::{self, TyCtxt, AdtDef, Ty};
use rustc::ty::subst::Substs;
use util::dump_mir;
use util::liveness::{self, LivenessMode};
use util::liveness::{self, IdentityMap, LivenessMode};
use rustc_data_structures::indexed_vec::Idx;
use rustc_data_structures::indexed_set::IdxSetBuf;
use std::collections::HashMap;
Expand Down Expand Up @@ -130,7 +130,7 @@ struct SuspensionPoint {
state: u32,
resume: BasicBlock,
drop: Option<BasicBlock>,
storage_liveness: liveness::LocalSet,
storage_liveness: liveness::LocalSet<Local>,
}

struct TransformVisitor<'a, 'tcx: 'a> {
Expand All @@ -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>,
storage_liveness: HashMap<BasicBlock, liveness::LocalSet<Local>>,

// A list of suspension points, generated during the transform
suspension_points: Vec<SuspensionPoint>,
Expand Down Expand Up @@ -317,7 +317,7 @@ fn replace_result_variable<'tcx>(ret_ty: Ty<'tcx>,
new_ret_local
}

struct StorageIgnored(liveness::LocalSet);
struct StorageIgnored(liveness::LocalSet<Local>);

impl<'tcx> Visitor<'tcx> for StorageIgnored {
fn visit_statement(&mut self,
Expand All @@ -332,7 +332,7 @@ impl<'tcx> Visitor<'tcx> for StorageIgnored {
}
}

struct BorrowedLocals(liveness::LocalSet);
struct BorrowedLocals(liveness::LocalSet<Local>);

fn mark_as_borrowed<'tcx>(place: &Place<'tcx>, locals: &mut BorrowedLocals) {
match *place {
Expand Down Expand Up @@ -361,12 +361,12 @@ impl<'tcx> Visitor<'tcx> for BorrowedLocals {
}
}

fn locals_live_across_suspend_points<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn locals_live_across_suspend_points<'a, 'tcx,>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &Mir<'tcx>,
source: MirSource,
movable: bool) ->
(liveness::LocalSet,
HashMap<BasicBlock, liveness::LocalSet>) {
(liveness::LocalSet<Local>,
HashMap<BasicBlock, liveness::LocalSet<Local>>) {
let dead_unwinds = IdxSetBuf::new_empty(mir.basic_blocks().len());
let node_id = tcx.hir.as_local_node_id(source.def_id).unwrap();

Expand Down Expand Up @@ -397,11 +397,22 @@ 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 liveness = liveness::liveness_of_locals(mir, LivenessMode {
include_regular_use: true,
include_drops: true,
});
liveness::dump_mir(tcx, "generator_liveness", source, mir, &liveness);
let mut liveness = liveness::liveness_of_locals(
mir,
LivenessMode {
include_regular_use: true,
include_drops: true,
},
&IdentityMap::new(mir),
);
liveness::dump_mir(
tcx,
"generator_liveness",
source,
mir,
&IdentityMap::new(mir),
&liveness,
);

let mut storage_liveness_map = HashMap::new();

Expand Down Expand Up @@ -468,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>)
HashMap<BasicBlock, liveness::LocalSet<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,
Expand Down
Loading