Make maybe_codegen_consume_direct iterate instead of doing recursion
This commit is contained in:
parent
50a0defd5a
commit
3fd4b22bce
@ -380,45 +380,47 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
|
||||
) -> Option<OperandRef<'tcx, Bx::Value>> {
|
||||
debug!("maybe_codegen_consume_direct(place={:?})", place);
|
||||
|
||||
// watch out for locals that do not have an
|
||||
// alloca; they are handled somewhat differently
|
||||
if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place {
|
||||
match self.locals[index] {
|
||||
LocalRef::Operand(Some(o)) => {
|
||||
return Some(o);
|
||||
}
|
||||
LocalRef::Operand(None) => {
|
||||
bug!("use of {:?} before def", place);
|
||||
}
|
||||
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
|
||||
// use path below
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Moves out of scalar and scalar pair fields are trivial.
|
||||
if let &mir::Place::Projection(ref proj) = place {
|
||||
if let Some(o) = self.maybe_codegen_consume_direct(bx, &proj.base) {
|
||||
match proj.elem {
|
||||
mir::ProjectionElem::Field(ref f, _) => {
|
||||
return Some(o.extract_field(bx, f.index()));
|
||||
}
|
||||
mir::ProjectionElem::Index(_) |
|
||||
mir::ProjectionElem::ConstantIndex { .. } => {
|
||||
// ZSTs don't require any actual memory access.
|
||||
// FIXME(eddyb) deduplicate this with the identical
|
||||
// checks in `codegen_consume` and `extract_field`.
|
||||
let elem = o.layout.field(bx.cx(), 0);
|
||||
if elem.is_zst() {
|
||||
return Some(OperandRef::new_zst(bx, elem));
|
||||
place.iterate(|place_base, place_projection| {
|
||||
if let mir::PlaceBase::Local(index) = place_base {
|
||||
match self.locals[*index] {
|
||||
LocalRef::Operand(Some(mut o)) => {
|
||||
// Moves out of scalar and scalar pair fields are trivial.
|
||||
for proj in place_projection {
|
||||
match proj.elem {
|
||||
mir::ProjectionElem::Field(ref f, _) => {
|
||||
o = o.extract_field(bx, f.index());
|
||||
}
|
||||
mir::ProjectionElem::Index(_) |
|
||||
mir::ProjectionElem::ConstantIndex { .. } => {
|
||||
// ZSTs don't require any actual memory access.
|
||||
// FIXME(eddyb) deduplicate this with the identical
|
||||
// checks in `codegen_consume` and `extract_field`.
|
||||
let elem = o.layout.field(bx.cx(), 0);
|
||||
if elem.is_zst() {
|
||||
o = OperandRef::new_zst(bx, elem);
|
||||
} else {
|
||||
return None;
|
||||
}
|
||||
}
|
||||
_ => return None,
|
||||
}
|
||||
}
|
||||
}
|
||||
_ => {}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
None
|
||||
Some(o)
|
||||
}
|
||||
LocalRef::Operand(None) => {
|
||||
bug!("use of {:?} before def", place);
|
||||
}
|
||||
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
|
||||
// watch out for locals that do not have an
|
||||
// alloca; they are handled somewhat differently
|
||||
None
|
||||
}
|
||||
}
|
||||
} else {
|
||||
None
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
pub fn codegen_consume(
|
||||
|
Loading…
Reference in New Issue
Block a user