diff options
| author | Jonas Schievink <jonasschievink@gmail.com> | 2020-11-11 20:59:05 +0100 |
|---|---|---|
| committer | GitHub <noreply@github.com> | 2020-11-11 20:59:05 +0100 |
| commit | 0b521e5c475d20b4968e2d7856c1fbacd6171165 (patch) | |
| tree | b1d33bf2763a2ffb05aa408b659cf6849d9019fb /src/test/mir-opt | |
| parent | 919177f7e42f7585bbc8353b942a0feb1b67705e (diff) | |
| parent | ffa70d75c8f5925ea26697c7ca5d20fd4d85cbb2 (diff) | |
| download | rust-0b521e5c475d20b4968e2d7856c1fbacd6171165.tar.gz rust-0b521e5c475d20b4968e2d7856c1fbacd6171165.zip | |
Rollup merge of #78899 - tmiasko:inline-diverging, r=oli-obk
Support inlining diverging function calls The existing heuristic does penalize diverging calls to some degree, but since it never inlined them previously it might need some further modifications. Additionally introduce storage markers for all temporaries created by the inliner. The temporary introduced for destination rebrorrow, didn't use them previously.
Diffstat (limited to 'src/test/mir-opt')
6 files changed, 180 insertions, 0 deletions
diff --git a/src/test/mir-opt/inline/inline-diverging.rs b/src/test/mir-opt/inline/inline-diverging.rs new file mode 100644 index 00000000000..ae6f814c290 --- /dev/null +++ b/src/test/mir-opt/inline/inline-diverging.rs @@ -0,0 +1,40 @@ +// Tests inlining of diverging calls. +// +// ignore-wasm32-bare compiled with panic=abort by default +#![crate_type = "lib"] + +// EMIT_MIR inline_diverging.f.Inline.diff +pub fn f() { + sleep(); +} + +// EMIT_MIR inline_diverging.g.Inline.diff +pub fn g(i: i32) -> u32 { + if i > 0 { + i as u32 + } else { + panic(); + } +} + +// EMIT_MIR inline_diverging.h.Inline.diff +pub fn h() { + call_twice(sleep); +} + +#[inline(always)] +pub fn call_twice<R, F: Fn() -> R>(f: F) -> (R, R) { + let a = f(); + let b = f(); + (a, b) +} + +#[inline(always)] +fn panic() -> ! { + panic!(); +} + +#[inline(always)] +fn sleep() -> ! { + loop {} +} diff --git a/src/test/mir-opt/inline/inline_diverging.f.Inline.diff b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff new file mode 100644 index 00000000000..6e36dc06a20 --- /dev/null +++ b/src/test/mir-opt/inline/inline_diverging.f.Inline.diff @@ -0,0 +1,26 @@ +- // MIR for `f` before Inline ++ // MIR for `f` after Inline + + fn f() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:7:12: 7:12 + let mut _1: !; // in scope 0 at $DIR/inline-diverging.rs:7:12: 9:2 + let _2: !; // in scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 ++ let mut _3: !; // in scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 ++ scope 1 (inlined sleep) { // at $DIR/inline-diverging.rs:8:5: 8:12 ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 +- sleep(); // scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 +- // mir::Constant +- // + span: $DIR/inline-diverging.rs:8:5: 8:10 +- // + literal: Const { ty: fn() -> ! {sleep}, val: Value(Scalar(<ZST>)) } ++ StorageLive(_3); // scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 ++ goto -> bb1; // scope 0 at $DIR/inline-diverging.rs:8:5: 8:12 ++ } ++ ++ bb1: { ++ goto -> bb1; // scope 1 at $DIR/inline-diverging.rs:8:5: 8:12 + } + } + diff --git a/src/test/mir-opt/inline/inline_diverging.g.Inline.diff b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff new file mode 100644 index 00000000000..3dc33354a5a --- /dev/null +++ b/src/test/mir-opt/inline/inline_diverging.g.Inline.diff @@ -0,0 +1,52 @@ +- // MIR for `g` before Inline ++ // MIR for `g` after Inline + + fn g(_1: i32) -> u32 { + debug i => _1; // in scope 0 at $DIR/inline-diverging.rs:12:10: 12:11 + let mut _0: u32; // return place in scope 0 at $DIR/inline-diverging.rs:12:21: 12:24 + let mut _2: bool; // in scope 0 at $DIR/inline-diverging.rs:13:8: 13:13 + let mut _3: i32; // in scope 0 at $DIR/inline-diverging.rs:13:8: 13:9 + let mut _4: i32; // in scope 0 at $DIR/inline-diverging.rs:14:9: 14:10 + let mut _5: !; // in scope 0 at $DIR/inline-diverging.rs:15:12: 17:6 + let _6: !; // in scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 ++ let mut _7: !; // in scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 ++ scope 1 (inlined panic) { // at $DIR/inline-diverging.rs:16:9: 16:16 ++ } + + bb0: { + StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:13:8: 13:13 + StorageLive(_3); // scope 0 at $DIR/inline-diverging.rs:13:8: 13:9 + _3 = _1; // scope 0 at $DIR/inline-diverging.rs:13:8: 13:9 + _2 = Gt(move _3, const 0_i32); // scope 0 at $DIR/inline-diverging.rs:13:8: 13:13 + StorageDead(_3); // scope 0 at $DIR/inline-diverging.rs:13:12: 13:13 + switchInt(_2) -> [false: bb1, otherwise: bb2]; // scope 0 at $DIR/inline-diverging.rs:13:5: 17:6 + } + + bb1: { + StorageLive(_6); // scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 +- panic(); // scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 ++ StorageLive(_7); // scope 0 at $DIR/inline-diverging.rs:16:9: 16:16 ++ begin_panic::<&str>(const "explicit panic"); // scope 1 at $DIR/inline-diverging.rs:16:9: 16:16 + // mir::Constant +- // + span: $DIR/inline-diverging.rs:16:9: 16:14 +- // + literal: Const { ty: fn() -> ! {panic}, val: Value(Scalar(<ZST>)) } ++ // + span: $DIR/inline-diverging.rs:16:9: 16:16 ++ // + literal: Const { ty: fn(&str) -> ! {std::rt::begin_panic::<&str>}, val: Value(Scalar(<ZST>)) } ++ // ty::Const ++ // + ty: &str ++ // + val: Value(Slice { data: Allocation { bytes: [101, 120, 112, 108, 105, 99, 105, 116, 32, 112, 97, 110, 105, 99], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [16383], len: Size { raw: 14 } }, size: Size { raw: 14 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 14 }) ++ // mir::Constant ++ // + span: $DIR/inline-diverging.rs:16:9: 16:16 ++ // + literal: Const { ty: &str, val: Value(Slice { data: Allocation { bytes: [101, 120, 112, 108, 105, 99, 105, 116, 32, 112, 97, 110, 105, 99], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [16383], len: Size { raw: 14 } }, size: Size { raw: 14 }, align: Align { pow2: 0 }, mutability: Not, extra: () }, start: 0, end: 14 }) } + } + + bb2: { + StorageLive(_4); // scope 0 at $DIR/inline-diverging.rs:14:9: 14:10 + _4 = _1; // scope 0 at $DIR/inline-diverging.rs:14:9: 14:10 + _0 = move _4 as u32 (Misc); // scope 0 at $DIR/inline-diverging.rs:14:9: 14:17 + StorageDead(_4); // scope 0 at $DIR/inline-diverging.rs:14:16: 14:17 + StorageDead(_2); // scope 0 at $DIR/inline-diverging.rs:18:1: 18:2 + return; // scope 0 at $DIR/inline-diverging.rs:18:2: 18:2 + } + } + diff --git a/src/test/mir-opt/inline/inline_diverging.h.Inline.diff b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff new file mode 100644 index 00000000000..b728ad4b428 --- /dev/null +++ b/src/test/mir-opt/inline/inline_diverging.h.Inline.diff @@ -0,0 +1,58 @@ +- // MIR for `h` before Inline ++ // MIR for `h` after Inline + + fn h() -> () { + let mut _0: (); // return place in scope 0 at $DIR/inline-diverging.rs:21:12: 21:12 + let _1: (!, !); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ let mut _2: fn() -> ! {sleep}; // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ let mut _7: (); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ let mut _8: (); // in scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) { // at $DIR/inline-diverging.rs:22:5: 22:22 ++ debug f => _2; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22 ++ let _3: !; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22 ++ let mut _4: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22 ++ let mut _5: &fn() -> ! {sleep}; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22 ++ let mut _6: !; // in scope 1 at $DIR/inline-diverging.rs:22:5: 22:22 ++ scope 2 { ++ debug a => _3; // in scope 2 at $DIR/inline-diverging.rs:22:5: 22:22 ++ scope 3 { ++ debug b => _6; // in scope 3 at $DIR/inline-diverging.rs:22:5: 22:22 ++ } ++ scope 6 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:22:5: 22:22 ++ scope 7 (inlined sleep) { // at $DIR/inline-diverging.rs:22:5: 22:22 ++ } ++ } ++ } ++ scope 4 (inlined <fn() -> ! {sleep} as Fn<()>>::call - shim(fn() -> ! {sleep})) { // at $DIR/inline-diverging.rs:22:5: 22:22 ++ scope 5 (inlined sleep) { // at $DIR/inline-diverging.rs:22:5: 22:22 ++ } ++ } ++ } + + bb0: { + StorageLive(_1); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 +- _1 = call_twice::<!, fn() -> ! {sleep}>(sleep) -> bb1; // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ StorageLive(_2); // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 ++ _2 = sleep; // scope 0 at $DIR/inline-diverging.rs:22:5: 22:22 + // mir::Constant +- // + span: $DIR/inline-diverging.rs:22:5: 22:15 +- // + literal: Const { ty: fn(fn() -> ! {sleep}) -> (!, !) {call_twice::<!, fn() -> ! {sleep}>}, val: Value(Scalar(<ZST>)) } +- // mir::Constant + // + span: $DIR/inline-diverging.rs:22:16: 22:21 + // + literal: Const { ty: fn() -> ! {sleep}, val: Value(Scalar(<ZST>)) } ++ StorageLive(_3); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22 ++ StorageLive(_4); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22 ++ _4 = &_2; // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22 ++ StorageLive(_7); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22 ++ _7 = const (); // scope 1 at $DIR/inline-diverging.rs:22:5: 22:22 ++ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:22:5: 22:22 + } + + bb1: { +- StorageDead(_1); // scope 0 at $DIR/inline-diverging.rs:22:22: 22:23 +- _0 = const (); // scope 0 at $DIR/inline-diverging.rs:21:12: 23:2 +- return; // scope 0 at $DIR/inline-diverging.rs:23:2: 23:2 ++ goto -> bb1; // scope 5 at $DIR/inline-diverging.rs:22:5: 22:22 + } + } + diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff index 0fbafd76e20..3c0dfb4a77e 100644 --- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff @@ -18,6 +18,7 @@ StorageLive(_2); // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 _2 = Box(std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 - (*_2) = Vec::<u32>::new() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 ++ StorageLive(_4); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 + _4 = &mut (*_2); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 + ((*_4).0: alloc::raw_vec::RawVec<u32>) = const alloc::raw_vec::RawVec::<u32> { ptr: Unique::<u32> { pointer: {0x4 as *const u32}, _marker: PhantomData::<u32> }, cap: 0_usize, alloc: std::alloc::Global }; // scope 2 at $DIR/inline-into-box-place.rs:8:33: 8:43 + // ty::Const @@ -34,6 +35,7 @@ + // + user_ty: UserType(0) + // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [255], len: Size { raw: 8 } }, size: Size { raw: 8 }, align: Align { pow2: 2 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } + ((*_4).1: usize) = const 0_usize; // scope 2 at $DIR/inline-into-box-place.rs:8:33: 8:43 ++ StorageDead(_4); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 _1 = move _2; // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 StorageDead(_2); // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43 _0 = const (); // scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2 diff --git a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff index 9277e57134e..a72db9cf1dc 100644 --- a/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff +++ b/src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff @@ -18,6 +18,7 @@ StorageLive(_2); // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 _2 = Box(std::vec::Vec<u32>); // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 - (*_2) = Vec::<u32>::new() -> [return: bb1, unwind: bb4]; // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 ++ StorageLive(_4); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 + _4 = &mut (*_2); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 + ((*_4).0: alloc::raw_vec::RawVec<u32>) = const alloc::raw_vec::RawVec::<u32> { ptr: Unique::<u32> { pointer: {0x4 as *const u32}, _marker: PhantomData::<u32> }, cap: 0_usize, alloc: std::alloc::Global }; // scope 2 at $DIR/inline-into-box-place.rs:8:33: 8:43 + // ty::Const @@ -34,6 +35,7 @@ + // + user_ty: UserType(0) + // + literal: Const { ty: alloc::raw_vec::RawVec<u32>, val: Value(ByRef { alloc: Allocation { bytes: [4, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0], relocations: Relocations(SortedMap { data: [] }), init_mask: InitMask { blocks: [65535], len: Size { raw: 16 } }, size: Size { raw: 16 }, align: Align { pow2: 3 }, mutability: Not, extra: () }, offset: Size { raw: 0 } }) } + ((*_4).1: usize) = const 0_usize; // scope 2 at $DIR/inline-into-box-place.rs:8:33: 8:43 ++ StorageDead(_4); // scope 0 at $DIR/inline-into-box-place.rs:8:33: 8:43 _1 = move _2; // scope 0 at $DIR/inline-into-box-place.rs:8:29: 8:43 StorageDead(_2); // scope 0 at $DIR/inline-into-box-place.rs:8:42: 8:43 _0 = const (); // scope 0 at $DIR/inline-into-box-place.rs:7:11: 9:2 |
