handle gen/kill sets together
This commit is contained in:
parent
243c5a5faa
commit
210f76816f
3 changed files with 51 additions and 51 deletions
|
@ -14,7 +14,6 @@
|
|||
|
||||
use rustc::ty::TyCtxt;
|
||||
use rustc::mir::{self, Mir, Location};
|
||||
use rustc_data_structures::bitslice::BitSlice; // adds set_bit/get_bit to &[usize] bitvector rep.
|
||||
use rustc_data_structures::bitslice::{BitwiseOperator};
|
||||
use rustc_data_structures::indexed_set::{IdxSet};
|
||||
use rustc_data_structures::indexed_vec::Idx;
|
||||
|
@ -504,7 +503,6 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MovingOutStatements<'a, 'gcx, 'tcx> {
|
|||
let stmt = &mir[location.block].statements[location.statement_index];
|
||||
let loc_map = &move_data.loc_map;
|
||||
let path_map = &move_data.path_map;
|
||||
let bits_per_block = self.bits_per_block();
|
||||
|
||||
match stmt.kind {
|
||||
// this analysis only tries to find moves explicitly
|
||||
|
@ -515,21 +513,15 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MovingOutStatements<'a, 'gcx, 'tcx> {
|
|||
_ => {
|
||||
debug!("stmt {:?} at loc {:?} moves out of move_indexes {:?}",
|
||||
stmt, location, &loc_map[location]);
|
||||
for move_index in &loc_map[location] {
|
||||
// Every path deinitialized by a *particular move*
|
||||
// has corresponding bit, "gen'ed" (i.e. set)
|
||||
// here, in dataflow vector
|
||||
zero_to_one(sets.gen_set.words_mut(), *move_index);
|
||||
}
|
||||
sets.gen_all_and_assert_dead(&loc_map[location]);
|
||||
}
|
||||
}
|
||||
|
||||
for_location_inits(tcx, mir, move_data, location,
|
||||
|mpi| for moi in &path_map[mpi] {
|
||||
assert!(moi.index() < bits_per_block);
|
||||
sets.kill_set.add(&moi);
|
||||
}
|
||||
);
|
||||
|mpi| sets.kill_all(&path_map[mpi]));
|
||||
}
|
||||
|
||||
fn terminator_effect(&self,
|
||||
|
@ -543,18 +535,10 @@ impl<'a, 'gcx, 'tcx> BitDenotation for MovingOutStatements<'a, 'gcx, 'tcx> {
|
|||
|
||||
debug!("terminator {:?} at loc {:?} moves out of move_indexes {:?}",
|
||||
term, location, &loc_map[location]);
|
||||
let bits_per_block = self.bits_per_block();
|
||||
for move_index in &loc_map[location] {
|
||||
assert!(move_index.index() < bits_per_block);
|
||||
zero_to_one(sets.gen_set.words_mut(), *move_index);
|
||||
}
|
||||
sets.gen_all_and_assert_dead(&loc_map[location]);
|
||||
|
||||
for_location_inits(tcx, mir, move_data, location,
|
||||
|mpi| for moi in &path_map[mpi] {
|
||||
assert!(moi.index() < bits_per_block);
|
||||
sets.kill_set.add(&moi);
|
||||
}
|
||||
);
|
||||
|mpi| sets.kill_all(&path_map[mpi]));
|
||||
}
|
||||
|
||||
fn propagate_call_return(&self,
|
||||
|
@ -585,11 +569,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
|
||||
fn start_block_effect(&self, sets: &mut BlockSets<InitIndex>) {
|
||||
let bits_per_block = self.bits_per_block();
|
||||
for init_index in (0..self.mir.arg_count).map(InitIndex::new) {
|
||||
assert!(init_index.index() < bits_per_block);
|
||||
sets.gen_set.add(&init_index);
|
||||
}
|
||||
sets.gen_all((0..self.mir.arg_count).map(InitIndex::new));
|
||||
}
|
||||
fn statement_effect(&self,
|
||||
sets: &mut BlockSets<InitIndex>,
|
||||
|
@ -599,14 +579,10 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
|
|||
let init_path_map = &move_data.init_path_map;
|
||||
let init_loc_map = &move_data.init_loc_map;
|
||||
let rev_lookup = &move_data.rev_lookup;
|
||||
let bits_per_block = self.bits_per_block();
|
||||
|
||||
debug!("statement {:?} at loc {:?} initializes move_indexes {:?}",
|
||||
stmt, location, &init_loc_map[location]);
|
||||
for init_index in &init_loc_map[location] {
|
||||
assert!(init_index.index() < bits_per_block);
|
||||
sets.gen_set.add(init_index);
|
||||
}
|
||||
sets.gen_all(&init_loc_map[location]);
|
||||
|
||||
match stmt.kind {
|
||||
mir::StatementKind::StorageDead(local) => {
|
||||
|
@ -615,10 +591,7 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
|
|||
if let LookupResult::Exact(mpi) = rev_lookup.find(&mir::Place::Local(local)) {
|
||||
debug!("stmt {:?} at loc {:?} clears the ever initialized status of {:?}",
|
||||
stmt, location, &init_path_map[mpi]);
|
||||
for ii in &init_path_map[mpi] {
|
||||
assert!(ii.index() < bits_per_block);
|
||||
sets.kill_set.add(&ii);
|
||||
}
|
||||
sets.kill_all(&init_path_map[mpi]);
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
|
@ -634,13 +607,11 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
|
|||
let init_loc_map = &move_data.init_loc_map;
|
||||
debug!("terminator {:?} at loc {:?} initializes move_indexes {:?}",
|
||||
term, location, &init_loc_map[location]);
|
||||
let bits_per_block = self.bits_per_block();
|
||||
for init_index in &init_loc_map[location] {
|
||||
if move_data.inits[*init_index].kind != InitKind::NonPanicPathOnly {
|
||||
assert!(init_index.index() < bits_per_block);
|
||||
sets.gen_set.add(init_index);
|
||||
}
|
||||
}
|
||||
sets.gen_all(
|
||||
init_loc_map[location].iter().filter(|init_index| {
|
||||
move_data.inits[**init_index].kind != InitKind::NonPanicPathOnly
|
||||
})
|
||||
);
|
||||
}
|
||||
|
||||
fn propagate_call_return(&self,
|
||||
|
@ -663,11 +634,6 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
|
|||
}
|
||||
}
|
||||
|
||||
fn zero_to_one(bitvec: &mut [usize], move_index: MoveOutIndex) {
|
||||
let retval = bitvec.set_bit(move_index.index());
|
||||
assert!(retval);
|
||||
}
|
||||
|
||||
impl<'a, 'gcx, 'tcx> BitwiseOperator for MaybeInitializedLvals<'a, 'gcx, 'tcx> {
|
||||
#[inline]
|
||||
fn join(&self, pred1: usize, pred2: usize) -> usize {
|
||||
|
|
|
@ -18,6 +18,7 @@ use rustc::ty::{self, TyCtxt};
|
|||
use rustc::mir::{self, Mir, BasicBlock, BasicBlockData, Location, Statement, Terminator};
|
||||
use rustc::session::Session;
|
||||
|
||||
use std::borrow::Borrow;
|
||||
use std::fmt::{self, Debug};
|
||||
use std::io;
|
||||
use std::mem;
|
||||
|
@ -492,10 +493,39 @@ impl<'a, E:Idx> BlockSets<'a, E> {
|
|||
self.gen_set.add(e);
|
||||
self.kill_set.remove(e);
|
||||
}
|
||||
fn gen_all<I>(&mut self, i: I)
|
||||
where I: IntoIterator,
|
||||
I::Item: Borrow<E>
|
||||
{
|
||||
for j in i {
|
||||
self.gen(j.borrow());
|
||||
}
|
||||
}
|
||||
|
||||
fn gen_all_and_assert_dead<I>(&mut self, i: I)
|
||||
where I: IntoIterator,
|
||||
I::Item: Borrow<E>
|
||||
{
|
||||
for j in i {
|
||||
let j = j.borrow();
|
||||
let retval = self.gen_set.add(j);
|
||||
self.kill_set.remove(j);
|
||||
assert!(retval);
|
||||
}
|
||||
}
|
||||
|
||||
fn kill(&mut self, e: &E) {
|
||||
self.gen_set.remove(e);
|
||||
self.kill_set.add(e);
|
||||
}
|
||||
fn kill_all<I>(&mut self, i: I)
|
||||
where I: IntoIterator,
|
||||
I::Item: Borrow<E>
|
||||
{
|
||||
for j in i {
|
||||
self.kill(j.borrow());
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<E:Idx> AllSets<E> {
|
||||
|
|
|
@ -8,6 +8,9 @@
|
|||
// option. This file may not be copied, modified, or distributed
|
||||
// except according to those terms.
|
||||
|
||||
// revisions: ast mir
|
||||
//[mir]compile-flags: -Z borrowck=mir
|
||||
|
||||
#![feature(box_syntax)]
|
||||
|
||||
fn call_f<F:FnOnce() -> isize>(f: F) -> isize {
|
||||
|
@ -18,5 +21,6 @@ fn main() {
|
|||
let t: Box<_> = box 3;
|
||||
|
||||
call_f(move|| { *t + 1 });
|
||||
call_f(move|| { *t + 1 }); //~ ERROR capture of moved value
|
||||
call_f(move|| { *t + 1 }); //[ast]~ ERROR capture of moved value
|
||||
//[mir]~^ ERROR use of moved value
|
||||
}
|
||||
|
|
Loading…
Reference in a new issue