Skip to content

Commit

Permalink
Rollup merge of rust-lang#118797 - tmiasko:dead-coro, r=davidtwco
Browse files Browse the repository at this point in the history
End locals' live range before suspending coroutine

State transforms retains storage statements for locals that are not
stored inside a coroutine. It ensures those locals are live when
resuming by inserting StorageLive as appropriate. It forgot to end the
storage of those locals when suspending, which is fixed here.

While the end of live range is implicit when executing return, it is
nevertheless useful for inliner which would otherwise extend the live
range beyond return.

Fixes rust-lang#117733
  • Loading branch information
compiler-errors authored Dec 12, 2023
2 parents b4dee53 + eaaa290 commit 8f117dc
Show file tree
Hide file tree
Showing 5 changed files with 27 additions and 8 deletions.
23 changes: 15 additions & 8 deletions compiler/rustc_mir_transform/src/coroutine.rs
Original file line number Diff line number Diff line change
Expand Up @@ -527,12 +527,26 @@ impl<'tcx> MutVisitor<'tcx> for TransformVisitor<'tcx> {
resume_arg
};

let storage_liveness: GrowableBitSet<Local> =
self.storage_liveness[block].clone().unwrap().into();

for i in 0..self.always_live_locals.domain_size() {
let l = Local::new(i);
let needs_storage_dead = storage_liveness.contains(l)
&& !self.remap.contains_key(&l)
&& !self.always_live_locals.contains(l);
if needs_storage_dead {
data.statements
.push(Statement { source_info, kind: StatementKind::StorageDead(l) });
}
}

self.suspension_points.push(SuspensionPoint {
state,
resume,
resume_arg,
drop,
storage_liveness: self.storage_liveness[block].clone().unwrap().into(),
storage_liveness,
});

VariantIdx::new(state)
Expand Down Expand Up @@ -1496,13 +1510,6 @@ fn create_cases<'tcx>(

// Create StorageLive instructions for locals with live storage
for i in 0..(body.local_decls.len()) {
if i == 2 {
// The resume argument is live on function entry. Don't insert a
// `StorageLive`, or the following `Assign` will read from uninitialized
// memory.
continue;
}

let l = Local::new(i);
let needs_storage_live = point.storage_liveness.contains(l)
&& !transform.remap.contains_key(&l)
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -178,6 +178,10 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
StorageLive(_20);
_20 = ();
_0 = Poll::<()>::Pending;
StorageDead(_3);
StorageDead(_4);
StorageDead(_19);
StorageDead(_20);
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 3;
return;
}
Expand Down Expand Up @@ -276,6 +280,9 @@ fn b::{closure#0}(_1: Pin<&mut {async fn body@$DIR/async_await.rs:15:18: 18:2}>,
StorageLive(_36);
_36 = ();
_0 = Poll::<()>::Pending;
StorageDead(_21);
StorageDead(_35);
StorageDead(_36);
discriminant((*(_1.0: &mut {async fn body@$DIR/async_await.rs:15:18: 18:2}))) = 4;
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -55,6 +55,9 @@ fn main::{closure#0}(_1: Pin<&mut {coroutine@$DIR/coroutine_tiny.rs:20:16: 20:24
StorageLive(_7);
_7 = ();
_0 = CoroutineState::<(), ()>::Yielded(move _7);
StorageDead(_4);
StorageDead(_6);
StorageDead(_7);
discriminant((*(_1.0: &mut {coroutine@$DIR/coroutine_tiny.rs:20:16: 20:24}))) = 3;
return;
}
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -89,6 +89,7 @@
+
+ bb6: {
+ _1 = CoroutineState::<i32, bool>::Yielded(move _8);
+ StorageDead(_8);
+ discriminant((*_6)) = 3;
+ goto -> bb2;
+ }
Expand Down
Original file line number Diff line number Diff line change
Expand Up @@ -103,6 +103,7 @@
+
+ bb8: {
+ _1 = CoroutineState::<i32, bool>::Yielded(move _8);
+ StorageDead(_8);
+ discriminant((*_6)) = 3;
+ goto -> bb4;
+ }
Expand Down

0 comments on commit 8f117dc

Please sign in to comment.