Skip to content

Commit

Permalink
trans: derefs don't need the pointer in an alloca.
Browse files Browse the repository at this point in the history
  • Loading branch information
eddyb committed Jun 20, 2016
1 parent 93c32b5 commit eb9cb4d
Show file tree
Hide file tree
Showing 2 changed files with 29 additions and 9 deletions.
7 changes: 7 additions & 0 deletions src/librustc_trans/mir/analyze.rs
Expand Up @@ -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);
}
}
Expand Down
31 changes: 22 additions & 9 deletions src/librustc_trans/mir/lvalue.rs
Expand Up @@ -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> {
Expand Down Expand Up @@ -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);
Expand All @@ -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);
Expand Down

0 comments on commit eb9cb4d

Please sign in to comment.