Skip to content

Commit 40a50a7

Browse files
committed
Transform large arrays into Repeat expressions when possible.
1 parent 27acd92 commit 40a50a7

File tree

4 files changed

+151
-1
lines changed

4 files changed

+151
-1
lines changed

compiler/rustc_mir_transform/src/gvn.rs

+14
Original file line numberDiff line numberDiff line change
@@ -786,6 +786,20 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
786786
.collect();
787787
let fields = fields?;
788788

789+
if let AggregateTy::Array = ty && fields.len() > 4 {
790+
let first = fields[0];
791+
if fields.iter().all(|&v| v == first) {
792+
let len = ty::Const::from_target_usize(self.tcx, fields.len().try_into().unwrap());
793+
if let Some(const_) = self.try_as_constant(first) {
794+
*rvalue = Rvalue::Repeat(Operand::Constant(Box::new(const_)), len);
795+
} else if let Some(local) = self.try_as_local(first, location) {
796+
*rvalue = Rvalue::Repeat(Operand::Copy(local.into()), len);
797+
self.reused_locals.insert(local);
798+
}
799+
return Some(Value::Repeat(first, len));
800+
}
801+
}
802+
789803
let value = Value::Aggregate(ty, variant_index, fields);
790804
Some(value)
791805
}

tests/mir-opt/gvn.aggregates.GVN.panic-abort.diff

+67
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@
88
let mut _4: [u16; 0];
99
let mut _6: ();
1010
let mut _8: ();
11+
let mut _11: i32;
12+
let mut _12: i32;
13+
let mut _13: i32;
14+
let mut _14: i32;
15+
let mut _15: i32;
16+
let mut _16: i32;
17+
let mut _17: i32;
18+
let mut _18: i32;
19+
let mut _19: i32;
20+
let mut _20: i32;
1121
scope 1 {
1222
debug a_array => _1;
1323
let _3: S<[u16; 0]>;
@@ -19,6 +29,14 @@
1929
let _7: S<()>;
2030
scope 4 {
2131
debug b_tuple => _7;
32+
let _9: i32;
33+
scope 5 {
34+
debug val => _9;
35+
let _10: [i32; 10];
36+
scope 6 {
37+
debug array => _10;
38+
}
39+
}
2240
}
2341
}
2442
}
@@ -55,7 +73,56 @@
5573
+ _8 = const ();
5674
+ _7 = const S::<()>(());
5775
StorageDead(_8);
76+
- StorageLive(_9);
77+
+ nop;
78+
_9 = const 5_i32;
79+
StorageLive(_10);
80+
StorageLive(_11);
81+
- _11 = _9;
82+
+ _11 = const 5_i32;
83+
StorageLive(_12);
84+
- _12 = _9;
85+
+ _12 = const 5_i32;
86+
StorageLive(_13);
87+
- _13 = _9;
88+
+ _13 = const 5_i32;
89+
StorageLive(_14);
90+
- _14 = _9;
91+
+ _14 = const 5_i32;
92+
StorageLive(_15);
93+
- _15 = _9;
94+
+ _15 = const 5_i32;
95+
StorageLive(_16);
96+
- _16 = _9;
97+
+ _16 = const 5_i32;
98+
StorageLive(_17);
99+
- _17 = _9;
100+
+ _17 = const 5_i32;
101+
StorageLive(_18);
102+
- _18 = _9;
103+
+ _18 = const 5_i32;
104+
StorageLive(_19);
105+
- _19 = _9;
106+
+ _19 = const 5_i32;
107+
StorageLive(_20);
108+
- _20 = _9;
109+
- _10 = [move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20];
110+
+ _20 = const 5_i32;
111+
+ _10 = [const 5_i32; 10];
112+
StorageDead(_20);
113+
StorageDead(_19);
114+
StorageDead(_18);
115+
StorageDead(_17);
116+
StorageDead(_16);
117+
StorageDead(_15);
118+
StorageDead(_14);
119+
StorageDead(_13);
120+
StorageDead(_12);
121+
StorageDead(_11);
58122
_0 = const ();
123+
StorageDead(_10);
124+
- StorageDead(_9);
125+
+ nop;
59126
StorageDead(_7);
60127
StorageDead(_5);
61128
StorageDead(_3);

tests/mir-opt/gvn.aggregates.GVN.panic-unwind.diff

+67
Original file line numberDiff line numberDiff line change
@@ -8,6 +8,16 @@
88
let mut _4: [u16; 0];
99
let mut _6: ();
1010
let mut _8: ();
11+
let mut _11: i32;
12+
let mut _12: i32;
13+
let mut _13: i32;
14+
let mut _14: i32;
15+
let mut _15: i32;
16+
let mut _16: i32;
17+
let mut _17: i32;
18+
let mut _18: i32;
19+
let mut _19: i32;
20+
let mut _20: i32;
1121
scope 1 {
1222
debug a_array => _1;
1323
let _3: S<[u16; 0]>;
@@ -19,6 +29,14 @@
1929
let _7: S<()>;
2030
scope 4 {
2131
debug b_tuple => _7;
32+
let _9: i32;
33+
scope 5 {
34+
debug val => _9;
35+
let _10: [i32; 10];
36+
scope 6 {
37+
debug array => _10;
38+
}
39+
}
2240
}
2341
}
2442
}
@@ -55,7 +73,56 @@
5573
+ _8 = const ();
5674
+ _7 = const S::<()>(());
5775
StorageDead(_8);
76+
- StorageLive(_9);
77+
+ nop;
78+
_9 = const 5_i32;
79+
StorageLive(_10);
80+
StorageLive(_11);
81+
- _11 = _9;
82+
+ _11 = const 5_i32;
83+
StorageLive(_12);
84+
- _12 = _9;
85+
+ _12 = const 5_i32;
86+
StorageLive(_13);
87+
- _13 = _9;
88+
+ _13 = const 5_i32;
89+
StorageLive(_14);
90+
- _14 = _9;
91+
+ _14 = const 5_i32;
92+
StorageLive(_15);
93+
- _15 = _9;
94+
+ _15 = const 5_i32;
95+
StorageLive(_16);
96+
- _16 = _9;
97+
+ _16 = const 5_i32;
98+
StorageLive(_17);
99+
- _17 = _9;
100+
+ _17 = const 5_i32;
101+
StorageLive(_18);
102+
- _18 = _9;
103+
+ _18 = const 5_i32;
104+
StorageLive(_19);
105+
- _19 = _9;
106+
+ _19 = const 5_i32;
107+
StorageLive(_20);
108+
- _20 = _9;
109+
- _10 = [move _11, move _12, move _13, move _14, move _15, move _16, move _17, move _18, move _19, move _20];
110+
+ _20 = const 5_i32;
111+
+ _10 = [const 5_i32; 10];
112+
StorageDead(_20);
113+
StorageDead(_19);
114+
StorageDead(_18);
115+
StorageDead(_17);
116+
StorageDead(_16);
117+
StorageDead(_15);
118+
StorageDead(_14);
119+
StorageDead(_13);
120+
StorageDead(_12);
121+
StorageDead(_11);
58122
_0 = const ();
123+
StorageDead(_10);
124+
- StorageDead(_9);
125+
+ nop;
59126
StorageDead(_7);
60127
StorageDead(_5);
61128
StorageDead(_3);

tests/mir-opt/gvn.rs

+3-1
Original file line numberDiff line numberDiff line change
@@ -60,7 +60,6 @@ fn subexpression_elimination(x: u64, y: u64, mut z: u64) {
6060
let e = &z;
6161
opaque(*e + x);
6262
opaque(*e + x);
63-
6463
}
6564

6665
fn wrap_unwrap<T: Copy>(x: T) -> T {
@@ -236,6 +235,9 @@ fn aggregates() {
236235

237236
let a_tuple: S<()> = S(());
238237
let b_tuple: S<()> = S(()); // But this can be with `a_tuple`.
238+
239+
let val = 5;
240+
let array = [val, val, val, val, val, val, val, val, val, val];
239241
}
240242

241243
fn main() {

0 commit comments

Comments
 (0)