Skip to content

Commit 2c04a25

Browse files
committed
Simplify aggregate projections.
1 parent 57b4ac9 commit 2c04a25

9 files changed

+192
-119
lines changed

compiler/rustc_mir_transform/src/gvn.rs

Lines changed: 40 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -269,6 +269,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
269269
}
270270
}
271271

272+
fn insert_scalar(&mut self, scalar: Scalar, ty: Ty<'tcx>) -> VnIndex {
273+
self.insert(Value::Constant(Const::from_scalar(self.tcx, scalar, ty)))
274+
}
275+
272276
#[instrument(level = "trace", skip(self), ret)]
273277
fn eval_to_const(&mut self, value: VnIndex) -> Option<OpTy<'tcx>> {
274278
use Value::*;
@@ -475,12 +479,33 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
475479
}
476480
}
477481
ProjectionElem::Downcast(name, index) => ProjectionElem::Downcast(name, index),
478-
ProjectionElem::Field(f, ty) => ProjectionElem::Field(f, ty),
482+
ProjectionElem::Field(f, ty) => {
483+
if let Value::Aggregate(_, _, fields) = self.get(value) {
484+
return Some(fields[f.as_usize()]);
485+
} else if let Value::Projection(outer_value, ProjectionElem::Downcast(_, read_variant)) = self.get(value)
486+
&& let Value::Aggregate(_, written_variant, fields) = self.get(*outer_value)
487+
&& written_variant == read_variant
488+
{
489+
return Some(fields[f.as_usize()]);
490+
}
491+
ProjectionElem::Field(f, ty)
492+
}
479493
ProjectionElem::Index(idx) => {
480494
let idx = self.locals[idx]?;
481495
ProjectionElem::Index(idx)
482496
}
483497
ProjectionElem::ConstantIndex { offset, min_length, from_end } => {
498+
match self.get(value) {
499+
Value::Aggregate(ty, _, operands) if ty.is_array() => {
500+
let offset = if from_end {
501+
operands.len() - offset as usize
502+
} else {
503+
offset as usize
504+
};
505+
return operands.get(offset).copied();
506+
}
507+
_ => {}
508+
};
484509
ProjectionElem::ConstantIndex { offset, min_length, from_end }
485510
}
486511
ProjectionElem::Subslice { from, to, from_end } => {
@@ -670,6 +695,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
670695
}
671696
Rvalue::Discriminant(ref mut place) => {
672697
let place = self.simplify_place_value(place, location)?;
698+
if let Some(discr) = self.simplify_discriminant(place) {
699+
return Some(discr);
700+
}
673701
Value::Discriminant(place)
674702
}
675703

@@ -679,6 +707,17 @@ impl<'body, 'tcx> VnState<'body, 'tcx> {
679707
debug!(?value);
680708
Some(self.insert(value))
681709
}
710+
711+
fn simplify_discriminant(&mut self, place: VnIndex) -> Option<VnIndex> {
712+
if let Value::Aggregate(enum_ty, variant, _) = *self.get(place)
713+
&& enum_ty.is_enum()
714+
{
715+
let discr = self.ecx.discriminant_for_variant(enum_ty, variant).ok()?;
716+
return Some(self.insert_scalar(discr.to_scalar(), discr.layout.ty));
717+
}
718+
719+
None
720+
}
682721
}
683722

684723
fn op_to_prop_const<'tcx>(

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,20 +115,21 @@
115115
- StorageLive(_18);
116116
+ nop;
117117
_18 = &mut _1;
118-
- StorageLive(_19);
119-
+ nop;
118+
StorageLive(_19);
120119
StorageLive(_20);
121120
StorageLive(_21);
122121
- _21 = move _18;
123122
- _20 = S::<&mut impl Sized>(move _21);
124123
+ _21 = _18;
125124
+ _20 = S::<&mut impl Sized>(_18);
126125
StorageDead(_21);
127-
_19 = move (_20.0: &mut impl Sized);
126+
- _19 = move (_20.0: &mut impl Sized);
127+
+ _19 = _18;
128128
StorageDead(_20);
129129
StorageLive(_22);
130130
StorageLive(_23);
131-
_23 = &(*_19);
131+
- _23 = &(*_19);
132+
+ _23 = &(*_18);
132133
_22 = opaque::<&impl Sized>(move _23) -> [return: bb9, unwind unreachable];
133134
}
134135

@@ -137,7 +138,8 @@
137138
StorageDead(_22);
138139
StorageLive(_24);
139140
StorageLive(_25);
140-
_25 = &mut (*_19);
141+
- _25 = &mut (*_19);
142+
+ _25 = &mut (*_18);
141143
_24 = opaque::<&mut impl Sized>(move _25) -> [return: bb10, unwind unreachable];
142144
}
143145

@@ -146,7 +148,8 @@
146148
StorageDead(_24);
147149
StorageLive(_26);
148150
StorageLive(_27);
149-
_27 = &raw const (*_19);
151+
- _27 = &raw const (*_19);
152+
+ _27 = &raw const (*_18);
150153
_26 = opaque::<*const impl Sized>(move _27) -> [return: bb11, unwind unreachable];
151154
}
152155

@@ -155,17 +158,17 @@
155158
StorageDead(_26);
156159
StorageLive(_28);
157160
StorageLive(_29);
158-
_29 = &raw mut (*_19);
161+
- _29 = &raw mut (*_19);
162+
+ _29 = &raw mut (*_18);
159163
_28 = opaque::<*mut impl Sized>(move _29) -> [return: bb12, unwind unreachable];
160164
}
161165

162166
bb12: {
163167
StorageDead(_29);
164168
StorageDead(_28);
165169
_0 = const ();
166-
- StorageDead(_19);
170+
StorageDead(_19);
167171
- StorageDead(_18);
168-
+ nop;
169172
+ nop;
170173
drop(_1) -> [return: bb13, unwind unreachable];
171174
}

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

Lines changed: 12 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -115,20 +115,21 @@
115115
- StorageLive(_18);
116116
+ nop;
117117
_18 = &mut _1;
118-
- StorageLive(_19);
119-
+ nop;
118+
StorageLive(_19);
120119
StorageLive(_20);
121120
StorageLive(_21);
122121
- _21 = move _18;
123122
- _20 = S::<&mut impl Sized>(move _21);
124123
+ _21 = _18;
125124
+ _20 = S::<&mut impl Sized>(_18);
126125
StorageDead(_21);
127-
_19 = move (_20.0: &mut impl Sized);
126+
- _19 = move (_20.0: &mut impl Sized);
127+
+ _19 = _18;
128128
StorageDead(_20);
129129
StorageLive(_22);
130130
StorageLive(_23);
131-
_23 = &(*_19);
131+
- _23 = &(*_19);
132+
+ _23 = &(*_18);
132133
_22 = opaque::<&impl Sized>(move _23) -> [return: bb9, unwind: bb14];
133134
}
134135

@@ -137,7 +138,8 @@
137138
StorageDead(_22);
138139
StorageLive(_24);
139140
StorageLive(_25);
140-
_25 = &mut (*_19);
141+
- _25 = &mut (*_19);
142+
+ _25 = &mut (*_18);
141143
_24 = opaque::<&mut impl Sized>(move _25) -> [return: bb10, unwind: bb14];
142144
}
143145

@@ -146,7 +148,8 @@
146148
StorageDead(_24);
147149
StorageLive(_26);
148150
StorageLive(_27);
149-
_27 = &raw const (*_19);
151+
- _27 = &raw const (*_19);
152+
+ _27 = &raw const (*_18);
150153
_26 = opaque::<*const impl Sized>(move _27) -> [return: bb11, unwind: bb14];
151154
}
152155

@@ -155,17 +158,17 @@
155158
StorageDead(_26);
156159
StorageLive(_28);
157160
StorageLive(_29);
158-
_29 = &raw mut (*_19);
161+
- _29 = &raw mut (*_19);
162+
+ _29 = &raw mut (*_18);
159163
_28 = opaque::<*mut impl Sized>(move _29) -> [return: bb12, unwind: bb14];
160164
}
161165

162166
bb12: {
163167
StorageDead(_29);
164168
StorageDead(_28);
165169
_0 = const ();
166-
- StorageDead(_19);
170+
StorageDead(_19);
167171
- StorageDead(_18);
168-
+ nop;
169172
+ nop;
170173
drop(_1) -> [return: bb13, unwind: bb15];
171174
}

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

Lines changed: 48 additions & 34 deletions
Original file line numberDiff line numberDiff line change
@@ -112,7 +112,8 @@
112112
StorageDead(_5);
113113
StorageLive(_7);
114114
StorageLive(_8);
115-
StorageLive(_9);
115+
- StorageLive(_9);
116+
+ nop;
116117
StorageLive(_10);
117118
StorageLive(_11);
118119
_11 = &(*_1);
@@ -122,7 +123,8 @@
122123
bb3: {
123124
StorageDead(_11);
124125
_9 = &_10;
125-
StorageLive(_12);
126+
- StorageLive(_12);
127+
+ nop;
126128
StorageLive(_13);
127129
StorageLive(_14);
128130
- _14 = &(*_4);
@@ -133,20 +135,25 @@
133135
bb4: {
134136
StorageDead(_14);
135137
_12 = &_13;
136-
_8 = (move _9, move _12);
137-
StorageDead(_12);
138-
StorageDead(_9);
139-
- StorageLive(_15);
138+
- _8 = (move _9, move _12);
139+
- StorageDead(_12);
140+
- StorageDead(_9);
141+
+ _8 = (_9, _12);
140142
+ nop;
141-
_15 = (_8.0: &*const u8);
142-
- StorageLive(_16);
143143
+ nop;
144-
_16 = (_8.1: &*const u8);
144+
StorageLive(_15);
145+
- _15 = (_8.0: &*const u8);
146+
+ _15 = _9;
147+
StorageLive(_16);
148+
- _16 = (_8.1: &*const u8);
149+
+ _16 = _12;
145150
StorageLive(_17);
146151
StorageLive(_18);
147-
_18 = (*_15);
152+
- _18 = (*_15);
153+
+ _18 = (*_9);
148154
StorageLive(_19);
149-
_19 = (*_16);
155+
- _19 = (*_16);
156+
+ _19 = (*_12);
150157
_17 = Eq(move _18, move _19);
151158
switchInt(move _17) -> [0: bb6, otherwise: bb5];
152159
}
@@ -156,10 +163,8 @@
156163
StorageDead(_18);
157164
_7 = const ();
158165
StorageDead(_17);
159-
- StorageDead(_16);
160-
- StorageDead(_15);
161-
+ nop;
162-
+ nop;
166+
StorageDead(_16);
167+
StorageDead(_15);
163168
StorageDead(_13);
164169
StorageDead(_10);
165170
StorageDead(_8);
@@ -190,13 +195,15 @@
190195
+ _23 = const core::panicking::AssertKind::Eq;
191196
StorageLive(_24);
192197
- StorageLive(_25);
198+
- _25 = &(*_15);
193199
+ nop;
194-
_25 = &(*_15);
200+
+ _25 = &(*_9);
195201
_24 = &(*_25);
196202
StorageLive(_26);
197203
- StorageLive(_27);
204+
- _27 = &(*_16);
198205
+ nop;
199-
_27 = &(*_16);
206+
+ _27 = &(*_12);
200207
_26 = &(*_27);
201208
StorageLive(_28);
202209
_28 = Option::<Arguments<'_>>::None;
@@ -209,7 +216,8 @@
209216
StorageDead(_31);
210217
StorageLive(_33);
211218
StorageLive(_34);
212-
StorageLive(_35);
219+
- StorageLive(_35);
220+
+ nop;
213221
StorageLive(_36);
214222
StorageLive(_37);
215223
_37 = &(*_1);
@@ -219,7 +227,8 @@
219227
bb8: {
220228
StorageDead(_37);
221229
_35 = &_36;
222-
StorageLive(_38);
230+
- StorageLive(_38);
231+
+ nop;
223232
StorageLive(_39);
224233
StorageLive(_40);
225234
_40 = &(*_29);
@@ -229,20 +238,25 @@
229238
bb9: {
230239
StorageDead(_40);
231240
_38 = &_39;
232-
_34 = (move _35, move _38);
233-
StorageDead(_38);
234-
StorageDead(_35);
235-
- StorageLive(_41);
241+
- _34 = (move _35, move _38);
242+
- StorageDead(_38);
243+
- StorageDead(_35);
244+
+ _34 = (_35, _38);
236245
+ nop;
237-
_41 = (_34.0: &*const u8);
238-
- StorageLive(_42);
239246
+ nop;
240-
_42 = (_34.1: &*const u8);
247+
StorageLive(_41);
248+
- _41 = (_34.0: &*const u8);
249+
+ _41 = _35;
250+
StorageLive(_42);
251+
- _42 = (_34.1: &*const u8);
252+
+ _42 = _38;
241253
StorageLive(_43);
242254
StorageLive(_44);
243-
_44 = (*_41);
255+
- _44 = (*_41);
256+
+ _44 = (*_35);
244257
StorageLive(_45);
245-
_45 = (*_42);
258+
- _45 = (*_42);
259+
+ _45 = (*_38);
246260
_43 = Eq(move _44, move _45);
247261
switchInt(move _43) -> [0: bb11, otherwise: bb10];
248262
}
@@ -252,10 +266,8 @@
252266
StorageDead(_44);
253267
_33 = const ();
254268
StorageDead(_43);
255-
- StorageDead(_42);
256-
- StorageDead(_41);
257-
+ nop;
258-
+ nop;
269+
StorageDead(_42);
270+
StorageDead(_41);
259271
StorageDead(_39);
260272
StorageDead(_36);
261273
StorageDead(_34);
@@ -282,13 +294,15 @@
282294
+ _49 = const core::panicking::AssertKind::Eq;
283295
StorageLive(_50);
284296
- StorageLive(_51);
297+
- _51 = &(*_41);
285298
+ nop;
286-
_51 = &(*_41);
299+
+ _51 = &(*_35);
287300
_50 = &(*_51);
288301
StorageLive(_52);
289302
- StorageLive(_53);
303+
- _53 = &(*_42);
290304
+ nop;
291-
_53 = &(*_42);
305+
+ _53 = &(*_38);
292306
_52 = &(*_53);
293307
StorageLive(_54);
294308
_54 = Option::<Arguments<'_>>::None;

0 commit comments

Comments
 (0)