summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* Add a TypeNameGenerator that uses names from a Module (#5437)Thomas Lively2023-01-182-1/+33
| | | | | | | | | If the module does not have a name for a particular type, the new utility falls back to use a different user-configurable type name generator, just like the existing IndexedTypeNameGenerator does. Also change how heap types are printed by this printing machinery (which is currently only used for debugging) so that their names are printed in addition to their contents. This makes the printer much more useful for debugging.
* Factor supertype-first type sort into separate header (#5436)Thomas Lively2023-01-182-25/+70
| | | | | | | | | | | | | | | type-updating.cpp implemented a topological sorts on heap types that would visit supertypes first. Since this same sort will be used by TypeMerging.cpp in #5432, factor it out into a shared utility in a new wasm-type-ordering.h header. At the same time, fix a bug in which the sort would visit types not in the input collection. Concretely, this bug would cause public supertypes of private types to be visited when only private types should have been visited. This functionality change will be tested in #5432. In principle the subtype-first sort used in subtypes.h could also be moved to this header, but that is not yet duplicated in the code base and is more efficient because it depends on implementation details of its current context, so do not move it for now.
* Add Valmari-Lehtinen DFA minimization as a standalone utility (#5430)Thomas Lively2023-01-173-0/+466
| | | | | | | | We used to have this algorithm in wasm-type.cpp, where we used it to implement equirecursive type canonicalization, but we removed it when we removed equirecursive typing. Bring the algorithm back as a standalone utility for future use in optimization passes. In particular, it will be useful in TypeMerging for identifying the greatest fixed point of mergeable types rather than the smallest fixed point.
* [NFC] Work a little more efficiently in RemoveUnusedModuleElements (#5429)Alon Zakai2023-01-131-22/+33
| | | | | | Before, we'd potentially add a new item to the queue multiple times, then do nothing when popping it from the queue in the second and later times. With this PR we add a new item to the reachable set and to the queue at the same time, so items cannot appear more than once in the queue.
* [Wasm GC] SignaturePruning should not prune fields from a type with subtypes ↵Alon Zakai2023-01-131-3/+11
| | | | | | (#5427) For subtyping to not break, we must leave the number of fields equal in both super and subtype, for each such pair.
* Move closed world flag to tool options (#5428)Alon Zakai2023-01-132-13/+13
| | | | This allows tools like wasm-reduce to be told to operate in closed-world mode. That lets them validate in the more strict way of that mode.
* [Wasm GC] Optimize successful casts better (#5426)Thomas Lively2023-01-132-26/+56
| | | | | | Optimize ref.cast instructions that must succeed by simply replacing them with their child in the case where the child has a more refined type or by propagating a further removed fallthrough value with a more refined type using a tee.
* [Wasm GC] Allow TypeMerging to merge cast types with TNH (#5425)Thomas Lively2023-01-121-4/+19
| | | | | | If traps are assumed never to happen, then ref.cast and call_indirect instructions cannot differentiate between types because they always succeed. Take advantage of this fact by only having these instructions inhibit type merges when we are not assuming traps never happen.
* [Wasm GC] Support and fuzz function subtyping (#5420)Thomas Lively2023-01-123-53/+196
| | | | | | | | | | Support function subtyping with contravariant parameters and covariant results. The actual change is a single line in wasm-type.cpp, so most of the patch is updating the type fuzzer to generate interesting function subtypes. Since function parameters are covariant, generating a function subtype requires generating supertypes of its parameter types, which required new functionality in the fuzzer. Also update the fuzzer to choose to reuse types at a finer grain, so for example individual function parameters or results might be reused unmodified while other parameters or results are still modified.
* [Wasm GC] Optimize casts of null values better (#5423)Thomas Lively2023-01-122-37/+29
| | | | | | | | | Instead of only looking at the final fallthrough value and seeing whether it is a `RefNull` expression to determine if we are casting a null value, check the type of each intermediate fallthrough value to see if it is a null reference. Also improve `evaluateCastCheck` to return `Failure` instead of `SuccessOnlyIfNonNull` if the cast value is a reference to bottom type, since those can never be non-null.
* [Wasm GC] Fix cast finding in TypeMerging (#5424)Thomas Lively2023-01-121-27/+14
| | | | | | | | | | The cast finding code in TypeMerging has been broken since we refactored how casts work to support nullable casts. The cast finding code only considered HeapType fields and the return type of `RefCast` to be potential cast targets, but `RefTest` and `BrOn` instructions now store their cast types as `Type` fields. Since cast targets are represented more heterogenously now, do not use the delegations macros to find them. Add tests showing that each cast instruction independently inhibits merging.
* [Wasm GC] Generalize `skipCast` to work with all type hierarchies (#5422)Thomas Lively2023-01-121-4/+5
| | | | | | | | `skipCast` takes an optional parameter that bounds how general the resulting type is allowed to be. That parameter previously had a default value of `anyref` with the intention of allowing all casts to be skipped, but that default inadvertently prevented any casts in the `func` or `extern` type hierarchies from being skipped. Update `skipCast` so that the default parameter allows all casts to be skipped in all hierarchies.
* [NFC] Remove GCTypeUtils::evaluateKindCheck (#5421)Thomas Lively2023-01-112-70/+33
| | | | | | | | Since we refactored all the old kind-checking instructions to be represented as general cast instructions, `GCTypeUtils::evaluateKindCheck` had become a vestigial wrapper around `GCTypeUtils::evaluateCastCheck` that was only used in RemoveUnusedBrs. Remove `evaluateKindCheck` and use `evaluateCastCheck` in RemoveUnusedBrs without changing any functionality. A future PR may use the extra information from `evaluateCastCheck` to further optimize branching casts.
* [binaryen.js] Avoid use of the global buffer var which emcc has removed (#5419)Alon Zakai2023-01-111-1/+1
|
* [Wasm GC] Handle an unreachable br_on_cast_fail in DCE (#5418)Alon Zakai2023-01-111-1/+4
| | | Without this we hit an assertion on unreachable not being a heap type.
* [Wasm GC] Add missing RefTest optimizations to parallel RefCast (#5417)Alon Zakai2023-01-101-10/+23
| | | | We already handled Success and Failure. Also handle SuccessOnlyIfNull and SuccessOnlyIfNonNull.
* [Wasm GC] Replace `HeapType::data` with `HeapType::struct_` (#5416)Thomas Lively2023-01-1016-196/+126
| | | | | | `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.
* Represent ref.as_{func,data,i31} with RefCast (#5413)Thomas Lively2023-01-1016-145/+91
| | | | | | | | | | | | | These operations are deprecated and directly representable as casts, so remove their opcodes in the internal IR and parse them as casts instead. For now, add logic to the printing and binary writing of RefCast to continue emitting the legacy instructions to minimize test changes. The few test changes necessary are because it is no longer valid to perform a ref.as_func on values outside the func type hierarchy now that ref.as_func is subject to the ref.cast validation rules. RefAsExternInternalize, RefAsExternExternalize, and RefAsNonNull are left unmodified. A future PR may remove RefAsNonNull as well, since it is also expressible with casts.
* [NFC] Refactor cast check logic (#5404)Alon Zakai2023-01-102-108/+81
| | | Add a new evaluateCastCheck() utility and use that in relevant places.
* [Wasm GC] Optimize ref.as_non_null of a nullable cast (#5415)Alon Zakai2023-01-101-0/+16
|
* Fix iterator invalidation bug in GlobalStructInference (#5414)Alon Zakai2023-01-101-1/+3
| | | Fixes #5406
* [Wasm GC] More minor cast optimizations (#5402)Alon Zakai2023-01-091-84/+89
| | | | | | | | Look for definitely-failing casts along all the fallthrough values. Specifically, if any cast in the middle proves the final cast will fail, then we know we will trap. Fully optimize redundant casts, considering both the type and the heap type. Combine a cast with a ref.as_non_null.
* Replace `RefIs` with `RefIsNull` (#5401)Thomas Lively2023-01-0928-283/+158
| | | | | | | | | | | | | | | * Replace `RefIs` with `RefIsNull` The other `ref.is*` instructions are deprecated and expressible in terms of `ref.test`. Update binary and text parsing to parse those instructions as `RefTest` expressions. Also update the printing and emitting of `RefTest` expressions to emit the legacy instructions for now to minimize test changes and make this a mostly non-functional change. Since `ref.is_null` is the only `RefIs` instruction left, remove the `RefIsOp` field and rename the expression class to `RefIsNull`. The few test changes are due to the fact that `ref.is*` instructions are now subject to `ref.test` validation, and in particular it is no longer valid to perform a `ref.is_func` on a value outside of the `func` type hierarchy.
* [Wasm GC] Do not treat extern conversions as casts (#5411)Thomas Lively2023-01-091-1/+6
| | | | | | | | In particular, do not treat the converted value as "falling through" the conversion. Since the conversions cross type hierarchies, treating the converted values as fallthrough values would make subsequent casts look like they must fail, when in fact they may not. Fixes #5407.
* [Wasm GC] Refinalize in Vacuum (#5412)Alon Zakai2023-01-091-0/+13
| | | | | | We use TypeUpdater there, which handles updating unreachability. But with wasm GC we also need to refinalize if we refine types. Somehow, this was not noticed until now, but the new ref.cast null assertion on not losing type info was enough to uncover this long-existing issue.
* [Wasm GC] Add missing unreachable check in evaluateKindCheck (#5410)Alon Zakai2023-01-091-1/+3
|
* Fix a bug optimizing out br_on_cast (#5403)Thomas Lively2023-01-061-3/+7
| | | | | | | We were considering casts between unrelated types as unconditionally failing, but in the case where the unrelated types are nullable, the cast could still succeed if the value is null. This bug was introduced in #5397.
* [Wasm GC] Optimize impossible ref.casts better (#5400)Alon Zakai2023-01-061-19/+42
| | | | | | Also add some comments on related optimization opportunities. Also delete a test of a combination of types between hierarchies, which will soon not be expressible at all in the IR.
* Consolidate br_on* operations (#5399)Thomas Lively2023-01-0615-222/+172
| | | | | | | | | | | | | | | | | | The `br_on{_non}_{data,i31,func}` operations are deprecated and directly representable in terms of the new `br_on_cast` and `br_on_cast_fail` instructions, so remove their dedicated IR opcodes in favor of representing them as casts. `br_on_null` and `br_on_non_null` cannot be consolidated the same way because their behavior is not directly representable in terms of `br_on_cast` and `br_on_cast_fail`; when the cast to null bottom type succeeds, the null check instructions implicitly drop the null value whereas the cast instructions would propagate it. Add special logic to the binary writer and printer to continue emitting the deprecated instructions for now. This will allow us to update the test suite in a separate future PR with no additional functional changes. Some tests are updated because the validator no longer allows passing non-func data to `br_on_func`. Doing so has not made sense since we separated the three reference type hierarchies.
* [Wasm GC] Fix optimizations on ref.cast of null, and optimize to ↵Alon Zakai2023-01-061-1/+19
| | | | | | | | | | ref.as_non_null (#5398) We were checking the heap type, but now casts care about the nullability as well. If the nullability is the only problem, that is, the heap type will be fine but we might have a null, we can at least switch a ref.cast (non-null) to a ref.as_non_null.
* Support br_on_cast null (#5397)Thomas Lively2023-01-0515-56/+114
| | | | | | | | | As well as br_on_cast_fail null. Unlike the existing br_on_cast* instructions, these new instructions treat the cast as succeeding when the input is a null. Update the internal representation of the cast type in `BrOn` expressions to be a `Type` rather than a `HeapType` so it will include nullability information. Also update and improve `RemoveUnusedBrs` to handle the new instructions correctly and optimize in more cases.
* [Wasm GC] Fix non-nullable cast optimizations with multiple children (#5396)Alon Zakai2023-01-051-1/+32
| | | This fixes an oversight in #5395
* [Wasm GC] Turn casts non-nullable when they lead to a trap on null anyhow ↵Alon Zakai2023-01-051-0/+15
| | | | (#5395)
* [Wasm GC] Clean up and improve null trap and cast optimizations (#5394)Alon Zakai2023-01-051-20/+21
| | | | | | | | | visitRefCast can use trapOnNonNull. To make this not regress, add fallthrough analysis there as well. Minor test changes are due to trapOnNonNull using getDroppedChildren which only emits drops of necessary children. It also tells us to refinalize so it is ok for it to change the type to unreachable.
* [Parser] Parse blocks (#5393)Thomas Lively2023-01-053-18/+240
| | | | | | | | | | | | | Parse both the folded and unfolded forms of blocks and structure the code to make supporting additional block instructions like if-else and try-catch relatively simple. Parsing block types is extra fun because they may implicitly define new signature heap types via a typeuse, but only if their types are not given by a single result type. To figuring out whether a new type may be introduced in all the relevant parsing stages, always track at least the arity of parsed results. The parser parses block labels, but more work will be required to support branch instructions that use them.
* wasm2js: Stop emitting nan and infinity (#5391)Will Cohen2023-01-043-30/+6
| | | | | | | As noted in #4739, legacy language emitting nan and infinity exists, with the observation that it can be removed once asm.js is no longer used and global NaN is available. This commit removes that asm.js-specific code accordingly.
* [Wasm GC] Ignore call.without.effects for closed world validation (#5392)Alon Zakai2023-01-041-2/+8
| | | | It is implemented as an import, but functionally it is a call within the module, so it does not cause types to be public.
* wasm2js: Avoid emitting non-JS code during opt (#5378)Will Cohen2023-01-043-1/+13
| | | | | | | | | | | As noted in #4806, trying to optimize past level 0 can result in passes emitting non-JS code, which is then unable to be converted during final output. This commit creates a new targetJS option in PassOptions, which can be checked inside each pass where non-JS code might be emitted. This commit initially adds that logic to OptimizeInstructions, where this issue was first noticed.
* Allow non-nullable ref.cast of nullable references (#5386)Thomas Lively2023-01-045-43/+27
| | | | | | | This new cast configuration was not expressible with the legacy cast instructions. Although it is valid in Wasm, do not allow nullable casts of non-nullable references, since those would unnecessarily lose type information. Convert such casts to be non-nullable during expression finalization.
* [Wasm GC] Enforce closed-world in GlobalStructInference (#5385)Alon Zakai2023-01-031-0/+4
| | | | | | | After making the pass error when not in closed world, some testcases required changes. One forward-looking testcase can just be removed - the point of it was to see what happens if a type escapes, and now closed-world errors on it - and another testcase needed to avoid types on the boundary, and to use anyref+casts.
* [Wasm GC] Fix GlobalStructInference reasoning on unoptimizability (#5381)Alon Zakai2023-01-031-4/+18
| | | | | | | | | | | | | | | We have a data structure there, typeGlobals, which maps types to the list of globals for that type. Previously we used the convention of not having an entry in the map to mean that a type is unoptimizable. However, this was not used consistently, and in fact one place could insert to the map in a dangerous way: a subtype's global is added to the list of globals of the super, and typeGlobals[super].add(sub-global) would then effectively make an unoptimizable super into an optimizable one. To fix that, check for unoptimizability before propagating sub-globals. We do still use the convention of not keeping data in typeGlobals for unoptimizable things as it is a minor optimization to avoid wasted work. Fixes #5379
* Write debug info in Pass-Debug mode 3 (#5384)Alon Zakai2023-01-031-1/+1
| | | | Without the names section debugging can be hard sometimes, on the binaries that that mode emits for each pass.
* [Parser] Parse array access instructions (#5375)Thomas Lively2023-01-031-5/+82
| | | | | | | | | | | | | | | | | | | | | | | | | | | | * [NFC][Parser] Track definition indices For each definition in a module, record that definition's index in the relevant index space. Previously the index was inferred from its position in a list of module definitions, but that scheme does not scale to data segments defined inline inside memory definitions because these data segments occupy a slot in the data segment index space but do not have their own independent definitions. * clarify comment * [Parser] Parse data segments Parse active and passive data segments, including all their variations and abbreviations as well as data segments declared inline in memory declarations. Switch to parsing data strings, memory limits, and memory types during the ParseDecls phase so that the inline data segments can be completely parsed during that phase and never revisited. Parsing the inline data segments in a later phase would not work because they would be incorrectly inserted at the end of the data segment index space. Also update the printer to print a memory use on active data segments that are initialized in a non-default memory. * [Parser] Parse array creation and data segment instructions * [Parser] Parse array access instructions
* [Parser] Parse array creation and data segment instructions (#5374)Thomas Lively2023-01-031-8/+145
| | | | | | | | | | | | | | | | | | | | | | | | | | * [NFC][Parser] Track definition indices For each definition in a module, record that definition's index in the relevant index space. Previously the index was inferred from its position in a list of module definitions, but that scheme does not scale to data segments defined inline inside memory definitions because these data segments occupy a slot in the data segment index space but do not have their own independent definitions. * clarify comment * [Parser] Parse data segments Parse active and passive data segments, including all their variations and abbreviations as well as data segments declared inline in memory declarations. Switch to parsing data strings, memory limits, and memory types during the ParseDecls phase so that the inline data segments can be completely parsed during that phase and never revisited. Parsing the inline data segments in a later phase would not work because they would be incorrectly inserted at the end of the data segment index space. Also update the printer to print a memory use on active data segments that are initialized in a non-default memory. * [Parser] Parse array creation and data segment instructions
* [Parser] Parse data segments (#5373)Thomas Lively2023-01-033-35/+196
| | | | | | | | | | | | | | | | | | | | | | | | * [NFC][Parser] Track definition indices For each definition in a module, record that definition's index in the relevant index space. Previously the index was inferred from its position in a list of module definitions, but that scheme does not scale to data segments defined inline inside memory definitions because these data segments occupy a slot in the data segment index space but do not have their own independent definitions. * clarify comment * [Parser] Parse data segments Parse active and passive data segments, including all their variations and abbreviations as well as data segments declared inline in memory declarations. Switch to parsing data strings, memory limits, and memory types during the ParseDecls phase so that the inline data segments can be completely parsed during that phase and never revisited. Parsing the inline data segments in a later phase would not work because they would be incorrectly inserted at the end of the data segment index space. Also update the printer to print a memory use on active data segments that are initialized in a non-default memory.
* Maintain first memory import/export in Multi-Memory Lowering Pass (#5363)Ashley Nelson2023-01-031-2/+50
| | | This PR maintains the first memory's import/export in the single combined memory after multi-memories are lowered.
* [NFC][Parser] Track definition indices (#5372)Thomas Lively2023-01-031-13/+17
| | | | | | | | | | | * [NFC][Parser] Track definition indices For each definition in a module, record that definition's index in the relevant index space. Previously the index was inferred from its position in a list of module definitions, but that scheme does not scale to data segments defined inline inside memory definitions because these data segments occupy a slot in the data segment index space but do not have their own independent definitions. * clarify comment
* Move assert in MultiMemoryLowering (#5376)Ashley Nelson2023-01-031-3/+6
| | | Moved the assert that checks whether the DataSegment* offset type is Const. This assert only needs to happen when the DataSegment belongs to a memory other than the first.
* [Wasm GC] Do not refine types of exported globals in closed world (#5380)Alon Zakai2023-01-034-10/+64
| | | | | | Doing so can cause us to switch from a private type to a public type and error. Also refactor export-utils to make this easy.
* Make wasm::IString::operator bool() explicit (#5371)higher-performance2022-12-211-1/+1
| | | Fixes #5370