Alon Zakai / @kripken
June 2016
WebAssembly (wasm) is a new binary executable format
Will allow even large compiled codebases to run efficiently on the web, even better than asm.js
Main initial focus is on C and C++, since those are very popular (e.g., in the games space: Unity, Unreal, etc.), but not only
Binaryen is a compiler and toolchain library for WebAssembly, in C++
Read, write, and transform wasm
Used with clang+LLVM+emscripten for C/C++ ⇒ wasm
Does wasm minification, like we have minifiers for JavaScript, CSS, etc.
Does general-purpose optimizations like dead code elimination, etc.
Partial list of Binaryen's optimization passes
Port of Cube 2/Sauerbraten to the Web
Interesting real-world codebase, medium size game engine
Binaryen on unoptimized asm.js (straight from asm.js backend):
binaryen opts | no | yes | ||
binary size (MB) | 3.80 | 2.46 | -35% | |
time (seconds) | 2.98 | 3.60 |
(less is better on all)
Binaryen's general and wasm-specific optimizations can optimize the code quite a lot
Note wall time increases by just 21%
Binaryen on optimized asm.js (using emscripten's asm.js optimizer):
binaryen opts | no | yes | ||
binary size (MB) | 2.44 | 2.16 | -13% | |
time (seconds) | 1.63 | 2.13 |
Less of a benefit since code is already fairly optimized, but still significant
wasm-specific optimization matters, general optimizations are not enough
Binaryen is also fast
Minimal, compact data structures
E.g., no parent/context pointers; cache-friendly, fast to traverse
Less general optimization framework than e.g. LLVM, and in some cases things need to be recomputed (use lists)
But tradeoff often worth it (similar philosophy to the B3 JIT which replaced LLVM in WebKit)
Speed part 2: parallelism
LLVM is single-threaded
Binaryen can both build IR, and optimize it, using multiple cores
Can also pipeline: optimize ready functions while others are still being generated
In some cases might be worth using Binaryen as a full compiler backend, without LLVM or something else:
compiler  ⇒  Binaryen  ⇒  wasm
Binaryen optimizes and emits wasm, and does so very quickly
https://github.com/brson/mir2wasm
Rust  ⇒  Rust MIR  ⇒  Binaryen  ⇒  wasm
Very early stage, can emit some numerical operations
Expect to have very good codegen times
Help is welcome!
https://github.com/WebAssembly/binaryen
Binaryen aims to be a flexible, fast, and easy to use way for compilers to target WebAssembly
Let's get more code on the web!
That's it, thank you for listening :)