summaryrefslogtreecommitdiff
path: root/test/lit/passes/optimize-instructions-call_ref.wast
Commit message (Collapse)AuthorAgeFilesLines
* Use empty blocks instead of nops for empty scopes in IRBuilder (#7080)Thomas Lively2024-11-141-1/+0
| | | | | | | | | | When IRBuilder builds an empty non-block scope such as a function body, an if arm, a try block, etc, it needs to produce some expression to represent the empty contents. Previously it produced a nop, but change it to produce an empty block instead. The binary writer and printer have special logic to elide empty blocks, so this produces smaller output. Update J2CLOpts to recognize functions containing empty blocks as trivial to avoid regressing one of its tests.
* Do not abbreviate items in element segments (#6737)Thomas Lively2024-07-121-1/+1
| | | | | | | | The full syntax for an expression in an element syntax looks like `(item (ref.null none))`, but we have been printing the abbreviated version, which omits the `(item ...)`. This abbreviation is only valid when the item has only a single instruction, so it is not always correct to use it. Rather than determining whether or not to use the abbreviation on a case-by-case basis, always print the full syntax.
* [DebugInfo] Copy debug info in call-utils.h (#6652)Alon Zakai2024-06-121-2/+23
| | | | | | | | | | | | | | | | | | | | | | | We automatically copy debuginfo in replaceCurrent(), but there are a few places that do other operations than simple replacements. call-utils.h will turn a call_ref with a select target into two direct calls, and we were missing the logic to copy debuginfo from the call_ref to the calls. To make this work, refactor out the copying logic from wasm-traversal, into debuginfo.h, and use it in call-utils.h. debuginfo.h itself is renamed from debug.h (as now this needs to be included from wasm-traversal, which nearly everything does, and it turns out some files have internal stuff like a debug() helper that ends up conflicing with the old debug namespace). Also rename the old copyDebugInfo function to copyDebugInfoBetweenFunctions which is more explicit. That is also moved from the header to a cpp file because it depends on wasm-traversal (so we'd end up with recursive headers otherwise). That is fine, as that method is called after copying a function, which is not that frequent. The new copyDebugInfoToReplacement (which was refactored out of wasm-traversal) is in the header because it can be called very frequently (every single instruction we optimize) and we want it to get inlined.
* [Parser] Enable the new text parser by default (#6371)Thomas Lively2024-04-251-0/+6
| | | | | | | | | | | | | | The new text parser is faster and more standards compliant than the old text parser. Enable it by default in wasm-opt and update the tests to reflect the slightly different results it produces. Besides following the spec, the new parser differs from the old parser in that it: - Does not synthesize `loop` and `try` labels unnecessarily - Synthesizes different block names in some cases - Parses exports in a different order - Parses `nop`s instead of empty blocks for empty control flow arms - Does not support parsing Poppy IR - Produces different error messages - Cannot parse `pop` except as the first instruction inside a `catch`
* [NFC] Add the type of the Expression when eliding it (#6362)Alon Zakai2024-02-281-2/+2
| | | | | | | | | | In some cases we don't print an Expression in full if it is unreachable, so we print something instead as a placeholder. This happens in unreachable code when the children don't provide enough info to print the parent (e.g. a StructGet with an unreachable reference doesn't know what struct type to use). This PR prints out the name of the Expression type of such things, which can help debugging sometimes.
* Require `then` and `else` with `if` (#6201)Thomas Lively2024-01-041-12/+20
| | | | | | | | | | | | 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
* Simplify and consolidate type printing (#5816)Thomas Lively2023-08-241-5/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | When printing Binaryen IR, we previously generated names for unnamed heap types based on their structure. This was useful for seeing the structure of simple types at a glance without having to separately go look up their definitions, but it also had two problems: 1. The same name could be generated for multiple types. The generated names did not take into account rec group structure or finality, so types that differed only in these properties would have the same name. Also, generated type names were limited in length, so very large types that shared only some structure could also end up with the same names. Using the same name for multiple types produces incorrect and unparsable output. 2. The generated names were not useful beyond the most trivial examples. Even with length limits, names for nontrivial types were extremely long and visually noisy, which made reading disassembled real-world code more challenging. Fix these problems by emitting simple indexed names for unnamed heap types instead. This regresses readability for very simple examples, but the trade off is worth it. This change also reduces the number of type printing systems we have by one. Previously we had the system in Print.cpp, but we had another, more general and extensible system in wasm-type-printing.h and wasm-type.cpp as well. Remove the old type printing system from Print.cpp and replace it with a much smaller use of the new system. This requires significant refactoring of Print.cpp so that PrintExpressionContents object now holds a reference to a parent PrintSExpression object that holds the type name state. This diff is very large because almost every test output changed slightly. To minimize the diff and ease review, change the type printer in wasm-type.cpp to behave the same as the old type printer in Print.cpp except for the differences in name generation. These changes will be reverted in much smaller PRs in the future to generally improve how types are printed.
* Use the standard syntax for ref.cast, ref.test and array.new_fixed (#5894)Jérôme Vouillon2023-08-231-1/+1
| | | | | | | | | * Update text output for `ref.cast` and `ref.test` * Update text output for `array.new_fixed` * Update tests with new syntax for `ref.cast` and `ref.test` * Update tests with new `array.new_fixed` syntax
* Further improve ref.cast during finalization (#5882)Thomas Lively2023-08-171-1/+1
| | | | | | We previously improved the nullability and heap type of the ref.cast target type in RefCast::finalize() based on what we knew about its input type. Simplify the code and make this improvement more powerful by using the greatest lower bound of the original cast target and input type.
* Improve cast optimizations (#5876)Thomas Lively2023-08-171-5/+8
| | | | | | | | | | | | Simplify the optimization of ref.cast and ref.test in OptimizeInstructions by moving the loop that examines fallthrough values one at a time out to a shared function in properties.h. Also simplify ref.cast optimization by analyzing the cast result in just one place. In addition to simplifying the code, also make the cast optimizations more powerful by analyzing the nullability and heap type of the cast value independently, resulting in a potentially more precise analysis of the cast behavior. Also improve optimization power by considering fallthrough values when optimizing the SuccessOnlyIfNonNull case.
* [Wasm GC] Replace `HeapType::data` with `HeapType::struct_` (#5416)Thomas Lively2023-01-101-4/+4
| | | | | | `struct` has replaced `data` in the upstream spec, so update Binaryen's types to match. We had already supported `struct` as an alias for data, but now remove support for `data` entirely. Also remove instructions like `ref.is_data` that are deprecated and do not make sense without a `data` type.
* Use non-nullable ref.cast for non-nullable input (#5335)Thomas Lively2022-12-091-1/+1
| | | | | | | | | | | | We switched from emitting the legacy `ref.cast_static` instruction to emitting `ref.cast null` in #5331, but that wasn't quite correct. The legacy instruction had polymorphic typing so that its output type was nullable if and only if its input type was nullable. In contrast, `ref.cast null` always has a a nullable output type. Fix our output by instead emitting non-nullable `ref.cast` if the output should be non-nullable. Parse `ref.cast` in binary and text forms as well. Since the IR can only represent the legacy polymorphic semantics, disallow unsupported casts from nullable to non-nullable references or vice versa for now.
* Add standard versions of WasmGC casts (#5331)Thomas Lively2022-12-071-1/+1
| | | | | | | We previously supported only the non-standard cast instructions introduced when we were experimenting with nominal types. Parse the names and opcodes of their standard counterparts and switch to emitting the standard names and opcodes. Port all of the tests to use the standard instructions, but add additional tests showing that the non-standard versions are still parsed correctly.
* Update tests ahead of transition from `data` to `struct` (#5320)Thomas Lively2022-12-071-7/+7
| | | | | | | | | | The upstream WasmGC spec has removed `data` and introduced `struct`. To make the migration easier, we have been supporting `struct` as an `alias` for `data` and `structref` as an alias for `dataref`. Update the tests to prefer the `struct` aliases over `data` for test input to make the future migration easier. Also update some tests that had stale comments about ref.null types being updated and remove some tests for instructions like br_on_data and ref.as_data that do not make sense without a `data` type.
* Change the default type system to isorecursive (#5239)Thomas Lively2022-11-231-14/+14
| | | | | | | | | | This makes Binaryen's default type system match the WasmGC spec. Update the way type definitions without supertypes are printed to reduce the output diff for MVP tests that do not involve WasmGC. Also port some type-builder.cpp tests from test/example to test/gtest since they needed to be rewritten to work with isorecursive type anyway. A follow-on PR will remove equirecursive types completely.
* Revert "Revert "Make `call_ref` type annotations mandatory (#5246)" (#5265)" ↵Thomas Lively2022-11-161-12/+14
| | | | | (#5266) This reverts commit 570007dbecf86db5ddba8d303896d841fc2b2d27.
* Revert "Make `call_ref` type annotations mandatory (#5246)" (#5265)Thomas Lively2022-11-161-14/+12
| | | | | This reverts commit b2054b72b7daa89b7ad161c0693befad06a20c90. It looks like the necessary V8 change has not rolled out everywhere yet.
* Make `call_ref` type annotations mandatory (#5246)Thomas Lively2022-11-151-12/+14
| | | | They were optional for a while to allow users to gracefully transition to using them, but now make them mandatory to match the upstream WasmGC spec.
* Implement bottom heap types (#5115)Thomas Lively2022-10-071-0/+3
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | These types, `none`, `nofunc`, and `noextern` are uninhabited, so references to them can only possibly be null. To simplify the IR and increase type precision, introduce new invariants that all `ref.null` instructions must be typed with one of these new bottom types and that `Literals` have a bottom type iff they represent null values. These new invariants requires several additional changes. First, it is now possible that the `ref` or `target` child of a `StructGet`, `StructSet`, `ArrayGet`, `ArraySet`, or `CallRef` instruction has a bottom reference type, so it is not possible to determine what heap type annotation to emit in the binary or text formats. (The bottom types are not valid type annotations since they do not have indices in the type section.) To fix that problem, update the printer and binary emitter to emit unreachables instead of the instruction with undetermined type annotation. This is a valid transformation because the only possible value that could flow into those instructions in that case is null, and all of those instructions trap on nulls. That fix uncovered a latent bug in the binary parser in which new unreachables within unreachable code were handled incorrectly. This bug was not previously found by the fuzzer because we generally stop emitting code once we encounter an instruction with type `unreachable`. Now, however, it is possible to emit an `unreachable` for instructions that do not have type `unreachable` (but are known to trap at runtime), so we will continue emitting code. See the new test/lit/parse-double-unreachable.wast for details. Update other miscellaneous code that creates `RefNull` expressions and null `Literals` to maintain the new invariants as well.
* Emit call_ref with a type annotation (#5079)Thomas Lively2022-09-231-3/+3
| | | | | | | Emit call_ref instructions with type annotations and a temporary opcode. Also implement support for parsing optional type annotations on call_ref in the text and binary formats. This is part of a multi-part graceful update to switch Binaryen and all of its users over to using the type-annotated version of call_ref without there being any breakage.
* Add a type annotation to return_call_ref (#5068)Thomas Lively2022-09-221-1/+1
| | | | | | The GC spec has been updated to have heap type annotations on call_ref and return_call_ref. To avoid breaking users, we will have a graceful, multi-step upgrade to the annotated version of call_ref, but since return_call_ref has no users yet, update it in a single step.
* Make `i31ref` and `dataref` nullable (#4843)Thomas Lively2022-08-261-4/+4
| | | | | | | Match the latest version of the GC spec. This change does not depend on V8 changing its interpretation of the shorthands because we are still temporarily not emitting the binary shorthands, but all Binaryen users will have to update their interpretations along with this change if they use the text or binary shorthands.
* Fix name of port_passes_tests_to_lit.py script. NFC (#4902)Sam Clegg2022-08-121-1/+1
| | | I was reading these tests and failing to find the names script.
* Remove RTTs (#4848)Thomas Lively2022-08-051-5/+1
| | | | | | | RTTs were removed from the GC spec and if they are added back in in the future, they will be heap types rather than value types as in our implementation. Updating our implementation to have RTTs be heap types would have been more work than deleting them for questionable benefit since we don't know how long it will be before they are specced again.
* OptimizeInstructions: Turn call_ref of a select into an if over two direct ↵Alon Zakai2022-05-271-1/+110
| | | | | | calls (#4660) This extends the existing call_indirect code to do the same for call_ref, basically. The shared code is added to a new helper utility.
* Optimize call_ref+table.get => call_indirect (#4207)Alon Zakai2021-10-041-5/+28
| | | Rather than load from the table and call that reference, call using the table.
* [Wasm GC] Fix invalid intermediate IR in OptimizeInstructions (#4169)Alon Zakai2021-09-201-4/+4
| | | | | | | | | | | | We added an optional ReFinalize in OptimizeInstructions at some point, but that is not valid: The ReFinalize only updates types when all other works is done, but the pass works incrementally. The bug the fuzzer found is that a child is changed to be unreachable, and then the parent is optimized before finalize() is called on it, which led to an assertion being hit (as the child was unreachable but not the parent, which should also be). To fix this, do not change types in this pass. Emit an extra block with a declared type when necessary. Other passes can remove the extra block.
* OptimizeInstructions: Handle trivial ref.cast and ref.test (#4097)Alon Zakai2021-08-241-5/+11
| | | | | If the types are completely incompatible, we know the cast will fail. However, ref.cast does allow a null to pass through, which makes it a little more complicated.
* Improve optimization of call_ref into direct calls (#4068)Alon Zakai2021-08-101-0/+203
First, move the tiny pattern of call-ref-of-ref-func from Directize into OptimizeInstructions. This is important because Directize is a global optimization pass - it looks at the table to see if a CallIndirect can be turned into a direct call. We only run global passes at the end of the pipeline, but we don't need any global data for call-ref of a ref-func, and OptimizeInstructions is the place for such patterns. Second, extend that to also handle fallthrough values. This is less simple, but as call_ref is so inefficient, it's worth doing all we can.