summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
...
* [Strings] string.compare does not return a bool (#5497)Alon Zakai2023-02-161-1/+3
| | | | string.eq does, and when we added string.compare I forgot to adjust the boolean property for that new opcode.
* Fuzzer: Replace with unreachable sometimes (#5496)Alon Zakai2023-02-162-15/+21
| | | | | | | | | | | | | This makes the fuzzer replace things with an unreachable instruction in rare situations. The hope was to find bugs like #5487, but instead it's mostly found bugs in the inliner actually (#5492, #5493). This also fixes an uncovered bug in the fuzzer, where we refinalized in more than one place. It is unsafe to do so before labels are fixed up (as duplicate labels can confuse us as to which types are needed; this is actually the same issue as in #5492). To fix that, remove the extra refinalize that was too early, and also rename the fixup function since it does a general fixup for all the things.
* Never flip a call from unreachable to reachable during inlining (#5493)Alon Zakai2023-02-161-8/+33
| | | | | | | | | | | | See example in the new comment. In general, we never want to go from unreachable to reachable (refinalize doesn't even try), as it misses out on DCE opportunities. Also it may have validation issues, which is how the fuzzer found this. Remove code in the same place that was redundant after the refinalize was added in #5492. That simplifies some existing testcases slightly, by removing an unneeded br we added, and now we add a new unreachable at the end in other cases that need it.
* [Strings] Initial string execution support (#5491)Alon Zakai2023-02-159-15/+104
| | | | | | | | | | Store string data as GC data. Inefficient (one Const per char), but ok for now. Implement string.new_wtf16 and string.const, enough for basic testing. Create strings in makeConstantExpression, which enables ctor-eval support. Print strings in fuzz-exec which makes testing easier.
* Unreachability fixes for inlining (#5492)Alon Zakai2023-02-151-5/+10
| | | | | | | | | | | | We must refinalize as inlining unreachable code can lead to more things becoming unreachable. We also must uniquify label names before refinalizing, as the IR must be valid at that time, so that code is moved. This causes some minor changes to existing test code (some label changes, and refinalization makes more things unreachable), but only the two new tests show actual problems that needed to be fixed.
* [wasm2js] Support nonzero offsets in memory.atomic.wait32 (#5489)Thomas Lively2023-02-143-6/+8
| | | | | The assertion that the offset is zero does not necessarily hold for code that uses this instruction via the clang builtin. Add support so that Emscripten wasm2js tests pass in the presence of such code.
* [Wasm GC] Fix array.new order of operand execution (#5487)Alon Zakai2023-02-141-4/+7
|
* Vacuum unneeded instructions even if children have effects (#5488)Alon Zakai2023-02-141-3/+12
| | | | | | | | | | | | | | | | | | | This can handle e.g. (drop (i32.add (call ..) (call ..) ) ) We can remove the add and just leave two dropped calls: (drop (call ..) ) (drop (call ..) )
* [Wasm GC] Optimize casts to bottom types (#5484)Alon Zakai2023-02-082-12/+34
| | | | | | | | | A cast to a non-nullable null (an impossible type) must trap. In traps-never-happen mode, a cast that either returns a null or traps will definitely return a null. Followup to #5461 which emits casts to bottom types.
* [C API] Add relaxed SIMD operations (#5482)dcode2023-02-073-0/+76
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Exposes the constants **Unary** * BinaryenRelaxedTruncSVecF32x4ToVecI32x4 * BinaryenRelaxedTruncSVecF32x4ToVecI32x4 * BinaryenRelaxedTruncZeroSVecF64x2ToVecI32x4 * BinaryenRelaxedTruncZeroUVecF64x2ToVecI32x4 **Binary** * BinaryenRelaxedSwizzleVecI8x16 * BinaryenRelaxedMinVecF32x4 * BinaryenRelaxedMaxVecF32x4 * BinaryenRelaxedMinVecF64x2 * BinaryenRelaxedMaxVecF64x2 * BinaryenRelaxedQ15MulrSVecI16x8 * BinaryenDotI8x16I7x16SToVecI16x8 **SIMDTernary** * BinaryenRelaxedFmaVecF32x4 * BinaryenRelaxedFmsVecF32x4 * BinaryenRelaxedFmaVecF64x2 * BinaryenRelaxedFmsVecF64x2 * BinaryenLaneselectI8x16 * BinaryenLaneselectI16x8 * BinaryenLaneselectI32x4 * BinaryenLaneselectI64x2 * BinaryenDotI8x16I7x16AddSToVecI32x4 so the respective instructions can be produced and inspected with the C API.
* [Strings] Add experimental string.hash instruction (#5480)Alon Zakai2023-02-036-0/+20
| | | See WebAssembly/stringref#60
* [Wasm GC] Add AbstractTypeRefining pass (#5461)Alon Zakai2023-02-038-82/+395
| | | | | | | | | | | | | | If a type hierarchy has abstract classes in the middle, that is, types that are never instantiated, then we can optimize casts and other operations to them. Say in Java that we have `AbstractList`, and it only has one subclass `IntList` that is ever created, then any place we have an `AbstractList` we must actually have an `IntList`, or a null. (Or, if no subtype is instantiated, then the value must definitely be a null.) The actual implementation does a type mapping, that is, it finds all places using an abstract type and makes them refer to the single instantiated subtype (or null). After that change, no references to the abstract type remain in the program, so this both refines types and also cleans up the type section.
* Fix issues with ref.cast_nop (#5473)Alon Zakai2023-02-033-3/+3
| | | | It did not have proper annotation for the safety field, and also it could not handle basic heap types.
* Optimize ref.as_non_null removal effect computation (#5479)Alon Zakai2023-02-031-8/+14
| | | Followup to #5474
* [Wasm GC] Fix struct.set / ref.as_non_null ordering issue (#5474)Alon Zakai2023-02-021-10/+51
| | | | | | | | | | | 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-5/+31
| | | | | | | | | | | | | | | | | | 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.
* Fix racing merge breakage (#5472)Alon Zakai2023-02-011-3/+1
|
* [C API] Add experimental StringNew and StringEq variants (#5471)dcode2023-02-013-7/+45
| | | | Adds APIs for string.from_code_point, string.new_utf8_try, string.new_utf8_array_try (#5459) and string.compare (#5453).
* RemoveUnusedModuleElements: Support function subtyping (#5470)Alon Zakai2023-02-011-18/+32
| | | | 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-012-3/+166
| | | | | | | | | | | | | | | | | | | | | | | | | | | | 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/+5
| | | | | 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/+23
| | | | | We only checked for an unsigned overflow, which was wrong. Fixes #5464
* [NFC] Refactor RemoveUsedModuleElements to clarify references and uses (#5444)Alon Zakai2023-01-311-196/+309
| | | | | | | | | | | | | | | | | | | This pass talked about reachability and uses and such, but it wasn't very clear on those things. This refactors it to clarify that we look for references and uses, and what that means. Specifically, a reference to something makes us keep it alive, as we need to refer to it; a use makes us also keep it identical in its contents so that when it is used no behavior changes. A function reference without a call_ref that can call it is an example of a reference without a use, which this pass already optimized. To make that more clear in the code, this refactors out the reference-finding logic into a new struct, ReferenceFinder. This also replaces the normal walking logic with a more manual traversal using ChildIterator. This is necessary to properly differentiate references from uses, but is not immediately useful in this PR except for clarity. It will be necessary in the next PR, which this prepares for, in which we'll optimize more reference-but-not-use things.
* [NFC] Improve debug printing for type canonicalization (#5465)Thomas Lively2023-01-301-2/+3
| | | | | | Use an `IndexedTypeNameGenerator` to give types stable names for the entire `dump` method rather than generating fresh type names every time a single type is printed. This makes it possible to understand the relationships between the types in the debug output.
* [Wasm GC] Refinalize fuzz fix in OptimizeInstructions cast optimizations (#5460)Alon Zakai2023-01-261-0/+6
|
* [Strings] Add experimental StringNew variants (#5459)Alon Zakai2023-01-2613-80/+194
| | | | | | string.from_code_point makes a string from an int code point. string.new_utf8*_try makes a utf8 string and returns null on a UTF8 encoding error rather than trap.
* Add explicit include for <cstdint> (#5458)rathann2023-01-261-0/+1
| | | | | | This fixes the following error when compiling with GCC 13: "'uint64_t' does not name a type"
* [Strings] Add string.compare (#5453)Alon Zakai2023-01-2512-30/+87
| | | See WebAssembly/stringref#58
* Merge more sibling types in TypeMerging (#5452)Thomas Lively2023-01-251-14/+21
| | | | | | | | | | | | | 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-7/+11
| | | | | 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.
* Fix a typo in Flat IR validation logic (#5450)Alon Zakai2023-01-251-1/+1
| | | `doVisitFunction` does not exist.
* Add a mechanism to skip a pass by name (#5448)Alon Zakai2023-01-243-0/+38
| | | | | | | | 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-3/+7
| | | StructSet cannot be dropped.
* Support using JSPI to load the secondary wasm split module. (#5431)Brendan Dahl2023-01-207-25/+119
| | | | | | | | | | 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.
* Fix segment fault in API BinaryenModuleParse (#5440) (#5441)Changqing Jing2023-01-203-14/+16
| | | | | | We cannot modify the input string safely. To avoid that, copy where needed. Fixes #5440
* [Wasm GC] Fix supertype ordering bug in GlobalTypeRewriter (#5442)Thomas Lively2023-01-193-5/+46
| | | | | | | | | | | | | 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.
* [Wasm GC] Do not merge supertypes into subtypes (#5439)Thomas Lively2023-01-191-3/+8
| | | | | | | | | | 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-50/+161
| | | | | | | | | | 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-183-148/+329
| | | | | | | | | | | | | | | | | | | | | 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.
* 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.