Skip to content

Commit 640ede7

Browse files
committed
Enable CopyProp by default, tune the impl a bit
1 parent 8dabf5d commit 640ede7

14 files changed

+248
-174
lines changed

compiler/rustc_middle/src/ty/adt.rs

+1
Original file line numberDiff line numberDiff line change
@@ -406,6 +406,7 @@ impl<'tcx> AdtDef<'tcx> {
406406
}
407407

408408
/// Return the index of `VariantDef` given a variant id.
409+
#[inline]
409410
pub fn variant_index_with_id(self, vid: DefId) -> VariantIdx {
410411
self.variants()
411412
.iter_enumerated()

compiler/rustc_mir_transform/src/copy_prop.rs

+2-2
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ pub struct CopyProp;
2222

2323
impl<'tcx> MirPass<'tcx> for CopyProp {
2424
fn is_enabled(&self, sess: &rustc_session::Session) -> bool {
25-
sess.mir_opt_level() >= 4
25+
sess.mir_opt_level() >= 1
2626
}
2727

2828
#[instrument(level = "trace", skip(self, tcx, body))]
@@ -96,7 +96,7 @@ fn fully_moved_locals(ssa: &SsaLocals, body: &Body<'_>) -> BitSet<Local> {
9696
fully_moved
9797
}
9898

99-
/// Utility to help performing subtitution of `*pattern` by `target`.
99+
/// Utility to help performing substitution of `*pattern` by `target`.
100100
struct Replacer<'a, 'tcx> {
101101
tcx: TyCtxt<'tcx>,
102102
fully_moved: BitSet<Local>,

compiler/rustc_mir_transform/src/ssa.rs

+39-4
Original file line numberDiff line numberDiff line change
@@ -19,6 +19,33 @@ pub struct SsaLocals {
1919
copy_classes: IndexVec<Local, Local>,
2020
}
2121

22+
/// We often encounter MIR bodies with 1 or 2 basic blocks. In those cases, it's unnecessary to
23+
/// actually compute dominators, we can just compare block indices because bb0 is always the first
24+
/// block, and in any body all other blocks are always always dominated by bb0.
25+
struct SmallDominators {
26+
inner: Option<Dominators<BasicBlock>>,
27+
}
28+
29+
trait DomExt {
30+
fn dominates(self, _other: Self, dominators: &SmallDominators) -> bool;
31+
}
32+
33+
impl DomExt for Location {
34+
fn dominates(self, other: Location, dominators: &SmallDominators) -> bool {
35+
if self.block == other.block {
36+
self.statement_index <= other.statement_index
37+
} else {
38+
dominators.dominates(self.block, other.block)
39+
}
40+
}
41+
}
42+
43+
impl SmallDominators {
44+
fn dominates(&self, dom: BasicBlock, node: BasicBlock) -> bool {
45+
if let Some(inner) = &self.inner { inner.dominates(dom, node) } else { dom < node }
46+
}
47+
}
48+
2249
impl SsaLocals {
2350
pub fn new<'tcx>(
2451
tcx: TyCtxt<'tcx>,
@@ -29,7 +56,9 @@ impl SsaLocals {
2956
let assignment_order = Vec::new();
3057

3158
let assignments = IndexVec::from_elem(Set1::Empty, &body.local_decls);
32-
let dominators = body.basic_blocks.dominators();
59+
let dominators =
60+
if body.basic_blocks.len() > 2 { Some(body.basic_blocks.dominators()) } else { None };
61+
let dominators = SmallDominators { inner: dominators };
3362
let mut visitor = SsaVisitor { assignments, assignment_order, dominators };
3463

3564
for (local, decl) in body.local_decls.iter_enumerated() {
@@ -41,8 +70,14 @@ impl SsaLocals {
4170
}
4271
}
4372

44-
for (bb, data) in traversal::reverse_postorder(body) {
45-
visitor.visit_basic_block_data(bb, data);
73+
if body.basic_blocks.len() > 2 {
74+
for (bb, data) in traversal::reverse_postorder(body) {
75+
visitor.visit_basic_block_data(bb, data);
76+
}
77+
} else {
78+
for (bb, data) in body.basic_blocks.iter_enumerated() {
79+
visitor.visit_basic_block_data(bb, data);
80+
}
4681
}
4782

4883
for var_debug_info in &body.var_debug_info {
@@ -139,7 +174,7 @@ enum LocationExtended {
139174
}
140175

141176
struct SsaVisitor {
142-
dominators: Dominators<BasicBlock>,
177+
dominators: SmallDominators,
143178
assignments: IndexVec<Local, Set1<LocationExtended>>,
144179
assignment_order: Vec<Local>,
145180
}

tests/codegen/move-operands.rs

+1-1
Original file line numberDiff line numberDiff line change
@@ -1,4 +1,4 @@
1-
// compile-flags: -C no-prepopulate-passes -Zmir-enable-passes=+DestinationPropagation
1+
// compile-flags: -C no-prepopulate-passes -Zmir-enable-passes=+DestinationPropagation,+CopyProp
22

33
#![crate_type = "lib"]
44

tests/codegen/simd-intrinsic/simd-intrinsic-transmute-array.rs

-3
Original file line numberDiff line numberDiff line change
@@ -21,23 +21,20 @@ pub struct U(f32, f32, f32, f32);
2121
// CHECK-LABEL: @build_array_s
2222
#[no_mangle]
2323
pub fn build_array_s(x: [f32; 4]) -> S<4> {
24-
// CHECK: call void @llvm.memcpy.{{.+}}({{.*}}, i{{[0-9]+}} 16, i1 false)
2524
// CHECK: call void @llvm.memcpy.{{.+}}({{.*}}, i{{[0-9]+}} 16, i1 false)
2625
S::<4>(x)
2726
}
2827

2928
// CHECK-LABEL: @build_array_t
3029
#[no_mangle]
3130
pub fn build_array_t(x: [f32; 4]) -> T {
32-
// CHECK: call void @llvm.memcpy.{{.+}}({{.*}}, i{{[0-9]+}} 16, i1 false)
3331
// CHECK: call void @llvm.memcpy.{{.+}}({{.*}}, i{{[0-9]+}} 16, i1 false)
3432
T(x)
3533
}
3634

3735
// CHECK-LABEL: @build_array_u
3836
#[no_mangle]
3937
pub fn build_array_u(x: [f32; 4]) -> U {
40-
// CHECK: call void @llvm.memcpy.{{.+}}({{.*}}, i{{[0-9]+}} 16, i1 false)
4138
// CHECK: call void @llvm.memcpy.{{.+}}({{.*}}, i{{[0-9]+}} 16, i1 false)
4239
unsafe { std::mem::transmute(x) }
4340
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
- // MIR for `f` before CopyProp
2+
+ // MIR for `f` after CopyProp
3+
4+
fn f(_1: NotCopy) -> () {
5+
let mut _0: (); // return place in scope 0 at $DIR/custom_move_arg.rs:+0:19: +0:19
6+
let mut _2: NotCopy; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
7+
let mut _3: NotCopy; // in scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
8+
9+
bb0: {
10+
- _2 = move _1; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
11+
_0 = opaque::<NotCopy>(move _1) -> bb1; // scope 0 at $DIR/custom_move_arg.rs:+3:9: +3:41
12+
// mir::Constant
13+
// + span: $DIR/custom_move_arg.rs:15:24: 15:30
14+
// + literal: Const { ty: fn(NotCopy) {opaque::<NotCopy>}, val: Value(<ZST>) }
15+
}
16+
17+
bb1: {
18+
- _3 = move _2; // scope 0 at $SRC_DIR/core/src/intrinsics/mir.rs:LL:COL
19+
- _0 = opaque::<NotCopy>(_3) -> bb2; // scope 0 at $DIR/custom_move_arg.rs:+7:9: +7:35
20+
+ _0 = opaque::<NotCopy>(_1) -> bb2; // scope 0 at $DIR/custom_move_arg.rs:+7:9: +7:35
21+
// mir::Constant
22+
// + span: $DIR/custom_move_arg.rs:19:24: 19:30
23+
// + literal: Const { ty: fn(NotCopy) {opaque::<NotCopy>}, val: Value(<ZST>) }
24+
}
25+
26+
bb2: {
27+
return; // scope 0 at $DIR/custom_move_arg.rs:+10:9: +10:17
28+
}
29+
}
30+
+32
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,32 @@
1+
// unit-test: CopyProp
2+
3+
#![feature(custom_mir, core_intrinsics)]
4+
#![allow(unused_assignments)]
5+
extern crate core;
6+
use core::intrinsics::mir::*;
7+
8+
struct NotCopy(bool);
9+
10+
// EMIT_MIR custom_move_arg.f.CopyProp.diff
11+
#[custom_mir(dialect = "analysis", phase = "post-cleanup")]
12+
fn f(_1: NotCopy) {
13+
mir!({
14+
let _2 = Move(_1);
15+
Call(RET, bb1, opaque(Move(_1)))
16+
}
17+
bb1 = {
18+
let _3 = Move(_2);
19+
Call(RET, bb2, opaque(_3))
20+
}
21+
bb2 = {
22+
Return()
23+
})
24+
}
25+
26+
#[inline(never)]
27+
fn opaque<T>(_t: T) {}
28+
29+
fn main() {
30+
f(NotCopy(true));
31+
println!("hi");
32+
}

tests/mir-opt/dataflow-const-prop/inherit_overflow.main.DataflowConstProp.diff

+7-5
Original file line numberDiff line numberDiff line change
@@ -10,19 +10,21 @@
1010
scope 2 (inlined <u8 as Add>::add) { // at $DIR/inherit_overflow.rs:7:13: 7:47
1111
debug self => _1; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
1212
debug other => _2; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
13-
let mut _3: u8; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
14-
let mut _4: u8; // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
15-
let mut _5: (u8, bool); // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
13+
let mut _3: (u8, bool); // in scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
1614
}
1715

1816
bb0: {
17+
StorageLive(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
1918
_1 = const u8::MAX; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
19+
StorageLive(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
2020
_2 = const 1_u8; // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
21-
_5 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
22-
assert(!move (_5.1: bool), "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
21+
_3 = CheckedAdd(const u8::MAX, const 1_u8); // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
22+
assert(!move (_3.1: bool), "attempt to compute `{} + {}`, which would overflow", const u8::MAX, const 1_u8) -> bb1; // scope 2 at $SRC_DIR/core/src/ops/arith.rs:LL:COL
2323
}
2424

2525
bb1: {
26+
StorageDead(_2); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
27+
StorageDead(_1); // scope 0 at $DIR/inherit_overflow.rs:+3:13: +3:47
2628
return; // scope 0 at $DIR/inherit_overflow.rs:+4:2: +4:2
2729
}
2830
}

tests/mir-opt/inline/inline_generator.main.Inline.diff

+26-34
Original file line numberDiff line numberDiff line change
@@ -7,29 +7,27 @@
77
let mut _2: std::pin::Pin<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>; // in scope 0 at $DIR/inline_generator.rs:+1:14: +1:32
88
let mut _3: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline_generator.rs:+1:23: +1:31
99
let mut _4: [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 0 at $DIR/inline_generator.rs:+1:28: +1:31
10-
+ let mut _7: bool; // in scope 0 at $DIR/inline_generator.rs:+1:33: +1:46
10+
+ let mut _5: bool; // in scope 0 at $DIR/inline_generator.rs:+1:33: +1:46
1111
scope 1 {
1212
debug _r => _1; // in scope 1 at $DIR/inline_generator.rs:+1:9: +1:11
1313
}
1414
+ scope 2 (inlined g) { // at $DIR/inline_generator.rs:9:28: 9:31
1515
+ }
1616
+ scope 3 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new) { // at $DIR/inline_generator.rs:9:14: 9:32
1717
+ debug pointer => _3; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL
18-
+ let mut _5: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 3 at $SRC_DIR/core/src/pin.rs:LL:COL
1918
+ scope 4 {
2019
+ scope 5 (inlined Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>::new_unchecked) { // at $SRC_DIR/core/src/pin.rs:LL:COL
21-
+ debug pointer => _5; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
22-
+ let mut _6: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
20+
+ debug pointer => _3; // in scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
2321
+ }
2422
+ }
2523
+ }
2624
+ scope 6 (inlined g::{closure#0}) { // at $DIR/inline_generator.rs:9:33: 9:46
27-
+ debug a => _7; // in scope 6 at $DIR/inline_generator.rs:15:6: 15:7
28-
+ let mut _8: i32; // in scope 6 at $DIR/inline_generator.rs:15:17: 15:39
29-
+ let mut _9: u32; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
25+
+ debug a => _5; // in scope 6 at $DIR/inline_generator.rs:15:6: 15:7
26+
+ let mut _6: i32; // in scope 6 at $DIR/inline_generator.rs:15:17: 15:39
27+
+ let mut _7: u32; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
28+
+ let mut _8: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
29+
+ let mut _9: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
3030
+ let mut _10: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
31-
+ let mut _11: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
32-
+ let mut _12: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]; // in scope 6 at $DIR/inline_generator.rs:15:5: 15:41
3331
+ }
3432

3533
bb0: {
@@ -64,28 +62,22 @@
6462
- }
6563
-
6664
- bb2: {
67-
+ StorageLive(_5); // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL
68-
+ _5 = move _3; // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL
69-
+ StorageLive(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
70-
+ _6 = move _5; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
71-
+ _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]> { pointer: move _6 }; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
72-
+ StorageDead(_6); // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
73-
+ StorageDead(_5); // scope 4 at $SRC_DIR/core/src/pin.rs:LL:COL
65+
+ _2 = Pin::<&mut [generator@$DIR/inline_generator.rs:15:5: 15:8]> { pointer: move _3 }; // scope 5 at $SRC_DIR/core/src/pin.rs:LL:COL
7466
StorageDead(_3); // scope 0 at $DIR/inline_generator.rs:+1:31: +1:32
7567
- _1 = <[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator<bool>>::resume(move _2, const false) -> [return: bb3, unwind: bb4]; // scope 0 at $DIR/inline_generator.rs:+1:14: +1:46
7668
- // mir::Constant
7769
- // + span: $DIR/inline_generator.rs:9:33: 9:39
7870
- // + literal: Const { ty: for<'a> fn(Pin<&'a mut [generator@$DIR/inline_generator.rs:15:5: 15:8]>, bool) -> GeneratorState<<[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator<bool>>::Yield, <[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator<bool>>::Return> {<[generator@$DIR/inline_generator.rs:15:5: 15:8] as Generator<bool>>::resume}, val: Value(<ZST>) }
79-
+ StorageLive(_7); // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46
80-
+ _7 = const false; // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46
81-
+ _10 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
82-
+ _9 = discriminant((*_10)); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
83-
+ switchInt(move _9) -> [0: bb3, 1: bb8, 3: bb7, otherwise: bb9]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
71+
+ StorageLive(_5); // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46
72+
+ _5 = const false; // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46
73+
+ _8 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
74+
+ _7 = discriminant((*_8)); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
75+
+ switchInt(move _7) -> [0: bb3, 1: bb8, 3: bb7, otherwise: bb9]; // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
8476
}
8577

8678
- bb3: {
8779
+ bb1: {
88-
+ StorageDead(_7); // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46
80+
+ StorageDead(_5); // scope 0 at $DIR/inline_generator.rs:+1:33: +1:46
8981
StorageDead(_2); // scope 0 at $DIR/inline_generator.rs:+1:45: +1:46
9082
StorageDead(_4); // scope 0 at $DIR/inline_generator.rs:+1:46: +1:47
9183
_0 = const (); // scope 0 at $DIR/inline_generator.rs:+0:11: +2:2
@@ -99,33 +91,33 @@
9991
+ }
10092
+
10193
+ bb3: {
102-
+ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:17: 15:39
103-
+ switchInt(_7) -> [0: bb5, otherwise: bb4]; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21
94+
+ StorageLive(_6); // scope 6 at $DIR/inline_generator.rs:15:17: 15:39
95+
+ switchInt(_5) -> [0: bb5, otherwise: bb4]; // scope 6 at $DIR/inline_generator.rs:15:20: 15:21
10496
+ }
10597
+
10698
+ bb4: {
107-
+ _8 = const 7_i32; // scope 6 at $DIR/inline_generator.rs:15:24: 15:25
99+
+ _6 = const 7_i32; // scope 6 at $DIR/inline_generator.rs:15:24: 15:25
108100
+ goto -> bb6; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39
109101
+ }
110102
+
111103
+ bb5: {
112-
+ _8 = const 13_i32; // scope 6 at $DIR/inline_generator.rs:15:35: 15:37
104+
+ _6 = const 13_i32; // scope 6 at $DIR/inline_generator.rs:15:35: 15:37
113105
+ goto -> bb6; // scope 6 at $DIR/inline_generator.rs:15:17: 15:39
114106
+ }
115107
+
116108
+ bb6: {
117-
+ _1 = GeneratorState::<i32, bool>::Yielded(move _8); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
118-
+ _11 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
119-
+ discriminant((*_11)) = 3; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
109+
+ _1 = GeneratorState::<i32, bool>::Yielded(move _6); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
110+
+ _9 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
111+
+ discriminant((*_9)) = 3; // scope 6 at $DIR/inline_generator.rs:15:11: 15:39
120112
+ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:11: 15:39
121113
+ }
122114
+
123115
+ bb7: {
124-
+ StorageLive(_8); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
125-
+ StorageDead(_8); // scope 6 at $DIR/inline_generator.rs:15:38: 15:39
126-
+ _1 = GeneratorState::<i32, bool>::Complete(_7); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
127-
+ _12 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
128-
+ discriminant((*_12)) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
116+
+ StorageLive(_6); // scope 6 at $DIR/inline_generator.rs:15:5: 15:41
117+
+ StorageDead(_6); // scope 6 at $DIR/inline_generator.rs:15:38: 15:39
118+
+ _1 = GeneratorState::<i32, bool>::Complete(_5); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
119+
+ _10 = deref_copy (_2.0: &mut [generator@$DIR/inline_generator.rs:15:5: 15:8]); // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
120+
+ discriminant((*_10)) = 1; // scope 6 at $DIR/inline_generator.rs:15:41: 15:41
129121
+ goto -> bb1; // scope 0 at $DIR/inline_generator.rs:15:41: 15:41
130122
+ }
131123
+

0 commit comments

Comments
 (0)