From 989bee0d792db9876b2945d7f07bccfa951e5fc5 Mon Sep 17 00:00:00 2001 From: Scott McMurray Date: Sun, 24 Mar 2024 11:31:32 -0700 Subject: [PATCH] Add a debug-info cost to MIR inlining --- .../rustc_mir_transform/src/cost_checker.rs | 13 ++ compiler/rustc_mir_transform/src/inline.rs | 2 + ...cked_ops.step_forward.PreCodegen.after.mir | 53 +++++++- .../loops.int_range.PreCodegen.after.mir | 77 +++--------- ...ward_loop.PreCodegen.after.panic-abort.mir | 97 +++++---------- ...ard_loop.PreCodegen.after.panic-unwind.mir | 101 +++++---------- ...iter_next.PreCodegen.after.panic-abort.mir | 62 +--------- ...ter_next.PreCodegen.after.panic-unwind.mir | 62 +--------- ...ange_loop.PreCodegen.after.panic-abort.mir | 111 ++++++----------- ...nge_loop.PreCodegen.after.panic-unwind.mir | 115 ++++++------------ 10 files changed, 227 insertions(+), 466 deletions(-) diff --git a/compiler/rustc_mir_transform/src/cost_checker.rs b/compiler/rustc_mir_transform/src/cost_checker.rs index 2c692c9500303..ad69793117117 100644 --- a/compiler/rustc_mir_transform/src/cost_checker.rs +++ b/compiler/rustc_mir_transform/src/cost_checker.rs @@ -7,6 +7,13 @@ const CALL_PENALTY: usize = 25; const LANDINGPAD_PENALTY: usize = 50; const RESUME_PENALTY: usize = 45; +// While debug info has no runtime cost, when inlining we do need to copy it +// into the caller MIR, which means we should give it a small cost to represent +// the compile-time impact of doing that, since just because something has few +// instructions doesn't necessarily mean it's cheap for us to inline. +// The backend can, of course, still inline such things later should it so wish. +const DEBUG_INFO_COST: usize = 1; + /// Verify that the callee body is compatible with the caller. #[derive(Clone)] pub(crate) struct CostChecker<'b, 'tcx> { @@ -31,6 +38,12 @@ impl<'b, 'tcx> CostChecker<'b, 'tcx> { self.cost } + // The MIR inliner doesn't actually call `visit_body`, so it doesn't work + // to put this in the visitor below. + pub fn before_body(&mut self, body: &Body<'tcx>) { + self.cost += body.var_debug_info.len() * DEBUG_INFO_COST; + } + fn instantiate_ty(&self, v: Ty<'tcx>) -> Ty<'tcx> { if let Some(instance) = self.instance { instance.instantiate_mir(self.tcx, ty::EarlyBinder::bind(&v)) diff --git a/compiler/rustc_mir_transform/src/inline.rs b/compiler/rustc_mir_transform/src/inline.rs index 78c0615b1650e..3a8fe2659bec1 100644 --- a/compiler/rustc_mir_transform/src/inline.rs +++ b/compiler/rustc_mir_transform/src/inline.rs @@ -506,6 +506,8 @@ impl<'tcx> Inliner<'tcx> { let mut checker = CostChecker::new(self.tcx, self.param_env, Some(callsite.callee), callee_body); + checker.before_body(callee_body); + // Traverse the MIR manually so we can account for the effects of inlining on the CFG. let mut work_list = vec![START_BLOCK]; let mut visited = BitSet::new_empty(callee_body.basic_blocks.len()); diff --git a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir index f1d0da28b4ef1..7c35fd01e338e 100644 --- a/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/checked_ops.step_forward.PreCodegen.after.mir @@ -4,12 +4,63 @@ fn step_forward(_1: u32, _2: usize) -> u32 { debug x => _1; debug n => _2; let mut _0: u32; + scope 1 (inlined ::forward) { + debug start => _1; + debug n => _2; + let _3: std::option::Option; + let mut _4: &std::option::Option; + let mut _6: u32; + scope 2 { + } + scope 3 (inlined Option::::is_none) { + debug self => _4; + scope 4 (inlined Option::::is_some) { + debug self => _4; + let mut _5: isize; + } + } + scope 5 (inlined core::num::::wrapping_add) { + debug self => _1; + debug rhs => _6; + } + } bb0: { - _0 = ::forward(move _1, move _2) -> [return: bb1, unwind continue]; + StorageLive(_4); + StorageLive(_3); + _3 = ::forward_checked(_1, _2) -> [return: bb1, unwind continue]; } bb1: { + _4 = &_3; + StorageLive(_5); + _5 = discriminant(_3); + switchInt(move _5) -> [1: bb2, 0: bb3, otherwise: bb5]; + } + + bb2: { + StorageDead(_5); + StorageDead(_3); + StorageDead(_4); + goto -> bb4; + } + + bb3: { + StorageDead(_5); + StorageDead(_3); + StorageDead(_4); + assert(!const true, "attempt to compute `{} + {}`, which would overflow", const core::num::::MAX, const 1_u32) -> [success: bb4, unwind continue]; + } + + bb4: { + StorageLive(_6); + _6 = _2 as u32 (IntToInt); + _0 = Add(_1, _6); + StorageDead(_6); return; } + + bb5: { + unreachable; + } } diff --git a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir index 0b5ed6ee169eb..d9904301ce1b1 100644 --- a/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir +++ b/tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir @@ -7,35 +7,17 @@ fn int_range(_1: usize, _2: usize) -> () { let mut _3: std::ops::Range; let mut _4: std::ops::Range; let mut _5: &mut std::ops::Range; - let mut _13: std::option::Option; - let _15: (); + let mut _6: std::option::Option; + let mut _7: isize; + let _9: (); scope 1 { debug iter => _4; - let _14: usize; + let _8: usize; scope 2 { - debug i => _14; + debug i => _8; } scope 4 (inlined iter::range::>::next) { debug self => _5; - scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - debug self => _5; - let mut _6: &usize; - let mut _7: &usize; - let mut _10: bool; - let _11: usize; - let mut _12: usize; - scope 6 { - debug old => _11; - scope 7 { - } - } - scope 8 (inlined std::cmp::impls::::lt) { - debug self => _6; - debug other => _7; - let mut _8: usize; - let mut _9: usize; - } - } } } scope 3 (inlined as IntoIterator>::into_iter) { @@ -50,54 +32,35 @@ fn int_range(_1: usize, _2: usize) -> () { } bb1: { - StorageLive(_13); - _5 = &mut _4; - StorageLive(_11); - StorageLive(_10); StorageLive(_6); - _6 = &(_4.0: usize); - StorageLive(_7); - _7 = &(_4.1: usize); - StorageLive(_8); - _8 = (_4.0: usize); - StorageLive(_9); - _9 = (_4.1: usize); - _10 = Lt(move _8, move _9); - StorageDead(_9); - StorageDead(_8); - switchInt(move _10) -> [0: bb2, otherwise: bb3]; + StorageLive(_5); + _5 = &mut _4; + _6 = as iter::range::RangeIteratorImpl>::spec_next(move _5) -> [return: bb2, unwind continue]; } bb2: { - StorageDead(_7); - StorageDead(_6); - StorageDead(_10); - StorageDead(_11); - StorageDead(_13); - StorageDead(_4); - return; + StorageDead(_5); + _7 = discriminant(_6); + switchInt(move _7) -> [0: bb3, 1: bb4, otherwise: bb6]; } bb3: { - StorageDead(_7); StorageDead(_6); - _11 = (_4.0: usize); - StorageLive(_12); - _12 = ::forward_unchecked(_11, const 1_usize) -> [return: bb4, unwind continue]; + StorageDead(_4); + return; } bb4: { - (_4.0: usize) = move _12; - StorageDead(_12); - _13 = Option::::Some(_11); - StorageDead(_10); - StorageDead(_11); - _14 = ((_13 as Some).0: usize); - _15 = opaque::(move _14) -> [return: bb5, unwind continue]; + _8 = ((_6 as Some).0: usize); + _9 = opaque::(move _8) -> [return: bb5, unwind continue]; } bb5: { - StorageDead(_13); + StorageDead(_6); goto -> bb1; } + + bb6: { + unreachable; + } } diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir index ed965770adbe0..bbf8801af026c 100644 --- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-abort.mir @@ -8,37 +8,19 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { let mut _4: std::ops::Range; let mut _5: std::ops::Range; let mut _6: &mut std::ops::Range; - let mut _14: std::option::Option; - let mut _16: &impl Fn(u32); - let mut _17: (u32,); - let _18: (); + let mut _7: std::option::Option; + let mut _8: isize; + let mut _10: &impl Fn(u32); + let mut _11: (u32,); + let _12: (); scope 1 { debug iter => _5; - let _15: u32; + let _9: u32; scope 2 { - debug x => _15; + debug x => _9; } scope 4 (inlined iter::range::>::next) { debug self => _6; - scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - debug self => _6; - let mut _7: &u32; - let mut _8: &u32; - let mut _11: bool; - let _12: u32; - let mut _13: u32; - scope 6 { - debug old => _12; - scope 7 { - } - } - scope 8 (inlined std::cmp::impls::::lt) { - debug self => _7; - debug other => _8; - let mut _9: u32; - let mut _10: u32; - } - } } } scope 3 (inlined as IntoIterator>::into_iter) { @@ -53,64 +35,45 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb1: { - StorageLive(_14); - _6 = &mut _5; - StorageLive(_12); - StorageLive(_11); StorageLive(_7); - _7 = &(_5.0: u32); - StorageLive(_8); - _8 = &(_5.1: u32); - StorageLive(_9); - _9 = (_5.0: u32); - StorageLive(_10); - _10 = (_5.1: u32); - _11 = Lt(move _9, move _10); - StorageDead(_10); - StorageDead(_9); - switchInt(move _11) -> [0: bb2, otherwise: bb4]; + StorageLive(_6); + _6 = &mut _5; + _7 = as iter::range::RangeIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind unreachable]; } bb2: { - StorageDead(_8); - StorageDead(_7); - StorageDead(_11); - StorageDead(_12); - StorageDead(_14); - StorageDead(_5); - drop(_3) -> [return: bb3, unwind unreachable]; + StorageDead(_6); + _8 = discriminant(_7); + switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb7]; } bb3: { - return; + StorageDead(_7); + StorageDead(_5); + drop(_3) -> [return: bb4, unwind unreachable]; } bb4: { - StorageDead(_8); - StorageDead(_7); - _12 = (_5.0: u32); - StorageLive(_13); - _13 = ::forward_unchecked(_12, const 1_usize) -> [return: bb5, unwind unreachable]; + return; } bb5: { - (_5.0: u32) = move _13; - StorageDead(_13); - _14 = Option::::Some(_12); - StorageDead(_11); - StorageDead(_12); - _15 = ((_14 as Some).0: u32); - StorageLive(_16); - _16 = &_3; - StorageLive(_17); - _17 = (_15,); - _18 = >::call(move _16, move _17) -> [return: bb6, unwind unreachable]; + _9 = ((_7 as Some).0: u32); + StorageLive(_10); + _10 = &_3; + StorageLive(_11); + _11 = (_9,); + _12 = >::call(move _10, move _11) -> [return: bb6, unwind unreachable]; } bb6: { - StorageDead(_17); - StorageDead(_16); - StorageDead(_14); + StorageDead(_11); + StorageDead(_10); + StorageDead(_7); goto -> bb1; } + + bb7: { + unreachable; + } } diff --git a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir index a7ee9be19bd4c..34df7b6d08563 100644 --- a/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir @@ -8,37 +8,19 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { let mut _4: std::ops::Range; let mut _5: std::ops::Range; let mut _6: &mut std::ops::Range; - let mut _14: std::option::Option; - let mut _16: &impl Fn(u32); - let mut _17: (u32,); - let _18: (); + let mut _7: std::option::Option; + let mut _8: isize; + let mut _10: &impl Fn(u32); + let mut _11: (u32,); + let _12: (); scope 1 { debug iter => _5; - let _15: u32; + let _9: u32; scope 2 { - debug x => _15; + debug x => _9; } scope 4 (inlined iter::range::>::next) { debug self => _6; - scope 5 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - debug self => _6; - let mut _7: &u32; - let mut _8: &u32; - let mut _11: bool; - let _12: u32; - let mut _13: u32; - scope 6 { - debug old => _12; - scope 7 { - } - } - scope 8 (inlined std::cmp::impls::::lt) { - debug self => _7; - debug other => _8; - let mut _9: u32; - let mut _10: u32; - } - } } } scope 3 (inlined as IntoIterator>::into_iter) { @@ -53,72 +35,53 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () { } bb1: { - StorageLive(_14); - _6 = &mut _5; - StorageLive(_12); - StorageLive(_11); StorageLive(_7); - _7 = &(_5.0: u32); - StorageLive(_8); - _8 = &(_5.1: u32); - StorageLive(_9); - _9 = (_5.0: u32); - StorageLive(_10); - _10 = (_5.1: u32); - _11 = Lt(move _9, move _10); - StorageDead(_10); - StorageDead(_9); - switchInt(move _11) -> [0: bb2, otherwise: bb4]; + StorageLive(_6); + _6 = &mut _5; + _7 = as iter::range::RangeIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind: bb8]; } bb2: { - StorageDead(_8); - StorageDead(_7); - StorageDead(_11); - StorageDead(_12); - StorageDead(_14); - StorageDead(_5); - drop(_3) -> [return: bb3, unwind continue]; + StorageDead(_6); + _8 = discriminant(_7); + switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb7]; } bb3: { - return; + StorageDead(_7); + StorageDead(_5); + drop(_3) -> [return: bb4, unwind continue]; } bb4: { - StorageDead(_8); - StorageDead(_7); - _12 = (_5.0: u32); - StorageLive(_13); - _13 = ::forward_unchecked(_12, const 1_usize) -> [return: bb5, unwind: bb7]; + return; } bb5: { - (_5.0: u32) = move _13; - StorageDead(_13); - _14 = Option::::Some(_12); - StorageDead(_11); - StorageDead(_12); - _15 = ((_14 as Some).0: u32); - StorageLive(_16); - _16 = &_3; - StorageLive(_17); - _17 = (_15,); - _18 = >::call(move _16, move _17) -> [return: bb6, unwind: bb7]; + _9 = ((_7 as Some).0: u32); + StorageLive(_10); + _10 = &_3; + StorageLive(_11); + _11 = (_9,); + _12 = >::call(move _10, move _11) -> [return: bb6, unwind: bb8]; } bb6: { - StorageDead(_17); - StorageDead(_16); - StorageDead(_14); + StorageDead(_11); + StorageDead(_10); + StorageDead(_7); goto -> bb1; } - bb7 (cleanup): { - drop(_3) -> [return: bb8, unwind terminate(cleanup)]; + bb7: { + unreachable; } bb8 (cleanup): { + drop(_3) -> [return: bb9, unwind terminate(cleanup)]; + } + + bb9 (cleanup): { resume; } } diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir index f674f6a300900..2a55ba0848188 100644 --- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-abort.mir @@ -5,73 +5,13 @@ fn range_iter_next(_1: &mut std::ops::Range) -> Option { let mut _0: std::option::Option; scope 1 (inlined iter::range::>::next) { debug self => _1; - scope 2 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - debug self => _1; - let mut _2: &u32; - let mut _3: &u32; - let mut _6: bool; - let _7: u32; - let mut _8: u32; - scope 3 { - debug old => _7; - scope 4 { - } - } - scope 5 (inlined std::cmp::impls::::lt) { - debug self => _2; - debug other => _3; - let mut _4: u32; - let mut _5: u32; - } - } } bb0: { - StorageLive(_7); - StorageLive(_6); - StorageLive(_2); - _2 = &((*_1).0: u32); - StorageLive(_3); - _3 = &((*_1).1: u32); - StorageLive(_4); - _4 = ((*_1).0: u32); - StorageLive(_5); - _5 = ((*_1).1: u32); - _6 = Lt(move _4, move _5); - StorageDead(_5); - StorageDead(_4); - switchInt(move _6) -> [0: bb1, otherwise: bb2]; + _0 = as iter::range::RangeIteratorImpl>::spec_next(move _1) -> [return: bb1, unwind unreachable]; } bb1: { - StorageDead(_3); - StorageDead(_2); - _0 = const Option::::None; - goto -> bb4; - } - - bb2: { - StorageDead(_3); - StorageDead(_2); - _7 = ((*_1).0: u32); - StorageLive(_8); - _8 = ::forward_unchecked(_7, const 1_usize) -> [return: bb3, unwind unreachable]; - } - - bb3: { - ((*_1).0: u32) = move _8; - StorageDead(_8); - _0 = Option::::Some(_7); - goto -> bb4; - } - - bb4: { - StorageDead(_6); - StorageDead(_7); return; } } - -ALLOC0 (size: 8, align: 4) { - 00 00 00 00 __ __ __ __ │ ....░░░░ -} diff --git a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir index a5029dcad3ad6..6e2a01bbca7b8 100644 --- a/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir @@ -5,73 +5,13 @@ fn range_iter_next(_1: &mut std::ops::Range) -> Option { let mut _0: std::option::Option; scope 1 (inlined iter::range::>::next) { debug self => _1; - scope 2 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - debug self => _1; - let mut _2: &u32; - let mut _3: &u32; - let mut _6: bool; - let _7: u32; - let mut _8: u32; - scope 3 { - debug old => _7; - scope 4 { - } - } - scope 5 (inlined std::cmp::impls::::lt) { - debug self => _2; - debug other => _3; - let mut _4: u32; - let mut _5: u32; - } - } } bb0: { - StorageLive(_7); - StorageLive(_6); - StorageLive(_2); - _2 = &((*_1).0: u32); - StorageLive(_3); - _3 = &((*_1).1: u32); - StorageLive(_4); - _4 = ((*_1).0: u32); - StorageLive(_5); - _5 = ((*_1).1: u32); - _6 = Lt(move _4, move _5); - StorageDead(_5); - StorageDead(_4); - switchInt(move _6) -> [0: bb1, otherwise: bb2]; + _0 = as iter::range::RangeIteratorImpl>::spec_next(move _1) -> [return: bb1, unwind continue]; } bb1: { - StorageDead(_3); - StorageDead(_2); - _0 = const Option::::None; - goto -> bb4; - } - - bb2: { - StorageDead(_3); - StorageDead(_2); - _7 = ((*_1).0: u32); - StorageLive(_8); - _8 = ::forward_unchecked(_7, const 1_usize) -> [return: bb3, unwind continue]; - } - - bb3: { - ((*_1).0: u32) = move _8; - StorageDead(_8); - _0 = Option::::Some(_7); - goto -> bb4; - } - - bb4: { - StorageDead(_6); - StorageDead(_7); return; } } - -ALLOC0 (size: 8, align: 4) { - 00 00 00 00 __ __ __ __ │ ....░░░░ -} diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir index 543e8918e3943..1be14324739f1 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-abort.mir @@ -8,43 +8,25 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _4: std::ops::Range; let mut _5: std::ops::Range; let mut _6: &mut std::ops::Range; - let mut _14: std::option::Option; - let mut _16: usize; - let mut _17: bool; - let mut _19: &impl Fn(usize, &T); - let mut _20: (usize, &T); - let _21: (); + let mut _7: std::option::Option; + let mut _8: isize; + let mut _10: usize; + let mut _11: bool; + let mut _13: &impl Fn(usize, &T); + let mut _14: (usize, &T); + let _15: (); scope 1 { debug iter => _5; - let _15: usize; + let _9: usize; scope 2 { - debug i => _15; - let _18: &T; + debug i => _9; + let _12: &T; scope 3 { - debug x => _18; + debug x => _12; } } scope 5 (inlined iter::range::>::next) { debug self => _6; - scope 6 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - debug self => _6; - let mut _7: &usize; - let mut _8: &usize; - let mut _11: bool; - let _12: usize; - let mut _13: usize; - scope 7 { - debug old => _12; - scope 8 { - } - } - scope 9 (inlined std::cmp::impls::::lt) { - debug self => _7; - debug other => _8; - let mut _9: usize; - let mut _10: usize; - } - } } } scope 4 (inlined as IntoIterator>::into_iter) { @@ -62,71 +44,52 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb1: { - StorageLive(_14); - _6 = &mut _5; - StorageLive(_12); - StorageLive(_11); StorageLive(_7); - _7 = &(_5.0: usize); - StorageLive(_8); - _8 = &(_5.1: usize); - StorageLive(_9); - _9 = (_5.0: usize); - StorageLive(_10); - _10 = (_5.1: usize); - _11 = Lt(move _9, move _10); - StorageDead(_10); - StorageDead(_9); - switchInt(move _11) -> [0: bb2, otherwise: bb4]; + StorageLive(_6); + _6 = &mut _5; + _7 = as iter::range::RangeIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind unreachable]; } bb2: { - StorageDead(_8); - StorageDead(_7); - StorageDead(_11); - StorageDead(_12); - StorageDead(_14); - StorageDead(_5); - drop(_2) -> [return: bb3, unwind unreachable]; + StorageDead(_6); + _8 = discriminant(_7); + switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb8]; } bb3: { - return; + StorageDead(_7); + StorageDead(_5); + drop(_2) -> [return: bb4, unwind unreachable]; } bb4: { - StorageDead(_8); - StorageDead(_7); - _12 = (_5.0: usize); - StorageLive(_13); - _13 = ::forward_unchecked(_12, const 1_usize) -> [return: bb5, unwind unreachable]; + return; } bb5: { - (_5.0: usize) = move _13; - StorageDead(_13); - _14 = Option::::Some(_12); - StorageDead(_11); - StorageDead(_12); - _15 = ((_14 as Some).0: usize); - _16 = Len((*_1)); - _17 = Lt(_15, _16); - assert(move _17, "index out of bounds: the length is {} but the index is {}", move _16, _15) -> [success: bb6, unwind unreachable]; + _9 = ((_7 as Some).0: usize); + _10 = Len((*_1)); + _11 = Lt(_9, _10); + assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, _9) -> [success: bb6, unwind unreachable]; } bb6: { - _18 = &(*_1)[_15]; - StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (_15, _18); - _21 = >::call(move _19, move _20) -> [return: bb7, unwind unreachable]; + _12 = &(*_1)[_9]; + StorageLive(_13); + _13 = &_2; + StorageLive(_14); + _14 = (_9, _12); + _15 = >::call(move _13, move _14) -> [return: bb7, unwind unreachable]; } bb7: { - StorageDead(_20); - StorageDead(_19); StorageDead(_14); + StorageDead(_13); + StorageDead(_7); goto -> bb1; } + + bb8: { + unreachable; + } } diff --git a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir index a16e9cd9e516d..451733f0a7f9f 100644 --- a/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir +++ b/tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir @@ -8,43 +8,25 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { let mut _4: std::ops::Range; let mut _5: std::ops::Range; let mut _6: &mut std::ops::Range; - let mut _14: std::option::Option; - let mut _16: usize; - let mut _17: bool; - let mut _19: &impl Fn(usize, &T); - let mut _20: (usize, &T); - let _21: (); + let mut _7: std::option::Option; + let mut _8: isize; + let mut _10: usize; + let mut _11: bool; + let mut _13: &impl Fn(usize, &T); + let mut _14: (usize, &T); + let _15: (); scope 1 { debug iter => _5; - let _15: usize; + let _9: usize; scope 2 { - debug i => _15; - let _18: &T; + debug i => _9; + let _12: &T; scope 3 { - debug x => _18; + debug x => _12; } } scope 5 (inlined iter::range::>::next) { debug self => _6; - scope 6 (inlined as iter::range::RangeIteratorImpl>::spec_next) { - debug self => _6; - let mut _7: &usize; - let mut _8: &usize; - let mut _11: bool; - let _12: usize; - let mut _13: usize; - scope 7 { - debug old => _12; - scope 8 { - } - } - scope 9 (inlined std::cmp::impls::::lt) { - debug self => _7; - debug other => _8; - let mut _9: usize; - let mut _10: usize; - } - } } } scope 4 (inlined as IntoIterator>::into_iter) { @@ -62,79 +44,60 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () { } bb1: { - StorageLive(_14); - _6 = &mut _5; - StorageLive(_12); - StorageLive(_11); StorageLive(_7); - _7 = &(_5.0: usize); - StorageLive(_8); - _8 = &(_5.1: usize); - StorageLive(_9); - _9 = (_5.0: usize); - StorageLive(_10); - _10 = (_5.1: usize); - _11 = Lt(move _9, move _10); - StorageDead(_10); - StorageDead(_9); - switchInt(move _11) -> [0: bb2, otherwise: bb4]; + StorageLive(_6); + _6 = &mut _5; + _7 = as iter::range::RangeIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind: bb9]; } bb2: { - StorageDead(_8); - StorageDead(_7); - StorageDead(_11); - StorageDead(_12); - StorageDead(_14); - StorageDead(_5); - drop(_2) -> [return: bb3, unwind continue]; + StorageDead(_6); + _8 = discriminant(_7); + switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb8]; } bb3: { - return; + StorageDead(_7); + StorageDead(_5); + drop(_2) -> [return: bb4, unwind continue]; } bb4: { - StorageDead(_8); - StorageDead(_7); - _12 = (_5.0: usize); - StorageLive(_13); - _13 = ::forward_unchecked(_12, const 1_usize) -> [return: bb5, unwind: bb8]; + return; } bb5: { - (_5.0: usize) = move _13; - StorageDead(_13); - _14 = Option::::Some(_12); - StorageDead(_11); - StorageDead(_12); - _15 = ((_14 as Some).0: usize); - _16 = Len((*_1)); - _17 = Lt(_15, _16); - assert(move _17, "index out of bounds: the length is {} but the index is {}", move _16, _15) -> [success: bb6, unwind: bb8]; + _9 = ((_7 as Some).0: usize); + _10 = Len((*_1)); + _11 = Lt(_9, _10); + assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, _9) -> [success: bb6, unwind: bb9]; } bb6: { - _18 = &(*_1)[_15]; - StorageLive(_19); - _19 = &_2; - StorageLive(_20); - _20 = (_15, _18); - _21 = >::call(move _19, move _20) -> [return: bb7, unwind: bb8]; + _12 = &(*_1)[_9]; + StorageLive(_13); + _13 = &_2; + StorageLive(_14); + _14 = (_9, _12); + _15 = >::call(move _13, move _14) -> [return: bb7, unwind: bb9]; } bb7: { - StorageDead(_20); - StorageDead(_19); StorageDead(_14); + StorageDead(_13); + StorageDead(_7); goto -> bb1; } - bb8 (cleanup): { - drop(_2) -> [return: bb9, unwind terminate(cleanup)]; + bb8: { + unreachable; } bb9 (cleanup): { + drop(_2) -> [return: bb10, unwind terminate(cleanup)]; + } + + bb10 (cleanup): { resume; } }