-
Notifications
You must be signed in to change notification settings - Fork 74
Description
Wasm now has branch hints (whether a branch is likely or unlikely) and compilation hints (whether code is hot, cold, etc.). Those hints are for wasm VMs. This issue is about writing up some form of convention for toolchain optimizations (which VMs would not care about, so this repo is probably the only place that makes sense).
Concretely, we have annotated code in a few ways in the Binaryen optimizer for a while, and that is used by various toolchains (Java, Dart, etc.), including features like:
- Assume a call has no side effects, allowing it to be removed if the result is unused. For example
x = getX();
bar(x.y);Imagine that we optimize away the last line (perhaps bar is an empty function after other optimizations), leaving
x = getX();
// x is unusedNormally we cannot remove that call to getX() if it has side effects, and perhaps it allocates some global object there the first time it is called for. When annotated as "no side effects", we can remove it. That is, the hint tells the optimizer that it can do more than the wasm semantics allow.
- Assume code does not trap (so paths leading to traps can be ignored/removed). This is a global flag in Binaryen atm (but could be function-level in theory).
We are considering some changes to our intrinsics, to build them around wasm code annotations, see discussion in WebAssembly/binaryen#7574 (comment) , and the question came up, is there interest in writing up such conventions at a higher level than Binaryen? That is what this issue is for.
That is, would other toolchains - producers, analyzers, optimizers, etc. - be interested to use such toolchain-focused optimization flags? Note that Binaryen's hints are used across toolchains already, in the sense that e.g. Java emits them and Binaryen optimizes with them, so I think we have some evidence of general usefulness.
If it helps, the current thinking in that Binaryen thread is to define something like these annotations, on functions:
@binaryen.no.side.effects- toolchain optimizer can assume this has no side effects, as in the example above.@binaryen.idempotent- toolchain optimizer can assume that subsequent calls to this do nothing at all / return the same result as before, allowing the following:
idempotent();
idempotent();
=> // any call after the first is removable
idempotent();x = idempotent();
y = idempotent();
// x == yOf course, if we decide to write up these conventions here, we can pick a better names for everything.
Thoughts?