Removes non-static locals collection (#2236)

This stops gathering `NonStaticLocals` during validation phase,
which was previously used to do the "fast pass" on variable search
by the frontend. However, it had no impact after the last mile refactoring
included in 1.7.0 and caused tons of allocations.

As as result, you can see the compilation perf improvements especially
around memory pressure without any impacts on the runtime perf

### Zig 
```
goos: darwin
goarch: arm64
pkg: github.com/tetratelabs/wazero/internal/integration_test/stdlibs
                             │ old_zig.txt │           new_zig.txt            │
                             │   sec/op    │   sec/op    vs base              │
Zig/Compile/test-opt.wasm-10    3.769 ± 1%   3.761 ± 1%       ~ (p=0.485 n=6)
Zig/Run/test-opt.wasm-10        18.78 ± 1%   18.74 ± 0%  -0.21% (p=0.041 n=6)
Zig/Compile/test.wasm-10        4.677 ± 1%   4.515 ± 0%  -3.48% (p=0.002 n=6)
Zig/Run/test.wasm-10            19.31 ± 1%   19.27 ± 1%       ~ (p=1.000 n=6)
geomean                         8.942        8.850       -1.04%

                             │ old_zig.txt  │            new_zig.txt             │
                             │     B/op     │     B/op      vs base              │
Zig/Compile/test-opt.wasm-10   394.7Mi ± 0%   393.5Mi ± 0%  -0.30% (p=0.002 n=6)
Zig/Run/test-opt.wasm-10       741.7Mi ± 0%   741.7Mi ± 0%       ~ (p=0.621 n=6)
Zig/Compile/test.wasm-10       659.5Mi ± 0%   599.3Mi ± 0%  -9.12% (p=0.002 n=6)
Zig/Run/test.wasm-10           1.296Gi ± 0%   1.296Gi ± 0%       ~ (p=0.102 n=6)
geomean                        711.5Mi        694.2Mi       -2.44%

                             │ old_zig.txt │            new_zig.txt             │
                             │  allocs/op  │  allocs/op   vs base               │
Zig/Compile/test-opt.wasm-10   362.6k ± 0%   343.2k ± 0%   -5.34% (p=0.002 n=6)
Zig/Run/test-opt.wasm-10       51.58k ± 0%   51.58k ± 0%        ~ (p=0.978 n=6)
Zig/Compile/test.wasm-10       514.7k ± 0%   288.1k ± 0%  -44.04% (p=0.002 n=6)
Zig/Run/test.wasm-10           2.156M ± 0%   2.156M ± 0%        ~ (p=0.273 n=6)
geomean                        379.5k        323.8k       -14.69%
```

### TinyGo
```
goos: darwin
goarch: arm64
pkg: github.com/tetratelabs/wazero/internal/integration_test/stdlibs
                                      │ old_tinygo.txt │            new_tinygo.txt             │
                                      │     sec/op     │    sec/op      vs base                │
TinyGo/Compile/container_heap.test-10    410.8m ± 1%     399.8m ± 0%    -2.69% (p=0.001 n=7)
TinyGo/Run/container_heap.test-10        14.41m ± 0%     14.29m ± 2%    -0.77% (p=0.026 n=7)
TinyGo/Compile/container_list.test-10    410.5m ± 1%     398.1m ± 0%    -3.02% (p=0.001 n=7)
TinyGo/Run/container_list.test-10        14.27m ± 2%     14.16m ± 1%         ~ (p=0.073 n=7)
TinyGo/Compile/container_ring.test-10    403.7m ± 1%     392.5m ± 2%    -2.77% (p=0.001 n=7)
TinyGo/Run/container_ring.test-10        14.24m ± 0%     14.27m ± 1%         ~ (p=0.259 n=7)
TinyGo/Compile/crypto_des.test-10        418.8m ± 0%     408.1m ± 0%    -2.56% (p=0.001 n=7)
TinyGo/Run/crypto_des.test-10            18.23m ± 0%     18.17m ± 1%         ~ (p=0.456 n=7)
TinyGo/Compile/crypto_md5.test-10        417.3m ± 2%     406.1m ± 1%    -2.68% (p=0.001 n=7)
TinyGo/Run/crypto_md5.test-10            20.50m ± 0%     20.45m ± 1%         ~ (p=0.128 n=7)
TinyGo/Compile/crypto_rc4.test-10        402.2m ± 1%     390.5m ± 0%    -2.90% (p=0.001 n=7)
TinyGo/Run/crypto_rc4.test-10            160.8m ± 0%     161.0m ± 1%         ~ (p=1.000 n=7)
TinyGo/Compile/crypto_sha1.test-10       417.2m ± 1%     404.5m ± 1%    -3.04% (p=0.001 n=7)
TinyGo/Run/crypto_sha1.test-10           15.93m ± 1%     15.90m ± 1%         ~ (p=0.710 n=7)
TinyGo/Compile/crypto_sha256.test-10     423.4m ± 1%     412.4m ± 1%    -2.60% (p=0.001 n=7)
TinyGo/Run/crypto_sha256.test-10         16.16m ±  ∞ ¹   16.05m ±  ∞ ¹       ~ (p=0.381 n=2+5)
geomean                                  94.17m          92.70m         -1.56%
¹ need >= 6 samples for confidence interval at level 0.95

                                      │ old_tinygo.txt │             new_tinygo.txt             │
                                      │      B/op      │      B/op       vs base                │
TinyGo/Compile/container_heap.test-10   48.55Mi ± 0%     48.30Mi ± 0%    -0.52% (p=0.001 n=7)
TinyGo/Run/container_heap.test-10       16.63Mi ± 0%     16.63Mi ± 0%         ~ (p=0.557 n=7)
TinyGo/Compile/container_list.test-10   48.53Mi ± 0%     48.29Mi ± 0%    -0.51% (p=0.001 n=7)
TinyGo/Run/container_list.test-10       16.40Mi ± 0%     16.40Mi ± 0%         ~ (p=0.364 n=7)
TinyGo/Compile/container_ring.test-10   47.78Mi ± 0%     47.53Mi ± 0%    -0.52% (p=0.001 n=7)
TinyGo/Run/container_ring.test-10       16.30Mi ± 0%     16.30Mi ± 0%         ~ (p=0.128 n=7)
TinyGo/Compile/crypto_des.test-10       48.67Mi ± 0%     48.42Mi ± 0%    -0.51% (p=0.001 n=7)
TinyGo/Run/crypto_des.test-10           16.76Mi ± 0%     16.76Mi ± 0%         ~ (p=0.902 n=7)
TinyGo/Compile/crypto_md5.test-10       48.73Mi ± 0%     48.48Mi ± 0%    -0.51% (p=0.001 n=7)
TinyGo/Run/crypto_md5.test-10           44.97Mi ± 0%     44.97Mi ± 0%         ~ (p=0.402 n=7)
TinyGo/Compile/crypto_rc4.test-10       47.76Mi ± 0%     47.52Mi ± 0%    -0.51% (p=0.001 n=7)
TinyGo/Run/crypto_rc4.test-10           29.28Mi ± 0%     29.28Mi ± 0%         ~ (p=0.104 n=7)
TinyGo/Compile/crypto_sha1.test-10      48.97Mi ± 0%     48.72Mi ± 0%    -0.52% (p=0.001 n=7)
TinyGo/Run/crypto_sha1.test-10          17.44Mi ± 0%     17.44Mi ± 0%         ~ (p=1.000 n=7)
TinyGo/Compile/crypto_sha256.test-10    48.81Mi ± 0%     48.56Mi ± 0%    -0.51% (p=0.001 n=7)
TinyGo/Run/crypto_sha256.test-10        17.53Mi ±  ∞ ¹   17.53Mi ±  ∞ ¹       ~ (p=0.381 n=2+5)
geomean                                 31.45Mi          31.37Mi         -0.26%
¹ need >= 6 samples for confidence interval at level 0.95

                                      │ old_tinygo.txt │            new_tinygo.txt             │
                                      │   allocs/op    │   allocs/op    vs base                │
TinyGo/Compile/container_heap.test-10    83.67k ± 0%     83.46k ± 0%    -0.25% (p=0.011 n=7)
TinyGo/Run/container_heap.test-10        374.9k ± 0%     374.9k ± 0%         ~ (p=1.000 n=7)
TinyGo/Compile/container_list.test-10    83.34k ± 0%     83.19k ± 0%    -0.19% (p=0.002 n=7)
TinyGo/Run/container_list.test-10        370.0k ± 0%     370.0k ± 0%         ~ (p=0.674 n=7)
TinyGo/Compile/container_ring.test-10    83.26k ± 0%     83.08k ± 0%    -0.22% (p=0.004 n=7)
TinyGo/Run/container_ring.test-10        367.6k ± 0%     367.6k ± 0%         ~ (p=0.249 n=7)
TinyGo/Compile/crypto_des.test-10        83.68k ± 0%     83.53k ± 0%    -0.18% (p=0.004 n=7)
TinyGo/Run/crypto_des.test-10            378.1k ± 0%     378.1k ± 0%         ~ (p=0.437 n=7)
TinyGo/Compile/crypto_md5.test-10        83.86k ± 0%     83.67k ± 0%    -0.23% (p=0.001 n=7)
TinyGo/Run/crypto_md5.test-10            393.3k ± 0%     393.3k ± 0%         ~ (p=0.592 n=7)
TinyGo/Compile/crypto_rc4.test-10        83.32k ± 0%     83.20k ± 0%    -0.14% (p=0.011 n=7)
TinyGo/Run/crypto_rc4.test-10            367.1k ± 0%     367.1k ± 0%         ~ (p=0.102 n=7)
TinyGo/Compile/crypto_sha1.test-10       84.05k ± 0%     83.87k ± 0%    -0.21% (p=0.002 n=7)
TinyGo/Run/crypto_sha1.test-10           392.7k ± 0%     392.7k ± 0%         ~ (p=1.000 n=7)
TinyGo/Compile/crypto_sha256.test-10     83.86k ± 0%     83.67k ± 0%    -0.24% (p=0.001 n=7)
TinyGo/Run/crypto_sha256.test-10         394.5k ±  ∞ ¹   394.5k ±  ∞ ¹       ~ (p=0.952 n=2+5)
geomean                                  178.2k          178.0k         -0.10%
```

### wasip1

```
goos: darwin
goarch: arm64
pkg: github.com/tetratelabs/wazero/internal/integration_test/stdlibs
                                            │ old_wasip1.txt │           new_wasip1.txt            │
                                            │     sec/op     │   sec/op     vs base                │
Wasip1/Compile/src_archive_tar.test-10          2.066 ± 1%      2.066 ± 1%       ~ (p=1.000 n=7)
Wasip1/Run/src_archive_tar.test-10             398.9m ± 1%     398.9m ± 0%       ~ (p=0.902 n=7)
Wasip1/Compile/src_bufio.test-10                1.405 ± 0%      1.405 ± 0%       ~ (p=0.318 n=7)
Wasip1/Run/src_bufio.test-10                   120.1m ± 0%     120.0m ± 0%       ~ (p=0.456 n=7)
Wasip1/Compile/src_bytes.test-10                1.453 ± 0%      1.452 ± 0%       ~ (p=0.383 n=7)
Wasip1/Run/src_bytes.test-10                   468.9m ± 1%     467.7m ± 1%       ~ (p=1.000 n=7)
Wasip1/Compile/src_context.test-10              1.565 ± 0%      1.562 ± 0%  -0.18% (p=0.001 n=7)
Wasip1/Run/src_context.test-10                 31.52m ± 1%     31.51m ± 1%       ~ (p=0.620 n=7)
Wasip1/Compile/src_encoding_ascii85.test-10     1.262 ±  ∞ ¹    1.262 ± 0%       ~ (p=0.889 n=2+7)
geomean                                        565.3m          564.9m       -0.07%
¹ need >= 6 samples for confidence interval at level 0.95

                                            │ old_wasip1.txt │            new_wasip1.txt            │
                                            │      B/op      │     B/op      vs base                │
Wasip1/Compile/src_archive_tar.test-10        93.16Mi ± 0%     92.70Mi ± 0%  -0.50% (p=0.001 n=7)
Wasip1/Run/src_archive_tar.test-10            286.0Mi ± 0%     286.0Mi ± 0%       ~ (p=0.246 n=7)
Wasip1/Compile/src_bufio.test-10              74.12Mi ± 0%     73.79Mi ± 0%  -0.45% (p=0.001 n=7)
Wasip1/Run/src_bufio.test-10                  105.3Mi ± 0%     105.3Mi ± 0%       ~ (p=0.780 n=7)
Wasip1/Compile/src_bytes.test-10              75.32Mi ± 0%     74.96Mi ± 0%  -0.47% (p=0.001 n=7)
Wasip1/Run/src_bytes.test-10                  605.0Mi ± 0%     605.0Mi ± 0%       ~ (p=1.000 n=7)
Wasip1/Compile/src_context.test-10            78.07Mi ± 0%     77.68Mi ± 0%  -0.49% (p=0.001 n=7)
Wasip1/Run/src_context.test-10                71.52Mi ± 0%     71.52Mi ± 0%       ~ (p=0.516 n=7)
Wasip1/Compile/src_encoding_ascii85.test-10   70.38Mi ±  ∞ ¹   70.08Mi ± 0%       ~ (p=0.056 n=2+7)
geomean                                       115.7Mi          115.4Mi       -0.26%
¹ need >= 6 samples for confidence interval at level 0.95

                                            │ old_wasip1.txt │            new_wasip1.txt             │
                                            │   allocs/op    │  allocs/op   vs base                  │
Wasip1/Compile/src_archive_tar.test-10         265.0k ± 0%     256.1k ± 0%  -3.37% (p=0.001 n=7)
Wasip1/Run/src_archive_tar.test-10             7.831k ± 0%     7.830k ± 0%       ~ (p=0.592 n=7)
Wasip1/Compile/src_bufio.test-10               195.3k ± 0%     189.1k ± 0%  -3.19% (p=0.001 n=7)
Wasip1/Run/src_bufio.test-10                   3.728k ± 0%     3.728k ± 0%       ~ (p=1.000 n=7)   ¹
Wasip1/Compile/src_bytes.test-10               203.7k ± 0%     197.0k ± 0%  -3.31% (p=0.001 n=7)
Wasip1/Run/src_bytes.test-10                   6.377k ± 0%     6.377k ± 0%       ~ (p=0.559 n=7)
Wasip1/Compile/src_context.test-10             221.4k ± 0%     214.2k ± 0%  -3.29% (p=0.001 n=7)
Wasip1/Run/src_context.test-10                 3.814k ± 1%     3.814k ± 0%       ~ (p=0.192 n=7)
Wasip1/Compile/src_encoding_ascii85.test-10    182.3k ±  ∞ ²   176.6k ± 0%       ~ (p=0.056 n=2+7)
geomean                                        40.64k          39.90k       -1.82%
```

Signed-off-by: Takeshi Yoneda <t.y.mathetake@gmail.com>
This commit is contained in:
Takeshi Yoneda
2024-06-07 12:50:25 -07:00
committed by GitHub
parent 747609b0f5
commit 0649820fb9
5 changed files with 72 additions and 95 deletions

View File

@@ -442,10 +442,10 @@ blk3: (v5:i32) <-- (blk1,blk2)
exp: ` exp: `
blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) blk0: (exec_ctx:i64, module_ctx:i64, v2:i32)
v3:i32 = Iconst_32 0x0 v3:i32 = Iconst_32 0x0
Jump blk1 Jump blk1, v2
blk1: () <-- (blk0) blk1: (v4:i32) <-- (blk0)
Return v2 Return v4
blk2: () blk2: ()
`, `,
@@ -462,15 +462,15 @@ blk1: () <-- (blk0)
m: testcases.ReferenceValueFromUnsealedBlock2.Module, m: testcases.ReferenceValueFromUnsealedBlock2.Module,
exp: ` exp: `
blk0: (exec_ctx:i64, module_ctx:i64, v2:i32) blk0: (exec_ctx:i64, module_ctx:i64, v2:i32)
Jump blk1 Jump blk1, v2
blk1: () <-- (blk0,blk1) blk1: (v3:i32) <-- (blk0,blk1)
Brnz v2, blk1 Brnz v3, blk1, v3
Jump blk4 Jump blk4
blk2: () <-- (blk3) blk2: () <-- (blk3)
v3:i32 = Iconst_32 0x0 v4:i32 = Iconst_32 0x0
Jump blk_ret, v3 Jump blk_ret, v4
blk3: () <-- (blk4) blk3: () <-- (blk4)
Jump blk2 Jump blk2
@@ -496,8 +496,8 @@ blk3: () <-- (blk4)
Jump fallthrough Jump fallthrough
blk2: () <-- (blk3) blk2: () <-- (blk3)
v3:i32 = Iconst_32 0x0 v4:i32 = Iconst_32 0x0
Jump blk_ret, v3 Jump blk_ret, v4
`, `,
}, },
{ {
@@ -1058,22 +1058,22 @@ blk1: () <-- (blk0)
Call f1:sig1, exec_ctx, module_ctx Call f1:sig1, exec_ctx, module_ctx
v5:i64 = Load module_ctx, 0x8 v5:i64 = Load module_ctx, 0x8
v6:i64 = Uload32 module_ctx, 0x10 v6:i64 = Uload32 module_ctx, 0x10
Jump blk3 Jump blk3, v2
blk2: () <-- (blk0) blk2: () <-- (blk0)
Jump blk3 Jump blk3, v2
blk3: () <-- (blk1,blk2) blk3: (v7:i32) <-- (blk1,blk2)
v7:i64 = Iconst_64 0x4 v8:i64 = Iconst_64 0x4
v8:i64 = UExtend v2, 32->64 v9:i64 = UExtend v7, 32->64
v9:i64 = Uload32 module_ctx, 0x10 v10:i64 = Uload32 module_ctx, 0x10
v10:i64 = Iadd v8, v7 v11:i64 = Iadd v9, v8
v11:i32 = Icmp lt_u, v9, v10 v12:i32 = Icmp lt_u, v10, v11
ExitIfTrue v11, exec_ctx, memory_out_of_bounds ExitIfTrue v12, exec_ctx, memory_out_of_bounds
v12:i64 = Load module_ctx, 0x8 v13:i64 = Load module_ctx, 0x8
v13:i64 = Iadd v12, v8 v14:i64 = Iadd v13, v9
v14:i32 = Load v13, 0x0 v15:i32 = Load v14, 0x0
Jump blk_ret, v14 Jump blk_ret, v15
`, `,
expAfterPasses: ` expAfterPasses: `
signatures: signatures:
@@ -1093,16 +1093,16 @@ blk2: () <-- (blk0)
Jump fallthrough Jump fallthrough
blk3: () <-- (blk1,blk2) blk3: () <-- (blk1,blk2)
v7:i64 = Iconst_64 0x4 v8:i64 = Iconst_64 0x4
v8:i64 = UExtend v2, 32->64 v9:i64 = UExtend v2, 32->64
v9:i64 = Uload32 module_ctx, 0x10 v10:i64 = Uload32 module_ctx, 0x10
v10:i64 = Iadd v8, v7 v11:i64 = Iadd v9, v8
v11:i32 = Icmp lt_u, v9, v10 v12:i32 = Icmp lt_u, v10, v11
ExitIfTrue v11, exec_ctx, memory_out_of_bounds ExitIfTrue v12, exec_ctx, memory_out_of_bounds
v12:i64 = Load module_ctx, 0x8 v13:i64 = Load module_ctx, 0x8
v13:i64 = Iadd v12, v8 v14:i64 = Iadd v13, v9
v14:i32 = Load v13, 0x0 v15:i32 = Load v14, 0x0
Jump blk_ret, v14 Jump blk_ret, v15
`, `,
}, },
{ {
@@ -2869,7 +2869,7 @@ blk0: (exec_ctx:i64, module_ctx:i64, v2:i32)
blk1: () <-- (blk0) blk1: () <-- (blk0)
v11:i32 = Load v9, 0x10 v11:i32 = Load v9, 0x10
Jump blk3 Jump blk3, v2
blk2: () <-- (blk0) blk2: () <-- (blk0)
v12:i32 = Load v9, 0x10 v12:i32 = Load v9, 0x10
@@ -2880,13 +2880,18 @@ blk2: () <-- (blk0)
ExitIfTrue v16, exec_ctx, memory_out_of_bounds ExitIfTrue v16, exec_ctx, memory_out_of_bounds
v17:i32 = Load v9, 0x30 v17:i32 = Load v9, 0x30
v18:i32 = Load v9, 0x25 v18:i32 = Load v9, 0x25
Jump blk3 Jump blk3, v2
blk3: () <-- (blk1,blk2) blk3: (v19:i32) <-- (blk1,blk2)
v19:i64 = Load module_ctx, 0x8 v20:i64 = Iconst_64 0x19
v20:i64 = UExtend v2, 32->64 v21:i64 = UExtend v19, 32->64
v21:i64 = Iadd v19, v20 v22:i64 = Uload32 module_ctx, 0x10
v22:i32 = Load v21, 0x15 v23:i64 = Iadd v21, v20
v24:i32 = Icmp lt_u, v22, v23
ExitIfTrue v24, exec_ctx, memory_out_of_bounds
v25:i64 = Load module_ctx, 0x8
v26:i64 = Iadd v25, v21
v27:i32 = Load v26, 0x15
Jump blk_ret Jump blk_ret
`, `,
}, },
@@ -2939,44 +2944,44 @@ blk0: (exec_ctx:i64, module_ctx:i64, v2:i32)
v8:i64 = Load module_ctx, 0x8 v8:i64 = Load module_ctx, 0x8
v9:i64 = Iadd v8, v4 v9:i64 = Iadd v8, v4
v10:i32 = Load v9, 0x10 v10:i32 = Load v9, 0x10
Jump blk1 Jump blk1, v2
blk1: () <-- (blk0,blk6) blk1: (v11:i32) <-- (blk0,blk6)
v11:i64 = Iconst_64 0x24 v12:i64 = Iconst_64 0x24
v12:i64 = UExtend v2, 32->64 v13:i64 = UExtend v11, 32->64
v13:i64 = Uload32 module_ctx, 0x10 v14:i64 = Uload32 module_ctx, 0x10
v14:i64 = Iadd v12, v11 v15:i64 = Iadd v13, v12
v15:i32 = Icmp lt_u, v13, v14 v16:i32 = Icmp lt_u, v14, v15
ExitIfTrue v15, exec_ctx, memory_out_of_bounds ExitIfTrue v16, exec_ctx, memory_out_of_bounds
v16:i64 = Load module_ctx, 0x8 v17:i64 = Load module_ctx, 0x8
v17:i64 = Iadd v16, v12 v18:i64 = Iadd v17, v13
v18:i32 = Load v17, 0x20 v19:i32 = Load v18, 0x20
Brz v18, blk4 Brz v19, blk4
Jump blk3 Jump blk3
blk2: () blk2: ()
blk3: () <-- (blk1) blk3: () <-- (blk1)
Jump blk6 Jump blk6, v11
blk4: () <-- (blk1) blk4: () <-- (blk1)
Brnz v2, blk_ret Brnz v11, blk_ret
Jump blk9 Jump blk9
blk5: () <-- (blk7,blk9) blk5: () <-- (blk7,blk9)
Jump blk_ret Jump blk_ret
blk6: () <-- (blk3) blk6: (v20:i32) <-- (blk3)
v19:i64 = Iconst_64 0x54 v21:i64 = Iconst_64 0x54
v20:i64 = UExtend v2, 32->64 v22:i64 = UExtend v20, 32->64
v21:i64 = Uload32 module_ctx, 0x10 v23:i64 = Uload32 module_ctx, 0x10
v22:i64 = Iadd v20, v19 v24:i64 = Iadd v22, v21
v23:i32 = Icmp lt_u, v21, v22 v25:i32 = Icmp lt_u, v23, v24
ExitIfTrue v23, exec_ctx, memory_out_of_bounds ExitIfTrue v25, exec_ctx, memory_out_of_bounds
v24:i64 = Load module_ctx, 0x8 v26:i64 = Load module_ctx, 0x8
v25:i64 = Iadd v24, v20 v27:i64 = Iadd v26, v22
v26:i32 = Load v25, 0x50 v28:i32 = Load v27, 0x50
Brnz v26, blk1 Brnz v28, blk1, v20
Jump blk8 Jump blk8
blk7: () <-- (blk8) blk7: () <-- (blk8)

View File

@@ -1086,16 +1086,8 @@ func (c *Compiler) lowerCurrentOpcode() {
break break
} }
variable := c.localVariable(index) variable := c.localVariable(index)
if _, ok := c.m.NonStaticLocals[c.wasmLocalFunctionIndex][index]; ok { state.push(builder.MustFindValue(variable))
state.push(builder.MustFindValue(variable))
} else {
// If a local is static, we can simply find it in the entry block which is either a function param
// or a zero value. This fast pass helps to avoid the overhead of searching the entire function plus
// avoid adding unnecessary block arguments.
// TODO: I think this optimization should be done in a SSA pass like passRedundantPhiEliminationOpt,
// but somehow there's some corner cases that it fails to optimize.
state.push(builder.MustFindValueInBlk(variable, c.ssaBuilder.EntryBlock()))
}
case wasm.OpcodeLocalSet: case wasm.OpcodeLocalSet:
index := c.readI32u() index := c.readI32u()
if state.unreachable { if state.unreachable {

View File

@@ -54,9 +54,6 @@ type Builder interface {
// MustFindValue searches the latest definition of the given Variable and returns the result. // MustFindValue searches the latest definition of the given Variable and returns the result.
MustFindValue(variable Variable) Value MustFindValue(variable Variable) Value
// MustFindValueInBlk is the same as MustFindValue except it searches the latest definition from the given BasicBlock.
MustFindValueInBlk(variable Variable, blk BasicBlock) Value
// FindValueInLinearPath tries to find the latest definition of the given Variable in the linear path to the current BasicBlock. // FindValueInLinearPath tries to find the latest definition of the given Variable in the linear path to the current BasicBlock.
// If it cannot find the definition, or it's not sealed yet, it returns ValueInvalid. // If it cannot find the definition, or it's not sealed yet, it returns ValueInvalid.
FindValueInLinearPath(variable Variable) Value FindValueInLinearPath(variable Variable) Value
@@ -476,11 +473,6 @@ func (b *builder) findValueInLinearPath(variable Variable, blk *basicBlock) Valu
return ValueInvalid return ValueInvalid
} }
func (b *builder) MustFindValueInBlk(variable Variable, blk BasicBlock) Value {
typ := b.definedVariableType(variable)
return b.findValue(typ, variable, blk.(*basicBlock))
}
// MustFindValue implements Builder.MustFindValue. // MustFindValue implements Builder.MustFindValue.
func (b *builder) MustFindValue(variable Variable) Value { func (b *builder) MustFindValue(variable Variable) Value {
typ := b.definedVariableType(variable) typ := b.definedVariableType(variable)

View File

@@ -67,11 +67,6 @@ func (m *Module) validateFunctionWithMaxStackValues(
declaredFunctionIndexes map[Index]struct{}, declaredFunctionIndexes map[Index]struct{},
br *bytes.Reader, br *bytes.Reader,
) error { ) error {
nonStaticLocals := make(map[Index]struct{})
if len(m.NonStaticLocals) > 0 {
m.NonStaticLocals[idx] = nonStaticLocals
}
functionType := &m.TypeSection[m.FunctionSection[idx]] functionType := &m.TypeSection[m.FunctionSection[idx]]
code := &m.CodeSection[idx] code := &m.CodeSection[idx]
body := code.Body body := code.Body
@@ -357,7 +352,6 @@ func (m *Module) validateFunctionWithMaxStackValues(
return fmt.Errorf("invalid local index for %s %d >= %d(=len(locals)+len(parameters))", return fmt.Errorf("invalid local index for %s %d >= %d(=len(locals)+len(parameters))",
OpcodeLocalSetName, index, l) OpcodeLocalSetName, index, l)
} }
nonStaticLocals[index] = struct{}{}
var expType ValueType var expType ValueType
if index < inputLen { if index < inputLen {
expType = functionType.Params[index] expType = functionType.Params[index]
@@ -373,7 +367,6 @@ func (m *Module) validateFunctionWithMaxStackValues(
return fmt.Errorf("invalid local index for %s %d >= %d(=len(locals)+len(parameters))", return fmt.Errorf("invalid local index for %s %d >= %d(=len(locals)+len(parameters))",
OpcodeLocalTeeName, index, l) OpcodeLocalTeeName, index, l)
} }
nonStaticLocals[index] = struct{}{}
var expType ValueType var expType ValueType
if index < inputLen { if index < inputLen {
expType = functionType.Params[index] expType = functionType.Params[index]

View File

@@ -185,9 +185,6 @@ type Module struct {
// as described in https://yurydelendik.github.io/webassembly-dwarf/, though it is not specified in the Wasm // as described in https://yurydelendik.github.io/webassembly-dwarf/, though it is not specified in the Wasm
// specification: https://github.com/WebAssembly/debugging/issues/1 // specification: https://github.com/WebAssembly/debugging/issues/1
DWARFLines *wasmdebug.DWARFLines DWARFLines *wasmdebug.DWARFLines
// NonStaticLocals collects the local indexes that will change its value through either local.get or local.tee.
NonStaticLocals []map[Index]struct{}
} }
// ModuleID represents sha256 hash value uniquely assigned to Module. // ModuleID represents sha256 hash value uniquely assigned to Module.
@@ -366,8 +363,6 @@ func (m *Module) validateFunctions(enabledFeatures api.CoreFeatures, functions [
br := bytes.NewReader(nil) br := bytes.NewReader(nil)
// Also, we reuse the stacks across multiple function validations to reduce allocations. // Also, we reuse the stacks across multiple function validations to reduce allocations.
vs := &stacks{} vs := &stacks{}
// Non-static locals are gathered during validation and used in the down-stream compilation.
m.NonStaticLocals = make([]map[Index]struct{}, len(m.FunctionSection))
for idx, typeIndex := range m.FunctionSection { for idx, typeIndex := range m.FunctionSection {
if typeIndex >= typeCount { if typeIndex >= typeCount {
return fmt.Errorf("invalid %s: type section index %d out of range", m.funcDesc(SectionIDFunction, Index(idx)), typeIndex) return fmt.Errorf("invalid %s: type section index %d out of range", m.funcDesc(SectionIDFunction, Index(idx)), typeIndex)