WebAssembly / WebAssembly/binaryen

Global store-to-load forwarding

Open
#8,691 6 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

This is similar to https://github.com/WebAssembly/binaryen/issues/8016 & https://github.com/WebAssembly/binaryen/issues/8002

See this repro.tar.gz. The optimized version was obtained via open world compilation

% wasm-opt \
  --enable-gc --enable-reference-types --enable-multivalue --enable-exception-handling --enable-nontrapping-float-to-int \
  --enable-sign-ext --enable-bulk-memory --enable-threads \
 --enable-simd '--no-inline=*<noInline>*' --traps-never-happen \
  -g -Os -Os -Os \
  repro.wasm -o repro.opt.wasm

It leaves the following behind

  (type $JSExternWrapper (sub $Object (struct
    (field $field0 i32)
    (field $field1 (mut i32))
    (field $_externRef externref))))

  (global $.a (import "" "a") (ref extern))
  (global $"C284 \"a\"" (ref $JSExternWrapper) (i32.const 97) (i32.const 0) (global.get $.a) (struct.new $JSExternWrapper))

  (func $"findExact <noInline>" (param $var0 (ref $JSExternWrapper)) (result i64)
    (local $var1 (ref $JSExternWrapper))
    block $label0
      block $label1
        block $label2
          block $label3 (result i32)
            block $label4
              global.get $"C284 \"a\""
              local.tee $var1
              struct.get $JSExternWrapper $field0
              i32.const 97
              i32.ne
              br_if $label4
              local.get $var0
              struct.get $JSExternWrapper $_externRef
              local.get $var1
              struct.get $JSExternWrapper $_externRef
              call $"wasm:js-string.equals (import)"
              i32.eqz
              br_if $label4
              i32.const 1
              br $label3
            end $label4
            i32.const 0
          end $label3
          i32.eqz

Notice that the

  • $C284 global is a non mutable global with known values being initialized
  • $JSExternWrapper.$field0 is a non mutable i32 field
    Therefore the
              global.get $"C284 \"a\""
              local.tee $var1
              struct.get $JSExternWrapper $field0

should be turned into

              i32.const 97

and the

              local.get $var1
              struct.get $JSExternWrapper $_externRef

should be turned into

             global.get $.a

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 by unpacking repro.tar.gz and running the provided wasm-opt command with the listed feature flags. Compare the resulting WAT with the requested transformations and read related issues 8016 and 8002. Done means the immutable global and struct-field loads are forwarded to the shown constants and imported global without changing behavior.

Written by the indexing model from the issue text.

Assessment

Tech stack
wasm
Domain
compilers, performance
Issue type
Bug
Difficulty
4/5
Estimated time
3-5 days
Activity status
Quiet
Clarity
Mostly clear
Newbie friendliness
46/100

Get new issues in your inbox

A short digest of beginner-friendly GitHub issues.