Can/Should we add an inlining pass -Copt-level=1

It does seem like an early pass for "trivial function elimination" could potentially be beneficial at low optimization levels (even potentially for optimized builds, w.r.t. code size).

To spec it very roughly,

  • Before any other inlining passes have run
  • For every "small" function
    • Where "small" could usefully be defined more aggressively than the standard inlining passes' definition as one of
      • Below some (small) threshold of IR statements
      • Below some (small) threshold of basic blocks
      • One of the above, but also has no unwind edges
        • (would require running after unwind edge elimination)
      • Any combination of the above
  • Replace calls to the function with the body of the function

Ideally this pass would run top-down to eliminate the most "trivial functions," which could later be dead code eliminated at higher opt levels. But if the threshold is tuned correctly (my initial idea was literally to cap it to a single basic block, or however many are required to just tail call a function with some argument shuffling) it may be equivalent either way.

Is this something that could be done by the MIR inliner? Doing this could even potentially e.g. remove the need to pass a bunch of monomorphizations of e.g. <&[T]>::into_iter calls to LLVM. If it's not too out there, I'm open to making this my first compiler contribution (as opposed to libs) if someone can mentor it. If we don't already have a pass similar to this it's definitely worth experimenting with. If we do already have a general inlining pass, we could experiment with a low threshold (the "trivial function" threshold) configuration of it run earlier, and additionally in -O1.

2 Likes

Until eventually cranelift becomes better at optimizing and we have -O1cf and -O1llvm :smiley:

Actually, the use case I was thinking of was iterator pipeline optimizations, so it wouldn't just be small functions. (or I guess you could mark collect methods as "entry-points" to the top-down inliner)

You want your first compiler contribution to be a new MIR optimization pass? Not to discourage you, but you're in for some pain :grin:

Inlining at -C opt-level=1 will be enabled once Rust switches to the new LLVM pass manager. We plan to do this switch after the upgrade to LLVM 13, as the new pass manager still has some issues in LLVM 12 (in particular it has a weak fat LTO pipeline). You can opt-in to the new behavior using -Z new-llvm-pass-manager.

7 Likes