From 8ad40479c5eb761d78b4b8b3ba0e411b217fb497 Mon Sep 17 00:00:00 2001 From: Ralf Jung Date: Sun, 19 Aug 2018 17:01:31 +0200 Subject: [PATCH] optimize creating a stack frame --- src/librustc/mir/interpret/value.rs | 2 ++ src/librustc_mir/interpret/eval_context.rs | 21 +++++++++++++++------ 2 files changed, 17 insertions(+), 6 deletions(-) diff --git a/src/librustc/mir/interpret/value.rs b/src/librustc/mir/interpret/value.rs index 3cb6839f3c9..b142de81c1e 100644 --- a/src/librustc/mir/interpret/value.rs +++ b/src/librustc/mir/interpret/value.rs @@ -178,6 +178,7 @@ pub fn to_bool(self) -> EvalResult<'tcx, bool> { } impl From for Scalar { + #[inline(always)] fn from(ptr: Pointer) -> Self { Scalar::Ptr(ptr) } @@ -210,6 +211,7 @@ pub enum ScalarMaybeUndef { } impl From for ScalarMaybeUndef { + #[inline(always)] fn from(s: Scalar) -> Self { ScalarMaybeUndef::Scalar(s) } diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index d42fc8746c4..33420b6150b 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -288,6 +288,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'mir, 'tcx>> LayoutOf for &'a EvalContext<'a, 'm type Ty = Ty<'tcx>; type TyLayout = EvalResult<'tcx, TyLayout<'tcx>>; + #[inline] fn layout_of(self, ty: Ty<'tcx>) -> Self::TyLayout { self.tcx.layout_of(self.param_env.and(ty)) .map_err(|layout| EvalErrorKind::Layout(layout).into()) @@ -559,7 +560,7 @@ pub fn push_stack_frame( // value we use for things that we know are initially dead. let dummy = LocalValue::Live(Operand::Immediate(Value::Scalar(ScalarMaybeUndef::Undef))); - self.frame_mut().locals = IndexVec::from_elem(dummy, &mir.local_decls); + let mut locals = IndexVec::from_elem(dummy, &mir.local_decls); // Now mark those locals as dead that we do not want to initialize match self.tcx.describe_def(instance.def_id()) { // statics and constants don't have `Storage*` statements, no need to look for them @@ -572,8 +573,7 @@ pub fn push_stack_frame( match stmt.kind { StorageLive(local) | StorageDead(local) => { - // Worst case we are overwriting a dummy, no deallocation needed - self.storage_dead(local); + locals[local] = LocalValue::Dead; } _ => {} } @@ -582,11 +582,20 @@ pub fn push_stack_frame( }, } // Finally, properly initialize all those that still have the dummy value - for local in mir.local_decls.indices() { - if self.frame().locals[local] == dummy { - self.storage_live(local)?; + for (local, decl) in locals.iter_mut().zip(mir.local_decls.iter()) { + match *local { + LocalValue::Live(_) => { + // This needs to be peoperly initialized. + let layout = self.layout_of(self.monomorphize(decl.ty, instance.substs))?; + *local = LocalValue::Live(self.uninit_operand(layout)?); + } + LocalValue::Dead => { + // Nothing to do + } } } + // done + self.frame_mut().locals = locals; } if self.stack.len() > self.stack_limit { -- 2.44.0