Clean up extra lifetime, add assertions
This commit is contained in:
parent
d8ed2e7ed4
commit
a68e2c7161
@ -33,7 +33,9 @@ fn bits_per_block(&self) -> usize {
|
||||
}
|
||||
|
||||
fn start_block_effect(&self, _on_entry: &mut BitSet<Local>) {
|
||||
// Nothing is live on function entry
|
||||
// Nothing is live on function entry (generators only have a self
|
||||
// argument, and we don't care about that)
|
||||
assert_eq!(1, self.body.arg_count);
|
||||
}
|
||||
|
||||
fn statement_effect(&self,
|
||||
@ -72,16 +74,16 @@ impl<'a, 'tcx> BottomValue for MaybeStorageLive<'a, 'tcx> {
|
||||
|
||||
/// Dataflow analysis that determines whether each local requires storage at a
|
||||
/// given location; i.e. whether its storage can go away without being observed.
|
||||
pub struct RequiresStorage<'mir, 'tcx, 'b> {
|
||||
pub struct RequiresStorage<'mir, 'tcx> {
|
||||
body: &'mir Body<'tcx>,
|
||||
borrowed_locals:
|
||||
RefCell<DataflowResultsRefCursor<'mir, 'tcx, 'b, HaveBeenBorrowedLocals<'mir, 'tcx>>>,
|
||||
RefCell<DataflowResultsRefCursor<'mir, 'tcx, HaveBeenBorrowedLocals<'mir, 'tcx>>>,
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx: 'mir, 'b> RequiresStorage<'mir, 'tcx, 'b> {
|
||||
impl<'mir, 'tcx: 'mir> RequiresStorage<'mir, 'tcx> {
|
||||
pub fn new(
|
||||
body: &'mir Body<'tcx>,
|
||||
borrowed_locals: &'b DataflowResults<'tcx, HaveBeenBorrowedLocals<'mir, 'tcx>>,
|
||||
borrowed_locals: &'mir DataflowResults<'tcx, HaveBeenBorrowedLocals<'mir, 'tcx>>,
|
||||
) -> Self {
|
||||
RequiresStorage {
|
||||
body,
|
||||
@ -94,7 +96,7 @@ pub fn body(&self) -> &Body<'tcx> {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx, 'b> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx, 'b> {
|
||||
impl<'mir, 'tcx> BitDenotation<'tcx> for RequiresStorage<'mir, 'tcx> {
|
||||
type Idx = Local;
|
||||
fn name() -> &'static str { "requires_storage" }
|
||||
fn bits_per_block(&self) -> usize {
|
||||
@ -102,7 +104,9 @@ fn bits_per_block(&self) -> usize {
|
||||
}
|
||||
|
||||
fn start_block_effect(&self, _sets: &mut BitSet<Local>) {
|
||||
// Nothing is live on function entry
|
||||
// Nothing is live on function entry (generators only have a self
|
||||
// argument, and we don't care about that)
|
||||
assert_eq!(1, self.body.arg_count);
|
||||
}
|
||||
|
||||
fn statement_effect(&self,
|
||||
@ -146,7 +150,7 @@ fn propagate_call_return(
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx, 'b> RequiresStorage<'mir, 'tcx, 'b> {
|
||||
impl<'mir, 'tcx> RequiresStorage<'mir, 'tcx> {
|
||||
/// Kill locals that are fully moved and have not been borrowed.
|
||||
fn check_for_move(&self, sets: &mut GenKillSet<Local>, loc: Location) {
|
||||
let mut visitor = MoveVisitor {
|
||||
@ -165,18 +169,18 @@ fn check_for_borrow(&self, sets: &mut GenKillSet<Local>, loc: Location) {
|
||||
}
|
||||
}
|
||||
|
||||
impl<'mir, 'tcx, 'b> BottomValue for RequiresStorage<'mir, 'tcx, 'b> {
|
||||
impl<'mir, 'tcx> BottomValue for RequiresStorage<'mir, 'tcx> {
|
||||
/// bottom = dead
|
||||
const BOTTOM_VALUE: bool = false;
|
||||
}
|
||||
|
||||
struct MoveVisitor<'a, 'b, 'mir, 'tcx> {
|
||||
struct MoveVisitor<'a, 'mir, 'tcx> {
|
||||
borrowed_locals:
|
||||
&'a RefCell<DataflowResultsRefCursor<'mir, 'tcx, 'b, HaveBeenBorrowedLocals<'mir, 'tcx>>>,
|
||||
&'a RefCell<DataflowResultsRefCursor<'mir, 'tcx, HaveBeenBorrowedLocals<'mir, 'tcx>>>,
|
||||
sets: &'a mut GenKillSet<Local>,
|
||||
}
|
||||
|
||||
impl<'a, 'b, 'mir: 'a, 'tcx> Visitor<'tcx> for MoveVisitor<'a, 'b, 'mir, 'tcx> {
|
||||
impl<'a, 'mir: 'a, 'tcx> Visitor<'tcx> for MoveVisitor<'a, 'mir, 'tcx> {
|
||||
fn visit_local(&mut self, local: &Local, context: PlaceContext, loc: Location) {
|
||||
if PlaceContext::NonMutatingUse(NonMutatingUseContext::Move) == context {
|
||||
let mut borrowed_locals = self.borrowed_locals.borrow_mut();
|
||||
|
@ -359,8 +359,8 @@ pub struct DataflowResultsCursor<'mir, 'tcx, BD, DR = DataflowResults<'tcx, BD>>
|
||||
body: &'mir Body<'tcx>,
|
||||
}
|
||||
|
||||
pub type DataflowResultsRefCursor<'mir, 'tcx, 'flow, BD> =
|
||||
DataflowResultsCursor<'mir, 'tcx, BD, &'flow DataflowResults<'tcx, BD>>;
|
||||
pub type DataflowResultsRefCursor<'mir, 'tcx, BD> =
|
||||
DataflowResultsCursor<'mir, 'tcx, BD, &'mir DataflowResults<'tcx, BD>>;
|
||||
|
||||
impl<'mir, 'tcx, BD, DR> DataflowResultsCursor<'mir, 'tcx, BD, DR>
|
||||
where
|
||||
|
@ -62,7 +62,6 @@
|
||||
use rustc_data_structures::bit_set::{BitSet, BitMatrix};
|
||||
use std::borrow::Cow;
|
||||
use std::iter;
|
||||
use std::marker::PhantomData;
|
||||
use std::mem;
|
||||
use crate::transform::{MirPass, MirSource};
|
||||
use crate::transform::simplify;
|
||||
@ -578,8 +577,8 @@ fn compute_storage_conflicts(
|
||||
body: &'mir Body<'tcx>,
|
||||
stored_locals: &liveness::LiveVarSet,
|
||||
ignored: &StorageIgnored,
|
||||
requires_storage: DataflowResults<'tcx, RequiresStorage<'mir, 'tcx, '_>>,
|
||||
_requires_storage_analysis: RequiresStorage<'mir, 'tcx, '_>,
|
||||
requires_storage: DataflowResults<'tcx, RequiresStorage<'mir, 'tcx>>,
|
||||
_requires_storage_analysis: RequiresStorage<'mir, 'tcx>,
|
||||
) -> BitMatrix<GeneratorSavedLocal, GeneratorSavedLocal> {
|
||||
assert_eq!(body.local_decls.len(), ignored.0.domain_size());
|
||||
assert_eq!(body.local_decls.len(), stored_locals.domain_size());
|
||||
@ -596,7 +595,6 @@ fn compute_storage_conflicts(
|
||||
body,
|
||||
stored_locals: &stored_locals,
|
||||
local_conflicts: BitMatrix::from_row_n(&ineligible_locals, body.local_decls.len()),
|
||||
_phantom: PhantomData::default(),
|
||||
};
|
||||
let mut state = FlowAtLocation::new(requires_storage);
|
||||
visitor.analyze_results(&mut state);
|
||||
@ -628,19 +626,18 @@ fn compute_storage_conflicts(
|
||||
storage_conflicts
|
||||
}
|
||||
|
||||
struct StorageConflictVisitor<'body: 'b, 'tcx, 's, 'b> {
|
||||
struct StorageConflictVisitor<'body, 'tcx, 's> {
|
||||
body: &'body Body<'tcx>,
|
||||
stored_locals: &'s liveness::LiveVarSet,
|
||||
// FIXME(tmandry): Consider using sparse bitsets here once we have good
|
||||
// benchmarks for generators.
|
||||
local_conflicts: BitMatrix<Local, Local>,
|
||||
_phantom: PhantomData<&'b ()>,
|
||||
}
|
||||
|
||||
impl<'body, 'tcx, 's, 'b> DataflowResultsConsumer<'body, 'tcx>
|
||||
for StorageConflictVisitor<'body, 'tcx, 's, 'b>
|
||||
impl<'body, 'tcx, 's> DataflowResultsConsumer<'body, 'tcx>
|
||||
for StorageConflictVisitor<'body, 'tcx, 's>
|
||||
{
|
||||
type FlowState = FlowAtLocation<'tcx, RequiresStorage<'body, 'tcx, 'b>>;
|
||||
type FlowState = FlowAtLocation<'tcx, RequiresStorage<'body, 'tcx>>;
|
||||
|
||||
fn body(&self) -> &'body Body<'tcx> {
|
||||
self.body
|
||||
@ -668,9 +665,9 @@ fn visit_terminator_entry(&mut self,
|
||||
}
|
||||
}
|
||||
|
||||
impl<'body, 'tcx, 's, 'b> StorageConflictVisitor<'body, 'tcx, 's, 'b> {
|
||||
impl<'body, 'tcx, 's> StorageConflictVisitor<'body, 'tcx, 's> {
|
||||
fn apply_state(&mut self,
|
||||
flow_state: &FlowAtLocation<'tcx, RequiresStorage<'body, 'tcx, 'b>>,
|
||||
flow_state: &FlowAtLocation<'tcx, RequiresStorage<'body, 'tcx>>,
|
||||
loc: Location) {
|
||||
// Ignore unreachable blocks.
|
||||
match self.body.basic_blocks()[loc.block].terminator().kind {
|
||||
|
Loading…
Reference in New Issue
Block a user