Avoid cloning Place in codegen_place

This commit is contained in:
Santiago Pastorino 2019-07-02 20:29:45 +02:00
parent e11adb13b6
commit 438aeb8ca3
6 changed files with 51 additions and 40 deletions

View File

@ -1954,6 +1954,15 @@ impl From<Local> for PlaceBase<'_> {
}
}
impl<'a, 'tcx> PlaceRef<'a, 'tcx> {
pub fn iterate<R>(
&self,
op: impl FnOnce(&PlaceBase<'tcx>, ProjectionsIter<'_, 'tcx>) -> R,
) -> R {
Place::iterate_over(self.base, self.projection, op)
}
}
/// A linked list of projections running up the stack; begins with the
/// innermost projection and extends to the outermost (e.g., `a.b.c`
/// would have the place `b` with a "next" pointer to `b.c`).

View File

@ -253,7 +253,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
PassMode::Direct(_) | PassMode::Pair(..) => {
let op =
self.codegen_consume(&mut bx, &mir::Place::RETURN_PLACE);
self.codegen_consume(&mut bx, &mir::Place::RETURN_PLACE.as_place_ref());
if let Ref(llval, _, align) = op.val {
bx.load(llval, align)
} else {
@ -314,7 +314,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
return
}
let place = self.codegen_place(&mut bx, location);
let place = self.codegen_place(&mut bx, &location.as_place_ref());
let (args1, args2);
let mut args = if let Some(llextra) = place.llextra {
args2 = [place.llval, llextra];
@ -1135,7 +1135,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
} else {
self.codegen_place(bx, dest)
self.codegen_place(bx, &mir::PlaceRef {
base: &dest.base,
projection: &dest.projection,
})
};
if fn_ret.is_indirect() {
if dest.align < dest.layout.align.abi {
@ -1168,7 +1171,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
LocalRef::Place(place) => self.codegen_transmute_into(bx, src, place),
LocalRef::UnsizedPlace(_) => bug!("transmute must not involve unsized locals"),
LocalRef::Operand(None) => {
let dst_layout = bx.layout_of(self.monomorphized_place_ty(dst));
let dst_layout = bx.layout_of(self.monomorphized_place_ty(&dst.as_place_ref()));
assert!(!dst_layout.ty.has_erasable_regions());
let place = PlaceRef::alloca(bx, dst_layout, "transmute_temp");
place.storage_live(bx);
@ -1183,7 +1186,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
} else {
let dst = self.codegen_place(bx, dst);
let dst = self.codegen_place(bx, &dst.as_place_ref());
self.codegen_transmute_into(bx, src, dst);
}
}

View File

@ -380,11 +380,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
fn maybe_codegen_consume_direct(
&mut self,
bx: &mut Bx,
place: &mir::Place<'tcx>
place_ref: &mir::PlaceRef<'_, 'tcx>
) -> Option<OperandRef<'tcx, Bx::Value>> {
debug!("maybe_codegen_consume_direct(place={:?})", place);
debug!("maybe_codegen_consume_direct(place_ref={:?})", place_ref);
place.iterate(|place_base, place_projection| {
place_ref.iterate(|place_base, place_projection| {
if let mir::PlaceBase::Local(index) = place_base {
match self.locals[*index] {
LocalRef::Operand(Some(mut o)) => {
@ -413,7 +413,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
Some(o)
}
LocalRef::Operand(None) => {
bug!("use of {:?} before def", place);
bug!("use of {:?} before def", place_ref);
}
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
// watch out for locals that do not have an
@ -430,11 +430,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
pub fn codegen_consume(
&mut self,
bx: &mut Bx,
place: &mir::Place<'tcx>
place_ref: &mir::PlaceRef<'_, 'tcx>
) -> OperandRef<'tcx, Bx::Value> {
debug!("codegen_consume(place={:?})", place);
debug!("codegen_consume(place_ref={:?})", place_ref);
let ty = self.monomorphized_place_ty(place);
let ty = self.monomorphized_place_ty(place_ref);
let layout = bx.cx().layout_of(ty);
// ZSTs don't require any actual memory access.
@ -442,13 +442,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
return OperandRef::new_zst(bx, layout);
}
if let Some(o) = self.maybe_codegen_consume_direct(bx, place) {
if let Some(o) = self.maybe_codegen_consume_direct(bx, place_ref) {
return o;
}
// for most places, to consume them we just load them
// out from their home
let place = self.codegen_place(bx, place);
let place = self.codegen_place(bx, place_ref);
bx.load_operand(place)
}
@ -462,7 +462,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
match *operand {
mir::Operand::Copy(ref place) |
mir::Operand::Move(ref place) => {
self.codegen_consume(bx, place)
self.codegen_consume(bx, &place.as_place_ref())
}
mir::Operand::Constant(ref constant) => {

View File

@ -428,15 +428,14 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
pub fn codegen_place(
&mut self,
bx: &mut Bx,
place: &mir::Place<'tcx>
place_ref: &mir::PlaceRef<'_, 'tcx>
) -> PlaceRef<'tcx, Bx::Value> {
debug!("codegen_place(place={:?})", place);
debug!("codegen_place(place_ref={:?})", place_ref);
let cx = self.cx;
let tcx = self.cx.tcx();
let result = match place {
mir::Place {
let result = match &place_ref {
mir::PlaceRef {
base: mir::PlaceBase::Local(index),
projection: None,
} => {
@ -448,11 +447,11 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
return bx.load_operand(place).deref(cx);
}
LocalRef::Operand(..) => {
bug!("using operand local {:?} as place", place);
bug!("using operand local {:?} as place", place_ref);
}
}
}
mir::Place {
mir::PlaceRef {
base: mir::PlaceBase::Static(box mir::Static {
ty,
kind: mir::StaticKind::Promoted(promoted),
@ -485,7 +484,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
}
mir::Place {
mir::PlaceRef {
base: mir::PlaceBase::Static(box mir::Static {
ty,
kind: mir::StaticKind::Static(def_id),
@ -498,7 +497,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let static_ = bx.get_static(*def_id);
PlaceRef::new_thin_place(bx, static_, layout, layout.align.abi)
},
mir::Place {
mir::PlaceRef {
base,
projection: Some(box mir::Projection {
base: proj_base,
@ -506,19 +505,19 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}),
} => {
// Load the pointer from its location.
self.codegen_consume(bx, &mir::Place {
base: base.clone(),
projection: proj_base.clone(),
self.codegen_consume(bx, &mir::PlaceRef {
base,
projection: proj_base,
}).deref(bx.cx())
}
mir::Place {
mir::PlaceRef {
base,
projection: Some(projection),
} => {
// FIXME turn this recursion into iteration
let cg_base = self.codegen_place(bx, &mir::Place {
base: base.clone(),
projection: projection.base.clone(),
let cg_base = self.codegen_place(bx, &mir::PlaceRef {
base,
projection: &projection.base,
});
match projection.elem {
@ -573,13 +572,13 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
};
debug!("codegen_place(place={:?}) => {:?}", place, result);
debug!("codegen_place(place={:?}) => {:?}", place_ref, result);
result
}
pub fn monomorphized_place_ty(&self, place: &mir::Place<'tcx>) -> Ty<'tcx> {
pub fn monomorphized_place_ty(&self, place_ref: &mir::PlaceRef<'_, 'tcx>) -> Ty<'tcx> {
let tcx = self.cx.tcx();
let place_ty = place.ty(self.mir, tcx);
let place_ty = mir::Place::ty_from(place_ref.base, place_ref.projection, self.mir, tcx);
self.monomorphize(&place_ty.ty)
}
}

View File

@ -355,7 +355,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
mir::Rvalue::Ref(_, bk, ref place) => {
let cg_place = self.codegen_place(&mut bx, place);
let cg_place = self.codegen_place(&mut bx, &place.as_place_ref());
let ty = cg_place.layout.ty;
@ -446,7 +446,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
mir::Rvalue::Discriminant(ref place) => {
let discr_ty = rvalue.ty(&*self.mir, bx.tcx());
let discr = self.codegen_place(&mut bx, place)
let discr = self.codegen_place(&mut bx, &place.as_place_ref())
.codegen_get_discr(&mut bx, discr_ty);
(bx, OperandRef {
val: OperandValue::Immediate(discr),
@ -527,7 +527,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
// use common size calculation for non zero-sized types
let cg_value = self.codegen_place(bx, place);
let cg_value = self.codegen_place(bx, &place.as_place_ref());
return cg_value.len(bx.cx());
}

View File

@ -46,12 +46,12 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
}
} else {
let cg_dest = self.codegen_place(&mut bx, place);
let cg_dest = self.codegen_place(&mut bx, &place.as_place_ref());
self.codegen_rvalue(bx, cg_dest, rvalue)
}
}
mir::StatementKind::SetDiscriminant{ref place, variant_index} => {
self.codegen_place(&mut bx, place)
self.codegen_place(&mut bx, &place.as_place_ref())
.codegen_set_discr(&mut bx, variant_index);
bx
}
@ -73,7 +73,7 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
}
mir::StatementKind::InlineAsm(ref asm) => {
let outputs = asm.outputs.iter().map(|output| {
self.codegen_place(&mut bx, output)
self.codegen_place(&mut bx, &output.as_place_ref())
}).collect();
let input_vals = asm.inputs.iter()