]> git.lizzy.rs Git - rust.git/commitdiff
optimize creating a stack frame
authorRalf Jung <post@ralfj.de>
Sun, 19 Aug 2018 15:01:31 +0000 (17:01 +0200)
committerRalf Jung <post@ralfj.de>
Wed, 22 Aug 2018 11:08:39 +0000 (13:08 +0200)
src/librustc/mir/interpret/value.rs
src/librustc_mir/interpret/eval_context.rs

index 3cb6839f3c944debe27a61a05aabec925bcb81de..b142de81c1e91ce96331e7146a82c646b592be1d 100644 (file)
@@ -178,6 +178,7 @@ pub fn to_bool(self) -> EvalResult<'tcx, bool> {
 }
 
 impl From<Pointer> for Scalar {
+    #[inline(always)]
     fn from(ptr: Pointer) -> Self {
         Scalar::Ptr(ptr)
     }
@@ -210,6 +211,7 @@ pub enum ScalarMaybeUndef {
 }
 
 impl From<Scalar> for ScalarMaybeUndef {
+    #[inline(always)]
     fn from(s: Scalar) -> Self {
         ScalarMaybeUndef::Scalar(s)
     }
index d42fc8746c4c058c3ece7ca13d3917deb89150ea..33420b6150bb789918f58825effad23f9ec5fbdd 100644 (file)
@@ -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 {