diff options
| author | Santiago Pastorino <spastorino@gmail.com> | 2019-05-22 05:51:50 +0200 |
|---|---|---|
| committer | Santiago Pastorino <spastorino@gmail.com> | 2019-05-22 14:22:37 +0200 |
| commit | 3fd4b22bce195e5c12e478296c8e0c03de6c8331 (patch) | |
| tree | 1645a435d3c9b4152161b101ff60118f75111f56 /src | |
| parent | 50a0defd5a93523067ef239936cc2e0755220904 (diff) | |
| download | rust-3fd4b22bce195e5c12e478296c8e0c03de6c8331.tar.gz rust-3fd4b22bce195e5c12e478296c8e0c03de6c8331.zip | |
Make maybe_codegen_consume_direct iterate instead of doing recursion
Diffstat (limited to 'src')
| -rw-r--r-- | src/librustc_codegen_ssa/mir/operand.rs | 70 |
1 files changed, 36 insertions, 34 deletions
diff --git a/src/librustc_codegen_ssa/mir/operand.rs b/src/librustc_codegen_ssa/mir/operand.rs index 3b8e5b44953..3db05b7214d 100644 --- a/src/librustc_codegen_ssa/mir/operand.rs +++ b/src/librustc_codegen_ssa/mir/operand.rs @@ -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 - } - } - } + 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, + } + } - // 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())); + Some(o) } - 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)); - } + 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 } - } - - None + }) } pub fn codegen_consume( |
