Skip to content
Merged
Changes from 1 commit
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Prev Previous commit
Next Next commit
Only evaluate yield place after resume in liveness.
  • Loading branch information
cjgillot committed Aug 16, 2023
commit e9990ce89ca62e9c9b62bcde89eb11314ec1dc22
46 changes: 31 additions & 15 deletions compiler/rustc_mir_dataflow/src/impls/liveness.rs
Original file line number Diff line number Diff line change
Expand Up @@ -74,13 +74,19 @@ impl<'tcx> GenKillAnalysis<'tcx> for MaybeLiveLocals {
_block: mir::BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
return_places.for_each(|place| {
CallReturnEffect(trans).visit_place(
&place,
PlaceContext::MutatingUse(MutatingUseContext::Store),
if let CallReturnPlaces::Yield(resume_place) = return_places {
YieldResumeEffect(trans).visit_place(
Comment thread
tmiasko marked this conversation as resolved.
Outdated
&resume_place,
PlaceContext::MutatingUse(MutatingUseContext::Yield),
Location::START,
)
});
} else {
return_places.for_each(|place| {
if let Some(local) = place.as_local() {
trans.kill(local);
}
});
}
}
}

Expand All @@ -91,12 +97,16 @@ where
T: GenKill<Local>,
{
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) {
Some(DefUse::Def) => {
if let PlaceContext::MutatingUse(
MutatingUseContext::Yield
| MutatingUseContext::Call
| MutatingUseContext::AsmOutput,
MutatingUseContext::Call | MutatingUseContext::AsmOutput,
) = context
{
// For the associated terminators, this is only a `Def` when the terminator returns
Expand All @@ -119,9 +129,9 @@ where
}
}

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
T: GenKill<Local>,
{
Expand Down Expand Up @@ -291,12 +301,18 @@ impl<'a, 'tcx> Analysis<'tcx> for MaybeTransitiveLiveLocals<'a> {
_block: mir::BasicBlock,
return_places: CallReturnPlaces<'_, 'tcx>,
) {
return_places.for_each(|place| {
CallReturnEffect(trans).visit_place(
&place,
PlaceContext::MutatingUse(MutatingUseContext::Store),
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);
}
});
}
}
}