Support inlining diverging function calls

Additionally introduce storage markers for all temporaries created by
the inliner. The temporary introduced for destination rebrorrow, didn't
use them previously.
This commit is contained in:
Tomasz Miąsko 2020-11-09 00:00:00 +00:00
parent dc4d74d149
commit ffa70d75c8
7 changed files with 257 additions and 77 deletions

View file

@ -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 {}
}

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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
}
}

View file

@ -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

View file

@ -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