summaryrefslogtreecommitdiffstats
path: root/compiler/rustc_mir_dataflow/src/impls/liveness.rs
diff options
context:
space:
mode:
Diffstat (limited to 'compiler/rustc_mir_dataflow/src/impls/liveness.rs')
-rw-r--r--compiler/rustc_mir_dataflow/src/impls/liveness.rs92
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);
+ }
+ });
+ }
}
}