summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* Support `ref.test null` (#5368)Thomas Lively2022-12-2114-44/+64
| | | 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-14/+99
| | | | | | | | | | | 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-206-6/+27
| | | | | | | | | | | | | | 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-2015-88/+96
| | | | | | | | | 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.
* [Wasm GC] Do not cache signature types in nominal mode if they have a super ↵Alon Zakai2022-12-191-1/+5
| | | | | | | (#5364) This reduces the amount of public types, since if there is a super then using the type in a public place would make the super also public. It is safer for closed-world mode to reuse types without supers.
* Remove unused types during type optimizations (#5361)Thomas Lively2022-12-195-10/+84
| | | | | | | | | | | | | | | | | | | | | The type rewriting utility in type-updating.cpp gathers all the used heap types, then rewrites them to newly built and possibly modified heap types. The problem is that for the isorecursive type system, the set of "used" heap types was overly broad because it also included unused heap types that are in a rec group with used types. In the context of emitting a binary, it is important to treat these types as used because failing to emit them would change the identity of the used types, but in the context of type optimizations it is ok to treat them as truly unused because we are changing type identities anyway. Update the type rewriting utility to only include truly used types in the set of output types. This causes all existing type optimizations to implicitly drop unused types, but only if they find any other optimizations to do and actually run the rewriter utitility. Their output will also still include unused types that were used before their optimizations were applied. To overcome these limitations and better match the optimizing power of nominal mode, which never includes unused types in the output, add a new type optimization pass that removes unused types and does nothing else and run it near the end of the global optimization pipeline.
* Do not optimize public types (#5347)Thomas Lively2022-12-1610-63/+244
| | | | | | | | | | | | | | | | | Do not optimize or modify public heap types in any way. Public heap types include the types of imported or exported functions, tables, globals, etc. This is important to maintain the public interface of a module and ensure it can still link interact as intended with the outside world. Also add validation error if we find any nontrivial public types that are not the types of imported or exported functions. This error is meant to help the user ensure that type optimizations are not silently inhibited. In the future, we may want to add options to silence this error or downgrade it to a warning. This commit only updates the type updating machinery to avoid updating public types. It does not update any optimization passes accordingly. Since we avoid modifying public signature types already, this is not expected to break anything, but in the future once we have function subtyping or if we make the error optional, we may have to update some of our optimization passes.
* [Wasm GC] Optimize away null arms that would trap (#5358)Alon Zakai2022-12-161-5/+74
| | | | | | | | | | | | | | | | | | | | | | | | E.g. (struct.get (select (ref.null ..) (something) (condition) ) ) If traps-never-happen then this can be (drop (condition)) (struct.get (something) ) That is, we can remove the arm that is null, as it would trap but traps are assumed to not happen. Also fix a bug this uncovers on struct.set on a null type.
* In --debug mode, print partial wasm data that was read (#5356)Alon Zakai2022-12-152-2/+12
| | | | | | | | | | | | | | | | | | | If wasm-opt or wasm-dis are given an invalid binary, after the error message we can also print out the wasm we did manage to read. That includes global stuff like imports and also all the functions up until there. This can help debugging in some situations. Only do this when --debug is passed as it can be very verbose and in general users might not want it. This is technically easy to do, it turns out, since we already use a thrown exception on an error in parsing, and we fill up the wasm as we go, so it just contains what we've read so far, and we can just print it. Fixes #5344 Also switch an existing test's comments to ;; from # which was noticed here.
* Properly use pass options in nested pass runners (up to -O1) (#5351)Alon Zakai2022-12-152-8/+25
| | | | | | | | | | | | | | | | | | This fixes a TODO. There is a runtime cost to this in higher opt levels, as passing through -O3 makes nested optimization work take longer. But it can lead to better results. For now, this PR moves us from 0 before to a maximum of 1, as a compromise. 1 does not regress compile times, but there may be further benefits to allowing 2 and 3 in the future. Also fix a fuzzer bug that becomes uncovered by tihs PR: Now that we actually optimize in simplify-globals, we need to handle the case of the optimizer there seeing a call with the effects of writing to a global (we had an assert on that never happening, but with function effects that can happen, and so a GlobalSet is not the only thing that can set a global). Aside from the opt and shrink levels this passes through all other options, like trapsNeverHappen.
* Add memory: init, copy, fill support to Multi-Memory Lowering Pass (#5346)Ashley Nelson2022-12-151-0/+112
| | | This PR adds support for memory.init, memory.copy, and memory.fill instructions in the multi-memory lowering pass. Also includes optional bounds checks per the wasm spec guidelines.
* Refactor Multi-Memory Lowering pass to support additional instructions (#5352)Ashley Nelson2022-12-151-44/+64
| | | This PR breaks up the two main functions involved in each memory instruction (getPtr, makeBoundsCheck) into several smaller functions. This is a first step in adding support for bounds checks in the instructions memory: init, copy, and fill. Each of these instructions is a more unique case than the other memory instructions that have already been added to the Multi-Memory Lowering pass.
* Fix opt/shrink levels when running the optimizer multiple times (#5333)Alon Zakai2022-12-142-15/+62
| | | | | | | | | | Previously -O3 -O1 would run -O1 twice since the last flag set the global opt level to 1, and then all invocations of the optimizer pipeline read that. This makes each pipeline define its own opt level. This has been a long-standing annoyance, which wasn't much noticed except that with wasm GC there is more of a need to run the optimization pipeline more than once. And sometimes it is nice to run different levels.
* [NFC] Add some notes to pass.h on closed world (#5345)Alon Zakai2022-12-141-0/+22
|
* Fix OOB string_view read in generated parser code (#5349)Thomas Lively2022-12-141-707/+705
| | | | | | | | | The `op` string_view was intentionally created to point into the `buf` buffer so that reading past its end would still be safe, but some C++ standard library implementations assert when reading past the end of a string_view. Change the generated code to read out of `buf` instead to avoid those assertions. Fixes #5322. Fixes #5342.
* [Wasm GC] Fix GlobalStructInference on unrefined globals (#5338)Alon Zakai2022-12-121-2/+20
| | | | | | | If a global's type is not fully refined, then when --gsi replaces a reference with a global.get, we end up with a type that might not be good enough. For example, if the type is any then it is not a subtype of eq and we can't do ref.eq on it, which this pass requires. We also can't just do struct.get on it if it is a too-distant parent or such.
* Add Atomics support to Multi-Memory Lowering Pass (#5339)Ashley Nelson2022-12-121-0/+41
| | | | | This PR adds support for Atomic instructions in the multi-memory lowering pass. Also includes optional bounds checks per the wasm spec guidelines, (visitAtomicRMW, visitAtomicCmpxchg, visitAtomicWait, visitAtomicNotify). Note: The latter two instructions, memory.atomic.wait and memory.atomic.notify, have browser engine implementations that predate the still-in-progress threads spec. And whether or not atomic.notify should trap for out-of-bounds addresses remains an open issue. For now, this PR is using the same semantics as v8, which is to bounds check all Atomic instructions the same way and trap for out-of-bounds.
* Add SIMD support to Multi-Memory Lowering Pass (#5336)Ashley Nelson2022-12-121-6/+34
| | | This PR adds support for SIMD instructions in the multi-memory lowering pass. Also includes optional bounds checks per the wasm spec guidelines, (SIMDLoad, SIMDLoadSplat, SIMDLoadExtend, SIMDLoadZero, SIMDLoadStoreLane load | store).
* Adds bounds checks to Load/Store in Multi-Memories Lowering Pass (#5256)Ashley Nelson2022-12-093-70/+116
| | | Per the wasm spec guidelines for Load (rule 10) & Store (rule 12), this PR adds an option for bounds checking, producing a runtime error if the instruction exceeds the bounds of the particular memory within the combined memory.
* Use non-nullable ref.cast for non-nullable input (#5335)Thomas Lively2022-12-095-11/+44
| | | | | | | | | | | | 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.
* Allow casting to basic heap types (#5332)Thomas Lively2022-12-083-34/+44
| | | | | | | The standard casting instructions now allow casting to basic heap types, not just user-defined types, but they also require that the intended type and argument type have a common supertype. Update the validator to use the standard rules, update the binary parser and printer to allow basic types, and update the tests to remove or modify newly invalid test cases.
* Validate ref.as_* argument is a reference (#5330)Alon Zakai2022-12-081-1/+5
| | | | | | | | | | | | | | Without this we hit an assert with no line number info (or in a no-asserts build, bad things can happen). With this: $ bin/wasm-opt -all ~/Downloads/crash.wat --nominal [parse exception: Invalid ref for ref.as (at 155065:119)] Fatal: error parsing wasm (That can only happen for ref.as_non_null, as all the others do not have that assert - their types do not depend on the child's type, so their finalize does not error. Still, it is nice to validate earlier for them as well, so this PR handles them all.)
* Add standard versions of WasmGC casts (#5331)Thomas Lively2022-12-079-136/+158
| | | | | | | 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.
* [Wasm GC] Add array support to TypeMerging (#5329)Alon Zakai2022-12-071-15/+14
|
* [Wasm GC] Add TypeMerging pass (#5321)Alon Zakai2022-12-077-0/+279
| | | | | | | | This finds types that can be merged into their super: types that add no fields, and are not used in casts, etc. - so we might as well use the super. This complements TypeSSA, in that it can merge back the new types that TypeSSA created, if we never found a use for them. Without this, TypeSSA can bloat binary size quite a lot (I see 10-20%).
* [Wasm GC] Add array support to TypeSSA (#5327)Alon Zakai2022-12-071-37/+79
| | | Previously it only handled structs.
* Fix Asyncify assertions after #5293 (#5328)Alon Zakai2022-12-071-4/+49
| | | | | | | | | | | Followup to #5293, this fixes a small regression there regarding assertions. We do have a need to visit non-instrumented functions if we want assertions, as we assert on some things there, namely that such functions do not change the state (if they changed it, we'd need to instrument them to handle that properly). This moves that logic into a new pass. We run that pass when assertions are enabled. Test diff basically undoes part the test diff from that earlier PR for that one file.
* Fix an Inlining bug with a name collision in a br nested in a call param (#5323)Alon Zakai2022-12-062-5/+25
|
* [Parser][NFC] Add `Idx` to type aliases representing indices (#5326)Thomas Lively2022-12-061-38/+42
| | | | | | | Previously we had types like `LocalT` and `MemoryT` to represent references to locals and memories, but when we added field indices in #5255, we had to use `FieldIdxT` instead of `FieldT` because `FieldT` was already in use as the type representing a field itself. Update `LocalT`, `MemoryT` and `GlobalT` to have `Idx` in their names to be consistent with `FieldIdxT`.
* Optimize Asyncify to not flatten/optimize unnecessarily (#5293)Alexander Guryanov2022-12-062-4/+55
| | | | | | | | | Add a way to proxy passes and the addition of passes in pass runners. With that we can make Asyncify only modify functions it actually needs to. On a project that Asyncify only needs to modify a few functions on, this can save a huge amount of time as it avoids flattening+optimizing the majority of the module. Fixes #4822
* Add CMake option to only build tools needed for Emscripten (#5319)Derek Schuff2022-12-021-3/+5
| | | This helps cut the size and build time of the emsdk package.
* [Wasm GC] Add TypeSSA pass (#5299)Alon Zakai2022-12-025-0/+286
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This creates new nominal types for each (interesting) struct.new. That then allows type-based optimizations to be more precise, as those optimizations will track separate info for each struct.new, in effect. That is kind of like SSA, however, we do not handle merges. For example: x = struct.new $A (5); print(x.value); y = struct.new $A (11); print(y.value); // => // x = struct.new $A.x (5); print(x.value); y = struct.new $A.y (11); print(y.value); After the pass runs each of those struct.new creates a unique type, and type-based analysis can see that 5 or 11 are the only values written in that type (if nothing else writes there). This bloats the type section with the new subtypes, so it is best used with a pass to merge unneeded duplicate types, which a later PR will add. That later PR will exactly merge back in the types created here, which are nominally different but indistinguishable otherwise. This pass is not enabled by default. It's not clear yet where is the best place to do it, as it must be balanced by type merging, but it might be better to do multiple rounds of optimization between the two. Needs more investigation.
* [NFC] Do not read past the end of a string_view (#5317)Thomas Lively2022-12-021-5/+5
| | | | | | | | wasm-s-parser.cpp was detecting the end of type strings by looking for null characters, but those null characters would be past the end of the relevant string_view. Bring that code in line with similar code by checking the length of the string_view instead. Fixes an assertion failure in MSVC debug mode. Fixes #5312.
* [Parser] Avoid calling `strtod` on NaNs entirely (#5316)Thomas Lively2022-12-021-5/+6
| | | | | | | | MSVC's implementation of `strtod` doesn't return a negative Nan for "-nan", so we already had a workaround to explicitly handle that case without calling `strtod`. Unfortunately the workaround was not used for negative NaNs with payloads, so there were still bugs. Fix the problem and make the code even more portable by avoiding `strtod` completely for any kind of nan, positive or negative, with or without payload.
* [NFC] Allow TypeBuilder::Entry::subTypeOf to take any HeapType (#5314)Thomas Lively2022-12-021-2/+1
| | | | We generalized the underlying API, TypeBuilder::setSubType, to allow it to take any HeapType as the supertype in #5045. Make the same change now in the helper.
* Remove more uses of NAN (#5310)Thomas Lively2022-12-021-0/+2
| | | | | In favor of the more portable code snippet using `std::copysign`. Also reintroduce assertions that the NaNs have the expected signs. This continues work started in #5302.
* Support `array` and `struct` types in the type fuzzer (#5308)Thomas Lively2022-12-021-40/+54
| | | | | | | Since `data` has been removed from the upstream proposal and `struct` has been added in its place, update the type fuzzer to be structured around `struct` and `array` (which it had not previously been updated to support) rather than `data`. A follow-on PR will make the broader change of removing `data` and adding `struct`.
* Use C++17's [[maybe_unused]]. NFC (#5309)Sam Clegg2022-12-0222-85/+35
|
* Do not special case ref.null in `LUBFinder` (#5307)Thomas Lively2022-12-017-120/+31
| | | | | | | | | | | | Before we implemented bottom heap types, `ref.null` had to be annotated with specific types. The `LUBFinder` utility ignored these types so that it could find the best LUB from all considered non-null expressions, then go back and update the type annotations on the nulls to match that LUB. Now that we have bottom types, however, none of that is necessary, and in fact ignoring nulls can miss possible refinements to bottom types. Update and simplify `LUBFinder` so that it is a simple wrapper around the underlying `Type::getLeastUpperBound` utility with no additional logic. Update tests to account for the more powerful optimizations.
* [Wasm GC] Implement closed-world flag (#5303)Alon Zakai2022-11-304-15/+46
| | | | | | | | | | | | | With this change we default to an open world, that is, we do the safe thing by default: we no longer assume a closed world. Users that want a closed world must pass --closed-world. Atm we just do not run passes that assume a closed world. (We might later refine them to find which types don't escape and only optimize those.) The RemoveUnusedModuleElements is an exception in that the closed-world flag influences one part of its operation, but not the rest. Fixes #5292
* [NFC] Avoid unneeded work in GTO (#5304)Alon Zakai2022-11-301-1/+3
| | | | | As noticed in #5303, the test changes here are because we did unnecessary work which created a new rec group, which then led to a rec group being printed out.
* [NFC] Avoid scanning SmallSets twice during insert (#5221)Alon Zakai2022-11-301-15/+39
| | | As suggested in #5218
* [NFC] Add a TODO in ReorderFunctions (#5205)Alon Zakai2022-11-301-0/+2
|
* Update comment in OptimizeAddedConstants.cpp (#5283)Alon Zakai2022-11-291-2/+2
|
* [Parser] Do not assume `NAN` is positive (#5302)Thomas Lively2022-11-291-3/+4
| | | | | | | It turns out that this assumption does not necessarily hold on Windows with Visual Studio 2019. Instead of using `NAN` and `-NAN`, explicitly construct positive and negative NaN values with `std::copysign`, which should be portable. Fixes #5291.
* [NFC] Remove unneeded check (#5300)Alon Zakai2022-11-291-5/+3
| | | | The caller fills the map with what is relevant anyhow, so we don't need to check before looking for an item in the map.
* Fix validation and inlining bugs (#5301)Thomas Lively2022-11-292-3/+8
| | | | | | | | | | | | | | Inlining had a bug where it gave return_calls in inlined callees concrete types even when they should have remained unreachable. This bug flew under the radar because validation had a bug where it allowed expressions to have concrete types when they should have been unreachable. The fuzzer found this bug by adding another pass after inlining where the unexpected types caused an assertion failure. Fix the bugs and add a test that would have triggered the inlining bug. Unfortunately the test would have also passed before this change due to the validation bug, but it's better than nothing. Fixes #5294.
* [NFC] Refactor GlobalTypeRewriter to split out the type mapping logic (#5295)Alon Zakai2022-11-292-13/+30
| | | | | | | | | | | The logic that is split out into mapTypes gets a map of old type => new type and then updates the module to replace the old with the new. This will be useful in a future pass to merge types. We will tell it to map the types to be merged with the types we want to merge them into. This removes an assert on all types being in the map to allow some of them not to be. (the new pass that will use this will only want to map some types).
* Validator: Print the field number on subtyping errors (#5297)Alon Zakai2022-11-291-4/+6
|
* [NFC] Print type names in BINARYEN_PRINT_FULL mode (#5296)Alon Zakai2022-11-291-3/+28
|