diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2023-09-16 09:35:46 +0000 |
|---|---|---|
| committer | Camille GILLOT <gillot.camille@gmail.com> | 2023-10-25 06:46:47 +0000 |
| commit | 48d2157a89ffddce3287c57b3e3817a7e093b6c5 (patch) | |
| tree | 1102b41765d669b7ca3ea6488ebfcca3406c8ef2 /compiler/rustc_mir_transform/src | |
| parent | 692e5286479e16b3e9b47ab842b543985e1a6ceb (diff) | |
| download | rust-48d2157a89ffddce3287c57b3e3817a7e093b6c5.tar.gz rust-48d2157a89ffddce3287c57b3e3817a7e093b6c5.zip | |
Simplify aggregate projections.
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/gvn.rs | 41 |
1 files changed, 40 insertions, 1 deletions
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index eaa1c70a5e9..70d0f22a7b9 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -276,6 +276,10 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } } + fn insert_scalar(&mut self, scalar: Scalar, ty: Ty<'tcx>) -> VnIndex { + self.insert(Value::Constant(Const::from_scalar(self.tcx, scalar, ty))) + } + #[instrument(level = "trace", skip(self), ret)] fn eval_to_const(&mut self, value: VnIndex) -> Option<OpTy<'tcx>> { use Value::*; @@ -483,12 +487,33 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } } ProjectionElem::Downcast(name, index) => ProjectionElem::Downcast(name, index), - ProjectionElem::Field(f, ty) => ProjectionElem::Field(f, ty), + ProjectionElem::Field(f, ty) => { + if let Value::Aggregate(_, _, fields) = self.get(value) { + return Some(fields[f.as_usize()]); + } else if let Value::Projection(outer_value, ProjectionElem::Downcast(_, read_variant)) = self.get(value) + && let Value::Aggregate(_, written_variant, fields) = self.get(*outer_value) + && written_variant == read_variant + { + return Some(fields[f.as_usize()]); + } + ProjectionElem::Field(f, ty) + } ProjectionElem::Index(idx) => { let idx = self.locals[idx]?; ProjectionElem::Index(idx) } ProjectionElem::ConstantIndex { offset, min_length, from_end } => { + match self.get(value) { + Value::Aggregate(ty, _, operands) if ty.is_array() => { + let offset = if from_end { + operands.len() - offset as usize + } else { + offset as usize + }; + return operands.get(offset).copied(); + } + _ => {} + }; ProjectionElem::ConstantIndex { offset, min_length, from_end } } ProjectionElem::Subslice { from, to, from_end } => { @@ -679,6 +704,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } Rvalue::Discriminant(ref mut place) => { let place = self.simplify_place_value(place, location)?; + if let Some(discr) = self.simplify_discriminant(place) { + return Some(discr); + } Value::Discriminant(place) } @@ -688,6 +716,17 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { debug!(?value); Some(self.insert(value)) } + + fn simplify_discriminant(&mut self, place: VnIndex) -> Option<VnIndex> { + if let Value::Aggregate(enum_ty, variant, _) = *self.get(place) + && enum_ty.is_enum() + { + let discr = self.ecx.discriminant_for_variant(enum_ty, variant).ok()?; + return Some(self.insert_scalar(discr.to_scalar(), discr.layout.ty)); + } + + None + } } fn op_to_prop_const<'tcx>( |
