diff options
| author | Eduard Burtescu <edy.burt@gmail.com> | 2016-06-09 18:14:47 +0300 |
|---|---|---|
| committer | Eduard Burtescu <edy.burt@gmail.com> | 2016-06-20 23:18:21 +0300 |
| commit | eb9cb4dbca6eab5b7a50934fe7385e1a99d9dc62 (patch) | |
| tree | 1e4b5eb623ce0bc2a0a4811f5992d5ce3a0c246b | |
| parent | 93c32b55e2f03bc88d3d1601626bcd9059924005 (diff) | |
| download | rust-eb9cb4dbca6eab5b7a50934fe7385e1a99d9dc62.tar.gz rust-eb9cb4dbca6eab5b7a50934fe7385e1a99d9dc62.zip | |
trans: derefs don't need the pointer in an alloca.
| -rw-r--r-- | src/librustc_trans/mir/analyze.rs | 7 | ||||
| -rw-r--r-- | src/librustc_trans/mir/lvalue.rs | 31 |
2 files changed, 29 insertions, 9 deletions
diff --git a/src/librustc_trans/mir/analyze.rs b/src/librustc_trans/mir/analyze.rs index d1c1053ac46..93ac002f2a9 100644 --- a/src/librustc_trans/mir/analyze.rs +++ b/src/librustc_trans/mir/analyze.rs @@ -151,6 +151,13 @@ impl<'mir, 'bcx, 'tcx> Visitor<'tcx> for TempAnalyzer<'mir, 'bcx, 'tcx> { } } + // A deref projection only reads the pointer, never needs the lvalue. + if let mir::Lvalue::Projection(ref proj) = *lvalue { + if let mir::ProjectionElem::Deref = proj.elem { + return self.visit_lvalue(&proj.base, LvalueContext::Consume); + } + } + self.super_lvalue(lvalue, context); } } diff --git a/src/librustc_trans/mir/lvalue.rs b/src/librustc_trans/mir/lvalue.rs index 0a66a147568..f7e15979747 100644 --- a/src/librustc_trans/mir/lvalue.rs +++ b/src/librustc_trans/mir/lvalue.rs @@ -27,6 +27,7 @@ use Disr; use std::ptr; use super::{MirContext, TempRef}; +use super::operand::OperandValue; #[derive(Copy, Clone, Debug)] pub struct LvalueRef<'tcx> { @@ -121,6 +122,26 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { let return_ty = fn_return_ty.unwrap(); LvalueRef::new_sized(llval, LvalueTy::from_ty(return_ty)) }, + mir::Lvalue::Projection(box mir::Projection { + ref base, + elem: mir::ProjectionElem::Deref + }) => { + // Load the pointer from its location. + let ptr = self.trans_consume(bcx, base); + let projected_ty = LvalueTy::from_ty(ptr.ty) + .projection_ty(tcx, &mir::ProjectionElem::Deref); + let projected_ty = bcx.monomorphize(&projected_ty); + let (llptr, llextra) = match ptr.val { + OperandValue::Immediate(llptr) => (llptr, ptr::null_mut()), + OperandValue::Pair(llptr, llextra) => (llptr, llextra), + OperandValue::Ref(_) => bug!("Deref of by-Ref type {:?}", ptr.ty) + }; + LvalueRef { + llval: llptr, + llextra: llextra, + ty: projected_ty, + } + } mir::Lvalue::Projection(ref projection) => { let tr_base = self.trans_lvalue(bcx, &projection.base); let projected_ty = tr_base.ty.projection_ty(tcx, &projection.elem); @@ -138,15 +159,7 @@ impl<'bcx, 'tcx> MirContext<'bcx, 'tcx> { }; let (llprojected, llextra) = match projection.elem { - mir::ProjectionElem::Deref => { - let base_ty = tr_base.ty.to_ty(tcx); - if common::type_is_sized(tcx, projected_ty.to_ty(tcx)) { - (base::load_ty_builder(bcx, tr_base.llval, base_ty), - ptr::null_mut()) - } else { - load_fat_ptr(bcx, tr_base.llval) - } - } + mir::ProjectionElem::Deref => bug!(), mir::ProjectionElem::Field(ref field, _) => { let base_ty = tr_base.ty.to_ty(tcx); let base_repr = adt::represent_type(ccx, base_ty); |
