Superoptimizer #900

Closed
wants to merge 7 commits into
from

Conversation

Projects
None yet
2 participants
@kripken
Member

kripken commented Feb 8, 2017

This adds a wasm-analyze tool that looks at a set of input files and runs a superoptimizer to find possible optimizations to suggest should be written. The general idea is based on Bansal & Aiken (2006), "Automatic Generation of Peephole Superoptimizers". In more detail:

  • Each input expression is normalized.
  • We compute a hash for each expression, based on running it (in our interpreter) on multiple inputs. The result is that expressions that are functionally identical should have identical hashes, but hopefully not others.
  • Find hash matches between different expressions.
  • Using additional brute force, try to rule out false matches (more effort than we expend in hashing, for time purposes).
  • Check if matches are interesting: run our optimizer on the input, and see that we don't already do better. What are left are possible suggested optimizations.
  • Group them by general patterns, ignoring things like specific constants (which would make the input noisy and long-tailed).
  • Sort them by the impact they would make on the inputs (i.e. improvement per instance * number of instances seen).
  • Present the sorted list. Hopefully, at the top of the list are optimizations we should add.

So far this is not much tuned, but already suggests a few new optimizations worth adding. I haven't gotten to that yet.

kripken added some commits Feb 7, 2017

add a superoptimizer-using wasm-analyze tool. this reasons about the …
…code it is shown, finding patters that it believe are valid optimizations, and suggesting them based on their importance/predicted impact
@kripken

This comment has been minimized.

Show comment
Hide comment
@kripken

kripken Feb 8, 2017

Member

See test.wast and test.txt for an example of this in use. The superoptimizer suggests the optimization rule (x << 1) << 1 => x << 2.

Member

kripken commented Feb 8, 2017

See test.wast and test.txt for an example of this in use. The superoptimizer suggests the optimization rule (x << 1) << 1 => x << 2.

@baptistemanson

This comment has been minimized.

Show comment
Hide comment
@baptistemanson

baptistemanson Feb 8, 2017

I'm curious and would like to ask you a question, if you excuse my ignorance.
Why did you decide to have the superoptimizer running on the wast? And not on the LLVM representation?

baptistemanson commented Feb 8, 2017

I'm curious and would like to ask you a question, if you excuse my ignorance.
Why did you decide to have the superoptimizer running on the wast? And not on the LLVM representation?

@kripken

This comment has been minimized.

Show comment
Hide comment
@kripken

kripken Feb 8, 2017

Member

Well, LLVM is just one thing that can produce wasm. Binaryen's optimizer should be able to optimize any wasm from any compiler, so having a superoptimizer here would benefit all those. Not many exist yet, of course, but hopefully they will.

I also think it's convenient to superoptimize in Binaryen - the technique used here requires the ability to execute code, which is trivial in Binaryen (using the built-in interpreter), but not practical in LLVM.

Member

kripken commented Feb 8, 2017

Well, LLVM is just one thing that can produce wasm. Binaryen's optimizer should be able to optimize any wasm from any compiler, so having a superoptimizer here would benefit all those. Not many exist yet, of course, but hopefully they will.

I also think it's convenient to superoptimize in Binaryen - the technique used here requires the ability to execute code, which is trivial in Binaryen (using the built-in interpreter), but not practical in LLVM.

@kripken

This comment has been minimized.

Show comment
Hide comment
@kripken

kripken Feb 12, 2017

Member

Ok, running the superoptimizer, it found a bunch of things missing in our optimizer, which I implemented in the 4 linked PRs (details in each one).

The total benefits of those PRs:

  • Code size is reduced by mostly around 0.5%, however some codebases benefit more significantly, such as Lua by 1.0%. Unity shrinks by 0.7%.
  • Most benchmarks don't benefit, but there are a few with 0.5%-1.0% speedups, and a few benefit more significantly, notably lua-scimark is 3% faster and bullet is 2% faster.

Those PRs seem to cover most of what the superoptimizer finds for now - we'll need to improve it to find more, lots of TODOs in the superoptimizer source, it's really very naive so far. Nice that even with such a simple superoptimizer we can find useful improvements.

As for this PR itself, for me personally it would be convenient to merge it, but possibly not worth it to increase build times for everyone, it could stay on this side branch. Thoughts?

Member

kripken commented Feb 12, 2017

Ok, running the superoptimizer, it found a bunch of things missing in our optimizer, which I implemented in the 4 linked PRs (details in each one).

The total benefits of those PRs:

  • Code size is reduced by mostly around 0.5%, however some codebases benefit more significantly, such as Lua by 1.0%. Unity shrinks by 0.7%.
  • Most benchmarks don't benefit, but there are a few with 0.5%-1.0% speedups, and a few benefit more significantly, notably lua-scimark is 3% faster and bullet is 2% faster.

Those PRs seem to cover most of what the superoptimizer finds for now - we'll need to improve it to find more, lots of TODOs in the superoptimizer source, it's really very naive so far. Nice that even with such a simple superoptimizer we can find useful improvements.

As for this PR itself, for me personally it would be convenient to merge it, but possibly not worth it to increase build times for everyone, it could stay on this side branch. Thoughts?

@kripken

This comment has been minimized.

Show comment
Hide comment
@kripken

kripken Feb 17, 2017

Member

Let's close this, the optimizations from this are helpful, but probably not much sense in getting the superoptimizer itself in-tree. It can stay in a side branch.

Member

kripken commented Feb 17, 2017

Let's close this, the optimizations from this are helpful, but probably not much sense in getting the superoptimizer itself in-tree. It can stay in a side branch.

@kripken kripken closed this Feb 17, 2017

@kripken kripken referenced this pull request in google/souper Apr 22, 2018

Open

Operate on WebAssembly? #323

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment