summaryrefslogtreecommitdiff
path: root/test/lit/passes
Commit message (Collapse)AuthorAgeFilesLines
* [Wasm GC] Fix struct.set / ref.as_non_null ordering issue (#5474)Alon Zakai2023-02-021-0/+47
| | | | | | | | | | | If traps can happen, then we can't always remove a trap on null on the ref input to struct.set, since it has two children, (struct.set (ref.as_non_null X) (call $foo)) Removing the ref.as would not prevent a trap, as the struct.set will trap, but it does move the trap to after the call which is bad.
* [Wasm GC] Fix RemoveUnusedModuleEffects struct field reads with ↵Alon Zakai2023-02-021-0/+73
| | | | | | | | | | | | | | | | | | call.without.effects (#5477) If we see (struct.new $A (call $call.without.effects ;; intrinsic (ref.func $getter) ) ) then we can ignore side effects in that call, as the intrinsic tells us to. However, that function is still called (it will be called normally, after intrinsics are lowered away), and we should not remove it. That is, such an intrinsic call can be removed, but it cannot be left as it is and also ignored as if it does not exist.
* RemoveUnusedModuleElements: Support function subtyping (#5470)Alon Zakai2023-02-011-8/+55
| | | | When we see a call_ref or call_indirect of a heap type, we might be calling a subtype of that type.
* RemoveUnusedModuleElements: Optimize unread struct.new fields (#5445)Alon Zakai2023-02-011-0/+1223
| | | | | | | | | | | | | | | | | | | | | | | | | | | | This is similar to the existing optimization for function references: a RefFunc is just a reference, and we do not consider the function actually used unless some CallRef can actually call it. Here we optimize StructNew fields by tracking if they are read. Consider this object: (struct.new $object (global.get $vtable) ) Before this PR, when we saw that StructNew we'd make that global used, and process all of its contents, which look like this: (global $vtable (struct.new $object (ref.func $foo) ) ) With this PR we track which fields on the struct types are even read. If they are not then we do not add uses of the things they refer to. In this example, the global vtable would be referenced, but not used, and likewise the RefFunc inside it. The technical way we handle this is to walk StructNews carefully: when we see a field that has been read, we can just read it normally, but if it has not been read then we note it on the side, and only process it later if we see a read.
* RemoveUnusedModuleElements: Handle changes to tables (#5469)Alon Zakai2023-01-311-0/+61
| | | | | This is a long-standing bug - we ignored the possibility of table.set in this pass. We have few tests for this so it took a while for the fuzzer to notice it I suppose.
* OptimizeInstructions: Handle signed overflow properly in canOverflow() (#5467)Alon Zakai2023-01-311-13/+67
| | | | | We only checked for an unsigned overflow, which was wrong. Fixes #5464
* Fix auto-updating of a test (#5462)Alon Zakai2023-01-271-3/+0
| | | | The test now has a CHECK-NOT, so we can't auto-update it - the auto-updater removes that line.
* [Wasm GC] Refinalize fuzz fix in OptimizeInstructions cast optimizations (#5460)Alon Zakai2023-01-261-0/+78
|
* Merge more sibling types in TypeMerging (#5452)Thomas Lively2023-01-251-0/+63
| | | | | | | | | | | | | TypeMerging was previously able to merge identical root types and identical siblings that were children of a distinct type, but only when the siblings had the same top-level structure as their parent. Improve the optimization by also merging identical children when they have a different top-level structure from their parent. This solution is not fully general because it does not merge shape-refining children of separate types that would become identical siblings only after their parent types are merged, but that full generality would require either modifying Valmari-Lehtinen DFA minimization or performing the DFA minimization in a loop until reaching a fixpoint.
* Avoid spurious warnings in pass skipping (#5451)Alon Zakai2023-01-251-1/+4
| | | | | Nested runners should be ignored, as they run some internal stuff in certain passes, which would not contain the pass the user asked to skip with --skip-pass.
* Add a mechanism to skip a pass by name (#5448)Alon Zakai2023-01-242-0/+78
| | | | | | | | For example, -O3 --skip-pass=vacuum will run -O3 normally but it will not run the vacuum pass at all (which normally runs more than once in -O3).
* Fix OptimizeInstructions on null trap of struct.set (#5449)Alon Zakai2023-01-241-4/+39
| | | StructSet cannot be dropped.
* Support using JSPI to load the secondary wasm split module. (#5431)Brendan Dahl2023-01-201-0/+30
| | | | | | | | | | When using JSPI with wasm-split, any calls to secondary module functions will now first check a global to see if the module is loaded. If not loaded it will call a JSPI'ed function that will handle loading module. The setup is split into the JSPI pass and wasm-split tool since the JSPI pass is first run by emscripten and we need to JSPI'ify the load secondary module function. wasm-split then injects all the checks and calls to the load function.
* [Wasm GC] Fix supertype ordering bug in GlobalTypeRewriter (#5442)Thomas Lively2023-01-191-0/+26
| | | | | | | | | | | | | GlobalTypeRewriter made sure to order supertypes before their subtypes so that type building would succeed, but this ordering previously did not account for the fact that supertypes might be replaced by the type updating. When a supertype is replaced, the replacement might not previously have had a supertype/subtype relationship with the subtype, so it might have happened to be ordered after the subtype. Fix the problem by taking supertype replacements into account when ordering types in the GlobalTypeRewriter. This requires generalizing the `SupertypesFirst` utility in wasm-type-ordering.h to allow users to modify how supertypes are found.
* Fix type merging test broken by semantic merge conflict (#5443)Thomas Lively2023-01-191-6/+6
|
* [Wasm GC] Do not merge supertypes into subtypes (#5439)Thomas Lively2023-01-191-0/+46
| | | | | | | | | | In TypeMerging we previously merged all subsequent types in a refined partition into whichever type happened to be first in the partition, but when that first type happened to be a subtype of one of the other types in the partition, that would cause type-updating.cpp to try to update that subtype's supertype to be itself, causing an assertion failure. Fix the problem by ensuring that the merge target is not a subtype of any other types in the partition.
* [Wasm GC] Merge root types with identical shapes (#5438)Thomas Lively2023-01-191-4/+158
| | | | | | | | | | The TypeMerging optimization usually tries to merge types into their supertypes, but it can also merge sibling types together without merging them into their common supertype. Implement this kind of sibling merging for root types that have no nontrivial supertypes. Root types were previously never merged. The implementation requires hashing and comparing the top-level structure of the root types so that root types with the same structure can be assigned to the same partition for DFA minimization.
* [Wasm GC] Use DFA minimization to merge types (#5432)Thomas Lively2023-01-182-71/+285
| | | | | | | | | | | | | | | | | | | | | Analyze type merging candidates as states in a DFA, using a partition refining DFA minimization algorithm to more aggressively find sets of mergeable types. The new implementation can merge types that the previous iteration would have taken an arbitrary number of iterations to merge or would not have been able to merge at all. The new implementation is also careful in its treatment of private and public types and should work as-is under an open world assumption or a relaxed closed-world assumption that admits more public types. Specifically, the new code avoids merging public types into their supertypes, but still allows private subtypes to be merged into their public supertypes. The new implementation supports merging function types, which the old implementation did not. Finally, the new implementation is able to merge identical sibling types even when the analysis determines that they cannot be merged into their common supertype. Extending this capability to sibling top-level types without nontrivial supertypes is left to a follow-on PR.
* [Wasm GC] SignaturePruning should not prune fields from a type with subtypes ↵Alon Zakai2023-01-131-0/+39
| | | | | | (#5427) For subtyping to not break, we must leave the number of fields equal in both super and subtype, for each such pair.
* [Wasm GC] Optimize successful casts better (#5426)Thomas Lively2023-01-131-40/+53
| | | | | | 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-0/+113
| | | | | | 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] Optimize casts of null values better (#5423)Thomas Lively2023-01-121-28/+54
| | | | | | | | | 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-0/+90
| | | | | | | | | | 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-12/+36
| | | | | | | | `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.
* [Wasm GC] Handle an unreachable br_on_cast_fail in DCE (#5418)Alon Zakai2023-01-111-2/+15
| | | 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-27/+55
| | | | We already handled Success and Failure. Also handle SuccessOnlyIfNull and SuccessOnlyIfNonNull.
* [Wasm GC] Replace `HeapType::data` with `HeapType::struct_` (#5416)Thomas Lively2023-01-1016-102/+70
| | | | | | `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-105-127/+29
| | | | | | | | | | | | | 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.
* [Wasm GC] Optimize ref.as_non_null of a nullable cast (#5415)Alon Zakai2023-01-101-4/+4
|
* [Wasm GC] More minor cast optimizations (#5402)Alon Zakai2023-01-091-128/+130
| | | | | | | | 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-093-147/+17
| | | | | | | | | | | | | | | * 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-0/+31
| | | | | | | | 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/+18
| | | | | | 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-0/+21
|
* Fix a bug optimizing out br_on_cast (#5403)Thomas Lively2023-01-061-4/+95
| | | | | | | 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-43/+90
| | | | | | 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-061-47/+1
| | | | | | | | | | | | | | | | | | 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-0/+63
| | | | | | | | | | 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-051-11/+57
| | | | | | | | | 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-0/+84
| | | 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-2/+2
| | | | (#5395)
* [Wasm GC] Clean up and improve null trap and cast optimizations (#5394)Alon Zakai2023-01-051-14/+32
| | | | | | | | | 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.
* Allow non-nullable ref.cast of nullable references (#5386)Thomas Lively2023-01-041-23/+21
| | | | | | | 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-032-60/+14
| | | | | | | 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-0/+159
| | | | | | | | | | | | | | | 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
* [Wasm GC] Do not refine types of exported globals in closed world (#5380)Alon Zakai2023-01-031-1/+82
| | | | | | 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.
* Support `ref.test null` (#5368)Thomas Lively2022-12-211-6/+143
| | | This new variant of ref.test returns 1 if the input is null.
* OptimizeInstructions: Check for possible added-constant overflows (#5227)Alon Zakai2022-12-201-0/+299
| | | | | | | | | | | Fix a regression from #5025 : we subtract constants there, and we need to be aware that such subtraction can change a constant from signed to unsigned if the comparison is signed, as 0x80000000 - 1 = 0x7fffffff 0x8000000 is a negative number when seen as signed, but always positive after the subtraction.
* Work around bugs with open world type optimizations (#5367)Thomas Lively2022-12-209-21/+15
| | | | | | | | | | | | | | Since #5347 public types are never updated by type optimizations, but the optimization passes have not yet been updated to take that into account, so they are all buggy under an open world assumption. In #5359 we worked around many closed world validation errors in the fuzzer by treating --closed-world like a feature flag and checking whether it was necessary for fuzzer input, but that did not prevent the type optimization passes from running under an open world, so it did not work around all the potential issues. Work around the problem more thoroughly by not running any type optimization passes in the fuzzer without --closed-world. Also add logic to those passes to error out if they are run without --closed-world and update the tests accordingly.
* Update RefCast representation to drop extra HeapType (#5350)Thomas Lively2022-12-203-7/+21
| | | | | | | | | The latest upstream version of ref.cast is parameterized with a target reference type, not just a heap type, because the nullability of the result is parameterizable. As a first step toward implementing these new, more flexible ref.cast instructions, change the internal representation of ref.cast to use the expression type as the cast target rather than storing a separate heap type field. For now require that the encoded semantics match the previously allowed semantics, though, so that none of the optimization passes need to be updated.