Skip to content
This repository was archived by the owner on May 28, 2025. It is now read-only.
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit a40a62a

Browse files
committedMar 26, 2024
Auto merge of rust-lang#123011 - scottmcm:inline-debuginfo-cost, r=<try>
Add a debug-info cost to MIR inlining Inspired by all the MIR I keep looking at that's inlined away like 7 different function calls so the body is 2 statements but 30 debug-infos. r? ghost
2 parents 536606b + ce93553 commit a40a62a

9 files changed

+249
-678
lines changed
 

‎compiler/rustc_mir_transform/src/cost_checker.rs

Lines changed: 13 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -7,6 +7,13 @@ const CALL_PENALTY: usize = 25;
77
const LANDINGPAD_PENALTY: usize = 50;
88
const RESUME_PENALTY: usize = 45;
99

10+
// While debug info has no runtime cost, when inlining we do need to copy it
11+
// into the caller MIR, which means we should give it a small cost to represent
12+
// the compile-time impact of doing that, since just because something has few
13+
// instructions doesn't necessarily mean it's cheap for us to inline.
14+
// The backend can, of course, still inline such things later should it so wish.
15+
const DEBUG_INFO_COST: usize = 2;
16+
1017
/// Verify that the callee body is compatible with the caller.
1118
#[derive(Clone)]
1219
pub(crate) struct CostChecker<'b, 'tcx> {
@@ -31,6 +38,12 @@ impl<'b, 'tcx> CostChecker<'b, 'tcx> {
3138
self.cost
3239
}
3340

41+
// The MIR inliner doesn't actually call `visit_body`, so it doesn't work
42+
// to put this in the visitor below.
43+
pub fn before_body(&mut self, body: &Body<'tcx>) {
44+
self.cost += body.var_debug_info.len() * DEBUG_INFO_COST;
45+
}
46+
3447
fn instantiate_ty(&self, v: Ty<'tcx>) -> Ty<'tcx> {
3548
if let Some(instance) = self.instance {
3649
instance.instantiate_mir(self.tcx, ty::EarlyBinder::bind(&v))

‎compiler/rustc_mir_transform/src/inline.rs

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -506,6 +506,8 @@ impl<'tcx> Inliner<'tcx> {
506506
let mut checker =
507507
CostChecker::new(self.tcx, self.param_env, Some(callsite.callee), callee_body);
508508

509+
checker.before_body(callee_body);
510+
509511
// Traverse the MIR manually so we can account for the effects of inlining on the CFG.
510512
let mut work_list = vec![START_BLOCK];
511513
let mut visited = BitSet::new_empty(callee_body.basic_blocks.len());

‎tests/mir-opt/pre-codegen/loops.int_range.PreCodegen.after.mir

Lines changed: 20 additions & 57 deletions
Original file line numberDiff line numberDiff line change
@@ -7,35 +7,17 @@ fn int_range(_1: usize, _2: usize) -> () {
77
let mut _3: std::ops::Range<usize>;
88
let mut _4: std::ops::Range<usize>;
99
let mut _5: &mut std::ops::Range<usize>;
10-
let mut _13: std::option::Option<usize>;
11-
let _15: ();
10+
let mut _6: std::option::Option<usize>;
11+
let mut _7: isize;
12+
let _9: ();
1213
scope 1 {
1314
debug iter => _4;
14-
let _14: usize;
15+
let _8: usize;
1516
scope 2 {
16-
debug i => _14;
17+
debug i => _8;
1718
}
1819
scope 4 (inlined iter::range::<impl Iterator for std::ops::Range<usize>>::next) {
1920
debug self => _5;
20-
scope 5 (inlined <std::ops::Range<usize> as iter::range::RangeIteratorImpl>::spec_next) {
21-
debug self => _5;
22-
let mut _6: &usize;
23-
let mut _7: &usize;
24-
let mut _10: bool;
25-
let _11: usize;
26-
let mut _12: usize;
27-
scope 6 {
28-
debug old => _11;
29-
scope 7 {
30-
}
31-
}
32-
scope 8 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
33-
debug self => _6;
34-
debug other => _7;
35-
let mut _8: usize;
36-
let mut _9: usize;
37-
}
38-
}
3921
}
4022
}
4123
scope 3 (inlined <std::ops::Range<usize> as IntoIterator>::into_iter) {
@@ -50,54 +32,35 @@ fn int_range(_1: usize, _2: usize) -> () {
5032
}
5133

5234
bb1: {
53-
StorageLive(_13);
54-
_5 = &mut _4;
55-
StorageLive(_11);
56-
StorageLive(_10);
5735
StorageLive(_6);
58-
_6 = &(_4.0: usize);
59-
StorageLive(_7);
60-
_7 = &(_4.1: usize);
61-
StorageLive(_8);
62-
_8 = (_4.0: usize);
63-
StorageLive(_9);
64-
_9 = (_4.1: usize);
65-
_10 = Lt(move _8, move _9);
66-
StorageDead(_9);
67-
StorageDead(_8);
68-
switchInt(move _10) -> [0: bb2, otherwise: bb3];
36+
StorageLive(_5);
37+
_5 = &mut _4;
38+
_6 = <std::ops::Range<usize> as iter::range::RangeIteratorImpl>::spec_next(move _5) -> [return: bb2, unwind continue];
6939
}
7040

7141
bb2: {
72-
StorageDead(_7);
73-
StorageDead(_6);
74-
StorageDead(_10);
75-
StorageDead(_11);
76-
StorageDead(_13);
77-
StorageDead(_4);
78-
return;
42+
StorageDead(_5);
43+
_7 = discriminant(_6);
44+
switchInt(move _7) -> [0: bb3, 1: bb4, otherwise: bb6];
7945
}
8046

8147
bb3: {
82-
StorageDead(_7);
8348
StorageDead(_6);
84-
_11 = (_4.0: usize);
85-
StorageLive(_12);
86-
_12 = <usize as Step>::forward_unchecked(_11, const 1_usize) -> [return: bb4, unwind continue];
49+
StorageDead(_4);
50+
return;
8751
}
8852

8953
bb4: {
90-
(_4.0: usize) = move _12;
91-
StorageDead(_12);
92-
_13 = Option::<usize>::Some(_11);
93-
StorageDead(_10);
94-
StorageDead(_11);
95-
_14 = ((_13 as Some).0: usize);
96-
_15 = opaque::<usize>(move _14) -> [return: bb5, unwind continue];
54+
_8 = ((_6 as Some).0: usize);
55+
_9 = opaque::<usize>(move _8) -> [return: bb5, unwind continue];
9756
}
9857

9958
bb5: {
100-
StorageDead(_13);
59+
StorageDead(_6);
10160
goto -> bb1;
10261
}
62+
63+
bb6: {
64+
unreachable;
65+
}
10366
}

‎tests/mir-opt/pre-codegen/range_iter.forward_loop.PreCodegen.after.panic-unwind.mir

Lines changed: 32 additions & 69 deletions
Original file line numberDiff line numberDiff line change
@@ -8,37 +8,19 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
88
let mut _4: std::ops::Range<u32>;
99
let mut _5: std::ops::Range<u32>;
1010
let mut _6: &mut std::ops::Range<u32>;
11-
let mut _14: std::option::Option<u32>;
12-
let mut _16: &impl Fn(u32);
13-
let mut _17: (u32,);
14-
let _18: ();
11+
let mut _7: std::option::Option<u32>;
12+
let mut _8: isize;
13+
let mut _10: &impl Fn(u32);
14+
let mut _11: (u32,);
15+
let _12: ();
1516
scope 1 {
1617
debug iter => _5;
17-
let _15: u32;
18+
let _9: u32;
1819
scope 2 {
19-
debug x => _15;
20+
debug x => _9;
2021
}
2122
scope 4 (inlined iter::range::<impl Iterator for std::ops::Range<u32>>::next) {
2223
debug self => _6;
23-
scope 5 (inlined <std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next) {
24-
debug self => _6;
25-
let mut _7: &u32;
26-
let mut _8: &u32;
27-
let mut _11: bool;
28-
let _12: u32;
29-
let mut _13: u32;
30-
scope 6 {
31-
debug old => _12;
32-
scope 7 {
33-
}
34-
}
35-
scope 8 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
36-
debug self => _7;
37-
debug other => _8;
38-
let mut _9: u32;
39-
let mut _10: u32;
40-
}
41-
}
4224
}
4325
}
4426
scope 3 (inlined <std::ops::Range<u32> as IntoIterator>::into_iter) {
@@ -53,72 +35,53 @@ fn forward_loop(_1: u32, _2: u32, _3: impl Fn(u32)) -> () {
5335
}
5436

5537
bb1: {
56-
StorageLive(_14);
57-
_6 = &mut _5;
58-
StorageLive(_12);
59-
StorageLive(_11);
6038
StorageLive(_7);
61-
_7 = &(_5.0: u32);
62-
StorageLive(_8);
63-
_8 = &(_5.1: u32);
64-
StorageLive(_9);
65-
_9 = (_5.0: u32);
66-
StorageLive(_10);
67-
_10 = (_5.1: u32);
68-
_11 = Lt(move _9, move _10);
69-
StorageDead(_10);
70-
StorageDead(_9);
71-
switchInt(move _11) -> [0: bb2, otherwise: bb4];
39+
StorageLive(_6);
40+
_6 = &mut _5;
41+
_7 = <std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind: bb8];
7242
}
7343

7444
bb2: {
75-
StorageDead(_8);
76-
StorageDead(_7);
77-
StorageDead(_11);
78-
StorageDead(_12);
79-
StorageDead(_14);
80-
StorageDead(_5);
81-
drop(_3) -> [return: bb3, unwind continue];
45+
StorageDead(_6);
46+
_8 = discriminant(_7);
47+
switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb7];
8248
}
8349

8450
bb3: {
85-
return;
51+
StorageDead(_7);
52+
StorageDead(_5);
53+
drop(_3) -> [return: bb4, unwind continue];
8654
}
8755

8856
bb4: {
89-
StorageDead(_8);
90-
StorageDead(_7);
91-
_12 = (_5.0: u32);
92-
StorageLive(_13);
93-
_13 = <u32 as Step>::forward_unchecked(_12, const 1_usize) -> [return: bb5, unwind: bb7];
57+
return;
9458
}
9559

9660
bb5: {
97-
(_5.0: u32) = move _13;
98-
StorageDead(_13);
99-
_14 = Option::<u32>::Some(_12);
100-
StorageDead(_11);
101-
StorageDead(_12);
102-
_15 = ((_14 as Some).0: u32);
103-
StorageLive(_16);
104-
_16 = &_3;
105-
StorageLive(_17);
106-
_17 = (_15,);
107-
_18 = <impl Fn(u32) as Fn<(u32,)>>::call(move _16, move _17) -> [return: bb6, unwind: bb7];
61+
_9 = ((_7 as Some).0: u32);
62+
StorageLive(_10);
63+
_10 = &_3;
64+
StorageLive(_11);
65+
_11 = (_9,);
66+
_12 = <impl Fn(u32) as Fn<(u32,)>>::call(move _10, move _11) -> [return: bb6, unwind: bb8];
10867
}
10968

11069
bb6: {
111-
StorageDead(_17);
112-
StorageDead(_16);
113-
StorageDead(_14);
70+
StorageDead(_11);
71+
StorageDead(_10);
72+
StorageDead(_7);
11473
goto -> bb1;
11574
}
11675

117-
bb7 (cleanup): {
118-
drop(_3) -> [return: bb8, unwind terminate(cleanup)];
76+
bb7: {
77+
unreachable;
11978
}
12079

12180
bb8 (cleanup): {
81+
drop(_3) -> [return: bb9, unwind terminate(cleanup)];
82+
}
83+
84+
bb9 (cleanup): {
12285
resume;
12386
}
12487
}

‎tests/mir-opt/pre-codegen/range_iter.range_iter_next.PreCodegen.after.panic-unwind.mir

Lines changed: 1 addition & 61 deletions
Original file line numberDiff line numberDiff line change
@@ -5,73 +5,13 @@ fn range_iter_next(_1: &mut std::ops::Range<u32>) -> Option<u32> {
55
let mut _0: std::option::Option<u32>;
66
scope 1 (inlined iter::range::<impl Iterator for std::ops::Range<u32>>::next) {
77
debug self => _1;
8-
scope 2 (inlined <std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next) {
9-
debug self => _1;
10-
let mut _2: &u32;
11-
let mut _3: &u32;
12-
let mut _6: bool;
13-
let _7: u32;
14-
let mut _8: u32;
15-
scope 3 {
16-
debug old => _7;
17-
scope 4 {
18-
}
19-
}
20-
scope 5 (inlined std::cmp::impls::<impl PartialOrd for u32>::lt) {
21-
debug self => _2;
22-
debug other => _3;
23-
let mut _4: u32;
24-
let mut _5: u32;
25-
}
26-
}
278
}
289

2910
bb0: {
30-
StorageLive(_7);
31-
StorageLive(_6);
32-
StorageLive(_2);
33-
_2 = &((*_1).0: u32);
34-
StorageLive(_3);
35-
_3 = &((*_1).1: u32);
36-
StorageLive(_4);
37-
_4 = ((*_1).0: u32);
38-
StorageLive(_5);
39-
_5 = ((*_1).1: u32);
40-
_6 = Lt(move _4, move _5);
41-
StorageDead(_5);
42-
StorageDead(_4);
43-
switchInt(move _6) -> [0: bb1, otherwise: bb2];
11+
_0 = <std::ops::Range<u32> as iter::range::RangeIteratorImpl>::spec_next(move _1) -> [return: bb1, unwind continue];
4412
}
4513

4614
bb1: {
47-
StorageDead(_3);
48-
StorageDead(_2);
49-
_0 = const Option::<u32>::None;
50-
goto -> bb4;
51-
}
52-
53-
bb2: {
54-
StorageDead(_3);
55-
StorageDead(_2);
56-
_7 = ((*_1).0: u32);
57-
StorageLive(_8);
58-
_8 = <u32 as Step>::forward_unchecked(_7, const 1_usize) -> [return: bb3, unwind continue];
59-
}
60-
61-
bb3: {
62-
((*_1).0: u32) = move _8;
63-
StorageDead(_8);
64-
_0 = Option::<u32>::Some(_7);
65-
goto -> bb4;
66-
}
67-
68-
bb4: {
69-
StorageDead(_6);
70-
StorageDead(_7);
7115
return;
7216
}
7317
}
74-
75-
ALLOC0 (size: 8, align: 4) {
76-
00 00 00 00 __ __ __ __ │ ....░░░░
77-
}

‎tests/mir-opt/pre-codegen/slice_iter.enumerated_loop.PreCodegen.after.panic-unwind.mir

Lines changed: 50 additions & 141 deletions
Original file line numberDiff line numberDiff line change
@@ -4,190 +4,99 @@ fn enumerated_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
44
debug slice => _1;
55
debug f => _2;
66
let mut _0: ();
7-
let mut _13: std::slice::Iter<'_, T>;
8-
let mut _14: std::iter::Enumerate<std::slice::Iter<'_, T>>;
9-
let mut _15: std::iter::Enumerate<std::slice::Iter<'_, T>>;
10-
let mut _16: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
11-
let mut _17: std::option::Option<(usize, &T)>;
12-
let mut _18: isize;
13-
let mut _21: &impl Fn(usize, &T);
14-
let mut _22: (usize, &T);
15-
let _23: ();
7+
let mut _3: std::slice::Iter<'_, T>;
8+
let mut _4: std::iter::Enumerate<std::slice::Iter<'_, T>>;
9+
let mut _5: std::iter::Enumerate<std::slice::Iter<'_, T>>;
10+
let mut _6: &mut std::iter::Enumerate<std::slice::Iter<'_, T>>;
11+
let mut _7: std::option::Option<(usize, &T)>;
12+
let mut _8: isize;
13+
let mut _11: &impl Fn(usize, &T);
14+
let mut _12: (usize, &T);
15+
let _13: ();
1616
scope 1 {
17-
debug iter => _15;
18-
let _19: usize;
19-
let _20: &T;
17+
debug iter => _5;
18+
let _9: usize;
19+
let _10: &T;
2020
scope 2 {
21-
debug i => _19;
22-
debug x => _20;
21+
debug i => _9;
22+
debug x => _10;
2323
}
2424
}
2525
scope 3 (inlined core::slice::<impl [T]>::iter) {
2626
debug self => _1;
27-
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
28-
debug slice => _1;
29-
let _3: usize;
30-
let mut _5: std::ptr::NonNull<[T]>;
31-
let mut _8: bool;
32-
let mut _9: *mut T;
33-
let mut _10: *mut T;
34-
let mut _12: *const T;
35-
scope 5 {
36-
debug len => _3;
37-
let _7: std::ptr::NonNull<T>;
38-
scope 6 {
39-
debug ptr => _7;
40-
scope 7 {
41-
let _11: *const T;
42-
scope 8 {
43-
debug end_or_len => _11;
44-
}
45-
scope 14 (inlined without_provenance::<T>) {
46-
debug addr => _3;
47-
scope 15 {
48-
}
49-
}
50-
scope 16 (inlined NonNull::<T>::as_ptr) {
51-
debug self => _7;
52-
}
53-
scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
54-
debug self => _9;
55-
debug count => _3;
56-
scope 18 {
57-
}
58-
}
59-
}
60-
}
61-
scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
62-
debug reference => _1;
63-
let mut _4: *const [T];
64-
scope 10 {
65-
}
66-
}
67-
scope 11 (inlined NonNull::<[T]>::cast::<T>) {
68-
debug self => _5;
69-
let mut _6: *const T;
70-
scope 12 {
71-
scope 13 (inlined NonNull::<[T]>::as_ptr) {
72-
debug self => _5;
73-
}
74-
}
75-
}
76-
}
77-
}
7827
}
79-
scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
80-
debug self => _13;
81-
scope 20 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
82-
debug iter => _13;
28+
scope 4 (inlined <std::slice::Iter<'_, T> as Iterator>::enumerate) {
29+
debug self => _3;
30+
scope 5 (inlined Enumerate::<std::slice::Iter<'_, T>>::new) {
31+
debug iter => _3;
8332
}
8433
}
85-
scope 21 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
86-
debug self => _14;
34+
scope 6 (inlined <Enumerate<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
35+
debug self => _4;
8736
}
8837

8938
bb0: {
90-
StorageLive(_13);
9139
StorageLive(_3);
92-
StorageLive(_7);
93-
StorageLive(_4);
94-
StorageLive(_6);
95-
_3 = Len((*_1));
96-
StorageLive(_5);
97-
_4 = &raw const (*_1);
98-
_5 = NonNull::<[T]> { pointer: _4 };
99-
_6 = _4 as *const T (PtrToPtr);
100-
_7 = NonNull::<T> { pointer: _6 };
101-
StorageDead(_5);
102-
StorageLive(_11);
103-
StorageLive(_8);
104-
_8 = const <T as std::mem::SizedTypeProperties>::IS_ZST;
105-
switchInt(move _8) -> [0: bb1, otherwise: bb2];
40+
_3 = std::slice::Iter::<'_, T>::new(move _1) -> [return: bb1, unwind: bb9];
10641
}
10742

10843
bb1: {
109-
StorageLive(_10);
110-
StorageLive(_9);
111-
_9 = _4 as *mut T (PtrToPtr);
112-
_10 = Offset(_9, _3);
113-
StorageDead(_9);
114-
_11 = move _10 as *const T (PointerCoercion(MutToConstPointer));
115-
StorageDead(_10);
116-
goto -> bb3;
44+
_4 = Enumerate::<std::slice::Iter<'_, T>> { iter: _3, count: const 0_usize };
45+
StorageDead(_3);
46+
StorageLive(_5);
47+
_5 = _4;
48+
goto -> bb2;
11749
}
11850

11951
bb2: {
120-
_11 = _3 as *const T (Transmute);
121-
goto -> bb3;
52+
StorageLive(_7);
53+
StorageLive(_6);
54+
_6 = &mut _5;
55+
_7 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _6) -> [return: bb3, unwind: bb9];
12256
}
12357

12458
bb3: {
125-
StorageDead(_8);
126-
StorageLive(_12);
127-
_12 = _11;
128-
_13 = std::slice::Iter::<'_, T> { ptr: _7, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
129-
StorageDead(_12);
130-
StorageDead(_11);
13159
StorageDead(_6);
132-
StorageDead(_4);
133-
StorageDead(_7);
134-
StorageDead(_3);
135-
_14 = Enumerate::<std::slice::Iter<'_, T>> { iter: _13, count: const 0_usize };
136-
StorageDead(_13);
137-
StorageLive(_15);
138-
_15 = _14;
139-
goto -> bb4;
60+
_8 = discriminant(_7);
61+
switchInt(move _8) -> [0: bb4, 1: bb6, otherwise: bb8];
14062
}
14163

14264
bb4: {
143-
StorageLive(_17);
144-
StorageLive(_16);
145-
_16 = &mut _15;
146-
_17 = <Enumerate<std::slice::Iter<'_, T>> as Iterator>::next(move _16) -> [return: bb5, unwind: bb11];
65+
StorageDead(_7);
66+
StorageDead(_5);
67+
drop(_2) -> [return: bb5, unwind continue];
14768
}
14869

14970
bb5: {
150-
StorageDead(_16);
151-
_18 = discriminant(_17);
152-
switchInt(move _18) -> [0: bb6, 1: bb8, otherwise: bb10];
71+
return;
15372
}
15473

15574
bb6: {
156-
StorageDead(_17);
157-
StorageDead(_15);
158-
drop(_2) -> [return: bb7, unwind continue];
75+
_9 = (((_7 as Some).0: (usize, &T)).0: usize);
76+
_10 = (((_7 as Some).0: (usize, &T)).1: &T);
77+
StorageLive(_11);
78+
_11 = &_2;
79+
StorageLive(_12);
80+
_12 = (_9, _10);
81+
_13 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _11, move _12) -> [return: bb7, unwind: bb9];
15982
}
16083

16184
bb7: {
162-
return;
85+
StorageDead(_12);
86+
StorageDead(_11);
87+
StorageDead(_7);
88+
goto -> bb2;
16389
}
16490

16591
bb8: {
166-
_19 = (((_17 as Some).0: (usize, &T)).0: usize);
167-
_20 = (((_17 as Some).0: (usize, &T)).1: &T);
168-
StorageLive(_21);
169-
_21 = &_2;
170-
StorageLive(_22);
171-
_22 = (_19, _20);
172-
_23 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _21, move _22) -> [return: bb9, unwind: bb11];
173-
}
174-
175-
bb9: {
176-
StorageDead(_22);
177-
StorageDead(_21);
178-
StorageDead(_17);
179-
goto -> bb4;
180-
}
181-
182-
bb10: {
18392
unreachable;
18493
}
18594

186-
bb11 (cleanup): {
187-
drop(_2) -> [return: bb12, unwind terminate(cleanup)];
95+
bb9 (cleanup): {
96+
drop(_2) -> [return: bb10, unwind terminate(cleanup)];
18897
}
18998

190-
bb12 (cleanup): {
99+
bb10 (cleanup): {
191100
resume;
192101
}
193102
}

‎tests/mir-opt/pre-codegen/slice_iter.forward_loop.PreCodegen.after.panic-unwind.mir

Lines changed: 41 additions & 132 deletions
Original file line numberDiff line numberDiff line change
@@ -4,177 +4,86 @@ fn forward_loop(_1: &[T], _2: impl Fn(&T)) -> () {
44
debug slice => _1;
55
debug f => _2;
66
let mut _0: ();
7-
let mut _13: std::slice::Iter<'_, T>;
8-
let mut _14: std::slice::Iter<'_, T>;
9-
let mut _15: &mut std::slice::Iter<'_, T>;
10-
let mut _16: std::option::Option<&T>;
11-
let mut _17: isize;
12-
let mut _19: &impl Fn(&T);
13-
let mut _20: (&T,);
14-
let _21: ();
7+
let mut _3: std::slice::Iter<'_, T>;
8+
let mut _4: std::slice::Iter<'_, T>;
9+
let mut _5: &mut std::slice::Iter<'_, T>;
10+
let mut _6: std::option::Option<&T>;
11+
let mut _7: isize;
12+
let mut _9: &impl Fn(&T);
13+
let mut _10: (&T,);
14+
let _11: ();
1515
scope 1 {
16-
debug iter => _14;
17-
let _18: &T;
16+
debug iter => _4;
17+
let _8: &T;
1818
scope 2 {
19-
debug x => _18;
19+
debug x => _8;
2020
}
2121
}
2222
scope 3 (inlined core::slice::<impl [T]>::iter) {
2323
debug self => _1;
24-
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
25-
debug slice => _1;
26-
let _3: usize;
27-
let mut _5: std::ptr::NonNull<[T]>;
28-
let mut _8: bool;
29-
let mut _9: *mut T;
30-
let mut _10: *mut T;
31-
let mut _12: *const T;
32-
scope 5 {
33-
debug len => _3;
34-
let _7: std::ptr::NonNull<T>;
35-
scope 6 {
36-
debug ptr => _7;
37-
scope 7 {
38-
let _11: *const T;
39-
scope 8 {
40-
debug end_or_len => _11;
41-
}
42-
scope 14 (inlined without_provenance::<T>) {
43-
debug addr => _3;
44-
scope 15 {
45-
}
46-
}
47-
scope 16 (inlined NonNull::<T>::as_ptr) {
48-
debug self => _7;
49-
}
50-
scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
51-
debug self => _9;
52-
debug count => _3;
53-
scope 18 {
54-
}
55-
}
56-
}
57-
}
58-
scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
59-
debug reference => _1;
60-
let mut _4: *const [T];
61-
scope 10 {
62-
}
63-
}
64-
scope 11 (inlined NonNull::<[T]>::cast::<T>) {
65-
debug self => _5;
66-
let mut _6: *const T;
67-
scope 12 {
68-
scope 13 (inlined NonNull::<[T]>::as_ptr) {
69-
debug self => _5;
70-
}
71-
}
72-
}
73-
}
74-
}
7524
}
76-
scope 19 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
77-
debug self => _13;
25+
scope 4 (inlined <std::slice::Iter<'_, T> as IntoIterator>::into_iter) {
26+
debug self => _3;
7827
}
7928

8029
bb0: {
81-
StorageLive(_3);
82-
StorageLive(_7);
83-
StorageLive(_4);
84-
StorageLive(_6);
85-
_3 = Len((*_1));
86-
StorageLive(_5);
87-
_4 = &raw const (*_1);
88-
_5 = NonNull::<[T]> { pointer: _4 };
89-
_6 = _4 as *const T (PtrToPtr);
90-
_7 = NonNull::<T> { pointer: _6 };
91-
StorageDead(_5);
92-
StorageLive(_11);
93-
StorageLive(_8);
94-
_8 = const <T as std::mem::SizedTypeProperties>::IS_ZST;
95-
switchInt(move _8) -> [0: bb1, otherwise: bb2];
30+
_3 = std::slice::Iter::<'_, T>::new(move _1) -> [return: bb1, unwind: bb9];
9631
}
9732

9833
bb1: {
99-
StorageLive(_10);
100-
StorageLive(_9);
101-
_9 = _4 as *mut T (PtrToPtr);
102-
_10 = Offset(_9, _3);
103-
StorageDead(_9);
104-
_11 = move _10 as *const T (PointerCoercion(MutToConstPointer));
105-
StorageDead(_10);
106-
goto -> bb3;
34+
StorageLive(_4);
35+
_4 = _3;
36+
goto -> bb2;
10737
}
10838

10939
bb2: {
110-
_11 = _3 as *const T (Transmute);
111-
goto -> bb3;
40+
StorageLive(_6);
41+
StorageLive(_5);
42+
_5 = &mut _4;
43+
_6 = <std::slice::Iter<'_, T> as Iterator>::next(move _5) -> [return: bb3, unwind: bb9];
11244
}
11345

11446
bb3: {
115-
StorageDead(_8);
116-
StorageLive(_12);
117-
_12 = _11;
118-
_13 = std::slice::Iter::<'_, T> { ptr: _7, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
119-
StorageDead(_12);
120-
StorageDead(_11);
121-
StorageDead(_6);
122-
StorageDead(_4);
123-
StorageDead(_7);
124-
StorageDead(_3);
125-
StorageLive(_14);
126-
_14 = _13;
127-
goto -> bb4;
47+
StorageDead(_5);
48+
_7 = discriminant(_6);
49+
switchInt(move _7) -> [0: bb4, 1: bb6, otherwise: bb8];
12850
}
12951

13052
bb4: {
131-
StorageLive(_16);
132-
StorageLive(_15);
133-
_15 = &mut _14;
134-
_16 = <std::slice::Iter<'_, T> as Iterator>::next(move _15) -> [return: bb5, unwind: bb11];
53+
StorageDead(_6);
54+
StorageDead(_4);
55+
drop(_2) -> [return: bb5, unwind continue];
13556
}
13657

13758
bb5: {
138-
StorageDead(_15);
139-
_17 = discriminant(_16);
140-
switchInt(move _17) -> [0: bb6, 1: bb8, otherwise: bb10];
59+
return;
14160
}
14261

14362
bb6: {
144-
StorageDead(_16);
145-
StorageDead(_14);
146-
drop(_2) -> [return: bb7, unwind continue];
63+
_8 = ((_6 as Some).0: &T);
64+
StorageLive(_9);
65+
_9 = &_2;
66+
StorageLive(_10);
67+
_10 = (_8,);
68+
_11 = <impl Fn(&T) as Fn<(&T,)>>::call(move _9, move _10) -> [return: bb7, unwind: bb9];
14769
}
14870

14971
bb7: {
150-
return;
72+
StorageDead(_10);
73+
StorageDead(_9);
74+
StorageDead(_6);
75+
goto -> bb2;
15176
}
15277

15378
bb8: {
154-
_18 = ((_16 as Some).0: &T);
155-
StorageLive(_19);
156-
_19 = &_2;
157-
StorageLive(_20);
158-
_20 = (_18,);
159-
_21 = <impl Fn(&T) as Fn<(&T,)>>::call(move _19, move _20) -> [return: bb9, unwind: bb11];
160-
}
161-
162-
bb9: {
163-
StorageDead(_20);
164-
StorageDead(_19);
165-
StorageDead(_16);
166-
goto -> bb4;
167-
}
168-
169-
bb10: {
17079
unreachable;
17180
}
17281

173-
bb11 (cleanup): {
174-
drop(_2) -> [return: bb12, unwind terminate(cleanup)];
82+
bb9 (cleanup): {
83+
drop(_2) -> [return: bb10, unwind terminate(cleanup)];
17584
}
17685

177-
bb12 (cleanup): {
86+
bb10 (cleanup): {
17887
resume;
17988
}
18089
}

‎tests/mir-opt/pre-codegen/slice_iter.range_loop.PreCodegen.after.panic-unwind.mir

Lines changed: 39 additions & 76 deletions
Original file line numberDiff line numberDiff line change
@@ -8,43 +8,25 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
88
let mut _4: std::ops::Range<usize>;
99
let mut _5: std::ops::Range<usize>;
1010
let mut _6: &mut std::ops::Range<usize>;
11-
let mut _14: std::option::Option<usize>;
12-
let mut _16: usize;
13-
let mut _17: bool;
14-
let mut _19: &impl Fn(usize, &T);
15-
let mut _20: (usize, &T);
16-
let _21: ();
11+
let mut _7: std::option::Option<usize>;
12+
let mut _8: isize;
13+
let mut _10: usize;
14+
let mut _11: bool;
15+
let mut _13: &impl Fn(usize, &T);
16+
let mut _14: (usize, &T);
17+
let _15: ();
1718
scope 1 {
1819
debug iter => _5;
19-
let _15: usize;
20+
let _9: usize;
2021
scope 2 {
21-
debug i => _15;
22-
let _18: &T;
22+
debug i => _9;
23+
let _12: &T;
2324
scope 3 {
24-
debug x => _18;
25+
debug x => _12;
2526
}
2627
}
2728
scope 5 (inlined iter::range::<impl Iterator for std::ops::Range<usize>>::next) {
2829
debug self => _6;
29-
scope 6 (inlined <std::ops::Range<usize> as iter::range::RangeIteratorImpl>::spec_next) {
30-
debug self => _6;
31-
let mut _7: &usize;
32-
let mut _8: &usize;
33-
let mut _11: bool;
34-
let _12: usize;
35-
let mut _13: usize;
36-
scope 7 {
37-
debug old => _12;
38-
scope 8 {
39-
}
40-
}
41-
scope 9 (inlined std::cmp::impls::<impl PartialOrd for usize>::lt) {
42-
debug self => _7;
43-
debug other => _8;
44-
let mut _9: usize;
45-
let mut _10: usize;
46-
}
47-
}
4830
}
4931
}
5032
scope 4 (inlined <std::ops::Range<usize> as IntoIterator>::into_iter) {
@@ -62,79 +44,60 @@ fn range_loop(_1: &[T], _2: impl Fn(usize, &T)) -> () {
6244
}
6345

6446
bb1: {
65-
StorageLive(_14);
66-
_6 = &mut _5;
67-
StorageLive(_12);
68-
StorageLive(_11);
6947
StorageLive(_7);
70-
_7 = &(_5.0: usize);
71-
StorageLive(_8);
72-
_8 = &(_5.1: usize);
73-
StorageLive(_9);
74-
_9 = (_5.0: usize);
75-
StorageLive(_10);
76-
_10 = (_5.1: usize);
77-
_11 = Lt(move _9, move _10);
78-
StorageDead(_10);
79-
StorageDead(_9);
80-
switchInt(move _11) -> [0: bb2, otherwise: bb4];
48+
StorageLive(_6);
49+
_6 = &mut _5;
50+
_7 = <std::ops::Range<usize> as iter::range::RangeIteratorImpl>::spec_next(move _6) -> [return: bb2, unwind: bb9];
8151
}
8252

8353
bb2: {
84-
StorageDead(_8);
85-
StorageDead(_7);
86-
StorageDead(_11);
87-
StorageDead(_12);
88-
StorageDead(_14);
89-
StorageDead(_5);
90-
drop(_2) -> [return: bb3, unwind continue];
54+
StorageDead(_6);
55+
_8 = discriminant(_7);
56+
switchInt(move _8) -> [0: bb3, 1: bb5, otherwise: bb8];
9157
}
9258

9359
bb3: {
94-
return;
60+
StorageDead(_7);
61+
StorageDead(_5);
62+
drop(_2) -> [return: bb4, unwind continue];
9563
}
9664

9765
bb4: {
98-
StorageDead(_8);
99-
StorageDead(_7);
100-
_12 = (_5.0: usize);
101-
StorageLive(_13);
102-
_13 = <usize as Step>::forward_unchecked(_12, const 1_usize) -> [return: bb5, unwind: bb8];
66+
return;
10367
}
10468

10569
bb5: {
106-
(_5.0: usize) = move _13;
107-
StorageDead(_13);
108-
_14 = Option::<usize>::Some(_12);
109-
StorageDead(_11);
110-
StorageDead(_12);
111-
_15 = ((_14 as Some).0: usize);
112-
_16 = Len((*_1));
113-
_17 = Lt(_15, _16);
114-
assert(move _17, "index out of bounds: the length is {} but the index is {}", move _16, _15) -> [success: bb6, unwind: bb8];
70+
_9 = ((_7 as Some).0: usize);
71+
_10 = Len((*_1));
72+
_11 = Lt(_9, _10);
73+
assert(move _11, "index out of bounds: the length is {} but the index is {}", move _10, _9) -> [success: bb6, unwind: bb9];
11574
}
11675

11776
bb6: {
118-
_18 = &(*_1)[_15];
119-
StorageLive(_19);
120-
_19 = &_2;
121-
StorageLive(_20);
122-
_20 = (_15, _18);
123-
_21 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _19, move _20) -> [return: bb7, unwind: bb8];
77+
_12 = &(*_1)[_9];
78+
StorageLive(_13);
79+
_13 = &_2;
80+
StorageLive(_14);
81+
_14 = (_9, _12);
82+
_15 = <impl Fn(usize, &T) as Fn<(usize, &T)>>::call(move _13, move _14) -> [return: bb7, unwind: bb9];
12483
}
12584

12685
bb7: {
127-
StorageDead(_20);
128-
StorageDead(_19);
12986
StorageDead(_14);
87+
StorageDead(_13);
88+
StorageDead(_7);
13089
goto -> bb1;
13190
}
13291

133-
bb8 (cleanup): {
134-
drop(_2) -> [return: bb9, unwind terminate(cleanup)];
92+
bb8: {
93+
unreachable;
13594
}
13695

13796
bb9 (cleanup): {
97+
drop(_2) -> [return: bb10, unwind terminate(cleanup)];
98+
}
99+
100+
bb10 (cleanup): {
138101
resume;
139102
}
140103
}

‎tests/mir-opt/pre-codegen/slice_iter.reverse_loop.PreCodegen.after.panic-unwind.mir

Lines changed: 51 additions & 142 deletions
Original file line numberDiff line numberDiff line change
@@ -4,192 +4,101 @@ fn reverse_loop(_1: &[T], _2: impl Fn(&T)) -> () {
44
debug slice => _1;
55
debug f => _2;
66
let mut _0: ();
7-
let mut _13: std::slice::Iter<'_, T>;
8-
let mut _14: std::iter::Rev<std::slice::Iter<'_, T>>;
9-
let mut _15: std::iter::Rev<std::slice::Iter<'_, T>>;
10-
let mut _16: &mut std::iter::Rev<std::slice::Iter<'_, T>>;
11-
let mut _18: std::option::Option<&T>;
12-
let mut _19: isize;
13-
let mut _21: &impl Fn(&T);
14-
let mut _22: (&T,);
15-
let _23: ();
7+
let mut _3: std::slice::Iter<'_, T>;
8+
let mut _4: std::iter::Rev<std::slice::Iter<'_, T>>;
9+
let mut _5: std::iter::Rev<std::slice::Iter<'_, T>>;
10+
let mut _6: &mut std::iter::Rev<std::slice::Iter<'_, T>>;
11+
let mut _8: std::option::Option<&T>;
12+
let mut _9: isize;
13+
let mut _11: &impl Fn(&T);
14+
let mut _12: (&T,);
15+
let _13: ();
1616
scope 1 {
17-
debug iter => _15;
18-
let _20: &T;
17+
debug iter => _5;
18+
let _10: &T;
1919
scope 2 {
20-
debug x => _20;
20+
debug x => _10;
2121
}
22-
scope 22 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
23-
debug self => _16;
24-
let mut _17: &mut std::slice::Iter<'_, T>;
22+
scope 7 (inlined <Rev<std::slice::Iter<'_, T>> as Iterator>::next) {
23+
debug self => _6;
24+
let mut _7: &mut std::slice::Iter<'_, T>;
2525
}
2626
}
2727
scope 3 (inlined core::slice::<impl [T]>::iter) {
2828
debug self => _1;
29-
scope 4 (inlined std::slice::Iter::<'_, T>::new) {
30-
debug slice => _1;
31-
let _3: usize;
32-
let mut _5: std::ptr::NonNull<[T]>;
33-
let mut _8: bool;
34-
let mut _9: *mut T;
35-
let mut _10: *mut T;
36-
let mut _12: *const T;
37-
scope 5 {
38-
debug len => _3;
39-
let _7: std::ptr::NonNull<T>;
40-
scope 6 {
41-
debug ptr => _7;
42-
scope 7 {
43-
let _11: *const T;
44-
scope 8 {
45-
debug end_or_len => _11;
46-
}
47-
scope 14 (inlined without_provenance::<T>) {
48-
debug addr => _3;
49-
scope 15 {
50-
}
51-
}
52-
scope 16 (inlined NonNull::<T>::as_ptr) {
53-
debug self => _7;
54-
}
55-
scope 17 (inlined std::ptr::mut_ptr::<impl *mut T>::add) {
56-
debug self => _9;
57-
debug count => _3;
58-
scope 18 {
59-
}
60-
}
61-
}
62-
}
63-
scope 9 (inlined <NonNull<[T]> as From<&[T]>>::from) {
64-
debug reference => _1;
65-
let mut _4: *const [T];
66-
scope 10 {
67-
}
68-
}
69-
scope 11 (inlined NonNull::<[T]>::cast::<T>) {
70-
debug self => _5;
71-
let mut _6: *const T;
72-
scope 12 {
73-
scope 13 (inlined NonNull::<[T]>::as_ptr) {
74-
debug self => _5;
75-
}
76-
}
77-
}
78-
}
79-
}
8029
}
81-
scope 19 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
82-
debug self => _13;
83-
scope 20 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
84-
debug iter => _13;
30+
scope 4 (inlined <std::slice::Iter<'_, T> as Iterator>::rev) {
31+
debug self => _3;
32+
scope 5 (inlined Rev::<std::slice::Iter<'_, T>>::new) {
33+
debug iter => _3;
8534
}
8635
}
87-
scope 21 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
88-
debug self => _14;
36+
scope 6 (inlined <Rev<std::slice::Iter<'_, T>> as IntoIterator>::into_iter) {
37+
debug self => _4;
8938
}
9039

9140
bb0: {
92-
StorageLive(_13);
9341
StorageLive(_3);
94-
StorageLive(_7);
95-
StorageLive(_4);
96-
StorageLive(_6);
97-
_3 = Len((*_1));
98-
StorageLive(_5);
99-
_4 = &raw const (*_1);
100-
_5 = NonNull::<[T]> { pointer: _4 };
101-
_6 = _4 as *const T (PtrToPtr);
102-
_7 = NonNull::<T> { pointer: _6 };
103-
StorageDead(_5);
104-
StorageLive(_11);
105-
StorageLive(_8);
106-
_8 = const <T as std::mem::SizedTypeProperties>::IS_ZST;
107-
switchInt(move _8) -> [0: bb1, otherwise: bb2];
42+
_3 = std::slice::Iter::<'_, T>::new(move _1) -> [return: bb1, unwind: bb9];
10843
}
10944

11045
bb1: {
111-
StorageLive(_10);
112-
StorageLive(_9);
113-
_9 = _4 as *mut T (PtrToPtr);
114-
_10 = Offset(_9, _3);
115-
StorageDead(_9);
116-
_11 = move _10 as *const T (PointerCoercion(MutToConstPointer));
117-
StorageDead(_10);
118-
goto -> bb3;
46+
_4 = Rev::<std::slice::Iter<'_, T>> { iter: _3 };
47+
StorageDead(_3);
48+
StorageLive(_5);
49+
_5 = _4;
50+
goto -> bb2;
11951
}
12052

12153
bb2: {
122-
_11 = _3 as *const T (Transmute);
123-
goto -> bb3;
54+
StorageLive(_8);
55+
_6 = &mut _5;
56+
StorageLive(_7);
57+
_7 = &mut (_5.0: std::slice::Iter<'_, T>);
58+
_8 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _7) -> [return: bb3, unwind: bb9];
12459
}
12560

12661
bb3: {
127-
StorageDead(_8);
128-
StorageLive(_12);
129-
_12 = _11;
130-
_13 = std::slice::Iter::<'_, T> { ptr: _7, end_or_len: move _12, _marker: const ZeroSized: PhantomData<&T> };
131-
StorageDead(_12);
132-
StorageDead(_11);
133-
StorageDead(_6);
134-
StorageDead(_4);
13562
StorageDead(_7);
136-
StorageDead(_3);
137-
_14 = Rev::<std::slice::Iter<'_, T>> { iter: _13 };
138-
StorageDead(_13);
139-
StorageLive(_15);
140-
_15 = _14;
141-
goto -> bb4;
63+
_9 = discriminant(_8);
64+
switchInt(move _9) -> [0: bb4, 1: bb6, otherwise: bb8];
14265
}
14366

14467
bb4: {
145-
StorageLive(_18);
146-
_16 = &mut _15;
147-
StorageLive(_17);
148-
_17 = &mut (_15.0: std::slice::Iter<'_, T>);
149-
_18 = <std::slice::Iter<'_, T> as DoubleEndedIterator>::next_back(move _17) -> [return: bb5, unwind: bb11];
68+
StorageDead(_8);
69+
StorageDead(_5);
70+
drop(_2) -> [return: bb5, unwind continue];
15071
}
15172

15273
bb5: {
153-
StorageDead(_17);
154-
_19 = discriminant(_18);
155-
switchInt(move _19) -> [0: bb6, 1: bb8, otherwise: bb10];
74+
return;
15675
}
15776

15877
bb6: {
159-
StorageDead(_18);
160-
StorageDead(_15);
161-
drop(_2) -> [return: bb7, unwind continue];
78+
_10 = ((_8 as Some).0: &T);
79+
StorageLive(_11);
80+
_11 = &_2;
81+
StorageLive(_12);
82+
_12 = (_10,);
83+
_13 = <impl Fn(&T) as Fn<(&T,)>>::call(move _11, move _12) -> [return: bb7, unwind: bb9];
16284
}
16385

16486
bb7: {
165-
return;
87+
StorageDead(_12);
88+
StorageDead(_11);
89+
StorageDead(_8);
90+
goto -> bb2;
16691
}
16792

16893
bb8: {
169-
_20 = ((_18 as Some).0: &T);
170-
StorageLive(_21);
171-
_21 = &_2;
172-
StorageLive(_22);
173-
_22 = (_20,);
174-
_23 = <impl Fn(&T) as Fn<(&T,)>>::call(move _21, move _22) -> [return: bb9, unwind: bb11];
175-
}
176-
177-
bb9: {
178-
StorageDead(_22);
179-
StorageDead(_21);
180-
StorageDead(_18);
181-
goto -> bb4;
182-
}
183-
184-
bb10: {
18594
unreachable;
18695
}
18796

188-
bb11 (cleanup): {
189-
drop(_2) -> [return: bb12, unwind terminate(cleanup)];
97+
bb9 (cleanup): {
98+
drop(_2) -> [return: bb10, unwind terminate(cleanup)];
19099
}
191100

192-
bb12 (cleanup): {
101+
bb10 (cleanup): {
193102
resume;
194103
}
195104
}

0 commit comments

Comments
 (0)
This repository has been archived.