WebAssembly / WebAssembly/binaryen

Pure calls / future of call.without.effects

Open
#7,574 44 comments 0 reactions 0 assignees View on GitHub

Nobody has claimed this yet.

Dominant language
WebAssembly
Stars
8.6k
Forks
885
Avg merge
1d 19h
Merged PRs (30d)
69

Description

Atm we provide a way to say that a call has no side effects with an intrinsic, which is just an imported function:

https://github.com/WebAssembly/binaryen/blob/f03044981fad2c1c4d366485b25995c6b4bb4052/src/ir/intrinsics.h#L42-L56

The wasm spec has been adding similar code metadata in the form of branch hints and compilation hints. While call.without.effects is not meant to be used by VMs (it only make sense at the toolchain level), it may be nice to implement it similarly, to be consistent. That is, instead of the current intrinsic which is a specially-named function import, we could annotate the code the way those two proposals do:

  • In the text format, using custom annotations, something like:
(@metadata.code.pure "\00")
(call $target)
  • In the binary format, add a custom section, and the binary offsets there point to the instructions that are annotated.

The binary format takes more work this way - in particular, it is easy to get the offsets wrong - but it is more consistent with other things in wasm. Thoughts on the tradeoff?

Separately, there are two changes we may want to make to call.without.effects if we make a new version of it:

  • We can annotate the function itself (once) rather than all calls to it (many). That is, unless there are cases where some calls to the same target should be considered effect-free, but not others?
  • Atm call.without.effects only considers side effects (discussion), but it does not guarantee that it returns the same value for the same inputs. In particular, marking a call to a JS export that does Math.random() as call.without.effects would be wrong - two such calls cannot be folded together. We could make the new version also assume it returns the same value, and call it "pure", perhaps?

Contributor guide

Open the contributing guide

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 src/ir/intrinsics.h and the existing call.without.effects intrinsic, then review the linked branch-hinting and compilation-hints proposals. The issue needs a resolved design for text and binary annotations, function-versus-call scope, and whether purity guarantees identical results; done would be an agreed implementation plan.

Written by the indexing model from the issue text.

Assessment

Tech stack
wasm
Domain
compilers
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.