handle gen/kill sets together

This commit is contained in:
Ariel Ben-Yehuda 2017-12-04 01:00:46 +02:00
parent 243c5a5faa
commit 210f76816f
3 changed files with 51 additions and 51 deletions

View file

@ -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);
}
// Every path deinitialized by a *particular move*
// has corresponding bit, "gen'ed" (i.e. set)
// here, in dataflow vector
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) => {
@ -614,11 +590,8 @@ impl<'a, 'gcx, 'tcx> BitDenotation for EverInitializedLvals<'a, 'gcx, 'tcx> {
// be reinitialized on the next iteration of the loop.
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);
}
stmt, location, &init_path_map[mpi]);
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 {

View file

@ -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> {

View file

@ -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
}