Skip to content

Commit dd34b79

Browse files
committed
Propagate from borrowed locals in CopyProp
1 parent 688ea65 commit dd34b79

File tree

7 files changed

+95
-130
lines changed

7 files changed

+95
-130
lines changed

compiler/rustc_mir_transform/src/ssa.rs

Lines changed: 4 additions & 8 deletions
Original file line numberDiff line numberDiff line change
@@ -293,9 +293,9 @@ impl<'tcx> Visitor<'tcx> for SsaVisitor<'_, 'tcx> {
293293
fn compute_copy_classes(ssa: &mut SsaLocals, body: &Body<'_>) {
294294
let mut direct_uses = std::mem::take(&mut ssa.direct_uses);
295295
let mut copies = IndexVec::from_fn_n(|l| l, body.local_decls.len());
296-
// We must not unify two locals that are borrowed. But this is fine if one is borrowed and
297-
// the other is not. This bitset is keyed by *class head* and contains whether any member of
298-
// the class is borrowed.
296+
// We can propagate from a borrowed local into other locals that aren't borrowed, since we know
297+
// that all uses of the other locals are dominated by the definition. This bitset is keyed by
298+
// *class head* and contains whether any member of the class is borrowed.
299299
let mut borrowed_classes = ssa.borrowed_locals().clone();
300300

301301
for (local, rvalue, _) in ssa.assignments(body) {
@@ -322,8 +322,7 @@ fn compute_copy_classes(ssa: &mut SsaLocals, body: &Body<'_>) {
322322
// visited before `local`, and we just have to copy the representing local.
323323
let head = copies[rhs];
324324

325-
// Do not unify borrowed locals.
326-
if borrowed_classes.contains(local) || borrowed_classes.contains(head) {
325+
if borrowed_classes.contains(local) {
327326
continue;
328327
}
329328

@@ -344,9 +343,6 @@ fn compute_copy_classes(ssa: &mut SsaLocals, body: &Body<'_>) {
344343
}
345344
} else {
346345
copies[local] = head;
347-
if borrowed_classes.contains(local) {
348-
borrowed_classes.insert(head);
349-
}
350346
}
351347
direct_uses[rhs] -= 1;
352348
}

tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-abort.diff

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
let mut _3: &T;
88

99
bb0: {
10-
_2 = copy _1;
10+
- _2 = copy _1;
1111
_3 = &_1;
1212
_0 = opaque::<&T>(copy _3) -> [return: bb1, unwind unreachable];
1313
}
1414

1515
bb1: {
16-
_0 = opaque::<T>(copy _2) -> [return: bb2, unwind unreachable];
16+
- _0 = opaque::<T>(copy _2) -> [return: bb2, unwind unreachable];
17+
+ _0 = opaque::<T>(copy _1) -> [return: bb2, unwind unreachable];
1718
}
1819

1920
bb2: {

tests/mir-opt/copy-prop/borrowed_local.borrowed.CopyProp.panic-unwind.diff

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -7,13 +7,14 @@
77
let mut _3: &T;
88

99
bb0: {
10-
_2 = copy _1;
10+
- _2 = copy _1;
1111
_3 = &_1;
1212
_0 = opaque::<&T>(copy _3) -> [return: bb1, unwind continue];
1313
}
1414

1515
bb1: {
16-
_0 = opaque::<T>(copy _2) -> [return: bb2, unwind continue];
16+
- _0 = opaque::<T>(copy _2) -> [return: bb2, unwind continue];
17+
+ _0 = opaque::<T>(copy _1) -> [return: bb2, unwind continue];
1718
}
1819

1920
bb2: {

tests/mir-opt/copy-prop/borrowed_local.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -50,11 +50,10 @@ fn compare_address() -> bool {
5050
fn borrowed<T: Copy + Freeze>(x: T) -> bool {
5151
// CHECK-LABEL: fn borrowed(
5252
// CHECK: bb0: {
53-
// CHECK-NEXT: _2 = copy _1;
5453
// CHECK-NEXT: _3 = &_1;
5554
// CHECK-NEXT: _0 = opaque::<&T>(copy _3)
5655
// CHECK: bb1: {
57-
// CHECK-NEXT: _0 = opaque::<T>(copy _2)
56+
// CHECK-NEXT: _0 = opaque::<T>(copy _1)
5857
mir! {
5958
{
6059
let a = x;

tests/mir-opt/copy-prop/write_to_borrowed.main.CopyProp.diff

Lines changed: 3 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -16,10 +16,11 @@
1616
_3 = const 'b';
1717
_5 = copy _3;
1818
_6 = &_3;
19-
_4 = copy _5;
19+
- _4 = copy _5;
2020
(*_1) = copy (*_6);
2121
_6 = &_5;
22-
_7 = dump_var::<char>(copy _4) -> [return: bb1, unwind unreachable];
22+
- _7 = dump_var::<char>(copy _4) -> [return: bb1, unwind unreachable];
23+
+ _7 = dump_var::<char>(copy _5) -> [return: bb1, unwind unreachable];
2324
}
2425

2526
bb1: {

tests/mir-opt/copy-prop/write_to_borrowed.rs

Lines changed: 1 addition & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -27,13 +27,12 @@ fn main() {
2727
_5 = _3;
2828
// CHECK-NEXT: _6 = &_3;
2929
_6 = &_3;
30-
// CHECK-NEXT: _4 = copy _5;
3130
_4 = _5;
3231
// CHECK-NEXT: (*_1) = copy (*_6);
3332
*_1 = *_6;
3433
// CHECK-NEXT: _6 = &_5;
3534
_6 = &_5;
36-
// CHECK-NEXT: _7 = dump_var::<char>(copy _4)
35+
// CHECK-NEXT: _7 = dump_var::<char>(copy _5)
3736
Call(_7 = dump_var(_4), ReturnTo(bb1), UnwindUnreachable())
3837
}
3938
bb1 = { Return() }

tests/mir-opt/pre-codegen/slice_filter.variant_a-{closure#0}.PreCodegen.after.mir

Lines changed: 80 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -10,18 +10,18 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
1010
let mut _8: &&usize;
1111
let _9: &usize;
1212
let mut _10: &&usize;
13-
let mut _15: bool;
13+
let mut _13: bool;
14+
let mut _14: &&usize;
15+
let _15: &usize;
1416
let mut _16: &&usize;
15-
let _17: &usize;
16-
let mut _18: &&usize;
17+
let mut _19: bool;
18+
let mut _20: &&usize;
19+
let _21: &usize;
20+
let mut _22: &&usize;
1721
let mut _23: bool;
1822
let mut _24: &&usize;
1923
let _25: &usize;
2024
let mut _26: &&usize;
21-
let mut _29: bool;
22-
let mut _30: &&usize;
23-
let _31: &usize;
24-
let mut _32: &&usize;
2525
scope 1 {
2626
debug a => _4;
2727
debug b => _5;
@@ -30,47 +30,39 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
3030
scope 2 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) {
3131
debug self => _8;
3232
debug other => _10;
33-
let mut _11: &usize;
34-
let mut _12: &usize;
3533
scope 3 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) {
36-
debug self => _11;
37-
debug other => _12;
38-
let mut _13: usize;
39-
let mut _14: usize;
34+
debug self => _4;
35+
debug other => _6;
36+
let mut _11: usize;
37+
let mut _12: usize;
4038
}
4139
}
4240
scope 4 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) {
43-
debug self => _16;
44-
debug other => _18;
45-
let mut _19: &usize;
46-
let mut _20: &usize;
41+
debug self => _14;
42+
debug other => _16;
4743
scope 5 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) {
48-
debug self => _19;
49-
debug other => _20;
50-
let mut _21: usize;
51-
let mut _22: usize;
44+
debug self => _7;
45+
debug other => _5;
46+
let mut _17: usize;
47+
let mut _18: usize;
5248
}
5349
}
5450
scope 6 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) {
55-
debug self => _24;
56-
debug other => _26;
57-
let mut _27: &usize;
58-
let mut _28: &usize;
51+
debug self => _20;
52+
debug other => _22;
5953
scope 7 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) {
60-
debug self => _27;
61-
debug other => _28;
54+
debug self => _6;
55+
debug other => _4;
6256
}
6357
}
6458
scope 8 (inlined std::cmp::impls::<impl PartialOrd for &usize>::le) {
65-
debug self => _30;
66-
debug other => _32;
67-
let mut _33: &usize;
68-
let mut _34: &usize;
59+
debug self => _24;
60+
debug other => _26;
6961
scope 9 (inlined std::cmp::impls::<impl PartialOrd for usize>::le) {
70-
debug self => _33;
71-
debug other => _34;
72-
let mut _35: usize;
73-
let mut _36: usize;
62+
debug self => _5;
63+
debug other => _7;
64+
let mut _27: usize;
65+
let mut _28: usize;
7466
}
7567
}
7668
}
@@ -81,23 +73,17 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
8173
_5 = &((*_3).1: usize);
8274
_6 = &((*_3).2: usize);
8375
_7 = &((*_3).3: usize);
84-
StorageLive(_15);
76+
StorageLive(_13);
8577
StorageLive(_8);
8678
_8 = &_4;
8779
StorageLive(_10);
8880
StorageLive(_9);
8981
_9 = copy _6;
9082
_10 = &_9;
91-
StorageLive(_11);
92-
StorageLive(_12);
93-
_11 = copy _4;
94-
_12 = copy _6;
95-
_13 = copy ((*_3).0: usize);
96-
_14 = copy ((*_3).2: usize);
97-
_15 = Le(copy _13, copy _14);
98-
StorageDead(_12);
99-
StorageDead(_11);
100-
switchInt(move _15) -> [0: bb1, otherwise: bb2];
83+
_11 = copy ((*_3).0: usize);
84+
_12 = copy ((*_3).2: usize);
85+
_13 = Le(copy _11, copy _12);
86+
switchInt(move _13) -> [0: bb1, otherwise: bb2];
10187
}
10288

10389
bb1: {
@@ -111,107 +97,89 @@ fn variant_a::{closure#0}(_1: &mut {closure@$DIR/slice_filter.rs:7:25: 7:39}, _2
11197
StorageDead(_9);
11298
StorageDead(_10);
11399
StorageDead(_8);
114-
StorageLive(_23);
100+
StorageLive(_19);
101+
StorageLive(_14);
102+
_14 = &_7;
115103
StorageLive(_16);
116-
_16 = &_7;
117-
StorageLive(_18);
104+
StorageLive(_15);
105+
_15 = copy _5;
106+
_16 = &_15;
118107
StorageLive(_17);
119-
_17 = copy _5;
120-
_18 = &_17;
121-
StorageLive(_19);
122-
StorageLive(_20);
123-
_19 = copy _7;
124-
_20 = copy _5;
125-
StorageLive(_21);
126-
_21 = copy ((*_3).3: usize);
127-
StorageLive(_22);
128-
_22 = copy ((*_3).1: usize);
129-
_23 = Le(move _21, move _22);
130-
StorageDead(_22);
131-
StorageDead(_21);
132-
StorageDead(_20);
133-
StorageDead(_19);
134-
switchInt(move _23) -> [0: bb3, otherwise: bb8];
108+
_17 = copy ((*_3).3: usize);
109+
StorageLive(_18);
110+
_18 = copy ((*_3).1: usize);
111+
_19 = Le(move _17, move _18);
112+
StorageDead(_18);
113+
StorageDead(_17);
114+
switchInt(move _19) -> [0: bb3, otherwise: bb8];
135115
}
136116

137117
bb3: {
138-
StorageDead(_17);
139-
StorageDead(_18);
118+
StorageDead(_15);
140119
StorageDead(_16);
120+
StorageDead(_14);
141121
goto -> bb4;
142122
}
143123

144124
bb4: {
145-
StorageLive(_29);
146-
StorageLive(_24);
147-
_24 = &_6;
148-
StorageLive(_26);
149-
StorageLive(_25);
150-
_25 = copy _4;
151-
_26 = &_25;
152-
StorageLive(_27);
153-
StorageLive(_28);
154-
_27 = copy _6;
155-
_28 = copy _4;
156-
_29 = Le(copy _14, copy _13);
157-
StorageDead(_28);
158-
StorageDead(_27);
159-
switchInt(move _29) -> [0: bb5, otherwise: bb6];
125+
StorageLive(_23);
126+
StorageLive(_20);
127+
_20 = &_6;
128+
StorageLive(_22);
129+
StorageLive(_21);
130+
_21 = copy _4;
131+
_22 = &_21;
132+
_23 = Le(copy _12, copy _11);
133+
switchInt(move _23) -> [0: bb5, otherwise: bb6];
160134
}
161135

162136
bb5: {
163-
StorageDead(_25);
164-
StorageDead(_26);
165-
StorageDead(_24);
137+
StorageDead(_21);
138+
StorageDead(_22);
139+
StorageDead(_20);
166140
_0 = const false;
167141
goto -> bb7;
168142
}
169143

170144
bb6: {
145+
StorageDead(_21);
146+
StorageDead(_22);
147+
StorageDead(_20);
148+
StorageLive(_24);
149+
_24 = &_5;
150+
StorageLive(_26);
151+
StorageLive(_25);
152+
_25 = copy _7;
153+
_26 = &_25;
154+
StorageLive(_27);
155+
_27 = copy ((*_3).1: usize);
156+
StorageLive(_28);
157+
_28 = copy ((*_3).3: usize);
158+
_0 = Le(move _27, move _28);
159+
StorageDead(_28);
160+
StorageDead(_27);
171161
StorageDead(_25);
172162
StorageDead(_26);
173163
StorageDead(_24);
174-
StorageLive(_30);
175-
_30 = &_5;
176-
StorageLive(_32);
177-
StorageLive(_31);
178-
_31 = copy _7;
179-
_32 = &_31;
180-
StorageLive(_33);
181-
StorageLive(_34);
182-
_33 = copy _5;
183-
_34 = copy _7;
184-
StorageLive(_35);
185-
_35 = copy ((*_3).1: usize);
186-
StorageLive(_36);
187-
_36 = copy ((*_3).3: usize);
188-
_0 = Le(move _35, move _36);
189-
StorageDead(_36);
190-
StorageDead(_35);
191-
StorageDead(_34);
192-
StorageDead(_33);
193-
StorageDead(_31);
194-
StorageDead(_32);
195-
StorageDead(_30);
196164
goto -> bb7;
197165
}
198166

199167
bb7: {
200-
StorageDead(_29);
168+
StorageDead(_23);
201169
goto -> bb9;
202170
}
203171

204172
bb8: {
205-
StorageDead(_17);
206-
StorageDead(_18);
173+
StorageDead(_15);
207174
StorageDead(_16);
175+
StorageDead(_14);
208176
_0 = const true;
209177
goto -> bb9;
210178
}
211179

212180
bb9: {
213-
StorageDead(_23);
214-
StorageDead(_15);
181+
StorageDead(_19);
182+
StorageDead(_13);
215183
return;
216184
}
217185
}

0 commit comments

Comments
 (0)