[const-prop] Replace Use handling with use of InterpCx

This commit is contained in:
Wesley Wiser 2019-09-05 21:06:57 -04:00
parent bc17936c8a
commit 86c7c4d7be
2 changed files with 26 additions and 25 deletions

View File

@ -132,7 +132,7 @@ impl<'mir, 'tcx, M: Machine<'mir, 'tcx>> InterpCx<'mir, 'tcx, M> {
///
/// There is no separate `eval_rvalue` function. Instead, the code for handling each rvalue
/// type writes its results directly into the memory specified by the place.
fn eval_rvalue_into_place(
pub fn eval_rvalue_into_place(
&mut self,
rvalue: &mir::Rvalue<'tcx>,
place: &mir::Place<'tcx>,

View File

@ -300,11 +300,16 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
rvalue: &Rvalue<'tcx>,
place_layout: TyLayout<'tcx>,
source_info: SourceInfo,
place: &Place<'tcx>,
) -> Option<Const<'tcx>> {
let span = source_info.span;
match *rvalue {
Rvalue::Use(ref op) => {
self.eval_operand(op, source_info)
Rvalue::Use(_) |
Rvalue::Len(_) => {
self.use_ecx(source_info, |this| {
this.ecx.eval_rvalue_into_place(rvalue, place)?;
this.ecx.eval_place_to_op(place, Some(place_layout))
})
},
Rvalue::Ref(_, _, ref place) => {
let src = self.eval_place(place, source_info)?;
@ -324,22 +329,6 @@ impl<'mir, 'tcx> ConstPropagator<'mir, 'tcx> {
Ok(dest.into())
})
},
Rvalue::Len(ref place) => {
let place = self.eval_place(&place, source_info)?;
let mplace = place.try_as_mplace().ok()?;
if let ty::Slice(_) = mplace.layout.ty.kind {
let len = mplace.meta.unwrap().to_usize(&self.ecx).unwrap();
Some(ImmTy::from_uint(
len,
self.tcx.layout_of(self.param_env.and(self.tcx.types.usize)).ok()?,
).into())
} else {
trace!("not slice: {:?}", mplace.layout.ty.kind);
None
}
},
Rvalue::NullaryOp(NullOp::SizeOf, ty) => {
type_size_of(self.tcx, self.param_env, ty).and_then(|n| Some(
ImmTy::from_uint(
@ -626,15 +615,15 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
.ty(&self.local_decls, self.tcx)
.ty;
if let Ok(place_layout) = self.tcx.layout_of(self.param_env.and(place_ty)) {
if let Some(value) = self.const_prop(rval, place_layout, statement.source_info) {
if let Place {
base: PlaceBase::Local(local),
projection: box [],
} = *place {
if let Place {
base: PlaceBase::Local(local),
projection: box [],
} = *place {
if let Some(value) = self.const_prop(rval, place_layout, statement.source_info, place) {
trace!("checking whether {:?} can be stored to {:?}", value, local);
if self.can_const_prop[local] {
trace!("storing {:?} to {:?}", value, local);
assert!(self.get_const(local).is_none());
assert!(self.get_const(local).is_none() || self.get_const(local) == Some(value));
self.set_const(local, value);
if self.should_const_prop() {
@ -648,6 +637,18 @@ impl<'mir, 'tcx> MutVisitor<'tcx> for ConstPropagator<'mir, 'tcx> {
}
}
}
} else if let StatementKind::StorageLive(local) = statement.kind {
if self.can_const_prop[local] {
let frame = self.ecx.frame_mut();
frame.locals[local].value = LocalValue::Uninitialized;
}
} else if let StatementKind::StorageDead(local) = statement.kind {
if self.can_const_prop[local] {
let frame = self.ecx.frame_mut();
frame.locals[local].value = LocalValue::Dead;
}
}
self.super_statement(statement, location);
}