1
Fork 0

Rollup merge of #91278 - SparrowLii:place, r=spastorino

Use iterator instead of recursion in `codegen_place`

This PR fixes the FIXME in `codegen_place` about using iterator instead of recursion when processing the `projection` field in `mir::PlaceRef`. At the same time, it also reduces the right drift.
This commit is contained in:
Matthias Krüger 2022-01-19 10:42:14 +01:00 committed by GitHub
commit 3a1db90efb
No known key found for this signature in database
GPG key ID: 4AEE18F83AFDEB23

View file

@ -429,30 +429,31 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let cx = self.cx; let cx = self.cx;
let tcx = self.cx.tcx(); let tcx = self.cx.tcx();
let result = match place_ref { let mut base = 0;
mir::PlaceRef { local, projection: [] } => match self.locals[local] { let mut cg_base = match self.locals[place_ref.local] {
LocalRef::Place(place) => { LocalRef::Place(place) => place,
return place; LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
}
LocalRef::UnsizedPlace(place) => {
return bx.load_operand(place).deref(cx);
}
LocalRef::Operand(..) => { LocalRef::Operand(..) => {
if let Some(elem) = place_ref
.projection
.iter()
.enumerate()
.find(|elem| matches!(elem.1, mir::ProjectionElem::Deref))
{
base = elem.0 + 1;
self.codegen_consume(
bx,
mir::PlaceRef { projection: &place_ref.projection[..elem.0], ..place_ref },
)
.deref(bx.cx())
} else {
bug!("using operand local {:?} as place", place_ref); bug!("using operand local {:?} as place", place_ref);
} }
},
mir::PlaceRef { local, projection: [proj_base @ .., mir::ProjectionElem::Deref] } => {
// Load the pointer from its location.
self.codegen_consume(bx, mir::PlaceRef { local, projection: proj_base })
.deref(bx.cx())
} }
mir::PlaceRef { local, projection: &[ref proj_base @ .., elem] } => { };
// FIXME turn this recursion into iteration for elem in place_ref.projection[base..].iter() {
let cg_base = cg_base = match elem.clone() {
self.codegen_place(bx, mir::PlaceRef { local, projection: proj_base }); mir::ProjectionElem::Deref => bx.load_operand(cg_base).deref(bx.cx()),
match elem {
mir::ProjectionElem::Deref => bug!(),
mir::ProjectionElem::Field(ref field, _) => { mir::ProjectionElem::Field(ref field, _) => {
cg_base.project_field(bx, field.index()) cg_base.project_field(bx, field.index())
} }
@ -462,29 +463,20 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
let llindex = index.immediate(); let llindex = index.immediate();
cg_base.project_index(bx, llindex) cg_base.project_index(bx, llindex)
} }
mir::ProjectionElem::ConstantIndex { mir::ProjectionElem::ConstantIndex { offset, from_end: false, min_length: _ } => {
offset,
from_end: false,
min_length: _,
} => {
let lloffset = bx.cx().const_usize(offset as u64); let lloffset = bx.cx().const_usize(offset as u64);
cg_base.project_index(bx, lloffset) cg_base.project_index(bx, lloffset)
} }
mir::ProjectionElem::ConstantIndex { mir::ProjectionElem::ConstantIndex { offset, from_end: true, min_length: _ } => {
offset,
from_end: true,
min_length: _,
} => {
let lloffset = bx.cx().const_usize(offset as u64); let lloffset = bx.cx().const_usize(offset as u64);
let lllen = cg_base.len(bx.cx()); let lllen = cg_base.len(bx.cx());
let llindex = bx.sub(lllen, lloffset); let llindex = bx.sub(lllen, lloffset);
cg_base.project_index(bx, llindex) cg_base.project_index(bx, llindex)
} }
mir::ProjectionElem::Subslice { from, to, from_end } => { mir::ProjectionElem::Subslice { from, to, from_end } => {
let mut subslice = let mut subslice = cg_base.project_index(bx, bx.cx().const_usize(from as u64));
cg_base.project_index(bx, bx.cx().const_usize(from as u64));
let projected_ty = let projected_ty =
PlaceTy::from_ty(cg_base.layout.ty).projection_ty(tcx, elem).ty; PlaceTy::from_ty(cg_base.layout.ty).projection_ty(tcx, elem.clone()).ty;
subslice.layout = bx.cx().layout_of(self.monomorphize(projected_ty)); subslice.layout = bx.cx().layout_of(self.monomorphize(projected_ty));
if subslice.layout.is_unsized() { if subslice.layout.is_unsized() {
@ -505,11 +497,10 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
subslice subslice
} }
mir::ProjectionElem::Downcast(_, v) => cg_base.project_downcast(bx, v), mir::ProjectionElem::Downcast(_, v) => cg_base.project_downcast(bx, v),
}
}
}; };
debug!("codegen_place(place={:?}) => {:?}", place_ref, result); }
result debug!("codegen_place(place={:?}) => {:?}", place_ref, cg_base);
cg_base
} }
pub fn monomorphized_place_ty(&self, place_ref: mir::PlaceRef<'tcx>) -> Ty<'tcx> { pub fn monomorphized_place_ty(&self, place_ref: mir::PlaceRef<'tcx>) -> Ty<'tcx> {