Skip to content

Commit f40f235

Browse files
committed
Merge return place with other locals in CopyProp.
1 parent bc88895 commit f40f235

19 files changed

+601
-218
lines changed

Diff for: compiler/rustc_mir_transform/src/copy_prop.rs

+16-14
Original file line numberDiff line numberDiff line change
@@ -162,20 +162,22 @@ impl<'tcx> MutVisitor<'tcx> for Replacer<'_, 'tcx> {
162162
}
163163

164164
fn visit_statement(&mut self, stmt: &mut Statement<'tcx>, loc: Location) {
165-
match stmt.kind {
166-
// When removing storage statements, we need to remove both (#107511).
167-
StatementKind::StorageLive(l) | StatementKind::StorageDead(l)
168-
if self.storage_to_remove.contains(l) =>
169-
{
170-
stmt.make_nop()
171-
}
172-
StatementKind::Assign(box (ref place, ref mut rvalue))
173-
if place.as_local().is_some() =>
174-
{
175-
// Do not replace assignments.
176-
self.visit_rvalue(rvalue, loc)
177-
}
178-
_ => self.super_statement(stmt, loc),
165+
// When removing storage statements, we need to remove both (#107511).
166+
if let StatementKind::StorageLive(l) | StatementKind::StorageDead(l) = stmt.kind
167+
&& self.storage_to_remove.contains(l)
168+
{
169+
stmt.make_nop();
170+
return
171+
}
172+
173+
self.super_statement(stmt, loc);
174+
175+
// Do not leave tautological assignments around.
176+
if let StatementKind::Assign(box (lhs, ref rhs)) = stmt.kind
177+
&& let Rvalue::Use(Operand::Copy(rhs) | Operand::Move(rhs)) | Rvalue::CopyForDeref(rhs) = *rhs
178+
&& lhs == rhs
179+
{
180+
stmt.make_nop();
179181
}
180182
}
181183
}

Diff for: compiler/rustc_mir_transform/src/ssa.rs

+18-6
Original file line numberDiff line numberDiff line change
@@ -267,11 +267,6 @@ fn compute_copy_classes(ssa: &mut SsaVisitor, body: &Body<'_>) -> IndexVec<Local
267267
for &local in &ssa.assignment_order {
268268
debug!(?local);
269269

270-
if local == RETURN_PLACE {
271-
// `_0` is special, we cannot rename it.
272-
continue;
273-
}
274-
275270
// This is not SSA: mark that we don't know the value.
276271
debug!(assignments = ?ssa.assignments[local]);
277272
let Set1::One(LocationExtended::Plain(loc)) = ssa.assignments[local] else { continue };
@@ -290,7 +285,23 @@ fn compute_copy_classes(ssa: &mut SsaVisitor, body: &Body<'_>) -> IndexVec<Local
290285

291286
// We visit in `assignment_order`, ie. reverse post-order, so `rhs` has been
292287
// visited before `local`, and we just have to copy the representing local.
293-
copies[local] = copies[rhs];
288+
let head = copies[rhs];
289+
290+
if local == RETURN_PLACE {
291+
// `_0` is special, we cannot rename it. Instead, rename the class of `rhs` to
292+
// `RETURN_PLACE`. This is only possible if the class head is a temporary, not an
293+
// argument.
294+
if body.local_kind(head) != LocalKind::Temp {
295+
continue;
296+
}
297+
for h in copies.iter_mut() {
298+
if *h == head {
299+
*h = RETURN_PLACE;
300+
}
301+
}
302+
} else {
303+
copies[local] = head;
304+
}
294305
ssa.direct_uses[rhs] -= 1;
295306
}
296307

@@ -302,6 +313,7 @@ fn compute_copy_classes(ssa: &mut SsaVisitor, body: &Body<'_>) -> IndexVec<Local
302313
for &head in copies.iter() {
303314
assert_eq!(copies[head], head);
304315
}
316+
debug_assert_eq!(copies[RETURN_PLACE], RETURN_PLACE);
305317

306318
copies
307319
}

Diff for: tests/codegen/fewer-names.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,8 @@ pub fn sum(x: u32, y: u32) -> u32 {
1313

1414
// NO-LABEL: define{{.*}}i32 @sum(i32 noundef %x, i32 noundef %y)
1515
// NO-NEXT: start:
16-
// NO-NEXT: %z = add i32 %y, %x
17-
// NO-NEXT: ret i32 %z
16+
// NO-NEXT: %0 = add i32 %y, %x
17+
// NO-NEXT: ret i32 %0
1818
let z = x + y;
1919
z
2020
}

Diff for: tests/codegen/mem-replace-big-type.rs

+2-5
Original file line numberDiff line numberDiff line change
@@ -13,8 +13,7 @@ pub struct Big([u64; 7]);
1313
pub fn replace_big(dst: &mut Big, src: Big) -> Big {
1414
// Back in 1.68, this emitted six `memcpy`s.
1515
// `read_via_copy` in 1.69 got that down to three.
16-
// `write_via_move` it was originally down to the essential two, however
17-
// with nrvo disabled it is back at 3
16+
// `write_via_move` and nvro get this down to the essential two.
1817
std::mem::replace(dst, src)
1918
}
2019

@@ -26,11 +25,9 @@ pub fn replace_big(dst: &mut Big, src: Big) -> Big {
2625
// For a large type, we expect exactly three `memcpy`s
2726
// CHECK-LABEL: define internal void @{{.+}}mem{{.+}}replace{{.+}}sret(%Big)
2827
// CHECK-NOT: call void @llvm.memcpy
29-
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %result, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false)
28+
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %0, {{i8\*|ptr}} align 8 %dest, i{{.*}} 56, i1 false)
3029
// CHECK-NOT: call void @llvm.memcpy
3130
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %dest, {{i8\*|ptr}} align 8 %src, i{{.*}} 56, i1 false)
3231
// CHECK-NOT: call void @llvm.memcpy
33-
// CHECK: call void @llvm.memcpy.{{.+}}({{i8\*|ptr}} align 8 %0, {{i8\*|ptr}} align 8 %result, i{{.*}} 56, i1 false)
34-
// CHECK-NOT: call void @llvm.memcpy
3532

3633
// CHECK-NOT: call void @llvm.memcpy

Diff for: tests/codegen/var-names.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,7 @@ pub fn test(a: u32, b: u32) -> u32 {
99
// CHECK: %c = add i32 %a, %b
1010
let d = c;
1111
let e = d * a;
12-
// CHECK-NEXT: %e = mul i32 %c, %a
12+
// CHECK-NEXT: %0 = mul i32 %c, %a
1313
e
14-
// CHECK-NEXT: ret i32 %e
14+
// CHECK-NEXT: ret i32 %0
1515
}

Diff for: tests/mir-opt/copy-prop/copy_propagation_arg.arg_src.CopyProp.diff

+7-5
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@
66
let mut _0: i32; // return place in scope 0 at $DIR/copy_propagation_arg.rs:+0:27: +0:30
77
let _2: i32; // in scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
88
scope 1 {
9-
debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
9+
- debug y => _2; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
10+
+ debug y => _0; // in scope 1 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
1011
}
1112

1213
bb0: {
13-
StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
14-
_2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
14+
- StorageLive(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+1:9: +1:10
15+
- _2 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
16+
+ _0 = _1; // scope 0 at $DIR/copy_propagation_arg.rs:+1:13: +1:14
1517
_1 = const 123_i32; // scope 1 at $DIR/copy_propagation_arg.rs:+2:5: +2:12
16-
_0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
17-
StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2
18+
- _0 = _2; // scope 1 at $DIR/copy_propagation_arg.rs:+3:5: +3:6
19+
- StorageDead(_2); // scope 0 at $DIR/copy_propagation_arg.rs:+4:1: +4:2
1820
return; // scope 0 at $DIR/copy_propagation_arg.rs:+4:2: +4:2
1921
}
2022
}

Diff for: tests/mir-opt/inline/inline_into_box_place.main.Inline.diff

+4-8
Original file line numberDiff line numberDiff line change
@@ -16,8 +16,7 @@
1616
+ let mut _4: usize; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
1717
+ let mut _5: usize; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
1818
+ let mut _6: *mut u8; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
19-
+ let mut _7: std::boxed::Box<std::vec::Vec<u32>>; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
20-
+ let mut _8: *const std::vec::Vec<u32>; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
19+
+ let mut _7: *const std::vec::Vec<u32>; // in scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
2120
+ scope 4 {
2221
+ }
2322
+ }
@@ -66,12 +65,9 @@
6665
bb3: {
6766
- StorageDead(_1); // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2
6867
- return; // scope 0 at $DIR/inline_into_box_place.rs:+2:2: +2:2
69-
+ StorageLive(_7); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
70-
+ _7 = ShallowInitBox(move _6, std::vec::Vec<u32>); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
71-
+ _8 = (((_7.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
72-
+ (*_8) = move _2; // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
73-
+ _1 = move _7; // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
74-
+ StorageDead(_7); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
68+
+ _1 = ShallowInitBox(move _6, std::vec::Vec<u32>); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
69+
+ _7 = (((_1.0: std::ptr::Unique<std::vec::Vec<u32>>).0: std::ptr::NonNull<std::vec::Vec<u32>>).0: *const std::vec::Vec<u32>); // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
70+
+ (*_7) = move _2; // scope 3 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
7571
+ StorageDead(_2); // scope 0 at $DIR/inline_into_box_place.rs:+1:48: +1:49
7672
+ _0 = const (); // scope 0 at $DIR/inline_into_box_place.rs:+0:11: +2:2
7773
+ drop(_1) -> [return: bb1, unwind: bb2]; // scope 0 at $DIR/inline_into_box_place.rs:+2:1: +2:2

Diff for: tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.b.Inline.after.mir

+5-9
Original file line numberDiff line numberDiff line change
@@ -8,22 +8,18 @@ fn b(_1: &mut Box<T>) -> &mut T {
88
let mut _4: &mut std::boxed::Box<T>; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
99
scope 1 (inlined <Box<T> as AsMut<T>>::as_mut) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:8:7: 8:15
1010
debug self => _4; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
11-
let mut _5: &mut T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
12-
let mut _6: std::boxed::Box<T>; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
13-
let mut _7: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
11+
let mut _5: std::boxed::Box<T>; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
12+
let mut _6: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
1413
}
1514

1615
bb0: {
1716
StorageLive(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
1817
StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
1918
StorageLive(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
2019
_4 = &mut (*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
21-
StorageLive(_5); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:7: +1:15
22-
_6 = deref_copy (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
23-
_7 = (((_6.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
24-
_5 = &mut (*_7); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
25-
_3 = _5; // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
26-
StorageDead(_5); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:7: +1:15
20+
_5 = deref_copy (*_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
21+
_6 = (((_5.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
22+
_3 = &mut (*_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
2723
_2 = &mut (*_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
2824
StorageDead(_4); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15
2925
_0 = &mut (*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15

Diff for: tests/mir-opt/inline/issue_58867_inline_as_ref_as_mut.d.Inline.after.mir

+5-9
Original file line numberDiff line numberDiff line change
@@ -7,21 +7,17 @@ fn d(_1: &Box<T>) -> &T {
77
let mut _3: &std::boxed::Box<T>; // in scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
88
scope 1 (inlined <Box<T> as AsRef<T>>::as_ref) { // at $DIR/issue_58867_inline_as_ref_as_mut.rs:18:7: 18:15
99
debug self => _3; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
10-
let _4: &T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
11-
let mut _5: std::boxed::Box<T>; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
12-
let mut _6: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
10+
let mut _4: std::boxed::Box<T>; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
11+
let mut _5: *const T; // in scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
1312
}
1413

1514
bb0: {
1615
StorageLive(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
1716
StorageLive(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
1817
_3 = &(*_1); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
19-
StorageLive(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
20-
_5 = deref_copy (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
21-
_6 = (((_5.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
22-
_4 = &(*_6); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
23-
_2 = _4; // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
24-
StorageDead(_4); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
18+
_4 = deref_copy (*_3); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
19+
_5 = (((_4.0: std::ptr::Unique<T>).0: std::ptr::NonNull<T>).0: *const T); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
20+
_2 = &(*_5); // scope 1 at $SRC_DIR/alloc/src/boxed.rs:LL:COL
2521
_0 = &(*_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:5: +1:15
2622
StorageDead(_3); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+1:14: +1:15
2723
StorageDead(_2); // scope 0 at $DIR/issue_58867_inline_as_ref_as_mut.rs:+2:1: +2:2

0 commit comments

Comments
 (0)