Skip to content
Open
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
60 changes: 15 additions & 45 deletions compiler/rustc_mir_transform/src/gvn.rs
Original file line number Diff line number Diff line change
Expand Up @@ -192,14 +192,6 @@ enum AddressKind {
Address(RawPtrKind),
}

#[derive(Copy, Clone, Debug, PartialEq, Eq, Hash)]
enum AddressBase {
/// This address is based on this local.
Local(Local),
/// 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.
Expand Down Expand Up @@ -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<VnIndex, Ty<'tcx>>],
Expand Down Expand Up @@ -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 = 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)
};
let base = self.locals[place.local]?;
// 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 {
Expand Down Expand Up @@ -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
Expand Down Expand Up @@ -782,26 +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<VnIndex, Ty<'tcx>>],
) -> Option<VnIndex> {
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)
}
// 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)]
Expand Down Expand Up @@ -1291,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,
};
Expand Down
Loading