summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
...
* [Parser] Parse try_table (#6237)Thomas Lively2024-01-254-6/+190
|
* Memory flattening: Check for overflow (#6233)Alon Zakai2024-01-242-1/+49
| | | | | Fixes a fuzz testcase for wasm-ctor-eval. Add the beginnings of a polyfill for stdckdint.h to help that.
* [EH] Add translator from old to new EH instructions (#6210)Heejin Ahn2024-01-234-0/+826
| | | | | | | | | | | | | | | | | | | | This translates the old Phase 3 EH instructions, which include `try`, `catch`, `catch_all`, `delegate`, and `rethrow`, into the new EH instructions, which include `try_table` (with `catch` / `catch_ref` / `catch_all` / `catch_all_ref`) and `throw_ref`, passed at the Oct 2023 CG meeting. This translator can be used as a standalone tool by users of the previous EH toolchain to generate binaries for the new spec without recompiling, and also can be used at the end of the Binaryen pipeline to produce binaries for the new spec while the end-to-end toolchain implementation for the new spec is in progress. While the goal of this pass is not optimization, this tries to a little better than the most naive implementation, namely by omitting a few instructions where possible and trying to minimize the number of additional locals, because this can be used as a standalone translator or the last stage of the pipeline while we can't post-optimize the results because the whole pipeline (-On) is not ready for the new EH.
* Stop propagating/inlining string constants (#6234)Alon Zakai2024-01-232-6/+22
| | | | | This causes overhead atm since in VMs executing a string.const will actually allocate a string, and more copies means more allocations. For now, just do not add more. This required changes to two passes: SimplifyGlobals and Precompute.
* Rename stack variables in CFGWalker (NFC) (#6232)Heejin Ahn2024-01-221-26/+28
| | | | | | | This renames `***Stack` variables in `CFGWalker` to be consistent, as a preparation for adding another stack for the new EH. Currently `ifStack` and `loopStack` contains `BasicBlock*`s but `tryStack` contains `Expression*`, and `Try` expressions are rather contained in `unwindExprStack`, which to me is confusing.
* [EH] Support Stack IR for try_table (#6231)Heejin Ahn2024-01-224-27/+41
|
* Remove incorrect validation of segment sizes (#6228)Alon Zakai2024-01-221-9/+0
| | | | This should be a runtime error, not a validator error. It caused a fuzzer failure on wasm-ctor-eval.
* SimplifyGlobals: Apply constant globals to segment offsets (#6226)Alon Zakai2024-01-181-8/+32
| | | | | | | We already applied such globals to other globals, but can do the same to offsets of data and element segments. Suggested in #6220
* C API: Add BinaryenFunctionAppendVar (#6213)KinderGartenKiller2024-01-172-0/+8
|
* Make blockifyWithName correctly use name and type (#6223)Heejin Ahn2024-01-161-2/+5
| | | | | | | | - This passes `name` to `makeBlock` call, because `makeBlock` uses `BranchSeeker` when finalizing only when the block has a `name`. - This also refinalizes the block when an optional `type` is given. This was spun off from #6210, but I'm not sure how to add a standalone test for this.
* [NFC] Fix "initialised" => "initialized" (#6222)Thomas Lively2024-01-111-1/+1
|
* Typed continuations: resume instructions (#6083)Frank Emrich2024-01-1124-0/+323
| | | | | This PR is part of a series that adds basic support for the [typed continuations proposal](https://github.com/wasmfx/specfx). This particular PR adds support for the `resume` instruction. The most notable missing feature is validation, which is not implemented, yet.
* wasm-merge: Sort globals to ensure proper validation (#6221)Alon Zakai2024-01-112-6/+14
| | | | | | | | | | | | | If the first module has a global that reads from a global that appears in a later module, then we need to reorder the globals, because if we just append the globals from the later module we'd end up with a global reading from another that is not before it. Changes to the existing renamings test are just due to the global sorting pass that now runs (it not only fixes up validation errors but also tries to sort in a more optimal order for size). Fixes #6220
* Precompute into select arms (#6212)Alon Zakai2024-01-101-12/+318
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | E.g. (i32.add (select (i32.const 100) (i32.const 200) (..condition..) ) (i32.const 50) ) ;; => (select (i32.const 150) (i32.const 250) (..condition..) ) We cannot fully precompute the select, but we can "partially precompute" it, by precomputing its arms using the parent. This may require looking several steps up the parent chain, which is an awkward operation in our simple walkers, so to do it we capture stacks of parents and operate directly on them. This is a little slower than a normal walk, so only do it when we see a promising select, and only in -O2 and above (this makes the pass 7% or so slower; not a large cost, but best to avoid it in -O1).
* [Parser] Parse remaining heap and reference types (#6218)Thomas Lively2024-01-102-20/+60
| | | Parse types like `exnref` and `nofunc` that we did not previously support.
* [NFC] Add more const annotations + a trivial == (#6216)Alon Zakai2024-01-092-3/+8
|
* Fix global effect computation with -O flags (#6211)Alon Zakai2024-01-093-29/+31
| | | | | | | | | | | | | | | | | | | | We tested --generate-global-effects --vacuum and such, but not --generate-global-effects -O3 or the other -O flags. Unfortunately, our targeted testing missed a bug because of that. Specifically, we have special logic for -O flags to make sure the passes they expand into run with the proper opt and shrink levels, but that logic happened to also interfere with global effect computation. It would also interfere with allowing GUFA info or other things to be stored on the side, which we've proposed. This PR fixes that + future issues. The fix is to just allow a pass runner to execute more than once. We thought to avoid that and assert against it to keep the model "hermetic" (you create a pass runner, you run the passes, and you throw it out), which feels nice in a way, but it led to the bug here, and I'm not sure it would prevent any other ones really. It is also more code. It is simpler to allow a runner to execute more than once, and add a method to clear it. With that, the logic for -O3 execution is both simpler and does not interfere with anything but the opt and shrink level flags: we create a single runner, give it the proper options, and then keep using that runner + those options as we go, normally.
* Fix cmake dependency on wasm-intrinsics.wat (#6206)Sam Clegg2024-01-062-12/+5
| | | I think this is a nicer/better way to do #6204.
* Fix branches to loops in IRBuilder (#6205)Thomas Lively2024-01-051-5/+8
| | | | | | | Since branches to loops go to the beginnings of the loops, they should send values matching the input types for the loops (which are always none because we don't support loop input types). IRBuilder was previously using the output types of loops to determine what values the branches should carry, which was incorrect. Fix it.
* Rename CMake vars for modified intrinsics file (#6204)Alon Zakai2024-01-052-6/+12
| | | | | | The intrinsics file changed in #6201 and somehow CMake doesn't automatically update itself, and needs a manual step for people with existing checkouts (a new fresh checkout always works). To avoid annoyance for existing checkouts, rename the vars, which forces CMake to recompute the contents.
* [NFC] Add some const annotations (#6203)Alon Zakai2024-01-052-4/+4
|
* [Parser] Parse br_if correctly (#6202)Thomas Lively2024-01-047-16/+24
| | | | The new text parser and IRBuilder were previously not differentiating between `br` and `br_if`. Handle `br_if` correctly by popping and assigning a condition.
* Require `then` and `else` with `if` (#6201)Thomas Lively2024-01-043-160/+189
| | | | | | | | | | | | We previously supported (and primarily used) a non-standard text format for conditionals in which the condition, if-true expression, and if-false expression were all simply s-expression children of the `if` expression. The standard text format, however, requires the use of `then` and `else` forms to introduce the if-true and if-false arms of the conditional. Update the legacy text parser to require the standard format and update all tests to match. Update the printer to print the standard format as well. The .wast and .wat test inputs were mechanically updated with this script: https://gist.github.com/tlively/85ae7f01f92f772241ec994c840ccbb1
* Use the standard shared memory text format (#6200)Thomas Lively2024-01-032-64/+8
| | | | | Update the legacy text parser and all tests to use the standard text format for shared memories, e.g. `(memory $m 1 1 shared)` rather than `(memory $m (shared 1 1))`. Also remove support for non-standard in-line "data" or "segment" declarations. This change makes the tests more compatible with the new text parser, which only supports the standard format.
* [Parser] Go back to "sub final" intead of "sub open" (#6199)Thomas Lively2024-01-031-1/+1
| | | | The planned spec change to use "sub open" never came together, so the standard format remains "sub final".
* [Parser] Parse br_on_cast{_fail} input annotations (#6198)Thomas Lively2024-01-034-10/+24
| | | | And validate in IRBuilder both that the input annotation is valid and that the input matches it.
* Drop support for type annotations on array.len (#6197)Thomas Lively2024-01-031-8/+1
| | | | | | These type annotations were removed during the development of the GC proposal, but we maintained support for parsing them to ease the transition. Now that GC is shipped, remove support for the non-standard annotation and update our tests accordingly.
* [Parser] Parse folded instructions that contain parentheses (#6196)Thomas Lively2024-01-032-38/+51
| | | | | | | | | | | | To parse folded instructions in the right order, we need to defer parsing each instruction until we have parsed each of its children and found its closing parenthesis. Previously we naively looked for parentheses to determine where instructions began and ended before we parsed them, but that scheme did not correctly handle instructions that can contain parentheses in their immediates, such as call_indirect. Fix the problem by using the actual instruction parser functions with a placeholder context to find the end of the instructions, including any kind of immediates they might have.
* [EH] Misc. fixes for EH (#6195)Heejin Ahn2024-01-023-6/+16
| | | | | - Deletes a stray whitespace after `throw_ref` - Adds missing `makeThrowRef` to `wasm-builder.h` - Adds a case for `TryTable` in `ControlFlowWalker`
* wasm-reduce: Improve tryToReduceCurrentToConst() (#6193)Alon Zakai2024-01-021-9/+26
| | | | | | | | | Avoid replacing with the exact same thing in the case of RefNull and a default tuple. Also be more careful with handling of numbers. Before we exited immediately if we saw a number, but we can try to replace a number with a 0 or a 1, even if it was a number before. That is, we consider 1 simpler than e.g. 12345678, and 0 simpler than 1.
* [Parser] Support standalone import definitions (#6191)Thomas Lively2024-01-023-7/+95
| | | | We previously support the in-line import abbreviation, but now add support for explicit, non-abbreviated imports as well.
* Unify method pairs with and without Type param (#6184)Heejin Ahn2023-12-203-194/+124
| | | | | | | | | | | | | | | | As suggested in https://github.com/WebAssembly/binaryen/pull/6181#discussion_r1427188670, using `std::optional<Type>`, this unifies two different versions of `make***`, for block-like structures (`block`, `if`, `loop`, `try`, and `try_table`) with and without a type parameter. This also allows unifying of `finalize` methods, with and without a type. This also sets `breakability` argument of `Block::finalize` to `Unknown` so we can only have one `Block::finalize` that handles all cases. This also adds an optional `std::optional<Type> type` parameter to `blockifyWithName`, and `makeSequence` functions in `wasm-builder.h`. blockify was not included because it has a variadic parameter.
* Drop support for non-standard quoted function names (#6188)Thomas Lively2023-12-203-41/+54
| | | | | | | | | | | | | | | | | | We previously supported a non-standard `(func "name" ...` syntax for declaring functions exported with the quoted name. Since that is not part of the standard text format, drop support for it, replacing it with the standard `(func $name (export "name") ...` syntax instead. Also replace our other usage of the quoted form in our text output, which was where we quoted names containing characters that are not allowed to appear in standard names. To handle that case, adjust our output from `"$name"` to `$"name"`, which is the standards-track way of supporting such names. Also fix how we detect non-standard name characters to match the spec. Update the lit test output generation script to account for these changes, including by making the `$` prefix on names mandatory. This causes the script to stop interpreting declarative element segments with the `(elem declare ...` syntax as being named "declare", so prevent our generated output from regressing by counting "declare" as a name in the script.
* [NFC] Fix typo in Inlining (#6187)Alon Zakai2023-12-201-2/+2
|
* [EH] Add validation for new instructions (#6185)Heejin Ahn2023-12-201-5/+78
| | | | | | | | | | This adds validation for the new EH instructions (`try_table` and `throw_ref`): https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md This also adds a spec test for checking invalid modules. We cannot check the executions yet because we don't have the interpreter implementation. The new test file also contains tests for the existing `throw`, because this is meant to replace the old spec test someday.
* Add tuple.drop validation (#6186)Alon Zakai2023-12-191-0/+5
| | | | | Without this fuzzer testcases fail if the initial content has a tuple.drop but multivalue is disabled (then the initial content validates erroneously, and that content is remixed into more content using multivalue which fails to validate).
* [EH] Add instructions for new proposal (#6181)Heejin Ahn2023-12-1931-29/+503
| | | | | | | | | | | | | | | | | | | | | | | | This adds basic support for the new instructions in the new EH proposal passed at the Oct CG hybrid CG meeting: https://github.com/WebAssembly/meetings/blob/main/main/2023/CG-10.md https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md This mainly adds two instructions: `try_table` and `throw_ref`. This is the bare minimum required to read and write text and binary format, and does not include analyses or optimizations. (It includes some analysis required for validation of existing instructions.) Validation for the new instructions is not yet included. `try_table` faces the same problem with the `resume` instruction in #6083 that without the module-level tag info, we are unable to know the 'sent types' of `try_table`. This solves it with a similar approach taken in #6083: this adds `Module*` parameter to `finalize` methods, which defaults to `nullptr` when not given. The `Module*` parameter is given when called from the binary and text parser, and we cache those tag types in `sentTypes` array within `TryTable` class. In later optimization passes, as long as they don't touch tags, it is fine to call `finalize` without the `Module*`. Refer to https://github.com/WebAssembly/binaryen/pull/6083#issuecomment-1854634679 and #6096 for related discussions when `resume` was added.
* Remove empty _ARRAY/_VECTOR defines (NFC) (#6182)Heejin Ahn2023-12-1411-37/+3
| | | | | | | `_VECTOR` or `_ARRAY` defines in `wasm-delegations-fields.def` are supposed to be defined in terms of their non-vector/array counterparts when undefined. This removes empty `_VECTOR`/`_ARRAY` defines when including `wasm-delegations-fields.def`, while adding definitions for `DELEGATE_GET_FIELD` in case it is missing.
* [Parser] Parse explicit exports (#6179)Thomas Lively2023-12-143-0/+78
|
* [Parser] Parse tuple operations (#6174)Thomas Lively2023-12-135-18/+103
| | | | | Parse `tuple.make`, `tuple.extract`, and `tuple.drop`. Also slightly improve the way we break up tuples into individual elements in IRBuilder by using a `local.tee` instead of a block containing a `local.set` and `local.get`.
* Preserve multivalue drops in IRBuilder (#6150)Thomas Lively2023-12-132-10/+46
| | | | | | | | | In Binaryen IR, we allow single `Drop` expressions to drop multiple values packaged up as a tuple. When using IRBuilder to rebuild IR containing such a drop, it previously treated the drop as a normal WebAssembly drop that dropped only a single value, producing invalid IR that had extra, undropped values. Fix the problem by preserving the arity of `Drop` inputs in IRBuilder. To avoid bloating the IR, thread the size of the desired value through IRBuilder's pop implementation so that tuple values do not need to be split up and recombined.
* J2CL: Use a more future proof naming convention for once functions (#6173)Goktug Gokdogan2023-12-131-1/+1
| | | | Existing convention uses _@once@_ but we also use @ for class separation. It is cleaner&more future proof to use something other convention like _<once>_.
* [Parser] Parse the remaining array operations (#6158)Thomas Lively2023-12-127-53/+394
| | | | | | | Parse `array.new_elem`, `array.init_data`, and `array.init_elem`. Accidentally also includes: * [Parser] Parse string types and operations (#6161)
* [Parser] Parse rethrow (#6155)Thomas Lively2023-12-124-16/+50
| | | | Like `delegate`, rethrow takes a `Try` label. Refactor the delegate handling so that `Try` can share its logic.
* Add an arity immediate to tuple.extract (#6172)Thomas Lively2023-12-123-6/+12
| | | | | | | | Once support for tuple.extract lands in the new WAT parser, this arity immediate will let the parser determine how many values it should pop off the stack to serve as the tuple operand to `tuple.extract`. This will usually coincide with the arity of a tuple-producing instruction on top of the stack, but in the spirit of treating the input as a proper stack machine, it will not have to and the parser will still work correctly.
* [Parser] Parse table operations (#6154)Thomas Lively2023-12-125-16/+113
| | | | Including table.get, table.set, table.size, table.grow, table.fill, and table.copy.
* J2CL: Add extra guardrails (#6171)Goktug Gokdogan2023-12-121-4/+17
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | The patch puts a new guardrail that will only hoist the field if it is initialized with the owner class. The constant hoisting optimization in J2CL pass relies on the assumption that clinit that will initialize the field will be executed before the read of the field. That means the field that is optimized is within the same class: class Foo { public static final Object field = new Object(); } Although it is possible to observe the initial value, that is not intention of the developer (which the point of the optimization). However can also see a similar pattern in following: class Foo { public static Object field; } class Zoo { static { Foo.field = new Object(); } } Currently the pass also optimizes it as well since the field is only initialized once and by a clinit. However Zoo clinit is not guaranteed to be run before Foo.field access so it is less safe to speculate on the intention of the developer here hence it is not worth the risk. FWIW, we haven't seen this issue. But this is something we are also guarding in Closure Compiler so I decided it is worthwhile to do here as well.
* Add a `tuple.drop` text pseudoinstruction (#6170)Thomas Lively2023-12-125-1/+38
| | | | | | | | | | | | | | | | | We previously overloaded `drop` to mean both normal drops of single values and also drops of tuple values. That works fine in the legacy text parser since it can infer parent-child relationships directly from the s-expression structure of the input, so it knows that a drop should drop an entire tuple if the tuple-producing instruction is a child of the drop. The new text parser, however, is much more like the binary parser in that it uses instruction types to create parent-child instructions. The new parser always assumes that `drop` is meant to drop just a single value because that's what it does in WebAssembly. Since we want to continue to let `Drop` IR expressions consume tuples, and since we will need a way to write tests for that IR pattern that work with the new parser, introduce a new pseudoinstruction, `tuple.drop`, to represent drops of tuples. This pseudoinstruction only exists in the text format and it parses to normal `Drop` expressions. `tuple.drop` takes the arity of its operand as an immediate, which will let the new parser parse it correctly in the future.
* Update `tuple.make` text format to include arity (#6169)Thomas Lively2023-12-124-4/+11
| | | | | | | | | | Previously, the number of tuple elements was inferred from the number of s-expression children of the `tuple.make` expression, but that scheme would not work in the new wat parser, where s-expressions are optional and cannot be semantically meaningful. Update the text format to take the number of tuple elements (i.e. the tuple arity) as an immediate. This new format will be able to be implemented in the new parser as follow-on work.
* Add J2CL optimization pass to binaryen. (#6151)Goktug Gokdogan2023-12-124-0/+224
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This PR creates a new pass to optimize J2CL specific patterns that would otherwise difficult to recognize/prove generically by other binaryen passes. The pass currently handles fields what we call as "constant-like". These fields are fields initialized once and unconditionally through "clinit" function and technically they do have 2 observable states; - initial null/0 state - initialized state. However you can only observe initial null/0 state in contrived examples, not in real world/correct applications. This pass moves such "clinit" initialized fields to global initialization. Above pattern also matches other lazy init construct like String and Class literals (which binaryen already reduces to constant expressions). So the pass is generalized to include them as well. (by matching any functions with the name pattern "_@once_") In order for this pass to be effective: 1. It needs to run between O3 passes 2. We need to stop inlining of "once" functions. Stopping inlining of the once functions are important to preserve their structure. This both helps existing OnceReducer pass and new J2CL pass to be a lot more effective. Also it is not useful to inline these functions as by defintion they only executed once. This could be achieved by passing no-inline filter. Although the inlining is generally disabled for these functions, it is still needed for some cases since inliner is effectively responsible for removal of the once functions that are simplified into empty or simple delegating functions. For this reason, the pass will rename such trivial function so no-inline filter will no longer match them. Also note that after all optimizations completed, it does make sense to have a final stage where the "partial inline" of all once functions are allowed. This will speed them up by moving the initialization check to call-site.