From dafcfedb6d6d0131b4738552be0040d1c7dabbe2 Mon Sep 17 00:00:00 2001 From: dianqk Date: Tue, 21 Oct 2025 21:29:25 +0800 Subject: [PATCH 1/2] GVN: Use VnIndex for the local base in Address --- compiler/rustc_mir_transform/src/gvn.rs | 9 ++++----- 1 file changed, 4 insertions(+), 5 deletions(-) diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index bdf53f45feacb..1529ad1d72690 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -194,8 +194,8 @@ enum AddressKind { #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] enum AddressBase { - /// This address is based on this local. - Local(Local), + /// This address is based on the local. + Local(VnIndex), /// This address is based on the deref of this pointer. Deref(VnIndex), } @@ -457,13 +457,13 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { }; let mut projection = place.projection.iter(); + let base = self.locals[place.local]?; let base = if place.is_indirect_first_projection() { - let base = self.locals[place.local]?; // Skip the initial `Deref`. projection.next(); AddressBase::Deref(base) } else { - AddressBase::Local(place.local) + AddressBase::Local(base) }; // Do not try evaluating inside `Index`, this has been done by `simplify_place_projection`. let projection = @@ -788,7 +788,6 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { let (mut place_ty, mut value) = match base { // The base is a local, so we take the local's value and project from it. AddressBase::Local(local) => { - let local = self.locals[local]?; let place_ty = PlaceTy::from_ty(self.ty(local)); (place_ty, local) } From c4ac6e97e70f371b00f2e6efeeef79647b717485 Mon Sep 17 00:00:00 2001 From: dianqk Date: Tue, 21 Oct 2025 22:08:05 +0800 Subject: [PATCH 2/2] GVN: Remove AddressBase --- compiler/rustc_mir_transform/src/gvn.rs | 57 ++++++------------------- 1 file changed, 14 insertions(+), 43 deletions(-) diff --git a/compiler/rustc_mir_transform/src/gvn.rs b/compiler/rustc_mir_transform/src/gvn.rs index 1529ad1d72690..0fa71029050c5 100644 --- a/compiler/rustc_mir_transform/src/gvn.rs +++ b/compiler/rustc_mir_transform/src/gvn.rs @@ -192,14 +192,6 @@ enum AddressKind { Address(RawPtrKind), } -#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] -enum AddressBase { - /// This address is based on the local. - Local(VnIndex), - /// This address is based on the deref of this pointer. - Deref(VnIndex), -} - #[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)] enum Value<'a, 'tcx> { // Root values. @@ -232,7 +224,7 @@ enum Value<'a, 'tcx> { Repeat(VnIndex, ty::Const<'tcx>), /// The address of a place. Address { - base: AddressBase, + base: VnIndex, // We do not use a plain `Place` as we want to be able to reason about indices. // This does not contain any `Deref` projection. projection: &'a [ProjectionElem>], @@ -456,18 +448,12 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { AddressKind::Address(mutbl) => Ty::new_ptr(self.tcx, pty, mutbl.to_mutbl_lossy()), }; - let mut projection = place.projection.iter(); let base = self.locals[place.local]?; - let base = if place.is_indirect_first_projection() { - // Skip the initial `Deref`. - projection.next(); - AddressBase::Deref(base) - } else { - AddressBase::Local(base) - }; // Do not try evaluating inside `Index`, this has been done by `simplify_place_projection`. - let projection = - projection.map(|proj| proj.try_map(|index| self.locals[index], |ty| ty).ok_or(())); + let projection = place + .projection + .iter() + .map(|proj| proj.try_map(|index| self.locals[index], |ty| ty).ok_or(())); let projection = self.arena.try_alloc_from_iter(projection).ok()?; let index = self.values.insert_unique(ty, |provenance| Value::Address { @@ -644,12 +630,12 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { self.ecx.project(base, elem).discard_err()? } Address { base, projection, .. } => { - debug_assert!(!projection.contains(&ProjectionElem::Deref)); - let pointer = match base { - AddressBase::Deref(pointer) => self.eval_to_const(pointer)?, + let mut projection = projection.iter(); + let Some(ProjectionElem::Deref) = projection.next() else { // We have no stack to point to. - AddressBase::Local(_) => return None, + return None; }; + let pointer = self.eval_to_const(base)?; let mut mplace = self.ecx.deref_pointer(pointer).discard_err()?; for elem in projection { // `Index` by constants should have been replaced by `ConstantIndex` by @@ -782,25 +768,14 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { #[instrument(level = "trace", skip(self), ret)] fn dereference_address( &mut self, - base: AddressBase, + mut base: VnIndex, projection: &[ProjectionElem>], ) -> Option { - let (mut place_ty, mut value) = match base { - // The base is a local, so we take the local's value and project from it. - AddressBase::Local(local) => { - let place_ty = PlaceTy::from_ty(self.ty(local)); - (place_ty, local) - } - // The base is a pointer's deref, so we introduce the implicit deref. - AddressBase::Deref(reborrow) => { - let place_ty = PlaceTy::from_ty(self.ty(reborrow)); - self.project(place_ty, reborrow, ProjectionElem::Deref)? - } - }; + let mut place_ty = PlaceTy::from_ty(self.ty(base)); for &proj in projection { - (place_ty, value) = self.project(place_ty, value, proj)?; + (place_ty, base) = self.project(place_ty, base, proj)?; } - Some(value) + Some(base) } #[instrument(level = "trace", skip(self), ret)] @@ -1290,11 +1265,7 @@ impl<'body, 'a, 'tcx> VnState<'body, 'a, 'tcx> { } // `&mut *p`, `&raw *p`, etc don't change metadata. - Value::Address { base: AddressBase::Deref(reborrowed), projection, .. } - if projection.is_empty() => - { - reborrowed - } + Value::Address { base, projection: [ProjectionElem::Deref], .. } => base, _ => break, };