diff options
| author | Oliver Scherer <github35764891676564198441@oli-obk.de> | 2019-01-30 14:55:31 +0100 |
|---|---|---|
| committer | Oliver Scherer <github35764891676564198441@oli-obk.de> | 2019-01-30 14:55:31 +0100 |
| commit | bc528d93ec27758af5e61c21c3e05d8da077a9ce (patch) | |
| tree | b759a0d28e5a37ed30e788e0721185e4f5a24bf3 | |
| parent | 7cfb05fd23b5ecc6a13f4629844ff81ac758497c (diff) | |
| download | rust-bc528d93ec27758af5e61c21c3e05d8da077a9ce.tar.gz rust-bc528d93ec27758af5e61c21c3e05d8da077a9ce.zip | |
Allow `layout_of_local` to also use cached layouts
| -rw-r--r-- | src/librustc_mir/interpret/eval_context.rs | 11 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/operand.rs | 12 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/place.rs | 6 | ||||
| -rw-r--r-- | src/librustc_mir/interpret/terminator.rs | 4 |
4 files changed, 19 insertions, 14 deletions
diff --git a/src/librustc_mir/interpret/eval_context.rs b/src/librustc_mir/interpret/eval_context.rs index d2cabde9863..d890e2fbe46 100644 --- a/src/librustc_mir/interpret/eval_context.rs +++ b/src/librustc_mir/interpret/eval_context.rs @@ -317,13 +317,16 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc pub fn layout_of_local( &self, frame: &Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>, - local: mir::Local + local: mir::Local, + layout: Option<TyLayout<'tcx>>, ) -> EvalResult<'tcx, TyLayout<'tcx>> { let cell = &frame.locals[local].layout; if cell.get().is_none() { + let layout = ::interpret::operand::from_known_layout(layout, || { let local_ty = frame.mir.local_decls[local].ty; let local_ty = self.monomorphize_with_substs(local_ty, frame.instance.substs); - let layout = self.layout_of(local_ty)?; + self.layout_of(local_ty) + })?; cell.set(Some(layout)); } @@ -507,7 +510,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc match local.state { LocalState::Live(_) => { // This needs to be peoperly initialized. - let layout = self.layout_of_local(self.frame(), idx)?; + let layout = self.layout_of_local(self.frame(), idx, None)?; local.state = LocalState::Live(self.uninit_operand(layout)?); } LocalState::Dead => { @@ -601,7 +604,7 @@ impl<'a, 'mir, 'tcx: 'mir, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tc assert!(local != mir::RETURN_PLACE, "Cannot make return place live"); trace!("{:?} is now live", local); - let layout = self.layout_of_local(self.frame(), local)?; + let layout = self.layout_of_local(self.frame(), local, None)?; let init = LocalState::Live(self.uninit_operand(layout)?); // StorageLive *always* kills the value that's currently stored Ok(mem::replace(&mut self.frame_mut().locals[local].state, init)) diff --git a/src/librustc_mir/interpret/operand.rs b/src/librustc_mir/interpret/operand.rs index e4bee24c88c..a7e92d56794 100644 --- a/src/librustc_mir/interpret/operand.rs +++ b/src/librustc_mir/interpret/operand.rs @@ -227,7 +227,7 @@ impl<'tcx, Tag> OpTy<'tcx, Tag> // Use the existing layout if given (but sanity check in debug mode), // or compute the layout. #[inline(always)] -fn from_known_layout<'tcx>( +pub(super) fn from_known_layout<'tcx>( layout: Option<TyLayout<'tcx>>, compute: impl FnOnce() -> EvalResult<'tcx, TyLayout<'tcx>> ) -> EvalResult<'tcx, TyLayout<'tcx>> { @@ -461,10 +461,11 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> &self, frame: &super::Frame<'mir, 'tcx, M::PointerTag, M::FrameExtra>, local: mir::Local, + layout: Option<TyLayout<'tcx>>, ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { assert_ne!(local, mir::RETURN_PLACE); let op = *frame.locals[local].access()?; - let layout = self.layout_of_local(frame, local)?; + let layout = self.layout_of_local(frame, local, layout)?; Ok(OpTy { op, layout }) } @@ -473,14 +474,15 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> fn eval_place_to_op( &self, mir_place: &mir::Place<'tcx>, + layout: Option<TyLayout<'tcx>>, ) -> EvalResult<'tcx, OpTy<'tcx, M::PointerTag>> { use rustc::mir::Place::*; let op = match *mir_place { Local(mir::RETURN_PLACE) => return err!(ReadFromReturnPointer), - Local(local) => self.access_local(self.frame(), local)?, + Local(local) => self.access_local(self.frame(), local, layout)?, Projection(ref proj) => { - let op = self.eval_place_to_op(&proj.base)?; + let op = self.eval_place_to_op(&proj.base, None)?; self.operand_projection(op, &proj.elem)? } @@ -504,7 +506,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> // FIXME: do some more logic on `move` to invalidate the old location Copy(ref place) | Move(ref place) => - self.eval_place_to_op(place)?, + self.eval_place_to_op(place, layout)?, Constant(ref constant) => { let layout = from_known_layout(layout, || { diff --git a/src/librustc_mir/interpret/place.rs b/src/librustc_mir/interpret/place.rs index f3a948a6ca3..ffb8ec899a0 100644 --- a/src/librustc_mir/interpret/place.rs +++ b/src/librustc_mir/interpret/place.rs @@ -624,7 +624,7 @@ where // their layout on return. PlaceTy { place: *return_place, - layout: self.layout_of_local(self.frame(), mir::RETURN_PLACE)?, + layout: self.layout_of_local(self.frame(), mir::RETURN_PLACE, None)?, }, None => return err!(InvalidNullPointerUsage), }, @@ -633,7 +633,7 @@ where frame: self.cur_frame(), local, }, - layout: self.layout_of_local(self.frame(), local)?, + layout: self.layout_of_local(self.frame(), local, None)?, }, Projection(ref proj) => { @@ -901,7 +901,7 @@ where // We need the layout of the local. We can NOT use the layout we got, // that might e.g., be an inner field of a struct with `Scalar` layout, // that has different alignment than the outer field. - let local_layout = self.layout_of_local(&self.stack[frame], local)?; + let local_layout = self.layout_of_local(&self.stack[frame], local, None)?; let ptr = self.allocate(local_layout, MemoryKind::Stack); // We don't have to validate as we can assume the local // was already valid for its type. diff --git a/src/librustc_mir/interpret/terminator.rs b/src/librustc_mir/interpret/terminator.rs index 951e9fabe59..7e823524c18 100644 --- a/src/librustc_mir/interpret/terminator.rs +++ b/src/librustc_mir/interpret/terminator.rs @@ -309,7 +309,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> mir.spread_arg, mir.args_iter() .map(|local| - (local, self.layout_of_local(self.frame(), local).unwrap().ty) + (local, self.layout_of_local(self.frame(), local, None).unwrap().ty) ) .collect::<Vec<_>>() ); @@ -383,7 +383,7 @@ impl<'a, 'mir, 'tcx, M: Machine<'a, 'mir, 'tcx>> EvalContext<'a, 'mir, 'tcx, M> } } else { let callee_layout = - self.layout_of_local(self.frame(), mir::RETURN_PLACE)?; + self.layout_of_local(self.frame(), mir::RETURN_PLACE, None)?; if !callee_layout.abi.is_uninhabited() { return err!(FunctionRetMismatch( self.tcx.types.never, callee_layout.ty |
