diff options
| author | Camille GILLOT <gillot.camille@gmail.com> | 2025-04-04 10:27:50 +0000 |
|---|---|---|
| committer | Camille GILLOT <gillot.camille@gmail.com> | 2025-04-04 10:55:42 +0000 |
| commit | d9caf840e1b82d24238b516d714f3933a96ff04a (patch) | |
| tree | aa088a0cb69e155018259f05d2b44482f2ba0015 /compiler/rustc_mir_transform/src | |
| parent | 109edab245e72c876467938d46bd0ad65aaeee0b (diff) | |
| download | rust-d9caf840e1b82d24238b516d714f3933a96ff04a.tar.gz rust-d9caf840e1b82d24238b516d714f3933a96ff04a.zip | |
Only introduce stable projections.
Diffstat (limited to 'compiler/rustc_mir_transform/src')
| -rw-r--r-- | compiler/rustc_mir_transform/src/gvn.rs | 16 |
1 files changed, 12 insertions, 4 deletions
diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index a0fb20d1844..8b8d1efbbd2 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -980,7 +980,9 @@ impl<'body, 'tcx> VnState<'body, 'tcx> { } } - if let Some(place) = self.try_as_place(copy_from_local_value, location) { + // Allow introducing places with non-constant offsets, as those are still better than + // reconstructing an aggregate. + if let Some(place) = self.try_as_place(copy_from_local_value, location, true) { if rvalue.ty(self.local_decls, self.tcx) == place.ty(self.local_decls, self.tcx).ty { self.reused_locals.insert(place.local); *rvalue = Rvalue::Use(Operand::Copy(place)); @@ -1665,7 +1667,7 @@ impl<'tcx> VnState<'_, 'tcx> { fn try_as_operand(&mut self, index: VnIndex, location: Location) -> Option<Operand<'tcx>> { if let Some(const_) = self.try_as_constant(index) { Some(Operand::Constant(Box::new(const_))) - } else if let Some(place) = self.try_as_place(index, location) { + } else if let Some(place) = self.try_as_place(index, location, false) { self.reused_locals.insert(place.local); Some(Operand::Copy(place)) } else { @@ -1704,7 +1706,12 @@ impl<'tcx> VnState<'_, 'tcx> { /// dominate `loc`. If you used this place, add its base local to `reused_locals` to remove /// storage statements. #[instrument(level = "trace", skip(self), ret)] - fn try_as_place(&mut self, mut index: VnIndex, loc: Location) -> Option<Place<'tcx>> { + fn try_as_place( + &mut self, + mut index: VnIndex, + loc: Location, + allow_complex_projection: bool, + ) -> Option<Place<'tcx>> { let mut projection = SmallVec::<[PlaceElem<'tcx>; 1]>::new(); loop { if let Some(local) = self.try_as_local(index, loc) { @@ -1713,6 +1720,7 @@ impl<'tcx> VnState<'_, 'tcx> { Place { local, projection: self.tcx.mk_place_elems(projection.as_slice()) }; return Some(place); } else if let Value::Projection(pointer, proj) = *self.get(index) + && (allow_complex_projection || proj.is_stable_offset()) && let Some(proj) = self.try_as_place_elem(proj, loc) { projection.push(proj); @@ -1773,7 +1781,7 @@ impl<'tcx> MutVisitor<'tcx> for VnState<'_, 'tcx> { if let Some(value) = value { if let Some(const_) = self.try_as_constant(value) { *rvalue = Rvalue::Use(Operand::Constant(Box::new(const_))); - } else if let Some(place) = self.try_as_place(value, location) + } else if let Some(place) = self.try_as_place(value, location, false) && *rvalue != Rvalue::Use(Operand::Move(place)) && *rvalue != Rvalue::Use(Operand::Copy(place)) { |
