Expand description
Rewrite final-use copies before return into moves.
§The problem
MIR building represents reads of values whose type is Copy using
Operand::Copy, including when such a local is returned. If that local’s
address has ever been observed, MoveElimination conservatively considers
it live until its StorageDead or function exit. This keeps the local live
across _0 = copy local, so its live range overlaps with the return place
and MoveElimination cannot unify the source local with _0.
§The solution
At function return, all local allocations are about to become invalid
anyway. After borrowck, this pass can therefore turn a final-use Copy into
a Move, as long as shortening the source local’s live range has no
observable effect before the return happens. Concretely, between the
transformed copy (now a move) and the return, there may only be writes to
unborrowed locals, storage markers, nops, and gotos.
§The algorithm
Start from every Return terminator, with _0 treated as used by the
return. Then scan predecessor blocks backward through Goto edges, forming
a return-tail tree. The scan maintains used_after, the set of locals
accessed later on that path.
A Copy operand is rewritten to a Move when its base local is not in
used_after. Then any locals touched by that operand, including
index-projection locals, are added to used_after before the backward scan
continues.
The scan stops when accessing an indirect place because that may access any borrowed local, which would make the pass unable to prove any useful final uses. It also stops at writes to borrowed locals, because those can create a new address-observed allocation range whose overlap with an earlier borrowed local must be preserved.
Structs§
Functions§
- process_
operand 🔒 - Process one operand in an rvalue.
- process_
rvalue 🔒 - Process the RHS of an assignment in a pure return tail.
- record_
place_ 🔒locals - Records all locals used in a place, including
Indexprojections inused_after. - scan_
block 🔒 - Scan a block backward while the return-tail invariant still holds.