Topic: MIR 2.0 and MIR Optimizations
compiler team
Key People
eddyb, nikomatsakis, pnkfelix, rjung, oli-obk
Wednesday, 11:00-13:00
Meeting Style
  • Sketch for any changes to MIR
  • List of optimizations we would like to do, in what order, and example benefits we expect
Homework to do before meeting
  • jrmuizel: "the biggest problem is probably eliminating memmoves across basic blocks” (#56172)
  • jrmuizel: “we’ve also seen problems with llvm not eliminating memmoves inside of basic blocks” (#56191) 
  • Currently WebRender folks are using the memcpy-find tool to scan the assembly and hand-edit Rust code to eliminate “moves”, rewriting to use &mut or *mut etc.
  • The first two feel to me like the reason we want placement new, with jrmuizel basically doing it by hand.

  • What were its goals, in terms of code patterns to optimize?
  • What problems were encountered?
  • Would it have affected #56172?
  • MIR Review
  • Maybe give an overview of what passes and transitions we do today
  • Should all of these things operate on MIR? Should we have another intermediate form?
  • Significant phases:

  • MIR 2.0-related proposals
  • Shallow: Modification to flatten places (PR#53247)
  • Not a “deep change”, just a plan to change places from a recursive structure to a “flat structure”:
  • struct Place { base: PlaceBase, projections: &[PlaceProjection] }
  • The PR itself has been going for some time, but with some effort could definitely be landed
  • (eddyb) sadly the PR started off with
  • a really expensive approach of constructing shallow versions of the old recursive structures
  • and reinterning a lot instead of slicing/iterating projection lists (which is what the recursive code would’ve done had it been written for a flat structure),
  • and I didn’t have the time to mentor it - might have to redo some or all of it :(
  • Simplifies a lot of things
  • Shallow: Move towards “stable identifiers”  to make MIR more easily editable
  • Right now we use a lot of “absolute indices” like BasicBlock etc
  • This means that if you remove a basic block, you have to adjust all the numbering
  • Some form of “stable identifiers” would be better — e.g.,
  • leaving tombstones,
  • or having some indirection, etc
  • e.g. some of the simplifycfg code already treats BasicBlock and Local as a stable identifier (by “tombstoning over” dead blocks, and relying on Simplify to “do a GC”).
  • See also the Cranelift structure <needs link>
  • Deep: Notes on eddyb’s MIR 2.0 goals and thoughts?
  • Instead of embedding complex Place into the IR, build up through some form of statements. So e.g. instead of Op((*a.b.c).d.e) you might have:
  • tmp = &*(a.b.c) (copy/reborrow of a.b.c)
  • Op((*tmp).d.e)
  • These would not be “real borrows” but some kind of pseudo-borrows that the borrow checker knows how to treat specially