Only evaluate yield place after resume in liveness.

This commit is contained in:
Camille GILLOT 2023-05-27 17:20:48 +00:00
parent 7ded3409b8
commit e9990ce89c

View File

@ -74,13 +74,19 @@ fn call_return_effect(
_block: mir::BasicBlock, _block: mir::BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>, return_places: CallReturnPlaces<'_, 'tcx>,
) { ) {
return_places.for_each(|place| { if let CallReturnPlaces::Yield(resume_place) = return_places {
CallReturnEffect(trans).visit_place( YieldResumeEffect(trans).visit_place(
&place, &resume_place,
PlaceContext::MutatingUse(MutatingUseContext::Store), PlaceContext::MutatingUse(MutatingUseContext::Yield),
Location::START, Location::START,
) )
}); } else {
return_places.for_each(|place| {
if let Some(local) = place.as_local() {
trans.kill(local);
}
});
}
} }
} }
@ -91,12 +97,16 @@ impl<'tcx, T> Visitor<'tcx> for TransferFunction<'_, T>
T: GenKill<Local>, T: GenKill<Local>,
{ {
fn visit_place(&mut self, place: &mir::Place<'tcx>, context: PlaceContext, location: Location) { 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 `call_resume_effect`.
return;
}
match DefUse::for_place(*place, context) { match DefUse::for_place(*place, context) {
Some(DefUse::Def) => { Some(DefUse::Def) => {
if let PlaceContext::MutatingUse( if let PlaceContext::MutatingUse(
MutatingUseContext::Yield MutatingUseContext::Call | MutatingUseContext::AsmOutput,
| MutatingUseContext::Call
| MutatingUseContext::AsmOutput,
) = context ) = context
{ {
// For the associated terminators, this is only a `Def` when the terminator returns // For the associated terminators, this is only a `Def` when the terminator returns
@ -119,9 +129,9 @@ fn visit_local(&mut self, local: Local, context: PlaceContext, _: Location) {
} }
} }
struct CallReturnEffect<'a, T>(&'a mut T); struct YieldResumeEffect<'a, T>(&'a mut T);
impl<'tcx, T> Visitor<'tcx> for CallReturnEffect<'_, T> impl<'tcx, T> Visitor<'tcx> for YieldResumeEffect<'_, T>
where where
T: GenKill<Local>, T: GenKill<Local>,
{ {
@ -291,12 +301,18 @@ fn apply_call_return_effect(
_block: mir::BasicBlock, _block: mir::BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>, return_places: CallReturnPlaces<'_, 'tcx>,
) { ) {
return_places.for_each(|place| { if let CallReturnPlaces::Yield(resume_place) = return_places {
CallReturnEffect(trans).visit_place( YieldResumeEffect(trans).visit_place(
&place, &resume_place,
PlaceContext::MutatingUse(MutatingUseContext::Store), PlaceContext::MutatingUse(MutatingUseContext::Yield),
Location::START, Location::START,
) )
}); } else {
return_places.for_each(|place| {
if let Some(local) = place.as_local() {
trans.remove(local);
}
});
}
} }
} }