Skip to content

Commit 3fd4b22

Browse files
committed
Make maybe_codegen_consume_direct iterate instead of doing recursion
1 parent 50a0def commit 3fd4b22

File tree

1 file changed

+36
-34
lines changed

1 file changed

+36
-34
lines changed

Diff for: src/librustc_codegen_ssa/mir/operand.rs

+36-34
Original file line numberDiff line numberDiff line change
@@ -380,45 +380,47 @@ impl<'a, 'tcx: 'a, Bx: BuilderMethods<'a, 'tcx>> FunctionCx<'a, 'tcx, Bx> {
380380
) -> Option<OperandRef<'tcx, Bx::Value>> {
381381
debug!("maybe_codegen_consume_direct(place={:?})", place);
382382

383-
// watch out for locals that do not have an
384-
// alloca; they are handled somewhat differently
385-
if let mir::Place::Base(mir::PlaceBase::Local(index)) = *place {
386-
match self.locals[index] {
387-
LocalRef::Operand(Some(o)) => {
388-
return Some(o);
389-
}
390-
LocalRef::Operand(None) => {
391-
bug!("use of {:?} before def", place);
392-
}
393-
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
394-
// use path below
395-
}
396-
}
397-
}
383+
place.iterate(|place_base, place_projection| {
384+
if let mir::PlaceBase::Local(index) = place_base {
385+
match self.locals[*index] {
386+
LocalRef::Operand(Some(mut o)) => {
387+
// Moves out of scalar and scalar pair fields are trivial.
388+
for proj in place_projection {
389+
match proj.elem {
390+
mir::ProjectionElem::Field(ref f, _) => {
391+
o = o.extract_field(bx, f.index());
392+
}
393+
mir::ProjectionElem::Index(_) |
394+
mir::ProjectionElem::ConstantIndex { .. } => {
395+
// ZSTs don't require any actual memory access.
396+
// FIXME(eddyb) deduplicate this with the identical
397+
// checks in `codegen_consume` and `extract_field`.
398+
let elem = o.layout.field(bx.cx(), 0);
399+
if elem.is_zst() {
400+
o = OperandRef::new_zst(bx, elem);
401+
} else {
402+
return None;
403+
}
404+
}
405+
_ => return None,
406+
}
407+
}
398408

399-
// Moves out of scalar and scalar pair fields are trivial.
400-
if let &mir::Place::Projection(ref proj) = place {
401-
if let Some(o) = self.maybe_codegen_consume_direct(bx, &proj.base) {
402-
match proj.elem {
403-
mir::ProjectionElem::Field(ref f, _) => {
404-
return Some(o.extract_field(bx, f.index()));
409+
Some(o)
405410
}
406-
mir::ProjectionElem::Index(_) |
407-
mir::ProjectionElem::ConstantIndex { .. } => {
408-
// ZSTs don't require any actual memory access.
409-
// FIXME(eddyb) deduplicate this with the identical
410-
// checks in `codegen_consume` and `extract_field`.
411-
let elem = o.layout.field(bx.cx(), 0);
412-
if elem.is_zst() {
413-
return Some(OperandRef::new_zst(bx, elem));
414-
}
411+
LocalRef::Operand(None) => {
412+
bug!("use of {:?} before def", place);
413+
}
414+
LocalRef::Place(..) | LocalRef::UnsizedPlace(..) => {
415+
// watch out for locals that do not have an
416+
// alloca; they are handled somewhat differently
417+
None
415418
}
416-
_ => {}
417419
}
420+
} else {
421+
None
418422
}
419-
}
420-
421-
None
423+
})
422424
}
423425

424426
pub fn codegen_consume(

0 commit comments

Comments
 (0)