Skip to content
This commit does not belong to any branch on this repository, and may belong to a fork outside of the repository.

Commit 3407cae

Browse files
committedSep 28, 2023
Also consider call and yield as MIR SSA.
1 parent dd91aba commit 3407cae

13 files changed

+256
-129
lines changed
 

‎compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 22 additions & 15 deletions
Original file line numberDiff line numberDiff line change
@@ -63,7 +63,7 @@ use rustc_middle::mir::*;
6363
use rustc_middle::ty::{self, Ty, TyCtxt};
6464
use rustc_target::abi::{VariantIdx, FIRST_VARIANT};
6565

66-
use crate::ssa::SsaLocals;
66+
use crate::ssa::{AssignedValue, SsaLocals};
6767
use crate::MirPass;
6868

6969
pub struct GVN;
@@ -87,21 +87,28 @@ fn propagate_ssa<'tcx>(tcx: TyCtxt<'tcx>, body: &mut Body<'tcx>) {
8787
let dominators = body.basic_blocks.dominators().clone();
8888

8989
let mut state = VnState::new(tcx, param_env, &ssa, &dominators, &body.local_decls);
90-
for arg in body.args_iter() {
91-
if ssa.is_ssa(arg) {
92-
let value = state.new_opaque().unwrap();
93-
state.assign(arg, value);
94-
}
95-
}
96-
97-
ssa.for_each_assignment_mut(&mut body.basic_blocks, |local, rvalue, location| {
98-
let value = state.simplify_rvalue(rvalue, location).or_else(|| state.new_opaque()).unwrap();
99-
// FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark `local` as
100-
// reusable if we have an exact type match.
101-
if state.local_decls[local].ty == rvalue.ty(state.local_decls, tcx) {
90+
ssa.for_each_assignment_mut(
91+
body.basic_blocks.as_mut_preserves_cfg(),
92+
|local, value, location| {
93+
let value = match value {
94+
// We do not know anything of this assigned value.
95+
AssignedValue::Arg | AssignedValue::Terminator(_) => None,
96+
// Try to get some insight.
97+
AssignedValue::Rvalue(rvalue) => {
98+
let value = state.simplify_rvalue(rvalue, location);
99+
// FIXME(#112651) `rvalue` may have a subtype to `local`. We can only mark `local` as
100+
// reusable if we have an exact type match.
101+
if state.local_decls[local].ty != rvalue.ty(state.local_decls, tcx) {
102+
return;
103+
}
104+
value
105+
}
106+
};
107+
// `next_opaque` is `Some`, so `new_opaque` must return `Some`.
108+
let value = value.or_else(|| state.new_opaque()).unwrap();
102109
state.assign(local, value);
103-
}
104-
});
110+
},
111+
);
105112

106113
// Stop creating opaques during replacement as it is useless.
107114
state.next_opaque = None;

‎compiler/rustc_mir_transform/src/ssa.rs

Lines changed: 82 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,13 @@ impl SmallDominators<'_> {
4949
let assign_dominates = match *set {
5050
Set1::Empty | Set1::Many => false,
5151
Set1::One(LocationExtended::Arg) => true,
52-
Set1::One(LocationExtended::Plain(assign)) => {
52+
Set1::One(LocationExtended::Assign(assign)) => {
5353
self.dominates(assign.successor_within_block(), loc)
5454
}
55+
Set1::One(LocationExtended::Terminator(_, effect_bb)) => {
56+
let effect_loc = Location { block: effect_bb, statement_index: 0 };
57+
self.dominates(effect_loc, loc)
58+
}
5559
};
5660
// We are visiting a use that is not dominated by an assignment.
5761
// Either there is a cycle involved, or we are reading for uninitialized local.
@@ -62,6 +66,12 @@ impl SmallDominators<'_> {
6266
}
6367
}
6468

69+
pub enum AssignedValue<'a, 'tcx> {
70+
Arg,
71+
Rvalue(&'a mut Rvalue<'tcx>),
72+
Terminator(&'a mut TerminatorKind<'tcx>),
73+
}
74+
6575
impl SsaLocals {
6676
pub fn new<'tcx>(body: &Body<'tcx>) -> SsaLocals {
6777
let assignment_order = Vec::with_capacity(body.local_decls.len());
@@ -72,10 +82,12 @@ impl SsaLocals {
7282
let dominators = SmallDominators { inner: dominators };
7383

7484
let direct_uses = IndexVec::from_elem(0, &body.local_decls);
75-
let mut visitor = SsaVisitor { assignments, assignment_order, dominators, direct_uses };
85+
let mut visitor =
86+
SsaVisitor { body, assignments, assignment_order, dominators, direct_uses };
7687

7788
for local in body.args_iter() {
7889
visitor.assignments[local] = Set1::One(LocationExtended::Arg);
90+
visitor.assignment_order.push(local);
7991
}
8092

8193
if body.basic_blocks.len() > 2 {
@@ -136,13 +148,16 @@ impl SsaLocals {
136148
) -> bool {
137149
match self.assignments[local] {
138150
Set1::One(LocationExtended::Arg) => true,
139-
Set1::One(LocationExtended::Plain(ass)) => {
151+
Set1::One(LocationExtended::Assign(ass)) => {
140152
if ass.block == location.block {
141153
ass.statement_index < location.statement_index
142154
} else {
143155
dominators.dominates(ass.block, location.block)
144156
}
145157
}
158+
Set1::One(LocationExtended::Terminator(_, effect_bb)) => {
159+
dominators.dominates(effect_bb, location.block)
160+
}
146161
_ => false,
147162
}
148163
}
@@ -152,7 +167,7 @@ impl SsaLocals {
152167
body: &'a Body<'tcx>,
153168
) -> impl Iterator<Item = (Local, &'a Rvalue<'tcx>, Location)> + 'a {
154169
self.assignment_order.iter().filter_map(|&local| {
155-
if let Set1::One(LocationExtended::Plain(loc)) = self.assignments[local] {
170+
if let Set1::One(LocationExtended::Assign(loc)) = self.assignments[local] {
156171
// `loc` must point to a direct assignment to `local`.
157172
let Either::Left(stmt) = body.stmt_at(loc) else { bug!() };
158173
let Some((target, rvalue)) = stmt.kind.as_assign() else { bug!() };
@@ -166,18 +181,33 @@ impl SsaLocals {
166181

167182
pub fn for_each_assignment_mut<'tcx>(
168183
&self,
169-
basic_blocks: &mut BasicBlocks<'tcx>,
170-
mut f: impl FnMut(Local, &mut Rvalue<'tcx>, Location),
184+
basic_blocks: &mut IndexSlice<BasicBlock, BasicBlockData<'tcx>>,
185+
mut f: impl FnMut(Local, AssignedValue<'_, 'tcx>, Location),
171186
) {
172187
for &local in &self.assignment_order {
173-
if let Set1::One(LocationExtended::Plain(loc)) = self.assignments[local] {
174-
// `loc` must point to a direct assignment to `local`.
175-
let bbs = basic_blocks.as_mut_preserves_cfg();
176-
let bb = &mut bbs[loc.block];
177-
let stmt = &mut bb.statements[loc.statement_index];
178-
let StatementKind::Assign(box (target, ref mut rvalue)) = stmt.kind else { bug!() };
179-
assert_eq!(target.as_local(), Some(local));
180-
f(local, rvalue, loc)
188+
match self.assignments[local] {
189+
Set1::One(LocationExtended::Arg) => f(
190+
local,
191+
AssignedValue::Arg,
192+
Location { block: START_BLOCK, statement_index: 0 },
193+
),
194+
Set1::One(LocationExtended::Assign(loc)) => {
195+
// `loc` must point to a direct assignment to `local`.
196+
let bb = &mut basic_blocks[loc.block];
197+
let stmt = &mut bb.statements[loc.statement_index];
198+
let StatementKind::Assign(box (target, ref mut rvalue)) = stmt.kind else {
199+
bug!()
200+
};
201+
assert_eq!(target.as_local(), Some(local));
202+
f(local, AssignedValue::Rvalue(rvalue), loc)
203+
}
204+
Set1::One(LocationExtended::Terminator(block, _)) => {
205+
let loc =
206+
Location { block, statement_index: basic_blocks[block].statements.len() };
207+
let term = basic_blocks[block].terminator_mut();
208+
f(local, AssignedValue::Terminator(&mut term.kind), loc)
209+
}
210+
_ => {}
181211
}
182212
}
183213
}
@@ -230,18 +260,24 @@ impl SsaLocals {
230260

231261
#[derive(Copy, Clone, Debug, PartialEq, Eq)]
232262
enum LocationExtended {
233-
Plain(Location),
263+
/// This local was assigned as a function parameter, before any execution.
234264
Arg,
265+
/// `Location` points to the `Assign` statement.
266+
Assign(Location),
267+
/// The blocks are respectively the bb which contains the assignment,
268+
/// and the bb in which the assignment effect is complete.
269+
Terminator(BasicBlock, BasicBlock),
235270
}
236271

237-
struct SsaVisitor<'a> {
272+
struct SsaVisitor<'a, 'tcx> {
273+
body: &'a Body<'tcx>,
238274
dominators: SmallDominators<'a>,
239275
assignments: IndexVec<Local, Set1<LocationExtended>>,
240276
assignment_order: Vec<Local>,
241277
direct_uses: IndexVec<Local, u32>,
242278
}
243279

244-
impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
280+
impl<'tcx> Visitor<'tcx> for SsaVisitor<'_, 'tcx> {
245281
fn visit_local(&mut self, local: Local, ctxt: PlaceContext, loc: Location) {
246282
match ctxt {
247283
PlaceContext::MutatingUse(MutatingUseContext::Projection)
@@ -266,34 +302,46 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_> {
266302
}
267303

268304
fn visit_place(&mut self, place: &Place<'tcx>, ctxt: PlaceContext, loc: Location) {
269-
if place.projection.first() == Some(&PlaceElem::Deref) {
270-
// Do not do anything for storage statements and debuginfo.
305+
let location = match ctxt {
306+
PlaceContext::MutatingUse(MutatingUseContext::Store) => {
307+
Some(LocationExtended::Assign(loc))
308+
}
309+
PlaceContext::MutatingUse(MutatingUseContext::Call | MutatingUseContext::Yield) => {
310+
// The assignment happens on the `loc -> target` edge. We need to ensure that
311+
// this *edge* dominates all uses of the local. This is true if
312+
// `loc` dominates `target` *and* `target` dominates all uses.
313+
if let Some(target) = self.body.basic_blocks[loc.block].terminator().successors().next()
314+
&& self.dominators.dominates(loc, Location { block: target, statement_index: 0 })
315+
{
316+
Some(LocationExtended::Terminator(loc.block, target))
317+
} else {
318+
None
319+
}
320+
}
321+
_ => None,
322+
};
323+
if let Some(location) = location
324+
&& let Some(local) = place.as_local()
325+
{
326+
self.assignments[local].insert(location);
327+
if let Set1::One(_) = self.assignments[local] {
328+
// Only record if SSA-like, to avoid growing the vector needlessly.
329+
self.assignment_order.push(local);
330+
}
331+
} else if place.projection.first() == Some(&PlaceElem::Deref) {
332+
// Do not do anything for debuginfo.
271333
if ctxt.is_use() {
272334
// Only change the context if it is a real use, not a "use" in debuginfo.
273335
let new_ctxt = PlaceContext::NonMutatingUse(NonMutatingUseContext::Copy);
274336

275337
self.visit_projection(place.as_ref(), new_ctxt, loc);
276338
self.dominators.check_dominates(&mut self.assignments[place.local], loc);
277339
}
278-
return;
279340
} else {
280341
self.visit_projection(place.as_ref(), ctxt, loc);
281342
self.visit_local(place.local, ctxt, loc);
282343
}
283344
}
284-
285-
fn visit_assign(&mut self, place: &Place<'tcx>, rvalue: &Rvalue<'tcx>, loc: Location) {
286-
if let Some(local) = place.as_local() {
287-
self.assignments[local].insert(LocationExtended::Plain(loc));
288-
if let Set1::One(_) = self.assignments[local] {
289-
// Only record if SSA-like, to avoid growing the vector needlessly.
290-
self.assignment_order.push(local);
291-
}
292-
} else {
293-
self.visit_place(place, PlaceContext::MutatingUse(MutatingUseContext::Store), loc);
294-
}
295-
self.visit_rvalue(rvalue, loc);
296-
}
297345
}
298346

299347
#[instrument(level = "trace", skip(ssa, body))]
@@ -376,7 +424,7 @@ impl StorageLiveLocals {
376424
for (statement_index, statement) in bbdata.statements.iter().enumerate() {
377425
if let StatementKind::StorageLive(local) = statement.kind {
378426
storage_live[local]
379-
.insert(LocationExtended::Plain(Location { block, statement_index }));
427+
.insert(LocationExtended::Assign(Location { block, statement_index }));
380428
}
381429
}
382430
}
Lines changed: 21 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
- // MIR for `multiple_edges` before CopyProp
2+
+ // MIR for `multiple_edges` after CopyProp
3+
4+
fn multiple_edges(_1: bool) -> u8 {
5+
let mut _0: u8;
6+
let mut _2: u8;
7+
8+
bb0: {
9+
switchInt(_1) -> [1: bb1, otherwise: bb2];
10+
}
11+
12+
bb1: {
13+
_2 = dummy(const 13_u8) -> [return: bb2, unwind continue];
14+
}
15+
16+
bb2: {
17+
_0 = _2;
18+
return;
19+
}
20+
}
21+
Lines changed: 24 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,24 @@
1+
- // MIR for `nrvo` before CopyProp
2+
+ // MIR for `nrvo` after CopyProp
3+
4+
fn nrvo() -> u8 {
5+
let mut _0: u8;
6+
let _1: u8;
7+
scope 1 {
8+
- debug y => _1;
9+
+ debug y => _0;
10+
}
11+
12+
bb0: {
13+
- StorageLive(_1);
14+
- _1 = dummy(const 5_u8) -> [return: bb1, unwind continue];
15+
+ _0 = dummy(const 5_u8) -> [return: bb1, unwind continue];
16+
}
17+
18+
bb1: {
19+
- _0 = _1;
20+
- StorageDead(_1);
21+
return;
22+
}
23+
}
24+

‎tests/mir-opt/copy-prop/calls.rs

Lines changed: 43 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,43 @@
1+
// Check that CopyProp does propagate return values of call terminators.
2+
// unit-test: CopyProp
3+
// needs-unwind
4+
5+
#![feature(custom_mir, core_intrinsics)]
6+
use std::intrinsics::mir::*;
7+
8+
#[inline(never)]
9+
fn dummy(x: u8) -> u8 {
10+
x
11+
}
12+
13+
// EMIT_MIR calls.nrvo.CopyProp.diff
14+
fn nrvo() -> u8 {
15+
let y = dummy(5); // this should get NRVO
16+
y
17+
}
18+
19+
// EMIT_MIR calls.multiple_edges.CopyProp.diff
20+
#[custom_mir(dialect = "runtime", phase = "initial")]
21+
fn multiple_edges(t: bool) -> u8 {
22+
mir! {
23+
let x: u8;
24+
{
25+
match t { true => bbt, _ => ret }
26+
}
27+
bbt = {
28+
Call(x = dummy(13), ret)
29+
}
30+
ret = {
31+
// `x` is not assigned on the `bb0 -> ret` edge,
32+
// so should not be marked as SSA for merging with `_0`.
33+
RET = x;
34+
Return()
35+
}
36+
}
37+
}
38+
39+
fn main() {
40+
// Make sure the function actually gets instantiated.
41+
nrvo();
42+
multiple_edges(false);
43+
}

‎tests/mir-opt/inline/inline_diverging.h.Inline.panic-abort.diff

Lines changed: 2 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -8,11 +8,11 @@
88
+ scope 1 (inlined call_twice::<!, fn() -> ! {sleep}>) {
99
+ debug f => _2;
1010
+ let mut _3: &fn() -> ! {sleep};
11-
+ let mut _4: !;
11+
+ let _4: !;
1212
+ let mut _5: &fn() -> ! {sleep};
13-
+ let mut _6: !;
1413
+ scope 2 {
1514
+ debug a => _4;
15+
+ let _6: !;
1616
+ scope 3 {
1717
+ debug b => _6;
1818
+ }

‎tests/mir-opt/inline/inline_diverging.h.Inline.panic-unwind.diff

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -10,10 +10,10 @@
1010
+ let mut _3: &fn() -> ! {sleep};
1111
+ let _4: !;
1212
+ let mut _5: &fn() -> ! {sleep};
13-
+ let mut _6: !;
1413
+ let mut _7: !;
1514
+ scope 2 {
1615
+ debug a => _4;
16+
+ let _6: !;
1717
+ scope 3 {
1818
+ debug b => _6;
1919
+ }

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

Lines changed: 25 additions & 31 deletions
Original file line numberDiff line numberDiff line change
@@ -6,75 +6,69 @@ fn filter_mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> Option<U>) -> ()
66
let mut _0: ();
77
let mut _3: std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
88
let mut _4: std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
9-
let mut _5: std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
10-
let mut _8: std::option::Option<U>;
11-
let mut _9: isize;
12-
let _11: ();
13-
let mut _12: &mut std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
9+
let mut _7: std::option::Option<U>;
10+
let mut _8: isize;
11+
let _10: ();
12+
let mut _11: &mut std::iter::FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>>;
1413
scope 1 {
15-
debug iter => _5;
16-
let _10: U;
14+
debug iter => _4;
15+
let _9: U;
1716
scope 2 {
18-
debug x => _10;
17+
debug x => _9;
1918
}
2019
scope 4 (inlined <FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>> as Iterator>::next) {
21-
debug self => _12;
22-
let mut _6: &mut impl Iterator<Item = T>;
23-
let mut _7: &mut impl Fn(T) -> Option<U>;
20+
debug self => _11;
21+
let mut _5: &mut impl Iterator<Item = T>;
22+
let mut _6: &mut impl Fn(T) -> Option<U>;
2423
}
2524
}
2625
scope 3 (inlined <FilterMap<impl Iterator<Item = T>, impl Fn(T) -> Option<U>> as IntoIterator>::into_iter) {
2726
debug self => _3;
2827
}
2928

3029
bb0: {
31-
StorageLive(_4);
32-
StorageLive(_3);
3330
_3 = <impl Iterator<Item = T> as Iterator>::filter_map::<U, impl Fn(T) -> Option<U>>(move _1, move _2) -> [return: bb1, unwind continue];
3431
}
3532

3633
bb1: {
34+
StorageLive(_4);
3735
_4 = move _3;
38-
StorageDead(_3);
39-
StorageLive(_5);
40-
_5 = move _4;
4136
goto -> bb2;
4237
}
4338

4439
bb2: {
45-
StorageLive(_8);
46-
StorageLive(_6);
47-
_6 = &mut (_5.0: impl Iterator<Item = T>);
4840
StorageLive(_7);
49-
_7 = &mut (_5.1: impl Fn(T) -> Option<U>);
50-
_8 = <impl Iterator<Item = T> as Iterator>::find_map::<U, &mut impl Fn(T) -> Option<U>>(move _6, move _7) -> [return: bb3, unwind: bb9];
41+
StorageLive(_5);
42+
_5 = &mut (_4.0: impl Iterator<Item = T>);
43+
StorageLive(_6);
44+
_6 = &mut (_4.1: impl Fn(T) -> Option<U>);
45+
_7 = <impl Iterator<Item = T> as Iterator>::find_map::<U, &mut impl Fn(T) -> Option<U>>(move _5, move _6) -> [return: bb3, unwind: bb9];
5146
}
5247

5348
bb3: {
54-
StorageDead(_7);
5549
StorageDead(_6);
56-
_9 = discriminant(_8);
57-
switchInt(move _9) -> [0: bb4, 1: bb6, otherwise: bb8];
50+
StorageDead(_5);
51+
_8 = discriminant(_7);
52+
switchInt(move _8) -> [0: bb4, 1: bb6, otherwise: bb8];
5853
}
5954

6055
bb4: {
61-
StorageDead(_8);
62-
drop(_5) -> [return: bb5, unwind continue];
56+
StorageDead(_7);
57+
drop(_4) -> [return: bb5, unwind continue];
6358
}
6459

6560
bb5: {
66-
StorageDead(_5);
6761
StorageDead(_4);
6862
return;
6963
}
7064

7165
bb6: {
72-
_10 = move ((_8 as Some).0: U);
73-
_11 = opaque::<U>(move _10) -> [return: bb7, unwind: bb9];
66+
_9 = move ((_7 as Some).0: U);
67+
_10 = opaque::<U>(move _9) -> [return: bb7, unwind: bb9];
7468
}
7569

7670
bb7: {
77-
StorageDead(_8);
71+
StorageDead(_7);
7872
goto -> bb2;
7973
}
8074

@@ -83,7 +77,7 @@ fn filter_mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> Option<U>) -> ()
8377
}
8478

8579
bb9 (cleanup): {
86-
drop(_5) -> [return: bb10, unwind terminate(cleanup)];
80+
drop(_4) -> [return: bb10, unwind terminate(cleanup)];
8781
}
8882

8983
bb10 (cleanup): {

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

Lines changed: 20 additions & 26 deletions
Original file line numberDiff line numberDiff line change
@@ -6,67 +6,61 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
66
let mut _0: ();
77
let mut _3: std::iter::Map<impl Iterator<Item = T>, impl Fn(T) -> U>;
88
let mut _4: std::iter::Map<impl Iterator<Item = T>, impl Fn(T) -> U>;
9-
let mut _5: std::iter::Map<impl Iterator<Item = T>, impl Fn(T) -> U>;
10-
let mut _6: &mut std::iter::Map<impl Iterator<Item = T>, impl Fn(T) -> U>;
11-
let mut _7: std::option::Option<U>;
12-
let mut _8: isize;
13-
let _10: ();
9+
let mut _5: &mut std::iter::Map<impl Iterator<Item = T>, impl Fn(T) -> U>;
10+
let mut _6: std::option::Option<U>;
11+
let mut _7: isize;
12+
let _9: ();
1413
scope 1 {
15-
debug iter => _5;
16-
let _9: U;
14+
debug iter => _4;
15+
let _8: U;
1716
scope 2 {
18-
debug x => _9;
17+
debug x => _8;
1918
}
2019
}
2120
scope 3 (inlined <Map<impl Iterator<Item = T>, impl Fn(T) -> U> as IntoIterator>::into_iter) {
2221
debug self => _3;
2322
}
2423

2524
bb0: {
26-
StorageLive(_4);
27-
StorageLive(_3);
2825
_3 = <impl Iterator<Item = T> as Iterator>::map::<U, impl Fn(T) -> U>(move _1, move _2) -> [return: bb1, unwind continue];
2926
}
3027

3128
bb1: {
29+
StorageLive(_4);
3230
_4 = move _3;
33-
StorageDead(_3);
34-
StorageLive(_5);
35-
_5 = move _4;
3631
goto -> bb2;
3732
}
3833

3934
bb2: {
40-
StorageLive(_7);
4135
StorageLive(_6);
42-
_6 = &mut _5;
43-
_7 = <Map<impl Iterator<Item = T>, impl Fn(T) -> U> as Iterator>::next(move _6) -> [return: bb3, unwind: bb9];
36+
StorageLive(_5);
37+
_5 = &mut _4;
38+
_6 = <Map<impl Iterator<Item = T>, impl Fn(T) -> U> as Iterator>::next(move _5) -> [return: bb3, unwind: bb9];
4439
}
4540

4641
bb3: {
47-
StorageDead(_6);
48-
_8 = discriminant(_7);
49-
switchInt(move _8) -> [0: bb4, 1: bb6, otherwise: bb8];
42+
StorageDead(_5);
43+
_7 = discriminant(_6);
44+
switchInt(move _7) -> [0: bb4, 1: bb6, otherwise: bb8];
5045
}
5146

5247
bb4: {
53-
StorageDead(_7);
54-
drop(_5) -> [return: bb5, unwind continue];
48+
StorageDead(_6);
49+
drop(_4) -> [return: bb5, unwind continue];
5550
}
5651

5752
bb5: {
58-
StorageDead(_5);
5953
StorageDead(_4);
6054
return;
6155
}
6256

6357
bb6: {
64-
_9 = move ((_7 as Some).0: U);
65-
_10 = opaque::<U>(move _9) -> [return: bb7, unwind: bb9];
58+
_8 = move ((_6 as Some).0: U);
59+
_9 = opaque::<U>(move _8) -> [return: bb7, unwind: bb9];
6660
}
6761

6862
bb7: {
69-
StorageDead(_7);
63+
StorageDead(_6);
7064
goto -> bb2;
7165
}
7266

@@ -75,7 +69,7 @@ fn mapped(_1: impl Iterator<Item = T>, _2: impl Fn(T) -> U) -> () {
7569
}
7670

7771
bb9 (cleanup): {
78-
drop(_5) -> [return: bb10, unwind terminate(cleanup)];
72+
drop(_4) -> [return: bb10, unwind terminate(cleanup)];
7973
}
8074

8175
bb10 (cleanup): {

‎tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-abort.mir

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,13 @@ fn slice_index_range(_1: &[u32], _2: std::ops::Range<usize>) -> &[u32] {
77
scope 1 (inlined #[track_caller] core::slice::index::<impl Index<std::ops::Range<usize>> for [u32]>::index) {
88
debug self => _1;
99
debug index => _2;
10-
let _3: &[u32];
1110
}
1211

1312
bb0: {
14-
StorageLive(_3);
15-
_3 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, move _1) -> [return: bb1, unwind unreachable];
13+
_0 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, move _1) -> [return: bb1, unwind unreachable];
1614
}
1715

1816
bb1: {
19-
_0 = _3;
20-
StorageDead(_3);
2117
return;
2218
}
2319
}

‎tests/mir-opt/pre-codegen/slice_index.slice_index_range.PreCodegen.after.panic-unwind.mir

Lines changed: 1 addition & 5 deletions
Original file line numberDiff line numberDiff line change
@@ -7,17 +7,13 @@ fn slice_index_range(_1: &[u32], _2: std::ops::Range<usize>) -> &[u32] {
77
scope 1 (inlined #[track_caller] core::slice::index::<impl Index<std::ops::Range<usize>> for [u32]>::index) {
88
debug self => _1;
99
debug index => _2;
10-
let _3: &[u32];
1110
}
1211

1312
bb0: {
14-
StorageLive(_3);
15-
_3 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, move _1) -> [return: bb1, unwind continue];
13+
_0 = <std::ops::Range<usize> as SliceIndex<[u32]>>::index(move _2, move _1) -> [return: bb1, unwind continue];
1614
}
1715

1816
bb1: {
19-
_0 = _3;
20-
StorageDead(_3);
2117
return;
2218
}
2319
}

‎tests/mir-opt/reference_prop.debuginfo.ReferencePropagation.diff

Lines changed: 13 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -92,8 +92,8 @@
9292
StorageDead(_7);
9393
- StorageDead(_6);
9494
- StorageLive(_10);
95-
StorageLive(_11);
96-
StorageLive(_12);
95+
- StorageLive(_11);
96+
- StorageLive(_12);
9797
StorageLive(_13);
9898
_26 = const _;
9999
_13 = &(*_26);
@@ -105,21 +105,25 @@
105105
bb5: {
106106
StorageDead(_15);
107107
StorageDead(_13);
108-
_11 = &(*_12);
109-
_16 = Len((*_11));
108+
- _11 = &(*_12);
109+
- _16 = Len((*_11));
110+
+ _16 = Len((*_12));
110111
_17 = const 3_usize;
111112
_18 = Ge(move _16, move _17);
112113
switchInt(move _18) -> [0: bb7, otherwise: bb6];
113114
}
114115

115116
bb6: {
116117
StorageLive(_19);
117-
_19 = &(*_11)[1 of 3];
118+
- _19 = &(*_11)[1 of 3];
119+
+ _19 = &(*_12)[1 of 3];
118120
StorageLive(_20);
119-
_20 = &(*_11)[2:-1];
121+
- _20 = &(*_11)[2:-1];
122+
+ _20 = &(*_12)[2:-1];
120123
StorageLive(_21);
121-
_21 = &(*_11)[-1 of 3];
124+
- _21 = &(*_11)[-1 of 3];
122125
- _10 = const ();
126+
+ _21 = &(*_12)[-1 of 3];
123127
StorageDead(_21);
124128
StorageDead(_20);
125129
StorageDead(_19);
@@ -132,8 +136,8 @@
132136
}
133137

134138
bb8: {
135-
StorageDead(_12);
136-
StorageDead(_11);
139+
- StorageDead(_12);
140+
- StorageDead(_11);
137141
- StorageDead(_10);
138142
StorageLive(_22);
139143
StorageLive(_23);

‎tests/ui-fulldeps/stable-mir/crate-info.rs

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -58,7 +58,7 @@ fn test_stable_mir(_tcx: TyCtxt<'_>) -> ControlFlow<()> {
5858

5959
let foo_bar = get_item(&items, (DefKind::Fn, "foo_bar")).unwrap();
6060
let body = foo_bar.body();
61-
assert_eq!(body.locals.len(), 7);
61+
assert_eq!(body.locals.len(), 5);
6262
assert_eq!(body.blocks.len(), 4);
6363
let block = &body.blocks[0];
6464
match &block.terminator {

0 commit comments

Comments
 (0)
Please sign in to comment.