Skip to content

Commit 525c68c

Browse files
committed
make StorageLive lazy as well
1 parent cb51f87 commit 525c68c

File tree

2 files changed

+22
-37
lines changed

2 files changed

+22
-37
lines changed

src/librustc_mir/interpret/eval_context.rs

Lines changed: 21 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -131,6 +131,22 @@ pub enum LocalValue<Tag=(), Id=AllocId> {
131131
Live(Operand<Tag, Id>),
132132
}
133133

134+
impl<Tag: Copy> LocalValue<Tag> {
135+
/// The initial value of a local: ZST get "initialized" because they can be read from without
136+
/// ever having been written to.
137+
fn uninit_local(
138+
layout: TyLayout<'_>
139+
) -> LocalValue<Tag> {
140+
// FIXME: Can we avoid this ZST special case? That would likely require MIR
141+
// generation changes.
142+
if layout.is_zst() {
143+
LocalValue::Live(Operand::Immediate(Immediate::Scalar(Scalar::zst().into())))
144+
} else {
145+
LocalValue::Uninitialized
146+
}
147+
}
148+
}
149+
134150
impl<'tcx, Tag: Copy> LocalState<'tcx, Tag> {
135151
pub fn access(&self) -> EvalResult<'tcx, &Operand<Tag>> {
136152
match self.state {
@@ -518,19 +534,15 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
518534
}
519535
},
520536
}
521-
// FIXME: We initialize live ZST here. This should not be needed if MIR was
522-
// consistently generated for ZST, but that seems to not be the case -- there
523-
// is MIR (around promoteds in particular) that reads local ZSTs that never
524-
// were written to.
537+
// The remaining locals are uninitialized, fill them with `uninit_local`.
538+
// (For ZST this is not a NOP.)
525539
for (idx, local) in locals.iter_enumerated_mut() {
526540
match local.state {
527541
LocalValue::Uninitialized => {
528542
// This needs to be properly initialized.
529543
let ty = self.monomorphize(mir.local_decls[idx].ty)?;
530544
let layout = self.layout_of(ty)?;
531-
if layout.is_zst() {
532-
local.state = LocalValue::Live(self.uninit_operand(layout)?);
533-
}
545+
local.state = LocalValue::uninit_local(layout);
534546
local.layout = Cell::new(Some(layout));
535547
}
536548
LocalValue::Dead => {
@@ -622,9 +634,9 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tc
622634
trace!("{:?} is now live", local);
623635

624636
let layout = self.layout_of_local(self.frame(), local, None)?;
625-
let init = LocalValue::Live(self.uninit_operand(layout)?);
637+
let local_val = LocalValue::uninit_local(layout);
626638
// StorageLive *always* kills the value that's currently stored
627-
Ok(mem::replace(&mut self.frame_mut().locals[local].state, init))
639+
Ok(mem::replace(&mut self.frame_mut().locals[local].state, local_val))
628640
}
629641

630642
/// Returns the old value of the local.

src/librustc_mir/interpret/operand.rs

Lines changed: 1 addition & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -14,7 +14,7 @@ use rustc::mir::interpret::{
1414
};
1515
use super::{
1616
InterpretCx, Machine,
17-
MemPlace, MPlaceTy, PlaceTy, Place, MemoryKind,
17+
MemPlace, MPlaceTy, PlaceTy, Place,
1818
};
1919
pub use rustc::mir::interpret::ScalarMaybeUndef;
2020

@@ -373,33 +373,6 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> InterpretCx<'a, 'mir, 'tcx, M>
373373
Ok(str)
374374
}
375375

376-
pub fn uninit_operand(
377-
&mut self,
378-
layout: TyLayout<'tcx>
379-
) -> EvalResult<'tcx, Operand<M::PointerTag>> {
380-
// This decides which types we will use the Immediate optimization for, and hence should
381-
// match what `try_read_immediate` and `eval_place_to_op` support.
382-
if layout.is_zst() {
383-
return Ok(Operand::Immediate(Immediate::Scalar(Scalar::zst().into())));
384-
}
385-
386-
Ok(match layout.abi {
387-
layout::Abi::Scalar(..) =>
388-
Operand::Immediate(Immediate::Scalar(ScalarMaybeUndef::Undef)),
389-
layout::Abi::ScalarPair(..) =>
390-
Operand::Immediate(Immediate::ScalarPair(
391-
ScalarMaybeUndef::Undef,
392-
ScalarMaybeUndef::Undef,
393-
)),
394-
_ => {
395-
trace!("Forcing allocation for local of type {:?}", layout.ty);
396-
Operand::Indirect(
397-
*self.allocate(layout, MemoryKind::Stack)
398-
)
399-
}
400-
})
401-
}
402-
403376
/// Projection functions
404377
pub fn operand_field(
405378
&self,

0 commit comments

Comments
 (0)