add trait structs and other changes from V to local

This commit is contained in:
dylan_DPC 2018-07-08 02:14:57 +05:30
parent 38c7d1ab7c
commit f2b5583f60
4 changed files with 84 additions and 56 deletions

View File

@ -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, Local};
use rustc::ty::{self, RegionKind, RegionVid};
use rustc::util::nodemap::FxHashMap;
use rustc_data_structures::indexed_vec::Idx;
@ -208,9 +208,9 @@ pub(in borrow_check) fn compute_regions<'cx, 'gcx, 'tcx>(
(regioncx, polonius_output, closure_region_requirements)
}
fn dump_mir_results<'a, 'gcx, 'tcx, V: Idx>(
fn dump_mir_results<'a, 'gcx, 'tcx>(
infcx: &InferCtxt<'a, 'gcx, 'tcx>,
liveness: &LivenessResults<V>,
liveness: &LivenessResults<Local>,
source: MirSource,
mir: &Mir<'tcx>,
regioncx: &RegionInferenceContext,
@ -406,7 +406,7 @@ impl ToRegionVid for RegionVid {
}
}
fn live_variable_set<V: Idx>(regular: &LocalSet<V>, drops: &LocalSet<V>) -> String {
fn live_variable_set(regular: &LocalSet<Local>, drops: &LocalSet<Local>) -> String {
// sort and deduplicate:
let all_locals: BTreeSet<_> = regular.iter().chain(drops.iter()).collect();

View File

@ -34,10 +34,10 @@ use super::TypeChecker;
///
/// NB. This computation requires normalization; therefore, it must be
/// performed before
pub(super) fn generate<'gcx, 'tcx, V: Idx>(
pub(super) fn generate<'gcx, 'tcx>(
cx: &mut TypeChecker<'_, 'gcx, 'tcx>,
mir: &Mir<'tcx>,
liveness: &LivenessResults<V>,
liveness: &LivenessResults<Local>,
flow_inits: &mut FlowAtLocation<MaybeInitializedPlaces<'_, 'gcx, 'tcx>>,
move_data: &MoveData<'tcx>,
) {
@ -55,17 +55,16 @@ pub(super) fn generate<'gcx, 'tcx, V: Idx>(
}
}
struct TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx, V>
struct TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx>
where
'typeck: 'gen,
'flow: 'gen,
'tcx: 'typeck + 'flow,
'gcx: 'tcx,
V: Idx + 'gen,
{
cx: &'gen mut TypeChecker<'typeck, 'gcx, 'tcx>,
mir: &'gen Mir<'tcx>,
liveness: &'gen LivenessResults<V>,
liveness: &'gen LivenessResults<Local>,
flow_inits: &'gen mut FlowAtLocation<MaybeInitializedPlaces<'flow, 'gcx, 'tcx>>,
move_data: &'gen MoveData<'tcx>,
drop_data: FxHashMap<Ty<'tcx>, DropData<'tcx>>,
@ -76,7 +75,7 @@ struct DropData<'tcx> {
region_constraint_data: Option<Rc<Vec<QueryRegionConstraint<'tcx>>>>,
}
impl<'gen, 'typeck, 'flow, 'gcx, 'tcx, V: Idx> TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx, V> {
impl<'gen, 'typeck, 'flow, 'gcx, 'tcx> TypeLivenessGenerator<'gen, 'typeck, 'flow, 'gcx, 'tcx> {
/// Liveness constraints:
///
/// > If a variable V is live at point P, then all regions R in the type of V

View File

@ -126,14 +126,14 @@ fn self_arg() -> Local {
Local::new(1)
}
struct SuspensionPoint<V: Idx> {
struct SuspensionPoint {
state: u32,
resume: BasicBlock,
drop: Option<BasicBlock>,
storage_liveness: liveness::LocalSet<V>,
storage_liveness: liveness::LocalSet<Local>,
}
struct TransformVisitor<'a, 'tcx: 'a, V: Idx> {
struct TransformVisitor<'a, 'tcx: 'a> {
tcx: TyCtxt<'a, 'tcx, 'tcx>,
state_adt_ref: &'tcx AdtDef,
state_substs: &'tcx Substs<'tcx>,
@ -145,16 +145,16 @@ struct TransformVisitor<'a, 'tcx: 'a, V: Idx> {
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<V>>,
storage_liveness: HashMap<BasicBlock, liveness::LocalSet<Local>>,
// A list of suspension points, generated during the transform
suspension_points: Vec<SuspensionPoint<V>>,
suspension_points: Vec<SuspensionPoint>,
// The original RETURN_PLACE local
new_ret_local: Local,
}
impl<'a, 'tcx, V: Idx> TransformVisitor<'a, 'tcx, V> {
impl<'a, 'tcx> TransformVisitor<'a, 'tcx> {
// Make a GeneratorState rvalue
fn make_state(&self, idx: usize, val: Operand<'tcx>) -> Rvalue<'tcx> {
let adt = AggregateKind::Adt(self.state_adt_ref, idx, self.state_substs, None);
@ -191,7 +191,7 @@ impl<'a, 'tcx, V: Idx> TransformVisitor<'a, 'tcx, V> {
}
}
impl<'a, 'tcx, V: Idx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx, V> {
impl<'a, 'tcx> MutVisitor<'tcx> for TransformVisitor<'a, 'tcx> {
fn visit_local(&mut self,
local: &mut Local,
_: PlaceContext<'tcx>,
@ -317,9 +317,9 @@ fn replace_result_variable<'tcx>(ret_ty: Ty<'tcx>,
new_ret_local
}
struct StorageIgnored<V: Idx>(liveness::LocalSet<V>);
struct StorageIgnored(liveness::LocalSet<Local>);
impl<'tcx, V: Idx> Visitor<'tcx> for StorageIgnored<V> {
impl<'tcx> Visitor<'tcx> for StorageIgnored {
fn visit_statement(&mut self,
_block: BasicBlock,
statement: &Statement<'tcx>,
@ -332,9 +332,9 @@ impl<'tcx, V: Idx> Visitor<'tcx> for StorageIgnored<V> {
}
}
struct BorrowedLocals<V: Idx>(liveness::LocalSet<V>);
struct BorrowedLocals(liveness::LocalSet<Local>);
fn mark_as_borrowed<'tcx, V: Idx>(place: &Place<'tcx>, locals: &mut BorrowedLocals<V>) {
fn mark_as_borrowed<'tcx, V: Idx>(place: &Place<'tcx>, locals: &mut BorrowedLocals) {
match *place {
Place::Local(l) => { locals.0.add(&l); },
Place::Static(..) => (),
@ -349,7 +349,7 @@ fn mark_as_borrowed<'tcx, V: Idx>(place: &Place<'tcx>, locals: &mut BorrowedLoca
}
}
impl<'tcx, V: Idx> Visitor<'tcx> for BorrowedLocals<V> {
impl<'tcx> Visitor<'tcx> for BorrowedLocals {
fn visit_rvalue(&mut self,
rvalue: &Rvalue<'tcx>,
location: Location) {
@ -361,12 +361,12 @@ impl<'tcx, V: Idx> Visitor<'tcx> for BorrowedLocals<V> {
}
}
fn locals_live_across_suspend_points<'a, 'tcx, V: Idx>(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<V>,
HashMap<BasicBlock, liveness::LocalSet<V>>) {
(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();
@ -460,7 +460,7 @@ fn locals_live_across_suspend_points<'a, 'tcx, V: Idx>(tcx: TyCtxt<'a, 'tcx, 'tc
(set, storage_liveness_map)
}
fn compute_layout<'a, 'tcx, V: Idx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn compute_layout<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
source: MirSource,
upvars: Vec<Ty<'tcx>>,
interior: Ty<'tcx>,
@ -468,7 +468,7 @@ fn compute_layout<'a, 'tcx, V: Idx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &mut Mir<'tcx>)
-> (HashMap<Local, (Ty<'tcx>, usize)>,
GeneratorLayout<'tcx>,
HashMap<BasicBlock, liveness::LocalSet<V>>)
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,
@ -524,10 +524,10 @@ fn compute_layout<'a, 'tcx, V: Idx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
(remap, layout, storage_liveness)
}
fn insert_switch<'a, 'tcx, V: Idx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
fn insert_switch<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
mir: &mut Mir<'tcx>,
cases: Vec<(u32, BasicBlock)>,
transform: &TransformVisitor<'a, 'tcx, V>,
transform: &TransformVisitor<'a, 'tcx>,
default: TerminatorKind<'tcx>) {
let default_block = insert_term_block(mir, default);
@ -608,9 +608,9 @@ fn elaborate_generator_drops<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
}
}
fn create_generator_drop_shim<'a, 'tcx, V: Idx>(
fn create_generator_drop_shim<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
transform: &TransformVisitor<'a, 'tcx, V>,
transform: &TransformVisitor<'a, 'tcx>,
def_id: DefId,
source: MirSource,
gen_ty: Ty<'tcx>,
@ -719,9 +719,9 @@ fn insert_panic_block<'a, 'tcx>(tcx: TyCtxt<'a, 'tcx, 'tcx>,
assert_block
}
fn create_generator_resume_function<'a, 'tcx, V: Idx>(
fn create_generator_resume_function<'a, 'tcx>(
tcx: TyCtxt<'a, 'tcx, 'tcx>,
transform: TransformVisitor<'a, 'tcx, V>,
transform: TransformVisitor<'a, 'tcx>,
def_id: DefId,
source: MirSource,
mir: &mut Mir<'tcx>) {
@ -790,10 +790,10 @@ fn insert_clean_drop<'a, 'tcx>(mir: &mut Mir<'tcx>) -> BasicBlock {
drop_clean
}
fn create_cases<'a, 'tcx, F, V: Idx>(mir: &mut Mir<'tcx>,
transform: &TransformVisitor<'a, 'tcx, V>,
fn create_cases<'a, 'tcx, F>(mir: &mut Mir<'tcx>,
transform: &TransformVisitor<'a, 'tcx>,
target: F) -> Vec<(u32, BasicBlock)>
where F: Fn(&SuspensionPoint<V>) -> Option<BasicBlock> {
where F: Fn(&SuspensionPoint) -> Option<BasicBlock> {
let source_info = source_info(mir);
transform.suspension_points.iter().filter_map(|point| {

View File

@ -40,6 +40,7 @@ use rustc_data_structures::indexed_set::IdxSetBuf;
use rustc_data_structures::work_queue::WorkQueue;
use util::pretty::{dump_enabled, write_basic_block, write_mir_intro};
use rustc::ty::item_path;
use rustc::mir::Local;
use rustc::mir::visit::MirVisitable;
use std::path::{Path, PathBuf};
use std::fs;
@ -61,6 +62,28 @@ pub struct LivenessResult<V: Idx> {
pub outs: IndexVec<BasicBlock, LocalSet<V>>,
}
trait LiveVariableMap {
type LiveVar;
fn from_local(&self, local: Local) -> Option<Self::LiveVar>;
fn from_live_var(&self, local: Self::LiveVar) -> Local;
}
#[derive(Eq, PartialEq, Clone)]
struct IdentityMap;
impl LiveVariableMap for IdentityMap {
type LiveVar = Local;
fn from_local(&self, local: Local) -> Option<Self::LiveVar> {
Some(local)
}
fn from_live_var(&self, local: Self::LiveVar) -> Local {
local
}
}
#[derive(Copy, Clone, Debug)]
pub struct LivenessMode {
/// If true, then we will consider "regular uses" of a variable to be live.
@ -91,7 +114,7 @@ pub struct LivenessResults<V: Idx> {
}
impl<V: Idx> LivenessResults<V> {
pub fn compute<'tcx>(mir: &Mir<'tcx>) -> LivenessResults<V> {
pub fn compute<'tcx>(mir: &Mir<'tcx>, map: &dyn LiveVariableMap<LiveVar = V>) -> LivenessResults<V> {
LivenessResults {
regular: liveness_of_locals(
&mir,
@ -187,6 +210,7 @@ where V:Idx
defs_uses: DefsUses {
defs: LocalSet::new_empty(locals),
uses: LocalSet::new_empty(locals),
map: &IdentityMap {},
},
};
// Visit the various parts of the basic block in reverse. If we go
@ -283,25 +307,26 @@ pub fn categorize<'tcx>(context: PlaceContext<'tcx>, mode: LivenessMode) -> Opti
}
}
struct DefsUsesVisitor<V: Idx> {
struct DefsUsesVisitor<'lv> {
mode: LivenessMode,
defs_uses: DefsUses<V>,
defs_uses: DefsUses<'lv>,
}
#[derive(Eq, PartialEq, Clone)]
struct DefsUses<V: Idx>
struct DefsUses<'lv>
{
defs: LocalSet<V>,
uses: LocalSet<V>,
defs: LocalSet<Local>,
uses: LocalSet<Local>,
map: &'lv dyn LiveVariableMap<LiveVar=Local>,
}
impl<V: Idx> DefsUses<V> {
impl<'lv> DefsUses<'lv> {
fn clear(&mut self) {
self.uses.clear();
self.defs.clear();
}
fn apply(&self, bits: &mut LocalSet<V>) -> bool {
fn apply(&self, bits: &mut LocalSet<Local>) -> bool {
bits.subtract(&self.defs) | bits.union(&self.uses)
}
@ -315,8 +340,10 @@ impl<V: Idx> DefsUses<V> {
// X = 5
// // Defs = {}, Uses = {X}
// use(X)
self.uses.remove(&index);
self.defs.add(&index);
if let Some(v_index) = self.map.from_local(index) {
self.uses.remove(&v_index);
self.defs.add(&v_index);
}
}
fn add_use(&mut self, index: Local) {
@ -330,22 +357,23 @@ impl<V: Idx> DefsUses<V> {
// X = 5
// // Defs = {}, Uses = {X}
// use(X)
self.defs.remove(&index);
self.uses.add(&index);
if let Some(v_index) = self.map.from_local(index) {
self.defs.remove(&v_index);
self.uses.add(&v_index);
}
}
}
impl<V> DefsUsesVisitor<V>
where V: Idx
impl<'lv> DefsUsesVisitor<'lv>
{
/// Update `bits` with the effects of `value` and call `callback`. We
/// should always visit in reverse order. This method assumes that we have
/// not visited anything before; if you have, clear `bits` first.
fn update_bits_and_do_callback<'tcx, OP>(&mut self, location: Location,
value: &impl MirVisitable<'tcx>, bits: &mut LocalSet<V>,
value: &impl MirVisitable<'tcx>, bits: &mut LocalSet<Local>,
callback: &mut OP)
where
OP: FnMut(Location, &LocalSet<V>),
OP: FnMut(Location, &LocalSet<Local>),
{
value.apply(location, self);
self.defs_uses.apply(bits);
@ -353,7 +381,7 @@ where V: Idx
}
}
impl<'tcx, V: Idx> Visitor<'tcx> for DefsUsesVisitor<V> {
impl<'tcx, 'lv> Visitor<'tcx> for DefsUsesVisitor<'lv> {
fn visit_local(&mut self, &local: &Local, context: PlaceContext<'tcx>, _: Location) {
match categorize(context, self.mode) {
Some(DefUse::Def) => {
@ -369,12 +397,13 @@ impl<'tcx, V: Idx> Visitor<'tcx> for DefsUsesVisitor<V> {
}
}
fn block<'tcx, V: Idx>(mode: LivenessMode, b: &BasicBlockData<'tcx>, locals: usize) -> DefsUses<V> {
fn block<'tcx, 'lv>(mode: LivenessMode, b: &BasicBlockData<'tcx>, locals: usize) -> DefsUses<'lv> {
let mut visitor = DefsUsesVisitor {
mode,
defs_uses: DefsUses {
defs: LocalSet::new_empty(locals),
uses: LocalSet::new_empty(locals),
map: &IdentityMap {},
},
};
@ -398,7 +427,7 @@ pub fn dump_mir<'a, 'tcx, V: Idx>(
pass_name: &str,
source: MirSource,
mir: &Mir<'tcx>,
result: &LivenessResult<V>,
result: &LivenessResult<Local>,
) {
if !dump_enabled(tcx, pass_name, source) {
return;
@ -442,7 +471,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>| {
let print = |w: &mut dyn Write, prefix, result: &IndexVec<BasicBlock, LocalSet<V>>| {
let live: Vec<String> = mir.local_decls
.indices()
.filter(|i| result[block].contains(i))