Custom MIR -- howto add a PlaceAlias instruction

Hello,

For a research project, I want a MIR program transformation that creates a place alias after every mutable borrow such that subsequent borrows use the new alias. For example:

Before:

_2 = &mut _1
foo(_2)
_3 = &_1
bar(_3)

After:

_2 = &mut _1
_3 = mk_place_alias(_1)
foo(_2)
_4 = &_3
bar(_4)

Lowering to LLVM IR:

%_1 = alloca ..
call foo(%_1) 
%_3 = intrinsic_mk_place_alias(%_1)
call bar(%_3)

How do I go about adding this?

  1. I would assume that mk_place_alias has to be special cased in borrowck code (like retag) to be ignored or alternatively be added after borrowck.
  2. Should this instruction be put into MIR from the start or can it be added in a later dialect/phase? For a later phase how would I go about replaceAllUsesOfPlaceWithAlias(...)? Are there examples of this?
  3. Other thoughts?

thank you

1 Like

MirPatch in rustc_middle::mir::patch - Rust is your friend if you need to add statements in a bunch of places.

Do you really need to have the locals like that?

Your life would be way easier if you rewrote to

_400 = &mut _1
_2 = mk_place_alias(_400)

instead, since then you don't need to renumber everything else. (Where _400 is the Local you get from https://doc.rust-lang.org/nightly/nightly-rustc/rustc_index/struct.IndexVec.html#method.push on the local_decls.)

(If you want it renumbered for human reading convenience, you can use -Zmir-enable-passes=+ReorderLocals -- there's an existing pass to renumber everything.)

Thanks for the MirPatch pointer!

I believe so. I want to represent that a &mut creates a borrow and redefines the place in MIR syntax.

The (above) snippet is the end goal. My current understanding is that this LLVM code is straightforward to generate if I change the semantics of borrow in MIR itself.