diff options
Diffstat (limited to 'compiler/rustc_mir_dataflow/src/impls/liveness.rs')
-rw-r--r-- | compiler/rustc_mir_dataflow/src/impls/liveness.rs | 92 |
1 files changed, 45 insertions, 47 deletions
diff --git a/compiler/rustc_mir_dataflow/src/impls/liveness.rs b/compiler/rustc_mir_dataflow/src/impls/liveness.rs index 9662c1977..5aa73c7a9 100644 --- a/compiler/rustc_mir_dataflow/src/impls/liveness.rs +++ b/compiler/rustc_mir_dataflow/src/impls/liveness.rs @@ -1,8 +1,10 @@ use rustc_index::bit_set::{BitSet, ChunkedBitSet}; use rustc_middle::mir::visit::{MutatingUseContext, NonMutatingUseContext, PlaceContext, Visitor}; -use rustc_middle::mir::{self, Local, Location, Place, StatementKind}; +use rustc_middle::mir::{ + self, CallReturnPlaces, Local, Location, Place, StatementKind, TerminatorEdges, +}; -use crate::{Analysis, AnalysisDomain, Backward, CallReturnPlaces, GenKill, GenKillAnalysis}; +use crate::{Analysis, AnalysisDomain, Backward, GenKill, GenKillAnalysis}; /// A [live-variable dataflow analysis][liveness]. /// @@ -43,6 +45,10 @@ impl<'tcx> AnalysisDomain<'tcx> for MaybeLiveLocals { impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals { type Idx = Local; + fn domain_size(&self, body: &mir::Body<'tcx>) -> usize { + body.local_decls.len() + } + fn statement_effect( &mut self, trans: &mut impl GenKill<Self::Idx>, @@ -52,13 +58,14 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals { TransferFunction(trans).visit_statement(statement, location); } - fn terminator_effect( + fn terminator_effect<'mir>( &mut self, - trans: &mut impl GenKill<Self::Idx>, - terminator: &mir::Terminator<'tcx>, + trans: &mut Self::Domain, + terminator: &'mir mir::Terminator<'tcx>, location: Location, - ) { + ) -> TerminatorEdges<'mir, 'tcx> { TransferFunction(trans).visit_terminator(terminator, location); + terminator.edges() } fn call_return_effect( @@ -67,28 +74,23 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals { _block: mir::BasicBlock, return_places: CallReturnPlaces<'_, 'tcx>, ) { - return_places.for_each(|place| { - if let Some(local) = place.as_local() { - trans.kill(local); - } - }); - } - - fn yield_resume_effect( - &mut self, - trans: &mut impl GenKill<Self::Idx>, - _resume_block: mir::BasicBlock, - resume_place: mir::Place<'tcx>, - ) { - YieldResumeEffect(trans).visit_place( - &resume_place, - PlaceContext::MutatingUse(MutatingUseContext::Yield), - Location::START, - ) + if let CallReturnPlaces::Yield(resume_place) = return_places { + YieldResumeEffect(trans).visit_place( + &resume_place, + PlaceContext::MutatingUse(MutatingUseContext::Yield), + Location::START, + ) + } else { + return_places.for_each(|place| { + if let Some(local) = place.as_local() { + trans.kill(local); + } + }); + } } } -struct TransferFunction<'a, T>(&'a mut T); +pub struct TransferFunction<'a, T>(pub &'a mut T); impl<'tcx, T> Visitor<'tcx> for TransferFunction<'_, T> where @@ -97,7 +99,7 @@ where fn visit_place(&mut self, place: &mir::Place<'tcx>, context: PlaceContext, location: Location) { if let PlaceContext::MutatingUse(MutatingUseContext::Yield) = context { // The resume place is evaluated and assigned to only after generator resumes, so its - // effect is handled separately in `yield_resume_effect`. + // effect is handled separately in `call_resume_effect`. return; } @@ -283,13 +285,14 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> { TransferFunction(trans).visit_statement(statement, location); } - fn apply_terminator_effect( + fn apply_terminator_effect<'mir>( &mut self, trans: &mut Self::Domain, - terminator: &mir::Terminator<'tcx>, + terminator: &'mir mir::Terminator<'tcx>, location: Location, - ) { + ) -> TerminatorEdges<'mir, 'tcx> { TransferFunction(trans).visit_terminator(terminator, location); + terminator.edges() } fn apply_call_return_effect( @@ -298,23 +301,18 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> { _block: mir::BasicBlock, return_places: CallReturnPlaces<'_, 'tcx>, ) { - return_places.for_each(|place| { - if let Some(local) = place.as_local() { - trans.remove(local); - } - }); - } - - fn apply_yield_resume_effect( - &mut self, - trans: &mut Self::Domain, - _resume_block: mir::BasicBlock, - resume_place: mir::Place<'tcx>, - ) { - YieldResumeEffect(trans).visit_place( - &resume_place, - PlaceContext::MutatingUse(MutatingUseContext::Yield), - Location::START, - ) + if let CallReturnPlaces::Yield(resume_place) = return_places { + YieldResumeEffect(trans).visit_place( + &resume_place, + PlaceContext::MutatingUse(MutatingUseContext::Yield), + Location::START, + ) + } else { + return_places.for_each(|place| { + if let Some(local) = place.as_local() { + trans.remove(local); + } + }); + } } } |