summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--README.md112
1 files changed, 102 insertions, 10 deletions
diff --git a/README.md b/README.md
index 83a742071..238670b4e 100644
--- a/README.md
+++ b/README.md
@@ -16,15 +16,13 @@ effective**:
cores. Binaryen's IR also compiles down to WebAssembly extremely easily and
quickly because it is essentially a subset of WebAssembly.
- * **Effective**: Binaryen's optimizer has many [passes] that can improve code
- very significantly (e.g. local coloring to coalesce local variables; dead
- code elimination; precomputing expressions when possible at compile time;
- etc.). These optimizations aim to make Binaryen powerful enough to be used as
- a [compiler backend][backend] by itself. One specific area of focus is on
- WebAssembly-specific optimizations (that general-purpose compilers might not
- do), which you can think of as wasm [minification] , similar to minification
- for JavaScript, CSS, etc., all of which are language-specific (an example of
- such an optimization is block return value generation in `SimplifyLocals`).
+ * **Effective**: Binaryen's optimizer has many passes (see an overview later
+ down) that can improve code size and speed. These optimizations aim to make
+ Binaryen powerful enough to be used as a [compiler backend][backend] by
+ itself. One specific area of focus is on WebAssembly-specific optimizations
+ (that general-purpose compilers might not do), which you can think of as
+ wasm [minification], similar to minification for JavaScript, CSS, etc., all
+ of which are language-specific.
Compilers using Binaryen include:
@@ -173,6 +171,101 @@ This repository contains code that builds the following tools in `bin/`:
Usage instructions for each are below.
+## Binaryen Optimizations
+
+Binaryen contains
+[a lot of optimization passes](https://github.com/WebAssembly/binaryen/tree/master/src/passes)
+to make WebAssembly smaller and faster. You can run the Binaryen optimizer by
+using ``wasm-opt``, but also they can be run while using other tools, like
+``wasm2js`` and ``wasm-metadce``.
+
+* The default optimization pipeline is set up by functions like
+ [`addDefaultFunctionOptimizationPasses`](https://github.com/WebAssembly/binaryen/blob/369b8bdd3d9d49e4d9e0edf62e14881c14d9e352/src/passes/pass.cpp#L396).
+* There are various
+ [pass options](https://github.com/WebAssembly/binaryen/blob/369b8bdd3d9d49e4d9e0edf62e14881c14d9e352/src/pass.h#L85)
+ that you can set, to adjust the optimization and shrink levels, whether to
+ ignore unlikely traps, inlining heuristics, fast-math, and so forth. See
+ ``wasm-opt --help`` for how to set them and other details.
+
+See each optimization pass for details of what it does, but here is a quick
+overview of some of the relevant ones:
+
+* **CoalesceLocals** - Key “register allocation” pass. Does a live range
+ analysis and then reuses locals in order to minimize their number, as well as
+ to remove copies between them.
+* **CodeFolding** - Avoids duplicate code by merging it (e.g. if two `if` arms
+ have some shared instructions at their end).
+* **CodePushing** - “Pushes” code forward past branch operations, potentially
+ allowing the code to not be run if the branch is taken.
+* **DeadArgumentElimination** - LTO pass to remove arguments to a function if it
+ is always called with the same constants.
+* **DeadCodeElimination**
+* **Directize** - Turn an indirect call into a normal call, when the table index
+ is constant.
+* **DuplicateFunctionElimination** - LTO pass.
+* **Inlining** - LTO pass.
+* **LocalCSE** - Simple local common subexpression elimination.
+* **LoopInvariantCodeMotion**
+* **MemoryPacking** - Key "optimize data segments" pass that combines segments,
+ removes unneeded parts, etc.
+* **MergeBlocks** - Merge a `block` to an outer one where possible, reducing
+ their number.
+* **MergeLocals** - When two locals have the same value in part of their
+ overlap, pick in a way to help CoalesceLocals do better later (split off from
+ CoalesceLocals to keep the latter simple).
+* **MinifyImportsAndExports** - Minifies them to “a”, “b”, etc.
+* **OptimizeAddedConstants** - Optimize a load/store with an added constant into
+ a constant offset.
+* **OptimizeInstructions** - Key peephole optimization pass with a constantly
+ increasing list of patterns.
+* **PickLoadSigns** - Adjust whether a load is signed or unsigned in order to
+ avoid sign/unsign operations later.
+* **Precompute** - Calculates constant expressions at compile time, using the
+ built-in interpreter (which is guaranteed to be able to handle any constant
+ expression).
+* **ReReloop** - Transforms wasm structured control flow to a CFG and then goes
+ back to structured form using the Relooper algorithm, which may find more
+ optimal shapes.
+* **RedundantSetElimination** - Removes a `local.set` of a value that is already
+ present in a local. (Overlaps with CoalesceLocals; this achieves the specific
+ operation just mentioned without all the other work CoalesceLocals does, and
+ therefore is useful in other places in the optimization pipeline.)
+* **RemoveUnsedBrs** - Key “minor control flow optimizations” pass, including
+ jump threading and various transforms that can get rid of a `br` or `br_table`
+ (like turning a `block` with a `br` in the middle into an `if` when possible).
+* **RemoveUnusedModuleElements** - “Global DCE”, an LTO pass that removes
+ imports, functions, globals, etc., when they are not used.
+* **ReorderFunctions** - Put more-called functions first, potentially allowing
+ the LEB emitted to call them to be smaller (in a very large program).
+* **ReorderLocals** - Put more-used locals first, potentially allowing the LEB
+ emitted to use them to be smaller (in a very large function). After the
+ sorting, it also removes locals not used at all.
+* **SimplifyGlobals** - Optimizes globals in various ways, for example,
+ coalescing them, removing mutability from a global never modified, applying a
+ constant value from an immutable global, etc.
+* **SimplifyLocals** - Key “`local.get/set/tee`” optimization pass, doing things
+ like replacing a set and a get with moving the set’s value to the get (and
+ creating a tee) where possible. Also creates `block/if/loop` return values
+ instead of using a local to pass the value.
+* **Vacuum** - Key “remove silly unneeded code” pass, doing things like removing
+ an `if` arm that has no contents, a drop of a constant value with no side
+ effects, a `block` with a single child, etc.
+
+“LTO” in the above means an optimization is Link Time Optimization-like in that
+it works across multiple functions, but in a sense Binaryen is always “LTO” as
+it usually is run on the final linked wasm.
+
+Advanced optimization techniques in the Binaryen optimizer include
+[SSAification](https://github.com/WebAssembly/binaryen/blob/master/src/passes/SSAify.cpp),
+[Flat IR](https://github.com/WebAssembly/binaryen/blob/master/src/ir/flat.h), and
+[Stack/Poppy IR](https://github.com/WebAssembly/binaryen/blob/master/src/ir/stack-utils.h).
+
+Binaryen also contains various passes that do other things than optimizations,
+like
+[legalization for JavaScript](https://github.com/WebAssembly/binaryen/blob/master/src/passes/LegalizeJSInterface.cpp),
+[Asyncify](https://github.com/WebAssembly/binaryen/blob/master/src/passes/Asyncify.cpp),
+etc.
+
## Building
```
@@ -396,7 +489,6 @@ would be appreciated on Windows and OS X as most of the core devs are on Linux.
[control flow graph]: https://github.com/WebAssembly/binaryen/wiki/Compiling-to-WebAssembly-with-Binaryen#cfg-api
[JS_API]: https://github.com/WebAssembly/binaryen/wiki/binaryen.js-API
[compile_to_wasm]: https://github.com/WebAssembly/binaryen/wiki/Compiling-to-WebAssembly-with-Binaryen#what-do-i-need-to-have-in-order-to-use-binaryen-to-compile-to-webassembly
-[passes]: https://github.com/WebAssembly/binaryen/tree/master/src/passes
[backend]: https://kripken.github.io/talks/binaryen.html#/9
[minification]: https://kripken.github.io/talks/binaryen.html#/2
[unreachable]: https://github.com/WebAssembly/binaryen/issues/903