mirror of
https://github.com/rust-lang/rust.git
synced 2024-10-30 14:01:51 +00:00
Use iterator instead of recursion in codegen_place
This commit is contained in:
parent
e2f6fb9996
commit
61ff847203
@ -429,87 +429,78 @@ impl<'a, 'tcx, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
let cx = self.cx;
|
||||
let tcx = self.cx.tcx();
|
||||
|
||||
let result = match place_ref {
|
||||
mir::PlaceRef { local, projection: [] } => match self.locals[local] {
|
||||
LocalRef::Place(place) => {
|
||||
return place;
|
||||
}
|
||||
LocalRef::UnsizedPlace(place) => {
|
||||
return bx.load_operand(place).deref(cx);
|
||||
}
|
||||
LocalRef::Operand(..) => {
|
||||
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 })
|
||||
let mut base = 0;
|
||||
let mut cg_base = match self.locals[place_ref.local] {
|
||||
LocalRef::Place(place) => place,
|
||||
LocalRef::UnsizedPlace(place) => bx.load_operand(place).deref(cx),
|
||||
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())
|
||||
}
|
||||
mir::PlaceRef { local, projection: &[ref proj_base @ .., elem] } => {
|
||||
// FIXME turn this recursion into iteration
|
||||
let cg_base =
|
||||
self.codegen_place(bx, mir::PlaceRef { local, projection: proj_base });
|
||||
|
||||
match elem {
|
||||
mir::ProjectionElem::Deref => bug!(),
|
||||
mir::ProjectionElem::Field(ref field, _) => {
|
||||
cg_base.project_field(bx, field.index())
|
||||
}
|
||||
mir::ProjectionElem::Index(index) => {
|
||||
let index = &mir::Operand::Copy(mir::Place::from(index));
|
||||
let index = self.codegen_operand(bx, index);
|
||||
let llindex = index.immediate();
|
||||
cg_base.project_index(bx, llindex)
|
||||
}
|
||||
mir::ProjectionElem::ConstantIndex {
|
||||
offset,
|
||||
from_end: false,
|
||||
min_length: _,
|
||||
} => {
|
||||
let lloffset = bx.cx().const_usize(offset as u64);
|
||||
cg_base.project_index(bx, lloffset)
|
||||
}
|
||||
mir::ProjectionElem::ConstantIndex {
|
||||
offset,
|
||||
from_end: true,
|
||||
min_length: _,
|
||||
} => {
|
||||
let lloffset = bx.cx().const_usize(offset as u64);
|
||||
let lllen = cg_base.len(bx.cx());
|
||||
let llindex = bx.sub(lllen, lloffset);
|
||||
cg_base.project_index(bx, llindex)
|
||||
}
|
||||
mir::ProjectionElem::Subslice { from, to, from_end } => {
|
||||
let mut subslice =
|
||||
cg_base.project_index(bx, bx.cx().const_usize(from as u64));
|
||||
let projected_ty =
|
||||
PlaceTy::from_ty(cg_base.layout.ty).projection_ty(tcx, elem).ty;
|
||||
subslice.layout = bx.cx().layout_of(self.monomorphize(projected_ty));
|
||||
|
||||
if subslice.layout.is_unsized() {
|
||||
assert!(from_end, "slice subslices should be `from_end`");
|
||||
subslice.llextra = Some(bx.sub(
|
||||
cg_base.llextra.unwrap(),
|
||||
bx.cx().const_usize((from as u64) + (to as u64)),
|
||||
));
|
||||
}
|
||||
|
||||
// Cast the place pointer type to the new
|
||||
// array or slice type (`*[%_; new_len]`).
|
||||
subslice.llval = bx.pointercast(
|
||||
subslice.llval,
|
||||
bx.cx().type_ptr_to(bx.cx().backend_type(subslice.layout)),
|
||||
);
|
||||
|
||||
subslice
|
||||
}
|
||||
mir::ProjectionElem::Downcast(_, v) => cg_base.project_downcast(bx, v),
|
||||
} else {
|
||||
bug!("using operand local {:?} as place", place_ref);
|
||||
}
|
||||
}
|
||||
};
|
||||
debug!("codegen_place(place={:?}) => {:?}", place_ref, result);
|
||||
result
|
||||
for elem in place_ref.projection[base..].iter() {
|
||||
cg_base = match elem.clone() {
|
||||
mir::ProjectionElem::Deref => bx.load_operand(cg_base).deref(bx.cx()),
|
||||
mir::ProjectionElem::Field(ref field, _) => {
|
||||
cg_base.project_field(bx, field.index())
|
||||
}
|
||||
mir::ProjectionElem::Index(index) => {
|
||||
let index = &mir::Operand::Copy(mir::Place::from(index));
|
||||
let index = self.codegen_operand(bx, index);
|
||||
let llindex = index.immediate();
|
||||
cg_base.project_index(bx, llindex)
|
||||
}
|
||||
mir::ProjectionElem::ConstantIndex { offset, from_end: false, min_length: _ } => {
|
||||
let lloffset = bx.cx().const_usize(offset as u64);
|
||||
cg_base.project_index(bx, lloffset)
|
||||
}
|
||||
mir::ProjectionElem::ConstantIndex { offset, from_end: true, min_length: _ } => {
|
||||
let lloffset = bx.cx().const_usize(offset as u64);
|
||||
let lllen = cg_base.len(bx.cx());
|
||||
let llindex = bx.sub(lllen, lloffset);
|
||||
cg_base.project_index(bx, llindex)
|
||||
}
|
||||
mir::ProjectionElem::Subslice { from, to, from_end } => {
|
||||
let mut subslice = cg_base.project_index(bx, bx.cx().const_usize(from as u64));
|
||||
let projected_ty =
|
||||
PlaceTy::from_ty(cg_base.layout.ty).projection_ty(tcx, elem.clone()).ty;
|
||||
subslice.layout = bx.cx().layout_of(self.monomorphize(projected_ty));
|
||||
|
||||
if subslice.layout.is_unsized() {
|
||||
assert!(from_end, "slice subslices should be `from_end`");
|
||||
subslice.llextra = Some(bx.sub(
|
||||
cg_base.llextra.unwrap(),
|
||||
bx.cx().const_usize((from as u64) + (to as u64)),
|
||||
));
|
||||
}
|
||||
|
||||
// Cast the place pointer type to the new
|
||||
// array or slice type (`*[%_; new_len]`).
|
||||
subslice.llval = bx.pointercast(
|
||||
subslice.llval,
|
||||
bx.cx().type_ptr_to(bx.cx().backend_type(subslice.layout)),
|
||||
);
|
||||
|
||||
subslice
|
||||
}
|
||||
mir::ProjectionElem::Downcast(_, v) => cg_base.project_downcast(bx, v),
|
||||
};
|
||||
}
|
||||
debug!("codegen_place(place={:?}) => {:?}", place_ref, cg_base);
|
||||
cg_base
|
||||
}
|
||||
|
||||
pub fn monomorphized_place_ty(&self, place_ref: mir::PlaceRef<'tcx>) -> Ty<'tcx> {
|
||||
|
Loading…
Reference in New Issue
Block a user