Skip to content

Commit

Permalink
Enable MIR inlining on generators.
Browse files Browse the repository at this point in the history
  • Loading branch information
cjgillot committed Sep 7, 2022
1 parent 0369ff2 commit 3128b8f
Show file tree
Hide file tree
Showing 4 changed files with 72 additions and 14 deletions.
6 changes: 0 additions & 6 deletions compiler/rustc_mir_transform/src/inline.rs
Original file line number Diff line number Diff line change
Expand Up @@ -79,12 +79,6 @@ fn inline<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) -> bool {
if body.source.promoted.is_some() {
return false;
}
// Avoid inlining into generators, since their `optimized_mir` is used for layout computation,
// which can create a cycle, even when no attempt is made to inline the function in the other
// direction.
if tcx.generator_kind(def_id).is_some() {
return false;
}

let param_env = tcx.param_env_reveal_all_normalized(def_id);

Expand Down
17 changes: 9 additions & 8 deletions src/test/mir-opt/inline/inline-async.rs
Original file line number Diff line number Diff line change
@@ -1,5 +1,4 @@
// Checks that inliner doesn't introduce cycles when optimizing generators.
// The outcome of optimization is not verfied, just the absence of the cycle.
// Regression test for #76181.
//
// edition:2018
Expand All @@ -8,11 +7,13 @@

pub struct S;

impl S {
pub async fn g(&mut self) {
self.h();
}
pub fn h(&mut self) {
let _ = self.g();
}
// EMIT_MIR inline_async.g.Inline.diff
pub async fn g(s: &mut S) {
h(s);
}

// EMIT_MIR inline_async.h.Inline.diff
#[inline(always)]
pub fn h(s: &mut S) {
let _ = g(s);
}
34 changes: 34 additions & 0 deletions src/test/mir-opt/inline/inline_async.g.Inline.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,34 @@
- // MIR for `g` before Inline
+ // MIR for `g` after Inline

fn g(_1: &mut S) -> std::future::from_generator::GenFuture<[static generator@$DIR/inline-async.rs:11:27: 13:2]> {
debug s => _1; // in scope 0 at $DIR/inline-async.rs:+0:16: +0:17
let mut _0: std::future::from_generator::GenFuture<[static generator@$DIR/inline-async.rs:11:27: 13:2]>; // return place in scope 0 at $DIR/inline-async.rs:+0:27: +0:27
let mut _2: [static generator@$DIR/inline-async.rs:11:27: 13:2]; // in scope 0 at $DIR/inline-async.rs:+0:27: +2:2
+ scope 1 (inlined std::future::from_generator::<[static generator@$DIR/inline-async.rs:11:27: 13:2]>) { // at $DIR/inline-async.rs:11:27: 13:2
+ debug gen => _2; // in scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
+ let mut _3: [static generator@$DIR/inline-async.rs:11:27: 13:2]; // in scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
+ }

bb0: {
StorageLive(_2); // scope 0 at $DIR/inline-async.rs:+0:27: +2:2
Deinit(_2); // scope 0 at $DIR/inline-async.rs:+0:27: +2:2
(_2.0: &mut S) = move _1; // scope 0 at $DIR/inline-async.rs:+0:27: +2:2
discriminant(_2) = 0; // scope 0 at $DIR/inline-async.rs:+0:27: +2:2
- _0 = std::future::from_generator::<[static generator@$DIR/inline-async.rs:11:27: 13:2]>(move _2) -> bb1; // scope 0 at $DIR/inline-async.rs:+0:27: +2:2
- // mir::Constant
- // + span: $DIR/inline-async.rs:11:27: 13:2
- // + literal: Const { ty: fn([static generator@$DIR/inline-async.rs:11:27: 13:2]) -> impl Future<Output = ()> {std::future::from_generator::<[static generator@$DIR/inline-async.rs:11:27: 13:2]>}, val: Value(<ZST>) }
- }
-
- bb1: {
+ StorageLive(_3); // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
+ _3 = move _2; // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
+ Deinit(_0); // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
+ (_0.0: [static generator@$DIR/inline-async.rs:11:27: 13:2]) = move _3; // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
+ StorageDead(_3); // scope 1 at $SRC_DIR/core/src/future/mod.rs:LL:COL
StorageDead(_2); // scope 0 at $DIR/inline-async.rs:+2:1: +2:2
return; // scope 0 at $DIR/inline-async.rs:+2:2: +2:2
}
}

29 changes: 29 additions & 0 deletions src/test/mir-opt/inline/inline_async.h.Inline.diff
Original file line number Diff line number Diff line change
@@ -0,0 +1,29 @@
- // MIR for `h` before Inline
+ // MIR for `h` after Inline

fn h(_1: &mut S) -> () {
debug s => _1; // in scope 0 at $DIR/inline-async.rs:+0:10: +0:11
let mut _0: (); // return place in scope 0 at $DIR/inline-async.rs:+0:21: +0:21
let mut _2: std::future::from_generator::GenFuture<[static generator@$DIR/inline-async.rs:11:27: 13:2]>; // in scope 0 at $DIR/inline-async.rs:+1:13: +1:17
let mut _3: &mut S; // in scope 0 at $DIR/inline-async.rs:+1:15: +1:16
scope 1 {
}

bb0: {
StorageLive(_2); // scope 0 at $DIR/inline-async.rs:+1:13: +1:17
StorageLive(_3); // scope 0 at $DIR/inline-async.rs:+1:15: +1:16
_3 = &mut (*_1); // scope 0 at $DIR/inline-async.rs:+1:15: +1:16
_2 = g(move _3) -> bb1; // scope 0 at $DIR/inline-async.rs:+1:13: +1:17
// mir::Constant
// + span: $DIR/inline-async.rs:18:13: 18:14
// + literal: Const { ty: for<'r> fn(&'r mut S) -> impl for<'r> Future<Output = ()> {g}, val: Value(<ZST>) }
}

bb1: {
StorageDead(_3); // scope 0 at $DIR/inline-async.rs:+1:16: +1:17
StorageDead(_2); // scope 0 at $DIR/inline-async.rs:+1:17: +1:18
_0 = const (); // scope 0 at $DIR/inline-async.rs:+0:21: +2:2
return; // scope 0 at $DIR/inline-async.rs:+2:2: +2:2
}
}

0 comments on commit 3128b8f

Please sign in to comment.