about summary refs log tree commit diff
path: root/src/test/mir-opt
diff options
context:
space:
mode:
authorJonas Schievink <jonasschievink@gmail.com>2020-11-11 20:59:05 +0100
committerGitHub <noreply@github.com>2020-11-11 20:59:05 +0100
commit0b521e5c475d20b4968e2d7856c1fbacd6171165 (patch)
treeb1d33bf2763a2ffb05aa408b659cf6849d9019fb /src/test/mir-opt
parent919177f7e42f7585bbc8353b942a0feb1b67705e (diff)
parentffa70d75c8f5925ea26697c7ca5d20fd4d85cbb2 (diff)
downloadrust-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')
-rw-r--r--src/test/mir-opt/inline/inline-diverging.rs40
-rw-r--r--src/test/mir-opt/inline/inline_diverging.f.Inline.diff26
-rw-r--r--src/test/mir-opt/inline/inline_diverging.g.Inline.diff52
-rw-r--r--src/test/mir-opt/inline/inline_diverging.h.Inline.diff58
-rw-r--r--src/test/mir-opt/inline/inline_into_box_place.main.Inline.32bit.diff2
-rw-r--r--src/test/mir-opt/inline/inline_into_box_place.main.Inline.64bit.diff2
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