Avoid cloning Place in codegen_place
This commit is contained in:
parent
e11adb13b6
commit
438aeb8ca3
@ -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`).
|
||||
|
@ -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);
|
||||
}
|
||||
}
|
||||
|
@ -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) => {
|
||||
|
@ -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)
|
||||
}
|
||||
}
|
||||
|
@ -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());
|
||||
}
|
||||
|
||||
|
@ -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()
|
||||
|
Loading…
x
Reference in New Issue
Block a user