X-Git-Url: https://git.lizzy.rs/?a=blobdiff_plain;f=src%2Flibrustc_codegen_ssa%2Fmir%2Foperand.rs;h=0ae2fbe8071adb5787ae3a228094ef4ddacca1af;hb=760a98fb5e1c964efbe5cb36710fff892b547c51;hp=3b8e5b449538324c522328192b3bd61d470ba74c;hpb=a5000c5098d08d9240d875fcb4231533fb922ead;p=rust.git diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index 3b8e5b44953..0ae2fbe8071 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -1,7 +1,7 @@ -use rustc::mir::interpret::{ConstValue, ErrorHandled}; +use rustc::mir::interpret::{ConstValue, ErrorHandled, Pointer, Scalar}; use rustc::mir; use rustc::ty; -use rustc::ty::layout::{self, Align, LayoutOf, TyLayout}; +use rustc::ty::layout::{self, Align, LayoutOf, TyLayout, Size}; use crate::base; use crate::MemFlags; @@ -67,12 +67,12 @@ pub fn new_zst>( pub fn from_const>( bx: &mut Bx, - val: ty::Const<'tcx> - ) -> Result { + val: &'tcx ty::Const<'tcx> + ) -> Self { let layout = bx.layout_of(val.ty); if layout.is_zst() { - return Ok(OperandRef::new_zst(bx, layout)); + return OperandRef::new_zst(bx, layout); } let val = match val.val { @@ -92,28 +92,32 @@ pub fn from_const>( ); OperandValue::Immediate(llval) }, - ConstValue::Slice(a, b) => { + ConstValue::Slice { data, start, end } => { let a_scalar = match layout.abi { layout::Abi::ScalarPair(ref a, _) => a, _ => bug!("from_const: invalid ScalarPair layout: {:#?}", layout) }; + let a = Scalar::from(Pointer::new( + bx.tcx().alloc_map.lock().allocate(data), + Size::from_bytes(start as u64), + )).into(); let a_llval = bx.scalar_to_backend( a, a_scalar, bx.scalar_pair_element_backend_type(layout, 0, true), ); - let b_llval = bx.const_usize(b); + let b_llval = bx.const_usize((end - start) as u64); OperandValue::Pair(a_llval, b_llval) }, ConstValue::ByRef(ptr, alloc) => { - return Ok(bx.load_operand(bx.from_const_alloc(layout, alloc, ptr.offset))); + return bx.load_operand(bx.from_const_alloc(layout, alloc, ptr.offset)); }, }; - Ok(OperandRef { + OperandRef { val, layout - }) + } } /// Asserts that this operand refers to a scalar and returns @@ -380,45 +384,47 @@ fn maybe_codegen_consume_direct( ) -> Option> { debug!("maybe_codegen_consume_direct(place={:?})", place); - // watch out for locals that do not have an - // alloca; they are handled somewhat differently - if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place { - match self.locals[index] { - LocalRef::Operand(Some(o)) => { - return Some(o); - } - LocalRef::Operand(None) => { - bug!("use of {:?} before def", place); - } - LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => { - // use path below - } - } - } + place.iterate(|place_base, place_projection| { + if let mir::PlaceBase::Local(index) = place_base { + match self.locals[*index] { + LocalRef::Operand(Some(mut o)) => { + // Moves out of scalar and scalar pair fields are trivial. + for proj in place_projection { + match proj.elem { + mir::ProjectionElem::Field(ref f, _) => { + o = o.extract_field(bx, f.index()); + } + mir::ProjectionElem::Index(_) | + mir::ProjectionElem::ConstantIndex { .. } => { + // ZSTs don't require any actual memory access. + // FIXME(eddyb) deduplicate this with the identical + // checks in `codegen_consume` and `extract_field`. + let elem = o.layout.field(bx.cx(), 0); + if elem.is_zst() { + o = OperandRef::new_zst(bx, elem); + } else { + return None; + } + } + _ => return None, + } + } - // Moves out of scalar and scalar pair fields are trivial. - if let &mir::Place::Projection(ref proj) = place { - if let Some(o) = self.maybe_codegen_consume_direct(bx, &proj.base) { - match proj.elem { - mir::ProjectionElem::Field(ref f, _) => { - return Some(o.extract_field(bx, f.index())); + Some(o) } - mir::ProjectionElem::Index(_) | - mir::ProjectionElem::ConstantIndex { .. } => { - // ZSTs don't require any actual memory access. - // FIXME(eddyb) deduplicate this with the identical - // checks in `codegen_consume` and `extract_field`. - let elem = o.layout.field(bx.cx(), 0); - if elem.is_zst() { - return Some(OperandRef::new_zst(bx, elem)); - } + LocalRef::Operand(None) => { + bug!("use of {:?} before def", place); + } + LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => { + // watch out for locals that do not have an + // alloca; they are handled somewhat differently + None } - _ => {} } + } else { + None } - } - - None + }) } pub fn codegen_consume( @@ -462,7 +468,7 @@ pub fn codegen_operand( mir::Operand::Constant(ref constant) => { let ty = self.monomorphize(&constant.ty); self.eval_mir_constant(constant) - .and_then(|c| OperandRef::from_const(bx, c)) + .map(|c| OperandRef::from_const(bx, c)) .unwrap_or_else(|err| { match err { // errored or at least linted