Stream: t-compiler/wg-mir-opt

Topic: multiple return terminators


oli (Jul 13 2020 at 10:21, on Zulip):

So, there's one that I think is a good starting point implementation wise, but requires some discussion before exposing it to users. Implementing it will help the discussion as we can benchmark it and look at its effects in general. The optimization I'm talking about is https://github.com/rust-lang/rust/issues/72022

oli (Jul 13 2020 at 10:22, on Zulip):

We can easily set this new optimization to only run at mir-opt-level 3, which is where we keep our controversial or buggy optimizations

oli (Jul 13 2020 at 10:22, on Zulip):

(there are plans for making the bugginess explicit, but for now, we use mir-opt-level 3 for this)

oli (Jul 13 2020 at 10:22, on Zulip):

hmm... let me fork this discussion into a separate topic

oli (Jul 13 2020 at 10:27, on Zulip):

So, a first link to get you started: https://rustc-dev-guide.rust-lang.org/getting-started.html

oli (Jul 13 2020 at 10:27, on Zulip):

this is just about general rustc development

oli (Jul 13 2020 at 10:29, on Zulip):

you don't need to read all of it, but it helps you get the setup done and once you hit x.py in the guide, I'll give you some diverging instructions

Antoine Martin (Jul 13 2020 at 10:31, on Zulip):

alright, thanks for the pointers :) will clone rust and follow along

oli (Jul 13 2020 at 10:35, on Zulip):

What's usually done to work on mir optimizations is:

  1. build a rust source file in src/test/mir-opt that shows the code you want to optimize. Keep this simple, so no println! or other formatting infrastructure if not necessary for the optimization
  2. run ./x.py test --stage 1 --bless src/test/mir-opt in order to generate MIR dumps (read the readme in https://github.com/rust-lang/rust/tree/master/src/test/mir-opt for instructions on how to dump things)
    3 commit the current status

  3. implement a new optimization in src/librustc_mir/transform. Fastest way: pick a small optimization (e.g. https://github.com/rust-lang/rust/blob/master/src/librustc_mir/transform/no_landing_pads.rs) and copy it, add your optimization somewhere in https://github.com/rust-lang/rust/blob/e59b08e62ea691916d2f063cac5aab4634128022/src/librustc_mir/transform/mod.rs#L385, then start modifying your copied optimization

  4. Rerun the x.py command to regenerate the mir dumps and look at the diffs to see if they are what you expect
  5. Run ./x.py test --stage 1 --bless src/test/ui to see if your optimization broke anything
  6. Commit and open a PR (you can do this at any point, even if things aren't working yet, so you can ask for feedback on the PR. Open a WIP PR in that case)
Antoine Martin (Jul 13 2020 at 10:45, on Zulip):

so, making sure i'm understanding the optimization

it's something like

fn test() {
  if cond {
    // do stuff
  } else {
    // do stuff
  }

  return 42;
}

getting optimized to

fn test() {
  if cond {
    // do stuff
    return 42;
  } else {
    // do stuff
    return 42;
  }
}

(at a lower level of representation, of course)

which avoids the goto needed to skip else block if cond is true, for example

bjorn3 (Jul 13 2020 at 10:47, on Zulip):

Kind of the return value and the actual return are split at the MIR level. The first is an assignment of _0, while the latter is the Return terminator. This issue is only about moving the Return terminators.

bjorn3 (Jul 13 2020 at 10:50, on Zulip):
fn test(_1: bool) {
_0: ();
bb0 {
    SwitchInt(_1) -> [true: bb1, otherwise: bb2];
}
bb1 {
    // do stuff
    Goto bb3;
}
bb2 {
    // do stuff
    Goto bb3;
}
bb3 {
    Return;
}
}

->

fn test(_1: bool) {
_0: ();
bb0 {
    SwitchInt(_1) -> [true: bb1, otherwise: bb2];
}
bb1 {
    // do stuff
    Return;
}
bb2 {
    // do stuff
    Return;
}
}
Antoine Martin (Jul 13 2020 at 10:53, on Zulip):

makes sense

Antoine Martin (Jul 13 2020 at 11:16, on Zulip):

following the setup to build rustc, I'd like to point llvm-config in my config.toml to the system one to avoid recompiling it, but only llvm 10 and 9 are available as packages on my system. will that work with rustc ?

lcnr (Jul 13 2020 at 11:17, on Zulip):

I think so

Antoine Martin (Jul 27 2020 at 21:03, on Zulip):

finally getting time to work on this. opened draft PR here: https://github.com/rust-lang/rust/pull/74839

I've added a basic test file, which should optimize once I've implemented what's necessary

I'm not sure how the mir-opt tests work: I've ran ./x.py test --stage 1 --bless src/test/mir-opt and after searching for the produced mir dumps, I've found them in build/x86_64-unknown-linux-gnu/test/mir-opt/. But I don't really know which one I should look at, or if there's anything to do with those (yet ?). Should I now try implementing the optimization, then add a // EMIT_MIR rustc.test.MyNewFancyOpt.diff to my test file ?

Simon Vandel Sillesen (Jul 27 2020 at 21:07, on Zulip):

You can run a nighty compiler or stage 1 with the -Zmir-dump=<function name > on the test file. That should generate a folder with a file with before/after for each pass

Simon Vandel Sillesen (Jul 27 2020 at 21:08, on Zulip):

And when you have implemented the pass, you can add the emit_mir to the test file. The test suite should then run your pass on the test file and give you a diff

Antoine Martin (Jul 27 2020 at 21:14, on Zulip):

right, thanks ! I'll get started on the actual code then :)

oli (Jul 28 2020 at 06:18, on Zulip):

you can also add your optimization and make it not do anything. Then adding the diff comment will work, and show no changes.

oli (Jul 28 2020 at 06:19, on Zulip):

after you implement actual logic in your optimization, reblessing the test will then apply the changes

Antoine Martin (Aug 15 2020 at 17:45, on Zulip):

back from holiday, wrote a basic version of the optimization as I understand it :smile: I imagine the next step is to run an extensive test suite to make sure this didn't break anything ?

Antoine Martin (Aug 15 2020 at 18:14, on Zulip):

welp, looks like the codegen test suite did catch some problems, I'll look into it

Félix Fischer (Aug 15 2020 at 20:51, on Zulip):

yep, you got it, ideally if you feel that the feature is correct, you would run the test suites

Félix Fischer (Aug 15 2020 at 20:51, on Zulip):

and if all of them pass, you'd write tests for the new feature as well

Félix Fischer (Aug 15 2020 at 20:51, on Zulip):

:3

Antoine Martin (Oct 01 2020 at 12:56, on Zulip):

thanks for the help everyone, really glad my first contribution is merged :hug:

Last update: Jan 22 2021 at 13:15UTC