WebAssembly / WebAssembly/tool-conventions

Toolchain optimization hints?

Open
#255 1 comment 2 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
WebAssembly
Stars
372
Forks
75
PR merge metrics
No merged PRs in 30d

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 unused

Normally 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 https://github.com/WebAssembly/binaryen/issues/7574#issuecomment-3017060458 , 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 == y

Of course, if we decide to write up these conventions here, we can pick a better names for everything.

Thoughts?

Contributor guide

No contributing guide indexed for this repository

First steps

  1. Read the whole issue, then the project's contributing guide.
  2. Comment on the issue to say you are picking it up — it saves two people doing the same work.
  3. Fork the repository and make your change on a branch.
  4. Open a pull request that references the issue number.

Research direction

Start with the WebAssembly branch-hinting and compilation-hints proposals, then read the linked Binaryen issue #7574 discussion and the examples of existing Binaryen annotations in this issue. Determine whether multiple toolchains need shared toolchain-level conventions and agree on their scope, semantics, and names; done means a reviewed convention proposal is accepted.

Written by the indexing model from the issue text.

Assessment

Tech stack
wasm
Domain
compilers, tooling
Issue type
Feature
Difficulty
5/5
Estimated time
Over a week
Activity status
Stale
Clarity
Needs clarification
Newbie friendliness
25/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.