make StorageLive lazy as well
This commit is contained in:
parent
cb51f872a8
commit
525c68cf95
2 changed files with 22 additions and 37 deletions
|
@ -131,6 +131,22 @@ pub enum LocalValue<Tag=(), Id=AllocId> {
|
|||
Live(Operand<Tag, Id>),
|
||||
}
|
||||
|
||||
impl<Tag: Copy> LocalValue<Tag> {
|
||||
/// The initial value of a local: ZST get "initialized" because they can be read from without
|
||||
/// ever having been written to.
|
||||
fn uninit_local(
|
||||
layout: TyLayout<'_>
|
||||
) -> LocalValue<Tag> {
|
||||
// FIXME: Can we avoid this ZST special case? That would likely require MIR
|
||||
// generation changes.
|
||||
if layout.is_zst() {
|
||||
LocalValue::Live(Operand::Immediate(Immediate::Scalar(Scalar::zst().into())))
|
||||
} else {
|
||||
LocalValue::Uninitialized
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
impl<'tcx, Tag: Copy> LocalState<'tcx, Tag> {
|
||||
pub fn access(&self) -> EvalResult<'tcx, &Operand<Tag>> {
|
||||
match self.state {
|
||||
|
@ -518,19 +534,15 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
|
|||
}
|
||||
},
|
||||
}
|
||||
// FIXME: We initialize live ZST here. This should not be needed if MIR was
|
||||
// consistently generated for ZST, but that seems to not be the case -- there
|
||||
// is MIR (around promoteds in particular) that reads local ZSTs that never
|
||||
// were written to.
|
||||
// The remaining locals are uninitialized, fill them with `uninit_local`.
|
||||
// (For ZST this is not a NOP.)
|
||||
for (idx, local) in locals.iter_enumerated_mut() {
|
||||
match local.state {
|
||||
LocalValue::Uninitialized => {
|
||||
// This needs to be properly initialized.
|
||||
let ty = self.monomorphize(mir.local_decls[idx].ty)?;
|
||||
let layout = self.layout_of(ty)?;
|
||||
if layout.is_zst() {
|
||||
local.state = LocalValue::Live(self.uninit_operand(layout)?);
|
||||
}
|
||||
local.state = LocalValue::uninit_local(layout);
|
||||
local.layout = Cell::new(Some(layout));
|
||||
}
|
||||
LocalValue::Dead => {
|
||||
|
@ -622,9 +634,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
|
|||
trace!("{:?} is now live", local);
|
||||
|
||||
let layout = self.layout_of_local(self.frame(), local, None)?;
|
||||
let init = LocalValue::Live(self.uninit_operand(layout)?);
|
||||
let local_val = LocalValue::uninit_local(layout);
|
||||
// StorageLive *always* kills the value that's currently stored
|
||||
Ok(mem::replace(&mut self.frame_mut().locals[local].state, init))
|
||||
Ok(mem::replace(&mut self.frame_mut().locals[local].state, local_val))
|
||||
}
|
||||
|
||||
/// Returns the old value of the local.
|
||||
|
|
|
@ -14,7 +14,7 @@ use rustc::mir::interpret::{
|
|||
};
|
||||
use super::{
|
||||
InterpretCx, Machine,
|
||||
MemPlace, MPlaceTy, PlaceTy, Place, MemoryKind,
|
||||
MemPlace, MPlaceTy, PlaceTy, Place,
|
||||
};
|
||||
pub use rustc::mir::interpret::ScalarMaybeUndef;
|
||||
|
||||
|
@ -373,33 +373,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
|
|||
Ok(str)
|
||||
}
|
||||
|
||||
pub fn uninit_operand(
|
||||
&mut self,
|
||||
layout: TyLayout<'tcx>
|
||||
) -> EvalResult<'tcx, Operand<M::PointerTag>> {
|
||||
// This decides which types we will use the Immediate optimization for, and hence should
|
||||
// match what `try_read_immediate` and `eval_place_to_op` support.
|
||||
if layout.is_zst() {
|
||||
return Ok(Operand::Immediate(Immediate::Scalar(Scalar::zst().into())));
|
||||
}
|
||||
|
||||
Ok(match layout.abi {
|
||||
layout::Abi::Scalar(..) =>
|
||||
Operand::Immediate(Immediate::Scalar(ScalarMaybeUndef::Undef)),
|
||||
layout::Abi::ScalarPair(..) =>
|
||||
Operand::Immediate(Immediate::ScalarPair(
|
||||
ScalarMaybeUndef::Undef,
|
||||
ScalarMaybeUndef::Undef,
|
||||
)),
|
||||
_ => {
|
||||
trace!("Forcing allocation for local of type {:?}", layout.ty);
|
||||
Operand::Indirect(
|
||||
*self.allocate(layout, MemoryKind::Stack)
|
||||
)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
/// Projection functions
|
||||
pub fn operand_field(
|
||||
&self,
|
||||
|
|
Loading…
Reference in a new issue