Auto merge of #110713 - cjgillot:track-mir-opt, r=scottmcm

Add mir-opt tests to track MIR quality.

cc `@scottmcm` `@saethlin`

If you have other ideas, please say so.
This commit is contained in:
bors 2023-04-24 17:01:02 +00:00
commit 253b727f46
34 changed files with 757 additions and 170 deletions

View File

@ -1,27 +0,0 @@
// MIR for `ub_if_b` after PreCodegen
fn ub_if_b(_1: Thing) -> Thing {
debug t => _1; // in scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+0:23: +0:24
let mut _0: Thing; // return place in scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+0:36: +0:41
let mut _2: isize; // in scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+2:9: +2:17
scope 1 (inlined unreachable_unchecked) { // at $DIR/instcombine_duplicate_switch_targets_e2e.rs:14:21: 14:55
scope 2 {
scope 3 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
}
}
}
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+1:11: +1:12
switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+1:5: +1:12
}
bb1: {
unreachable; // scope 2 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
}
bb2: {
_0 = move _1; // scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+2:21: +2:22
return; // scope 0 at $DIR/instcombine_duplicate_switch_targets_e2e.rs:+5:2: +5:2
}
}

View File

@ -1,22 +0,0 @@
// MIR for `f_u64` after PreCodegen
fn f_u64() -> () {
let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:16: +0:16
scope 1 (inlined f_dispatch::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:15:5: 15:21
debug t => const 0_u64; // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23
let _1: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32
}
}
bb0: {
_1 = f_non_zst::<u64>(const 0_u64) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics_e2e.rs:23:9: 23:21
// mir::Constant
// + span: $DIR/lower_intrinsics_e2e.rs:23:9: 23:18
// + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(<ZST>) }
}
bb1: {
return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2
}
}

View File

@ -1,22 +0,0 @@
// MIR for `f_unit` after PreCodegen
fn f_unit() -> () {
let mut _0: (); // return place in scope 0 at $DIR/lower_intrinsics_e2e.rs:+0:17: +0:17
scope 1 (inlined f_dispatch::<()>) { // at $DIR/lower_intrinsics_e2e.rs:9:5: 9:19
debug t => const (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:19:22: 19:23
let _1: (); // in scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/lower_intrinsics_e2e.rs:20:8: 20:32
}
}
bb0: {
_1 = f_zst::<()>(const ()) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/lower_intrinsics_e2e.rs:21:9: 21:17
// mir::Constant
// + span: $DIR/lower_intrinsics_e2e.rs:21:9: 21:14
// + literal: Const { ty: fn(()) {f_zst::<()>}, val: Value(<ZST>) }
}
bb1: {
return; // scope 0 at $DIR/lower_intrinsics_e2e.rs:+2:2: +2:2
}
}

View File

@ -0,0 +1,3 @@
The goal of this directory is to track the quality of MIR that is given to codegen in a standard `-O` condiguration.
As such, feel free to `--bless` whatever changes you get here, so long as doing so doesn't add substantially more MIR.

View File

@ -1,5 +1,6 @@
// compile-flags: -Zmir-opt-level=2 -Zinline-mir
// compile-flags: -O -Zmir-opt-level=2 -Cdebuginfo=0
// ignore-debug: standard library debug assertions add a panic that breaks this optimization
#![crate_type = "lib"]
pub enum Thing {
@ -7,7 +8,7 @@ pub enum Thing {
B,
}
// EMIT_MIR instcombine_duplicate_switch_targets_e2e.ub_if_b.PreCodegen.after.mir
// EMIT_MIR duplicate_switch_targets.ub_if_b.PreCodegen.after.mir
pub unsafe fn ub_if_b(t: Thing) -> Thing {
match t {
Thing::A => t,

View File

@ -0,0 +1,27 @@
// MIR for `ub_if_b` after PreCodegen
fn ub_if_b(_1: Thing) -> Thing {
debug t => _1; // in scope 0 at $DIR/duplicate_switch_targets.rs:+0:23: +0:24
let mut _0: Thing; // return place in scope 0 at $DIR/duplicate_switch_targets.rs:+0:36: +0:41
let mut _2: isize; // in scope 0 at $DIR/duplicate_switch_targets.rs:+2:9: +2:17
scope 1 (inlined unreachable_unchecked) { // at $DIR/duplicate_switch_targets.rs:15:21: 15:55
scope 2 {
scope 3 (inlined unreachable_unchecked::runtime) { // at $SRC_DIR/core/src/intrinsics.rs:LL:COL
}
}
}
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/duplicate_switch_targets.rs:+1:11: +1:12
switchInt(move _2) -> [0: bb2, otherwise: bb1]; // scope 0 at $DIR/duplicate_switch_targets.rs:+1:5: +1:12
}
bb1: {
unreachable; // scope 2 at $SRC_DIR/core/src/intrinsics.rs:LL:COL
}
bb2: {
_0 = move _1; // scope 0 at $DIR/duplicate_switch_targets.rs:+2:21: +2:22
return; // scope 0 at $DIR/duplicate_switch_targets.rs:+5:2: +5:2
}
}

View File

@ -0,0 +1,26 @@
// MIR for `f_u64` after PreCodegen
fn f_u64() -> () {
let mut _0: (); // return place in scope 0 at $DIR/intrinsics.rs:+0:16: +0:16
let mut _1: u64; // in scope 0 at $DIR/intrinsics.rs:+1:5: +1:21
scope 1 (inlined f_dispatch::<u64>) { // at $DIR/intrinsics.rs:19:5: 19:21
debug t => const 0_u64; // in scope 1 at $DIR/intrinsics.rs:23:22: 23:23
let _2: (); // in scope 1 at $DIR/intrinsics.rs:27:9: 27:21
scope 2 (inlined std::mem::size_of::<u64>) { // at $DIR/intrinsics.rs:24:8: 24:32
}
}
bb0: {
StorageLive(_1); // scope 0 at $DIR/intrinsics.rs:+1:5: +1:21
_1 = const 0_u64; // scope 0 at $DIR/intrinsics.rs:+1:5: +1:21
_2 = f_non_zst::<u64>(move _1) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/intrinsics.rs:27:9: 27:21
// mir::Constant
// + span: $DIR/intrinsics.rs:27:9: 27:18
// + literal: Const { ty: fn(u64) {f_non_zst::<u64>}, val: Value(<ZST>) }
}
bb1: {
StorageDead(_1); // scope 0 at $DIR/intrinsics.rs:+1:5: +1:21
return; // scope 0 at $DIR/intrinsics.rs:+2:2: +2:2
}
}

View File

@ -0,0 +1,22 @@
// MIR for `f_unit` after PreCodegen
fn f_unit() -> () {
let mut _0: (); // return place in scope 0 at $DIR/intrinsics.rs:+0:17: +0:17
scope 1 (inlined f_dispatch::<()>) { // at $DIR/intrinsics.rs:13:5: 13:19
debug t => const (); // in scope 1 at $DIR/intrinsics.rs:23:22: 23:23
let _1: (); // in scope 1 at $DIR/intrinsics.rs:25:9: 25:17
scope 2 (inlined std::mem::size_of::<()>) { // at $DIR/intrinsics.rs:24:8: 24:32
}
}
bb0: {
_1 = f_zst::<()>(const ()) -> [return: bb1, unwind unreachable]; // scope 1 at $DIR/intrinsics.rs:25:9: 25:17
// mir::Constant
// + span: $DIR/intrinsics.rs:25:9: 25:14
// + literal: Const { ty: fn(()) {f_zst::<()>}, val: Value(<ZST>) }
}
bb1: {
return; // scope 0 at $DIR/intrinsics.rs:+2:2: +2:2
}
}

View File

@ -1,16 +1,20 @@
// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
// only-64bit
// ignore-debug
// Checks that we do not have any branches in the MIR for the two tested functions.
// compile-flags: -Cpanic=abort
#![feature(core_intrinsics)]
#![crate_type = "lib"]
// EMIT_MIR lower_intrinsics_e2e.f_unit.PreCodegen.after.mir
// EMIT_MIR intrinsics.f_unit.PreCodegen.after.mir
pub fn f_unit() {
f_dispatch(());
}
// EMIT_MIR lower_intrinsics_e2e.f_u64.PreCodegen.after.mir
// EMIT_MIR intrinsics.f_u64.PreCodegen.after.mir
pub fn f_u64() {
f_dispatch(0u64);
}

View File

@ -1,5 +1,4 @@
// ignore-wasm32 compiled with panic=abort by default
// unit-test
// compile-flags: -C overflow-checks=on
struct Point {

View File

@ -0,0 +1,91 @@
// MIR for `forward_loop` after PreCodegen
fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
debug start => _1; // in scope 0 at $DIR/range_iter.rs:+0:21: +0:26
debug end => _2; // in scope 0 at $DIR/range_iter.rs:+0:33: +0:36
debug f => _3; // in scope 0 at $DIR/range_iter.rs:+0:43: +0:44
let mut _0: (); // return place in scope 0 at $DIR/range_iter.rs:+0:60: +0:60
let mut _4: std::ops::Range<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
let mut _5: std::ops::Range<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
let _6: (); // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
let mut _8: &mut std::ops::Range<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:24
let mut _9: isize; // in scope 0 at $DIR/range_iter.rs:+1:5: +3:6
let mut _11: &impl Fn(u32); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:10
let mut _12: (u32,); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:13
scope 1 {
debug iter => _5; // in scope 1 at $DIR/range_iter.rs:+1:14: +1:24
let _10: u32; // in scope 1 at $DIR/range_iter.rs:+1:9: +1:10
scope 2 {
debug x => _10; // in scope 2 at $DIR/range_iter.rs:+1:9: +1:10
}
scope 4 (inlined iter::range::<impl Iterator for std::ops::Range<u32>>::next) { // at $DIR/range_iter.rs:21:14: 21:24
debug self => _8; // in scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL
}
}
scope 3 (inlined <std::ops::Range<u32> as IntoIterator>::into_iter) { // at $DIR/range_iter.rs:21:14: 21:24
debug self => _4; // in scope 3 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
}
bb0: {
_4 = std::ops::Range::<u32> { start: _1, end: _2 }; // scope 0 at $DIR/range_iter.rs:+1:14: +1:24
StorageLive(_5); // scope 0 at $DIR/range_iter.rs:+1:14: +1:24
_5 = move _4; // scope 0 at $DIR/range_iter.rs:+1:14: +1:24
goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6
}
bb1: {
StorageLive(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
_8 = &mut _5; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
_7 = <std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next(_8) -> [return: bb9, unwind: bb7]; // scope 4 at $SRC_DIR/core/src/iter/range.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/iter/range.rs:LL:COL
// + literal: Const { ty: for<'a> fn(&'a mut std::ops::Range<u32>) -> Option<<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::Item> {<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next}, val: Value(<ZST>) }
}
bb2: {
_10 = ((_7 as Some).0: u32); // scope 1 at $DIR/range_iter.rs:+1:9: +1:10
StorageLive(_11); // scope 2 at $DIR/range_iter.rs:+2:9: +2:10
_11 = &_3; // scope 2 at $DIR/range_iter.rs:+2:9: +2:10
StorageLive(_12); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
_12 = (_10,); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
_6 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb5, unwind: bb7]; // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
// mir::Constant
// + span: $DIR/range_iter.rs:22:9: 22:10
// + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(u32), (u32,)) -> <impl Fn(u32) as FnOnce<(u32,)>>::Output {<impl Fn(u32) as Fn<(u32,)>>::call}, val: Value(<ZST>) }
}
bb3: {
unreachable; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
}
bb4: {
StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6
StorageDead(_5); // scope 0 at $DIR/range_iter.rs:+3:5: +3:6
drop(_3) -> bb6; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2
}
bb5: {
StorageDead(_12); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13
StorageDead(_11); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13
StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6
goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6
}
bb6: {
return; // scope 0 at $DIR/range_iter.rs:+4:2: +4:2
}
bb7 (cleanup): {
drop(_3) -> [return: bb8, unwind terminate]; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2
}
bb8 (cleanup): {
resume; // scope 0 at $DIR/range_iter.rs:+0:1: +4:2
}
bb9: {
_9 = discriminant(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
switchInt(move _9) -> [0: bb4, 1: bb2, otherwise: bb3]; // scope 1 at $DIR/range_iter.rs:+1:14: +1:24
}
}

View File

@ -0,0 +1,95 @@
// MIR for `inclusive_loop` after PreCodegen
fn inclusive_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
debug start => _1; // in scope 0 at $DIR/range_iter.rs:+0:23: +0:28
debug end => _2; // in scope 0 at $DIR/range_iter.rs:+0:35: +0:38
debug f => _3; // in scope 0 at $DIR/range_iter.rs:+0:45: +0:46
let mut _0: (); // return place in scope 0 at $DIR/range_iter.rs:+0:62: +0:62
let mut _4: std::ops::RangeInclusive<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25
let mut _5: std::ops::RangeInclusive<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25
let _6: (); // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25
let mut _7: std::option::Option<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25
let mut _8: &mut std::ops::RangeInclusive<u32>; // in scope 0 at $DIR/range_iter.rs:+1:14: +1:25
let mut _9: isize; // in scope 0 at $DIR/range_iter.rs:+1:5: +3:6
let mut _11: &impl Fn(u32); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:10
let mut _12: (u32,); // in scope 0 at $DIR/range_iter.rs:+2:9: +2:13
scope 1 {
debug iter => _5; // in scope 1 at $DIR/range_iter.rs:+1:14: +1:25
let _10: u32; // in scope 1 at $DIR/range_iter.rs:+1:9: +1:10
scope 2 {
debug x => _10; // in scope 2 at $DIR/range_iter.rs:+1:9: +1:10
}
scope 5 (inlined iter::range::<impl Iterator for RangeInclusive<u32>>::next) { // at $DIR/range_iter.rs:28:14: 28:25
debug self => _8; // in scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
}
}
scope 3 (inlined RangeInclusive::<u32>::new) { // at $DIR/range_iter.rs:28:14: 28:25
debug start => _1; // in scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL
debug end => _2; // in scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL
}
scope 4 (inlined <RangeInclusive<u32> as IntoIterator>::into_iter) { // at $DIR/range_iter.rs:28:14: 28:25
debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
}
bb0: {
_4 = RangeInclusive::<u32> { start: _1, end: _2, exhausted: const false }; // scope 3 at $SRC_DIR/core/src/ops/range.rs:LL:COL
StorageLive(_5); // scope 0 at $DIR/range_iter.rs:+1:14: +1:25
_5 = move _4; // scope 0 at $DIR/range_iter.rs:+1:14: +1:25
goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6
}
bb1: {
StorageLive(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:25
_8 = &mut _5; // scope 1 at $DIR/range_iter.rs:+1:14: +1:25
_7 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(_8) -> [return: bb9, unwind: bb7]; // scope 5 at $SRC_DIR/core/src/iter/range.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/iter/range.rs:LL:COL
// + literal: Const { ty: for<'a> fn(&'a mut RangeInclusive<u32>) -> Option<<RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::Item> {<RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next}, val: Value(<ZST>) }
}
bb2: {
_10 = ((_7 as Some).0: u32); // scope 1 at $DIR/range_iter.rs:+1:9: +1:10
StorageLive(_11); // scope 2 at $DIR/range_iter.rs:+2:9: +2:10
_11 = &_3; // scope 2 at $DIR/range_iter.rs:+2:9: +2:10
StorageLive(_12); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
_12 = (_10,); // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
_6 = <impl Fn(u32) as Fn<(u32,)>>::call(move _11, move _12) -> [return: bb5, unwind: bb7]; // scope 2 at $DIR/range_iter.rs:+2:9: +2:13
// mir::Constant
// + span: $DIR/range_iter.rs:29:9: 29:10
// + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(u32), (u32,)) -> <impl Fn(u32) as FnOnce<(u32,)>>::Output {<impl Fn(u32) as Fn<(u32,)>>::call}, val: Value(<ZST>) }
}
bb3: {
unreachable; // scope 1 at $DIR/range_iter.rs:+1:14: +1:25
}
bb4: {
StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6
StorageDead(_5); // scope 0 at $DIR/range_iter.rs:+3:5: +3:6
drop(_3) -> bb6; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2
}
bb5: {
StorageDead(_12); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13
StorageDead(_11); // scope 2 at $DIR/range_iter.rs:+2:12: +2:13
StorageDead(_7); // scope 1 at $DIR/range_iter.rs:+3:5: +3:6
goto -> bb1; // scope 1 at $DIR/range_iter.rs:+1:5: +3:6
}
bb6: {
return; // scope 0 at $DIR/range_iter.rs:+4:2: +4:2
}
bb7 (cleanup): {
drop(_3) -> [return: bb8, unwind terminate]; // scope 0 at $DIR/range_iter.rs:+4:1: +4:2
}
bb8 (cleanup): {
resume; // scope 0 at $DIR/range_iter.rs:+0:1: +4:2
}
bb9: {
_9 = discriminant(_7); // scope 1 at $DIR/range_iter.rs:+1:14: +1:25
switchInt(move _9) -> [0: bb4, 1: bb2, otherwise: bb3]; // scope 1 at $DIR/range_iter.rs:+1:14: +1:25
}
}

View File

@ -0,0 +1,20 @@
// MIR for `range_inclusive_iter_next` after PreCodegen
fn range_inclusive_iter_next(_1: &mut RangeInclusive<u32>) -> Option<u32> {
debug it => _1; // in scope 0 at $DIR/range_iter.rs:+0:34: +0:36
let mut _0: std::option::Option<u32>; // return place in scope 0 at $DIR/range_iter.rs:+0:67: +0:78
scope 1 (inlined iter::range::<impl Iterator for RangeInclusive<u32>>::next) { // at $DIR/range_iter.rs:16:8: 16:14
debug self => _1; // in scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL
}
bb0: {
_0 = <RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next(_1) -> bb1; // scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/iter/range.rs:LL:COL
// + literal: Const { ty: for<'a> fn(&'a mut RangeInclusive<u32>) -> Option<<RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::Item> {<RangeInclusive<u32> as iter::range::RangeInclusiveIteratorImpl>::spec_next}, val: Value(<ZST>) }
}
bb1: {
return; // scope 0 at $DIR/range_iter.rs:+2:2: +2:2
}
}

View File

@ -0,0 +1,20 @@
// MIR for `range_iter_next` after PreCodegen
fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
debug it => _1; // in scope 0 at $DIR/range_iter.rs:+0:24: +0:26
let mut _0: std::option::Option<u32>; // return place in scope 0 at $DIR/range_iter.rs:+0:48: +0:59
scope 1 (inlined iter::range::<impl Iterator for std::ops::Range<u32>>::next) { // at $DIR/range_iter.rs:11:8: 11:14
debug self => _1; // in scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL
}
bb0: {
_0 = <std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next(_1) -> bb1; // scope 1 at $SRC_DIR/core/src/iter/range.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/iter/range.rs:LL:COL
// + literal: Const { ty: for<'a> fn(&'a mut std::ops::Range<u32>) -> Option<<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::Item> {<std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next}, val: Value(<ZST>) }
}
bb1: {
return; // scope 0 at $DIR/range_iter.rs:+2:2: +2:2
}
}

View File

@ -0,0 +1,31 @@
// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
// only-64bit
// ignore-debug
#![crate_type = "lib"]
use std::ops::{Range, RangeInclusive};
// EMIT_MIR range_iter.range_iter_next.PreCodegen.after.mir
pub fn range_iter_next(it: &mut Range<u32>) -> Option<u32> {
it.next()
}
// EMIT_MIR range_iter.range_inclusive_iter_next.PreCodegen.after.mir
pub fn range_inclusive_iter_next(it: &mut RangeInclusive<u32>) -> Option<u32> {
it.next()
}
// EMIT_MIR range_iter.forward_loop.PreCodegen.after.mir
pub fn forward_loop(start: u32, end: u32, f: impl Fn(u32)) {
for x in start..end {
f(x)
}
}
// EMIT_MIR range_iter.inclusive_loop.PreCodegen.after.mir
pub fn inclusive_loop(start: u32, end: u32, f: impl Fn(u32)) {
for x in start..=end {
f(x)
}
}

View File

@ -0,0 +1,56 @@
// MIR for `ezmap` after PreCodegen
fn ezmap(_1: Option<i32>) -> Option<i32> {
debug x => _1; // in scope 0 at $DIR/simple_option_map.rs:+0:14: +0:15
let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/simple_option_map.rs:+0:33: +0:44
let mut _6: i32; // in scope 0 at $DIR/simple_option_map.rs:11:25: 11:29
scope 1 (inlined map::<i32, i32, [closure@$DIR/simple_option_map.rs:18:12: 18:15]>) { // at $DIR/simple_option_map.rs:18:5: 18:22
debug slf => _1; // in scope 1 at $DIR/simple_option_map.rs:6:17: 6:20
debug f => const ZeroSized: [closure@$DIR/simple_option_map.rs:18:12: 18:15]; // in scope 1 at $DIR/simple_option_map.rs:6:33: 6:34
let mut _2: isize; // in scope 1 at $DIR/simple_option_map.rs:11:9: 11:16
let _3: i32; // in scope 1 at $DIR/simple_option_map.rs:11:14: 11:15
let mut _4: i32; // in scope 1 at $DIR/simple_option_map.rs:11:25: 11:29
let mut _5: (i32,); // in scope 1 at $DIR/simple_option_map.rs:11:25: 11:29
scope 2 {
debug x => _3; // in scope 2 at $DIR/simple_option_map.rs:11:14: 11:15
scope 3 (inlined ezmap::{closure#0}) { // at $DIR/simple_option_map.rs:11:25: 11:29
debug n => _6; // in scope 3 at $DIR/simple_option_map.rs:+1:13: +1:14
}
}
}
bb0: {
StorageLive(_3); // scope 0 at $DIR/simple_option_map.rs:+1:5: +1:22
_2 = discriminant(_1); // scope 1 at $DIR/simple_option_map.rs:10:11: 10:14
switchInt(move _2) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 1 at $DIR/simple_option_map.rs:10:5: 10:14
}
bb1: {
_0 = Option::<i32>::None; // scope 1 at $DIR/simple_option_map.rs:12:17: 12:21
goto -> bb4; // scope 1 at $DIR/simple_option_map.rs:12:17: 12:21
}
bb2: {
unreachable; // scope 1 at $DIR/simple_option_map.rs:10:11: 10:14
}
bb3: {
_3 = ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map.rs:11:14: 11:15
StorageLive(_4); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29
StorageLive(_5); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29
_5 = (move _3,); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29
StorageLive(_6); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29
_6 = move (_5.0: i32); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29
_4 = Add(_6, const 1_i32); // scope 3 at $DIR/simple_option_map.rs:+1:16: +1:21
StorageDead(_6); // scope 2 at $DIR/simple_option_map.rs:11:25: 11:29
StorageDead(_5); // scope 2 at $DIR/simple_option_map.rs:11:28: 11:29
_0 = Option::<i32>::Some(move _4); // scope 2 at $DIR/simple_option_map.rs:11:20: 11:30
StorageDead(_4); // scope 2 at $DIR/simple_option_map.rs:11:29: 11:30
goto -> bb4; // scope 1 at $DIR/simple_option_map.rs:14:1: 14:2
}
bb4: {
StorageDead(_3); // scope 0 at $DIR/simple_option_map.rs:+1:5: +1:22
return; // scope 0 at $DIR/simple_option_map.rs:+2:2: +2:2
}
}

View File

@ -1,3 +1,7 @@
// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
// only-64bit
// ignore-debug
#[inline(always)]
fn map<T, U, F>(slf: Option<T>, f: F) -> Option<U>
where
@ -9,7 +13,7 @@ where
}
}
// EMIT_MIR simple_option_map_e2e.ezmap.PreCodegen.after.mir
// EMIT_MIR simple_option_map.ezmap.PreCodegen.after.mir
pub fn ezmap(x: Option<i32>) -> Option<i32> {
map(x, |n| n + 1)
}

View File

@ -0,0 +1,103 @@
// MIR for `forward_loop` after PreCodegen
fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
debug slice => _1; // in scope 0 at $DIR/slice_iter.rs:+0:28: +0:33
debug f => _2; // in scope 0 at $DIR/slice_iter.rs:+0:44: +0:45
let mut _0: (); // return place in scope 0 at $DIR/slice_iter.rs:+0:60: +0:60
let mut _3: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
let mut _4: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
let mut _5: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
let _6: (); // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
let mut _7: std::option::Option<&T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
let mut _8: &mut std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
let mut _9: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +3:6
let mut _11: &impl Fn(&T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:10
let mut _12: (&T,); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:13
scope 1 {
debug iter => _5; // in scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
let _10: &T; // in scope 1 at $DIR/slice_iter.rs:+1:9: +1:10
scope 2 {
debug x => _10; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10
}
}
scope 3 (inlined core::slice::<impl [T]>::iter) { // at $DIR/slice_iter.rs:28:20: 28:26
debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
}
scope 4 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:28:14: 28:26
debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
}
bb0: {
StorageLive(_3); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
StorageLive(_4); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
_4 = std::slice::Iter::<'_, T>::new(_1) -> [return: bb10, unwind: bb8]; // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/slice/mod.rs:LL:COL
// + user_ty: UserType(0)
// + literal: Const { ty: fn(&[T]) -> std::slice::Iter<'_, T> {std::slice::Iter::<'_, T>::new}, val: Value(<ZST>) }
}
bb1: {
StorageLive(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
_8 = &mut _5; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
_7 = <std::slice::Iter<'_, T> as Iterator>::next(_8) -> [return: bb2, unwind: bb8]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
// mir::Constant
// + span: $DIR/slice_iter.rs:28:14: 28:26
// + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option<<std::slice::Iter<'_, T> as Iterator>::Item> {<std::slice::Iter<'_, T> as Iterator>::next}, val: Value(<ZST>) }
}
bb2: {
_9 = discriminant(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
switchInt(move _9) -> [0: bb5, 1: bb3, otherwise: bb4]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
}
bb3: {
_10 = ((_7 as Some).0: &T); // scope 1 at $DIR/slice_iter.rs:+1:9: +1:10
StorageLive(_11); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10
_11 = &_2; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10
StorageLive(_12); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13
_12 = (_10,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13
_6 = <impl Fn(&T) as Fn<(&T,)>>::call(move _11, move _12) -> [return: bb6, unwind: bb8]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13
// mir::Constant
// + span: $DIR/slice_iter.rs:29:9: 29:10
// + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(&T), (&T,)) -> <impl Fn(&T) as FnOnce<(&T,)>>::Output {<impl Fn(&T) as Fn<(&T,)>>::call}, val: Value(<ZST>) }
}
bb4: {
unreachable; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:26
}
bb5: {
StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6
StorageDead(_5); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6
StorageDead(_3); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6
drop(_2) -> bb7; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2
}
bb6: {
StorageDead(_12); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13
StorageDead(_11); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13
StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6
goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6
}
bb7: {
return; // scope 0 at $DIR/slice_iter.rs:+4:2: +4:2
}
bb8 (cleanup): {
drop(_2) -> [return: bb9, unwind terminate]; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2
}
bb9 (cleanup): {
resume; // scope 0 at $DIR/slice_iter.rs:+0:1: +4:2
}
bb10: {
_3 = move _4; // scope 4 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
StorageDead(_4); // scope 0 at $DIR/slice_iter.rs:+1:25: +1:26
StorageLive(_5); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
_5 = move _3; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6
}
}

View File

@ -0,0 +1,114 @@
// MIR for `reverse_loop` after PreCodegen
fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
debug slice => _1; // in scope 0 at $DIR/slice_iter.rs:+0:28: +0:33
debug f => _2; // in scope 0 at $DIR/slice_iter.rs:+0:44: +0:45
let mut _0: (); // return place in scope 0 at $DIR/slice_iter.rs:+0:60: +0:60
let mut _3: std::iter::Rev<std::slice::Iter<'_, T>>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32
let mut _4: std::slice::Iter<'_, T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
let mut _5: std::iter::Rev<std::slice::Iter<'_, T>>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32
let _6: (); // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32
let mut _7: std::option::Option<&T>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32
let mut _8: &mut std::iter::Rev<std::slice::Iter<'_, T>>; // in scope 0 at $DIR/slice_iter.rs:+1:14: +1:32
let mut _9: isize; // in scope 0 at $DIR/slice_iter.rs:+1:5: +3:6
let mut _11: &impl Fn(&T); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:10
let mut _12: (&T,); // in scope 0 at $DIR/slice_iter.rs:+2:9: +2:13
scope 1 {
debug iter => _5; // in scope 1 at $DIR/slice_iter.rs:+1:14: +1:32
let _10: &T; // in scope 1 at $DIR/slice_iter.rs:+1:9: +1:10
scope 2 {
debug x => _10; // in scope 2 at $DIR/slice_iter.rs:+1:9: +1:10
}
scope 7 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) { // at $DIR/slice_iter.rs:35:14: 35:32
debug self => _8; // in scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
let mut _13: &mut std::slice::Iter<'_, T>; // in scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
}
}
scope 3 (inlined core::slice::<impl [T]>::iter) { // at $DIR/slice_iter.rs:35:20: 35:26
debug self => _1; // in scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
}
scope 4 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) { // at $DIR/slice_iter.rs:35:27: 35:32
debug self => _4; // in scope 4 at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
scope 5 (inlined Rev::<std::slice::Iter<'_, T>>::new) { // at $SRC_DIR/core/src/iter/traits/iterator.rs:LL:COL
debug iter => _4; // in scope 5 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
}
}
scope 6 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) { // at $DIR/slice_iter.rs:35:14: 35:32
debug self => _3; // in scope 6 at $SRC_DIR/core/src/iter/traits/collect.rs:LL:COL
}
bb0: {
StorageLive(_4); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:26
_4 = std::slice::Iter::<'_, T>::new(_1) -> [return: bb9, unwind: bb7]; // scope 3 at $SRC_DIR/core/src/slice/mod.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/slice/mod.rs:LL:COL
// + user_ty: UserType(0)
// + literal: Const { ty: fn(&[T]) -> std::slice::Iter<'_, T> {std::slice::Iter::<'_, T>::new}, val: Value(<ZST>) }
}
bb1: {
StorageLive(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32
_8 = &mut _5; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32
StorageLive(_13); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
_13 = &mut ((*_8).0: std::slice::Iter<'_, T>); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
_7 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _13) -> [return: bb10, unwind: bb7]; // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
// mir::Constant
// + span: $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
// + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option<<std::slice::Iter<'_, T> as Iterator>::Item> {<std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back}, val: Value(<ZST>) }
}
bb2: {
_10 = ((_7 as Some).0: &T); // scope 1 at $DIR/slice_iter.rs:+1:9: +1:10
StorageLive(_11); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10
_11 = &_2; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:10
StorageLive(_12); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13
_12 = (_10,); // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13
_6 = <impl Fn(&T) as Fn<(&T,)>>::call(move _11, move _12) -> [return: bb5, unwind: bb7]; // scope 2 at $DIR/slice_iter.rs:+2:9: +2:13
// mir::Constant
// + span: $DIR/slice_iter.rs:36:9: 36:10
// + literal: Const { ty: for<'a> extern "rust-call" fn(&'a impl Fn(&T), (&T,)) -> <impl Fn(&T) as FnOnce<(&T,)>>::Output {<impl Fn(&T) as Fn<(&T,)>>::call}, val: Value(<ZST>) }
}
bb3: {
unreachable; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32
}
bb4: {
StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6
StorageDead(_5); // scope 0 at $DIR/slice_iter.rs:+3:5: +3:6
drop(_2) -> bb6; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2
}
bb5: {
StorageDead(_12); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13
StorageDead(_11); // scope 2 at $DIR/slice_iter.rs:+2:12: +2:13
StorageDead(_7); // scope 1 at $DIR/slice_iter.rs:+3:5: +3:6
goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6
}
bb6: {
return; // scope 0 at $DIR/slice_iter.rs:+4:2: +4:2
}
bb7 (cleanup): {
drop(_2) -> [return: bb8, unwind terminate]; // scope 0 at $DIR/slice_iter.rs:+4:1: +4:2
}
bb8 (cleanup): {
resume; // scope 0 at $DIR/slice_iter.rs:+0:1: +4:2
}
bb9: {
_3 = Rev::<std::slice::Iter<'_, T>> { iter: move _4 }; // scope 5 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
StorageDead(_4); // scope 0 at $DIR/slice_iter.rs:+1:31: +1:32
StorageLive(_5); // scope 0 at $DIR/slice_iter.rs:+1:14: +1:32
_5 = move _3; // scope 0 at $DIR/slice_iter.rs:+1:14: +1:32
goto -> bb1; // scope 1 at $DIR/slice_iter.rs:+1:5: +3:6
}
bb10: {
StorageDead(_13); // scope 7 at $SRC_DIR/core/src/iter/adapters/rev.rs:LL:COL
_9 = discriminant(_7); // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32
switchInt(move _9) -> [0: bb4, 1: bb2, otherwise: bb3]; // scope 1 at $DIR/slice_iter.rs:+1:14: +1:32
}
}

View File

@ -0,0 +1,38 @@
// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
// only-64bit
// ignore-debug
#![crate_type = "lib"]
// When this test was added, the MIR for `next` was 174 lines just for the basic
// blocks -- far more if you counted the scopes. The goal of having this here
// is to hopefully keep it a reasonable size, ideally eventually small enough
// that the mir inliner would actually be willing to inline it, since it's an
// important building block and usually very few *backend* instructions.
// As such, feel free to `--bless` whatever changes you get here, so long as
// doing so doesn't add substantially more MIR.
// EMIT_MIR slice_iter.slice_iter_next.PreCodegen.after.mir
pub fn slice_iter_next<'a, T>(it: &mut std::slice::Iter<'a, T>) -> Option<&'a T> {
it.next()
}
// EMIT_MIR slice_iter.slice_iter_mut_next_back.PreCodegen.after.mir
pub fn slice_iter_mut_next_back<'a, T>(it: &mut std::slice::IterMut<'a, T>) -> Option<&'a mut T> {
it.next_back()
}
// EMIT_MIR slice_iter.forward_loop.PreCodegen.after.mir
pub fn forward_loop<'a, T>(slice: &'a [T], f: impl Fn(&T)) {
for x in slice.iter() {
f(x)
}
}
// EMIT_MIR slice_iter.reverse_loop.PreCodegen.after.mir
pub fn reverse_loop<'a, T>(slice: &'a [T], f: impl Fn(&T)) {
for x in slice.iter().rev() {
f(x)
}
}

View File

@ -0,0 +1,17 @@
// MIR for `slice_iter_mut_next_back` after PreCodegen
fn slice_iter_mut_next_back(_1: &mut std::slice::IterMut<'_, T>) -> Option<&mut T> {
debug it => _1; // in scope 0 at $DIR/slice_iter.rs:+0:40: +0:42
let mut _0: std::option::Option<&mut T>; // return place in scope 0 at $DIR/slice_iter.rs:+0:80: +0:97
bb0: {
_0 = <std::slice::IterMut<'_, T> as DoubleEndedIterator>::next_back(_1) -> bb1; // scope 0 at $DIR/slice_iter.rs:+1:5: +1:19
// mir::Constant
// + span: $DIR/slice_iter.rs:23:8: 23:17
// + literal: Const { ty: for<'a> fn(&'a mut std::slice::IterMut<'_, T>) -> Option<<std::slice::IterMut<'_, T> as Iterator>::Item> {<std::slice::IterMut<'_, T> as DoubleEndedIterator>::next_back}, val: Value(<ZST>) }
}
bb1: {
return; // scope 0 at $DIR/slice_iter.rs:+2:2: +2:2
}
}

View File

@ -0,0 +1,17 @@
// MIR for `slice_iter_next` after PreCodegen
fn slice_iter_next(_1: &mut std::slice::Iter<'_, T>) -> Option<&T> {
debug it => _1; // in scope 0 at $DIR/slice_iter.rs:+0:31: +0:33
let mut _0: std::option::Option<&T>; // return place in scope 0 at $DIR/slice_iter.rs:+0:68: +0:81
bb0: {
_0 = <std::slice::Iter<'_, T> as Iterator>::next(_1) -> bb1; // scope 0 at $DIR/slice_iter.rs:+1:5: +1:14
// mir::Constant
// + span: $DIR/slice_iter.rs:18:8: 18:12
// + literal: Const { ty: for<'a> fn(&'a mut std::slice::Iter<'_, T>) -> Option<<std::slice::Iter<'_, T> as Iterator>::Item> {<std::slice::Iter<'_, T> as Iterator>::next}, val: Value(<ZST>) }
}
bb1: {
return; // scope 0 at $DIR/slice_iter.rs:+2:2: +2:2
}
}

View File

@ -1,66 +1,70 @@
// MIR for `new` after PreCodegen
fn new(_1: Result<T, E>) -> Result<T, E> {
debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15
let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46
let mut _2: std::ops::ControlFlow<E, T>; // in scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
let mut _3: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:22
let _4: T; // in scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
let _5: E; // in scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
let mut _6: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+8:13: +8:37
let _7: T; // in scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
let _8: E; // in scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
debug x => _1; // in scope 0 at $DIR/try_identity.rs:+0:14: +0:15
let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity.rs:+0:34: +0:46
let mut _2: std::ops::ControlFlow<E, T>; // in scope 0 at $DIR/try_identity.rs:+2:15: +7:10
let mut _3: isize; // in scope 0 at $DIR/try_identity.rs:+4:17: +4:22
let _4: T; // in scope 0 at $DIR/try_identity.rs:+4:20: +4:21
let _5: E; // in scope 0 at $DIR/try_identity.rs:+5:21: +5:22
let mut _6: isize; // in scope 0 at $DIR/try_identity.rs:+8:13: +8:37
let _7: T; // in scope 0 at $DIR/try_identity.rs:+8:35: +8:36
let _8: E; // in scope 0 at $DIR/try_identity.rs:+9:32: +9:33
scope 1 {
debug v => _4; // in scope 1 at $DIR/try_identity_e2e.rs:+4:20: +4:21
debug v => _4; // in scope 1 at $DIR/try_identity.rs:+4:20: +4:21
}
scope 2 {
debug e => _5; // in scope 2 at $DIR/try_identity_e2e.rs:+5:21: +5:22
debug e => _5; // in scope 2 at $DIR/try_identity.rs:+5:21: +5:22
}
scope 3 {
debug v => _7; // in scope 3 at $DIR/try_identity_e2e.rs:+8:35: +8:36
debug v => _7; // in scope 3 at $DIR/try_identity.rs:+8:35: +8:36
}
scope 4 {
debug e => _8; // in scope 4 at $DIR/try_identity_e2e.rs:+9:32: +9:33
debug e => _8; // in scope 4 at $DIR/try_identity.rs:+9:32: +9:33
}
bb0: {
StorageLive(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
_3 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+3:19: +3:20
switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:20
StorageLive(_2); // scope 0 at $DIR/try_identity.rs:+2:15: +7:10
_3 = discriminant(_1); // scope 0 at $DIR/try_identity.rs:+3:19: +3:20
switchInt(move _3) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity.rs:+3:13: +3:20
}
bb1: {
_5 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+5:21: +5:22
_2 = ControlFlow::<E, T>::Break(move _5); // scope 2 at $DIR/try_identity_e2e.rs:+5:27: +5:48
goto -> bb4; // scope 0 at $DIR/try_identity_e2e.rs:+5:47: +5:48
_5 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity.rs:+5:21: +5:22
_2 = ControlFlow::<E, T>::Break(move _5); // scope 2 at $DIR/try_identity.rs:+5:27: +5:48
goto -> bb4; // scope 0 at $DIR/try_identity.rs:+5:47: +5:48
}
bb2: {
unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+3:19: +3:20
unreachable; // scope 0 at $DIR/try_identity.rs:+3:19: +3:20
}
bb3: {
_4 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+4:20: +4:21
_2 = ControlFlow::<E, T>::Continue(move _4); // scope 1 at $DIR/try_identity_e2e.rs:+4:26: +4:50
goto -> bb4; // scope 0 at $DIR/try_identity_e2e.rs:+4:49: +4:50
_4 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity.rs:+4:20: +4:21
_2 = ControlFlow::<E, T>::Continue(move _4); // scope 1 at $DIR/try_identity.rs:+4:26: +4:50
goto -> bb4; // scope 0 at $DIR/try_identity.rs:+4:49: +4:50
}
bb4: {
_6 = discriminant(_2); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +7:10
switchInt(move _6) -> [0: bb6, 1: bb5, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +7:10
_6 = discriminant(_2); // scope 0 at $DIR/try_identity.rs:+2:15: +7:10
switchInt(move _6) -> [0: bb6, 1: bb5, otherwise: bb2]; // scope 0 at $DIR/try_identity.rs:+2:9: +7:10
}
bb5: {
_8 = move ((_2 as Break).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+9:32: +9:33
_0 = Result::<T, E>::Err(move _8); // scope 4 at $DIR/try_identity_e2e.rs:+9:45: +9:51
StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
_8 = move ((_2 as Break).0: E); // scope 0 at $DIR/try_identity.rs:+9:32: +9:33
_0 = Result::<T, E>::Err(move _8); // scope 4 at $DIR/try_identity.rs:+9:45: +9:51
StorageDead(_2); // scope 0 at $DIR/try_identity.rs:+12:1: +12:2
goto -> bb7; // scope 0 at $DIR/try_identity.rs:+12:1: +12:2
}
bb6: {
_7 = move ((_2 as Continue).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+8:35: +8:36
_0 = Result::<T, E>::Ok(move _7); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +11:6
StorageDead(_2); // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
return; // scope 0 at $DIR/try_identity_e2e.rs:+12:1: +12:2
_7 = move ((_2 as Continue).0: T); // scope 0 at $DIR/try_identity.rs:+8:35: +8:36
_0 = Result::<T, E>::Ok(move _7); // scope 0 at $DIR/try_identity.rs:+1:5: +11:6
StorageDead(_2); // scope 0 at $DIR/try_identity.rs:+12:1: +12:2
goto -> bb7; // scope 0 at $DIR/try_identity.rs:+12:1: +12:2
}
bb7: {
return; // scope 0 at $DIR/try_identity.rs:+12:2: +12:2
}
}

View File

@ -1,36 +1,40 @@
// MIR for `old` after PreCodegen
fn old(_1: Result<T, E>) -> Result<T, E> {
debug x => _1; // in scope 0 at $DIR/try_identity_e2e.rs:+0:14: +0:15
let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity_e2e.rs:+0:34: +0:46
let mut _2: isize; // in scope 0 at $DIR/try_identity_e2e.rs:+3:13: +3:18
let _3: T; // in scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
let _4: E; // in scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
debug x => _1; // in scope 0 at $DIR/try_identity.rs:+0:14: +0:15
let mut _0: std::result::Result<T, E>; // return place in scope 0 at $DIR/try_identity.rs:+0:34: +0:46
let mut _2: isize; // in scope 0 at $DIR/try_identity.rs:+3:13: +3:18
let _3: T; // in scope 0 at $DIR/try_identity.rs:+3:16: +3:17
let _4: E; // in scope 0 at $DIR/try_identity.rs:+4:17: +4:18
scope 1 {
debug v => _3; // in scope 1 at $DIR/try_identity_e2e.rs:+3:16: +3:17
debug v => _3; // in scope 1 at $DIR/try_identity.rs:+3:16: +3:17
}
scope 2 {
debug e => _4; // in scope 2 at $DIR/try_identity_e2e.rs:+4:17: +4:18
debug e => _4; // in scope 2 at $DIR/try_identity.rs:+4:17: +4:18
}
bb0: {
_2 = discriminant(_1); // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16
switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity_e2e.rs:+2:9: +2:16
_2 = discriminant(_1); // scope 0 at $DIR/try_identity.rs:+2:15: +2:16
switchInt(move _2) -> [0: bb3, 1: bb1, otherwise: bb2]; // scope 0 at $DIR/try_identity.rs:+2:9: +2:16
}
bb1: {
_4 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity_e2e.rs:+4:17: +4:18
_0 = Result::<T, E>::Err(move _4); // scope 2 at $DIR/try_identity_e2e.rs:+4:30: +4:36
return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2
_4 = move ((_1 as Err).0: E); // scope 0 at $DIR/try_identity.rs:+4:17: +4:18
_0 = Result::<T, E>::Err(move _4); // scope 2 at $DIR/try_identity.rs:+4:30: +4:36
goto -> bb4; // scope 0 at $DIR/try_identity.rs:+7:1: +7:2
}
bb2: {
unreachable; // scope 0 at $DIR/try_identity_e2e.rs:+2:15: +2:16
unreachable; // scope 0 at $DIR/try_identity.rs:+2:15: +2:16
}
bb3: {
_3 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity_e2e.rs:+3:16: +3:17
_0 = Result::<T, E>::Ok(move _3); // scope 0 at $DIR/try_identity_e2e.rs:+1:5: +6:6
return; // scope 0 at $DIR/try_identity_e2e.rs:+7:1: +7:2
_3 = move ((_1 as Ok).0: T); // scope 0 at $DIR/try_identity.rs:+3:16: +3:17
_0 = Result::<T, E>::Ok(move _3); // scope 0 at $DIR/try_identity.rs:+1:5: +6:6
goto -> bb4; // scope 0 at $DIR/try_identity.rs:+7:1: +7:2
}
bb4: {
return; // scope 0 at $DIR/try_identity.rs:+7:2: +7:2
}
}

View File

@ -1,9 +1,13 @@
// compile-flags: -O -C debuginfo=0 -Zmir-opt-level=2
// only-64bit
// ignore-debug
// Track the status of MIR optimizations simplifying `Ok(res?)` for both the old and new desugarings
// of that syntax.
use std::ops::ControlFlow;
// EMIT_MIR try_identity_e2e.new.PreCodegen.after.mir
// EMIT_MIR try_identity.new.PreCodegen.after.mir
fn new<T, E>(x: Result<T, E>) -> Result<T, E> {
Ok(
match {
@ -18,7 +22,7 @@ fn new<T, E>(x: Result<T, E>) -> Result<T, E> {
)
}
// EMIT_MIR try_identity_e2e.old.PreCodegen.after.mir
// EMIT_MIR try_identity.old.PreCodegen.after.mir
fn old<T, E>(x: Result<T, E>) -> Result<T, E> {
Ok(
match x {

View File

@ -1,42 +0,0 @@
// MIR for `ezmap` after PreCodegen
fn ezmap(_1: Option<i32>) -> Option<i32> {
debug x => _1; // in scope 0 at $DIR/simple_option_map_e2e.rs:+0:14: +0:15
let mut _0: std::option::Option<i32>; // return place in scope 0 at $DIR/simple_option_map_e2e.rs:+0:33: +0:44
scope 1 (inlined map::<i32, i32, [closure@$DIR/simple_option_map_e2e.rs:14:12: 14:15]>) { // at $DIR/simple_option_map_e2e.rs:14:5: 14:22
debug slf => _1; // in scope 1 at $DIR/simple_option_map_e2e.rs:2:17: 2:20
debug f => const ZeroSized: [closure@$DIR/simple_option_map_e2e.rs:14:12: 14:15]; // in scope 1 at $DIR/simple_option_map_e2e.rs:2:33: 2:34
let mut _2: isize; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:9: 7:16
let _3: i32; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15
let mut _4: i32; // in scope 1 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
scope 2 {
debug x => _3; // in scope 2 at $DIR/simple_option_map_e2e.rs:7:14: 7:15
scope 3 (inlined ezmap::{closure#0}) { // at $DIR/simple_option_map_e2e.rs:7:25: 7:29
debug n => _3; // in scope 3 at $DIR/simple_option_map_e2e.rs:+1:13: +1:14
}
}
}
bb0: {
_2 = discriminant(_1); // scope 1 at $DIR/simple_option_map_e2e.rs:6:11: 6:14
switchInt(move _2) -> [0: bb1, 1: bb3, otherwise: bb2]; // scope 1 at $DIR/simple_option_map_e2e.rs:6:5: 6:14
}
bb1: {
_0 = Option::<i32>::None; // scope 1 at $DIR/simple_option_map_e2e.rs:8:17: 8:21
return; // scope 1 at $DIR/simple_option_map_e2e.rs:8:17: 8:21
}
bb2: {
unreachable; // scope 1 at $DIR/simple_option_map_e2e.rs:6:11: 6:14
}
bb3: {
_3 = ((_1 as Some).0: i32); // scope 1 at $DIR/simple_option_map_e2e.rs:7:14: 7:15
StorageLive(_4); // scope 2 at $DIR/simple_option_map_e2e.rs:7:25: 7:29
_4 = Add(_3, const 1_i32); // scope 3 at $DIR/simple_option_map_e2e.rs:+1:16: +1:21
_0 = Option::<i32>::Some(move _4); // scope 2 at $DIR/simple_option_map_e2e.rs:7:20: 7:30
StorageDead(_4); // scope 2 at $DIR/simple_option_map_e2e.rs:7:29: 7:30
return; // scope 1 at $DIR/simple_option_map_e2e.rs:10:1: 10:2
}
}