summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* 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.
* Inlining: Copy no-inline flags when copying a function (#6165)Alon Zakai2023-12-121-0/+3
| | | | Those fields should be copied together with all the rest of the metadata that already is. This was just missed in the prior PR.
* [EH] Use random value for exnref encoding when legacy GC is used (#6166)Heejin Ahn2023-12-111-6/+20
| | | | | Currently the legacy GC encoding's nullexternref encoding overlaps with exnref's. We assume the legacy GC encoding won't be used with the exnref for the moment and assign a random value to it to prevent the clash.
* [EH] Add exnref type back (#6149)Heejin Ahn2023-12-089-11/+131
| | | | | | | | | | | | | At the Oct hybrid CG meeting, we decided to add back `exnref`, which was removed in 2020: https://github.com/WebAssembly/meetings/blob/main/main/2023/CG-10.md The new version of the proposal reflected in the explainer: https://github.com/WebAssembly/exception-handling/blob/main/proposals/exception-handling/Exceptions.md While adding support for `exnref` in the current codebase which has all GC subtype hierarchies, I noticed we might need `noexn` heap type for the bottom type of `exn`. We don't have it now so I just set it to 0xff for the moment.
* [NFC] Use a reference instead of a pointer in Inlining (#6153)Alon Zakai2023-12-071-11/+11
|
* [Outlining] Add loop instruction supportAshley Nelson2023-12-071-0/+3
| | | | | | | | | | Adds support for the loop instruction to be outlined and a test showing a repeat loop being outlined. Reviewers: tlively Reviewed By: tlively Pull Request: https://github.com/WebAssembly/binaryen/pull/6141
* [Outlining] Improve debug loggingAshley Nelson2023-12-073-22/+36
| | | | | | | | | | | | - Change outlining debug logs to use std::cerr - Add controlFlowQueue push log - Fix build error with wasm-ir-builder log's use of ShallowExpression Reviewers: tlively Reviewed By: tlively Pull Request: https://github.com/WebAssembly/binaryen/pull/6140
* [Outlining] Fix outlining control flowAshley Nelson2023-12-063-10/+23
| | | | | | | | | | Changes the controlFlowQueue used in stringify-walker to push values of Expression*, This ensures that we walk the Wasm module in the same order, regardless of whether the control flow expression is outlined. Reviewers: tlively Reviewed By: tlively Pull Request: https://github.com/WebAssembly/binaryen/pull/6139
* [Parser] Parse call_indirect and return_call_indirect (#6148)Thomas Lively2023-12-064-3/+36
|
* [Parser] Parse tables and element segments (#6147)Thomas Lively2023-12-066-20/+540
| | | | | | | These module fields are especially complex to parse because they contain both nontrivial types and instructions, so their parsing logic needs to be spread out across the ParseDecls, ParseModuleTypes, and ParseDefs phases of parsing. This applies to in-line elements in table definitions as well, which means we need to be able to match a table to its in-line element segment across multiple phases.
* Add no-inline IR annotation, and passes to set it based on function name (#6146)Alon Zakai2023-12-066-8/+108
| | | | | | | | | | | | | Any function can now be annotated as not to be inlined fully (normally) or not to be inlined partially. In the future we'll want to read those annotations from the proposed wasm metadata section on code hints, and from wat text as well, but for now add trivial passes that set those fields based on function name wildcards, e.g.: --no-inline=*leave-alone* --inlining That will not inline any function whose name contains "leave-alone" in the name. --no-inline disables all inlining (full or partial) while --no-full-inline and --no-partial-inline affect only full or partial inlining.
* Inlining: Inline trivial calls (#6143)Alon Zakai2023-12-052-13/+49
| | | | | | | | | | | | | | | | A trivial call is something like a function that just calls another immediately, function foo(x, y) { return bar(y, 15); } We can inline those and expect to benefit in most cases, though we might increase code size slightly. Hence it makes sense to inline such cases, even though in general we are careful and do not inline functions with calls in them; a "trampoline" like that likely has most of the work in the call itself, which we can avoid by inlining. Suggested based on findings in Java.
* wasm-metadce all the things (#6142)Alon Zakai2023-11-304-141/+162
| | | | | | | | | | | | | | | Remove hardcoded paths for globals/functions/etc. in favor of general code paths that support all the module elements uniformly. As a result of that, we now support all parts of wasm, such as tables and element segments, that we didn't before. This refactoring is NFC aside from adding functionality. Note that this reduces the size of wasm-metadce by 10% while increasing its functionality - the benefits of writing generic code. To support this, add some trivial generic helpers to get or iterate over module elements using their kind in a dynamic manner. Using them might make wasm-metadce slightly slower, but I can't measure any difference.
* wasm-metadce: Improve name deduplication (#6138)Alon Zakai2023-11-301-2/+5
| | | | | | | | | | | | Avoid adding suffixes when we don't need them to keep names unique. As background, the suffixes are not used by emcc at all, so they are just for internal use in the tool. How that works is that metadce gets as input the list of things the user cares about, with names for them, so it knows the proper names to give imports and exports, and makes up names for other things. Those made up names will not be read by the user, so we can make them prettier as this PR does without breaking anything. The main benefit of this PR is to make debugging easier.