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:
@@ -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)
|
||||||
|
|||||||
@@ -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 {
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
@@ -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]
|
||||||
|
|||||||
@@ -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)
|
||||||
|
|||||||
Reference in New Issue
Block a user