1
Fork 0

add new rval, pull deref early

This commit is contained in:
ouz-a 2022-06-13 16:37:41 +03:00
parent b3f4c31199
commit cb0017f2f8
41 changed files with 274 additions and 103 deletions

View file

@ -61,7 +61,7 @@ mod syntax;
pub use syntax::*;
mod switch_sources;
pub mod tcx;
mod terminator;
pub mod terminator;
pub use terminator::*;
pub mod traversal;
@ -925,6 +925,15 @@ impl<'tcx> LocalDecl<'tcx> {
}
}
/// Returns `true` if this is a DerefTemp
pub fn is_deref_temp(&self) -> bool {
match self.local_info {
Some(box LocalInfo::DerefTemp) => return true,
_ => (),
}
return false;
}
/// Returns `true` is the local is from a compiler desugaring, e.g.,
/// `__next` from a `for` loop.
#[inline]
@ -1795,6 +1804,7 @@ impl<'tcx> Rvalue<'tcx> {
Rvalue::Cast(CastKind::PointerExposeAddress, _, _) => false,
Rvalue::Use(_)
| Rvalue::CopyForDeref(_)
| Rvalue::Repeat(_, _)
| Rvalue::Ref(_, _, _)
| Rvalue::ThreadLocalRef(_)
@ -1889,6 +1899,8 @@ impl<'tcx> Debug for Rvalue<'tcx> {
write!(fmt, "&{}{}{:?}", region, kind_str, place)
}
CopyForDeref(ref place) => write!(fmt, "deref_copy {:#?}", place),
AddressOf(mutability, ref place) => {
let kind_str = match mutability {
Mutability::Mut => "mut",

View file

@ -52,6 +52,8 @@ pub enum MirPhase {
/// of the `mir_promoted` query), these promoted elements are available in the `promoted_mir`
/// query.
ConstsPromoted = 2,
/// After this projections may only contain deref projections as the first element.
Derefered = 3,
/// Beginning with this phase, the following variants are disallowed:
/// * [`TerminatorKind::DropAndReplace`]
/// * [`TerminatorKind::FalseUnwind`]
@ -66,9 +68,7 @@ pub enum MirPhase {
/// Furthermore, `Drop` now uses explicit drop flags visible in the MIR and reaching a `Drop`
/// terminator means that the auto-generated drop glue will be invoked. Also, `Copy` operands
/// are allowed for non-`Copy` types.
DropsLowered = 3,
/// After this projections may only contain deref projections as the first element.
Derefered = 4,
DropsLowered = 4,
/// Beginning with this phase, the following variant is disallowed:
/// * [`Rvalue::Aggregate`] for any `AggregateKind` except `Array`
///
@ -1051,6 +1051,16 @@ pub enum Rvalue<'tcx> {
/// initialized but its content as uninitialized. Like other pointer casts, this in general
/// affects alias analysis.
ShallowInitBox(Operand<'tcx>, Ty<'tcx>),
/// A CopyForDeref is equivalent to a read from a place at the
/// codegen level, but is treated specially by drop elaboration. When such a read happens, it
/// is guaranteed (via nature of the mir_opt `Derefer` in rustc_mir_transform/src/deref_separator)
/// that the only use of the returned value is a deref operation, immediately
/// followed by one or more projections. Drop elaboration treats this rvalue as if the
/// read never happened and just projects further. This allows simplifying various MIR
/// optimizations and codegen backends that previously had to handle deref operations anywhere
/// in a place.
CopyForDeref(Place<'tcx>),
}
#[cfg(all(target_arch = "x86_64", target_pointer_width = "64"))]

View file

@ -211,6 +211,7 @@ impl<'tcx> Rvalue<'tcx> {
}
},
Rvalue::ShallowInitBox(_, ty) => tcx.mk_box(ty),
Rvalue::CopyForDeref(ref place) => place.ty(local_decls, tcx).ty,
}
}

View file

@ -122,6 +122,7 @@ impl<'tcx> TypeFoldable<'tcx> for Rvalue<'tcx> {
Ref(region, bk, place) => {
Ref(region.try_fold_with(folder)?, bk, place.try_fold_with(folder)?)
}
CopyForDeref(place) => CopyForDeref(place.try_fold_with(folder)?),
AddressOf(mutability, place) => AddressOf(mutability, place.try_fold_with(folder)?),
Len(place) => Len(place.try_fold_with(folder)?),
Cast(kind, op, ty) => Cast(kind, op.try_fold_with(folder)?, ty.try_fold_with(folder)?),

View file

@ -78,6 +78,10 @@ impl<'tcx> TypeVisitable<'tcx> for Rvalue<'tcx> {
use crate::mir::Rvalue::*;
match *self {
Use(ref op) => op.visit_with(visitor),
CopyForDeref(ref place) => {
let op = &Operand::Copy(*place);
op.visit_with(visitor)
}
Repeat(ref op, _) => op.visit_with(visitor),
ThreadLocalRef(did) => did.visit_with(visitor),
Ref(region, _, ref place) => {

View file

@ -711,6 +711,13 @@ macro_rules! make_mir_visitor {
};
self.visit_place(path, ctx, location);
}
Rvalue::CopyForDeref(place) => {
self.visit_place(
place,
PlaceContext::NonMutatingUse(NonMutatingUseContext::Inspect),
location
);
}
Rvalue::AddressOf(m, path) => {
let ctx = match m {