summaryrefslogtreecommitdiff
Commit message (Collapse)AuthorAgeFilesLines
* Debug location parser: accept arbitrary paths (#6594)Jérôme Vouillon2024-05-152-17/+38
| | | | | The whole annotation was parsed as a keyword, which prevented file paths with non-ascii characters or paths starting with `/` or `.`. Also, there was a typo: one was comparing `fileSize` rather than `lineSize` to `contents->npos`.
* [Strings] Remove operations not included in imported strings (#6589)Thomas Lively2024-05-1532-2111/+380
| | | | | | The stringref proposal has been superseded by the imported JS strings proposal, but the former has many more operations than the latter. To reduce complexity, remove all operations that are part of stringref but not part of imported strings.
* [Strings] Remove stringview types and instructions (#6579)Thomas Lively2024-05-1556-2615/+714
| | | | | | | | | | | | | | | | | | | | | | | | | | | | The stringview types from the stringref proposal have three irregularities that break common invariants and require pervasive special casing to handle properly: they are supertypes of `none` but not subtypes of `any`, they cannot be the targets of casts, and they cannot be used to construct nullable references. At the same time, the stringref proposal has been superseded by the imported strings proposal, which does not have these irregularities. The cost of maintaing and improving our support for stringview types is no longer worth the benefit of supporting them. Simplify the code base by entirely removing the stringview types and related instructions that do not have analogues in the imported strings proposal and do not make sense in the absense of stringviews. Three remaining instructions, `stringview_wtf16.get_codeunit`, `stringview_wtf16.slice`, and `stringview_wtf16.length` take stringview operands in the stringref proposal but cannot be removed because they lower to operations from the imported strings proposal. These instructions are changed to take stringref operands in Binaryen IR, and to allow a graceful upgrade path for users of these instructions, the text and binary parsers still accept but ignore `string.as_wtf16`, which is the instruction used to convert stringrefs to stringviews. The binary writer emits code sequences that use scratch locals and `string.as_wtf16` to keep the output valid. Future PRs will further align binaryen with the imported strings proposal instead of the stringref proposal, for example by making `string` a subtype of `extern` instead of a subtype of `any` and by removing additional instructions that do not have analogues in the imported strings proposal.
* LocalCSE: Fix regression from #6587 by accumulating generativity (#6591)Alon Zakai2024-05-153-33/+113
| | | | | | | | | | | | | #6587 was incorrect: It checked generativity early in an incremental manner, but it did not accumulate that information as we do with hashes. As a result we could end up optimizing something with a generative child, and sadly we lacked testing for that case. This adds incremental generativity computation alongside hashes. It also splits out this check from isRelevant. Also add a test for nested effects (as opposed to generativity), but that already worked before this PR (as we compute effects and invalidation as we go, already).
* Remove redundant ptrType from MemorySize/Grow instructions. NFC (#6590)Sam Clegg2024-05-158-26/+9
| | | | I recently add TableSize/Grow and noticed I didn't need these. It seems they are superfluous.
* Source maps: Allow specifying that an expression has no debug info in text ↵Jérôme Vouillon2024-05-1411-40/+165
| | | | | | | | | | | | (#6520) ;;@ with nothing else (no source:line) can be used to specify that the following expression does not have any debug info associated to it. This can be used to stop the automatic propagation of debug info in the text parsers. The text printer has also been updated to output this comment when needed.
* [NFC] Add printing for EffectAnalyzer (#6586)Alon Zakai2024-05-143-0/+147
| | | | | | | | | With this you can do std::cout << effects and get something like EffectAnalyzer { writesMemory hasSideEffects }
* LocalCSE: Ignore traps of code in between (#6588)Alon Zakai2024-05-142-1/+63
| | | | | | | | | | | | | | | | | | Given: (ORIGINAL) (in between) (COPY) We want to change that to (local.tee $temp (ORIGINAL)) (in between) (local.get $temp) It is fine if "in between" traps: then we never reach the new local.get. This is a safer situation than most optimizations because we are not reordering anything, only replacing known-equivalent code.
* LocalCSE: Check effects/generativity early (#6587)Alon Zakai2024-05-145-29/+116
| | | | | | | | | | | | | | | | | | | | Previously we checked late, and as a result might end up failing to optimize when a sub-pattern could have worked. E.g. (call (A) ) (call (A) ) The call cannot be optimized, but the A pattern repeats. Before this PR we'd greedily focus on the entire call and then fail. After this PR we skip the call before we commit to which patterns to try to optimize, so we succeed. Add a isShallowlyGenerative helper here as we compute this step by step as we go. Also remove a parameter to the generativity code (it did not use the features it was passed).
* Simplify scratch local calculation (#6583)Thomas Lively2024-05-134-83/+92
| | | | | | | | | | | Change `countScratchLocals` to return the count and type of necessary scratch locals. It used to encode them as keys in the global map from scratch local types to local indices, which could not handle having more than one scratch local of a given type and was generally harder to reason about due to its use of global state. Take the opportunity to avoid emitting unnecessary scratch locals for `TupleExtract` expressions that will be optimized to not use them. Also simplify and better document the calculation of the mapping from IR indices to binary indices for all locals, scratch and non-scratch.
* [Parser] Parse wast scripts (#6581)Thomas Lively2024-05-1313-26/+555
| | | | | | | | | | | The spec tests use an extension of the standard text format that includes various commands and assertions used to test WebAssembly implementations. Add a utility to parse this extended WebAssembly script format and use it in wasm-shell to check that it parses our spec tests without error. Fix a few errors the new parser found in our spec tests. A future PR will rewrite wasm-shell to interpret the results of the new parser, but for now to keep the diff smaller, do not do anything with the new parser except check for errors.
* [interp] Make memory and table handling more consistency. NFC (#6582)Sam Clegg2024-05-131-83/+73
|
* [memory64] Add table64 to existing memory64 support (#6577)Sam Clegg2024-05-1016-179/+375
| | | | | | | Tests is still very limited. Hopefully we can use the upstream spec tests soon and avoid having to write our own tests for `.set/.set/.fill/etc`. See https://github.com/WebAssembly/memory64/issues/51
* Fix running just a single spec test via `check.py spec --spec-test foo`. ↵Sam Clegg2024-05-101-5/+6
| | | | NFC (#6580)
* Fuzzer: Add another stringview subtyping error message to ignore (#6575)Alon Zakai2024-05-091-0/+1
|
* [StackIR] Run StackIR during binary writing and not as a pass (#6568)Alon Zakai2024-05-0978-1017/+1007
| | | | | | | | | | | | | | | | | | | | | | | | | | Previously we had passes --generate-stack-ir, --optimize-stack-ir, --print-stack-ir that could be run like any other passes. After generating StackIR it was stashed on the function and invalidated if we modified BinaryenIR. If it wasn't invalidated then it was used during binary writing. This PR switches things so that we optionally generate, optimize, and print StackIR only during binary writing. It also removes all traces of StackIR from wasm.h - after this, StackIR is a feature of binary writing (and printing) logic only. This is almost NFC, but there are some minor noticeable differences: 1. We no longer print has StackIR in the text format when we see it is there. It will not be there during normal printing, as it is only present during binary writing. (but --print-stack-ir still works as before; as mentioned above it runs during writing). 2. --generate/optimize/print-stack-ir change from being passes to being flags that control that behavior instead. As passes, their order on the commandline mattered, while now it does not, and they only "globally" affect things during writing. 3. The C API changes slightly, as there is no need to pass it an option "optimize" to the StackIR APIs. Whether we optimize is handled by --optimize-stack-ir which is set like other optimization flags on the PassOptions object, so we don't need the old option to those C APIs. The main benefit here is simplifying the code, so we don't need to think about StackIR in more places than just binary writing. That may also allow future improvements to our usage of StackIR.
* [validator] Remove indexType helper function (#6576)Sam Clegg2024-05-091-23/+18
| | | | It seems like that each of the callsites already has looked up the `Memory` object so this helper is not doing anything useful.
* [J2Cl] Make J2clOpts more effective with transitive deps in constant ↵Roberto Lublinerman2024-05-093-65/+305
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | intialization (#6571) Constants that need to be hoisted sometimes are initialized by calling getters of other constants that need to be hoisted. These getters are non-trivial, e.g. (func $getConst1_<once>_@X (result (ref null $A)) (block (result (ref null $A)) (if (i32.eqz (ref.is_null (global.get $$const1@X))) (then (return (global.get $$const1@X)) ) ) (global.set $$const1@X (struct.new $A (i32.const 2))) (global.get $$const1@X) ) (func $getConst2_<once>_@X (result (ref null $A)) (block (result (ref null $A)) (if (i32.eqz (ref.is_null (global.get $$const2@X))) (then (return (global.get $$const2@X)) ) ) (global.set $$const2@X .... expression with (call $getConst1_<once>_@X) ....)) (global.get $$const2@X) ) and can only be simplified after the constants they initialize are hoisted. After the constant is hoisted the getter can be inlined and constants that depend on it for their initialization can now be hoisted. Before this pass, inlining would happen after the pass was run by a subsequent run of the inliner (likely as part of -O3), requiring as many runs of this pass, interleaved with the inliner, as the depth in the call sequence. By having a simpler inliner run as part of the loop in this pass, the pass becomes more effective and more independent of the call depths.
* Fix CFGWalker issue in single-threaded mode (#6573)许鑫权2024-05-091-0/+2
| | | | | In that mode a walk on an entire module will reuse the same CFGWalker instance, so we must manually clear some fields, and we forgot some before.
* Fuzzer: Stop emitting nullable stringviews (#6574)Alon Zakai2024-05-083-5/+29
| | | | | | | | | | | | | As of https://chromium-review.googlesource.com/c/v8/v8/+/5471674 V8 requires stringviews to be non-nullable. It might be possible to make that change in our IR, or to remove views entirely, but for now this PR makes the fuzzer stop emitting nullable stringviews as a workaround to allow us to fuzz current V8. There are still rare corner cases where this pattern is emitted, that we have not tracked down, and so this also makes the fuzzer ignore the error for now.
* wasm-split: Handle RefFuncs (#6513)Alon Zakai2024-05-083-8/+245
| | | | | When we have a ref.func that refers to the secondary module then make a trampoline that calls it directly. The trampoline's call is then fixed up like all direct calls to the secondary module.
* Allow DWARF and multivalue together (#6570)Heejin Ahn2024-05-063-9/+135
| | | | | | | | | This allows writing of binaries with DWARF info when multivalue is enabled. Currently we just crash when both are enabled together. This just assumes, unless we have run DWARF-invalidating passes, all locals added for tuples or scratch locals would have been added at the end of the local list, so just printing all locals in order would preserve the DWARF info. Tuple locals are expanded in place and scratch locals are added at the end.
* Source map fixes (#6550)Jérôme Vouillon2024-05-0210-27/+74
| | | | | | | | | | | | | | | | | | | | | | | | | * Keep debug locations at function start The `fn_prolog_epilog.debugInfo` test is failing otherwise, since there was debug information associated to the nop instruction at the beginning of the function. * Do not clear the debug information when reaching the end of the source map The last segment should extend to the end of the function. * Propagate debug location from the function prolog to its first instruction * Fix printing of epilogue location The text parser no longer propagates locations to the epilogue, so we should always print the location if there is one. * Fix debug location smearing The debug location of the last instruction should not smear into the function epilogue, and a debug location from a previous function should not smear into the prologue of the current function.
* Respect the Web limitation on Table size (#6567)Alon Zakai2024-05-017-9/+71
| | | | | Without this the fuzzer can error on differences in behavior between V8 and us. Also move the limitations constants to their own header.
* [StackIR] Support source maps and DWARF with StackIR (#6564)Alon Zakai2024-05-015-1953/+1951
| | | | | | | | | | | | | | Helping #6509, this fixes debugging support for StackIR, which makes it more possible to use StackIR in more places. The fix is basically just to pass around some more state, and then to call the parent with "please write debug info" at the correct times, mirroring the similar calls in BinaryenIRWriter. The relevant Emscripten tests pass, and the source map test modified here produces identical output in StackIR and non-StackIR modes (the test is also simplified to remove --new-wat-parser which is no longer needed, after which the test can clearly show that StackIR has the same output as BinaryenIR).
* J2CLOpts: Add "precompute" and "remove-unused-brs" as additional cleanupRoberto Lublinerman2024-04-302-0/+54
| | | | This makes the cleanup of bodies of functions that have had constants hoisted from them more effective.
* [Strings] Limit string allocations like we do arrays (#6562)Alon Zakai2024-04-291-3/+8
| | | | | | | | When we concat strings, check if their length exceeds a reasonable limit. (We do not need to do this for string.new as that reads from an array, which is already properly limited.) This avoids very slow pauses in the fuzzer (that sometimes OOM).
* [Strings] wasm-ctor-eval: Stop on seeing a string view, which we cannot ↵Alon Zakai2024-04-292-0/+40
| | | | precompute (#6561)
* Use the new wat parser in tests (#6556)Thomas Lively2024-04-295-79/+94
| | | | | | | Some of the example and gtest tests parse wat. Update them to use the new wat parser, fixing problems with their text input. In one case, comment out an outlining test entirely for now because the new parser produces different IR that changes the test output, but it is not obvious how to understand and fix the test.
* [Parser] Re-use blocks instead of wrapping where possible (#6552)Thomas Lively2024-04-294-81/+74
| | | | | | | When the input has branches to block scope, IR builder generally has to add a wrapper block with a label name for the branch to target. To reduce the parsed IR size, add a special case for when the wrapped expression is already an unnamed block. In that case we can simply add the label to the existing block instead of creating a new wrapper block.
* Re-enable fuzzing of text round trips (#6560)Thomas Lively2024-04-291-2/+1
| | | The bug that had been preventing this fuzzing no longer reproduces.
* [Strings] Work around ref.cast not working on string views, and add fuzzing ↵Alon Zakai2024-04-296-39/+163
| | | | | | | | | | | | | (#6549) As suggested in #6434 (comment) , lower ref.cast of string views to ref.as_non_null in binary writing. It is a simple hack that avoids the problem of V8 not allowing them to be cast. Add fuzzing support for the last three core string operations, after which that problem becomes very frequent. Also add yet another makeTrappingRefUse that was missing in that fuzzer code.
* [jspi] Fix invalid wat in test case. (#6559)Brendan Dahl2024-04-291-1/+1
|
* [Parser][NFC] Clean up the lexer index/pos API (#6553)Thomas Lively2024-04-293-32/+30
| | | | | The lexer previously had both `getPos` and `getIndex` APIs that did different things, but after a recent refactoring there is no difference between the index and the position. Deduplicate the API surface.
* [NFC] Use the new wat parser in RemoveNonJSOps (#6554)Thomas Lively2024-04-291-5/+4
|
* Use the new wat parser in the C API (#6555)Thomas Lively2024-04-291-7/+4
|
* Improve return validation (#6551)Thomas Lively2024-04-292-10/+35
| | | | Disallow returns from having any children, even unreachable children, in function that do not return any values.
* Fix a bug with unreachable control flow in IRBuilder (#6558)Jérôme Vouillon2024-04-293-56/+148
| | | | | | | | | | | | When branches target control flow structures other than blocks or loops, the IRBuilder wraps those control flow structures with an extra block for the branches to target in Binaryen IR. When the control flow structure is unreachable because all its bodies are unreachable, the wrapper block may still need to have a non-unreachable type if it is targeted by branches. This is achieved by tracking whether the wrapper block will be targeted by any branches and use the control flow structure's original, non-unreachable type if so. However, this was not properly tracked when moving into the `else` branch of an `if` or the `catch`/`cath_all` handlers of a `try` block.
* [jspi] - Support new version of JSPI for module splitting. (#6546)Brendan Dahl2024-04-293-117/+72
| | | | | | With the old version of JSPI, the JSPI pass was required to be run before splitting and would automatically add an export to be able to find the load_secondary_module function. Now that the pass is no longer needed, just add an import manually for the load_secondary_module function.
* [Parser] Do not eagerly lex numbers (#6544)Thomas Lively2024-04-252-293/+141
| | | | Lex integers and floats on demand to avoid wasted work. Remove `Token` completely now that all kinds of tokens are lexed on demand.
* [Parser] Do not eagerly lex strings (#6543)Thomas Lively2024-04-252-49/+25
| | | Lex them on demand instead to avoid wasted work.
* [Parser] Do not eagerly lex IDs (#6542)Thomas Lively2024-04-252-43/+23
| | | Lex them on demand instead to avoid wasted work.
* [Parser] Do not eagerly lex keywords (#6541)Thomas Lively2024-04-252-85/+56
| | | Lex them on demand instead to avoid wasted work.
* [Parser] Do not eagerly lex parens (#6540)Thomas Lively2024-04-254-69/+36
| | | | | | | | | | | The lexer currently lexes tokens eagerly and stores them in a `Token` variant ahead of when they are actually requested by the parser. It is wasteful, however, to classify tokens before they are requested by the parser because it is likely that the next token will be precisely the kind the parser requests. The work of checking and rejecting other possible classifications ahead of time is not useful. To make incremental progress toward removing `Token` completely, lex parentheses on demand instead of eagerly.
* [Strings] Fix effects of string.compare and add fuzzing (#6547)Alon Zakai2024-04-255-45/+153
| | | | | | | | We added string.compare late in the spec process, and forgot to add effects for it. Unlike string.eq, it can trap. Also use makeTrappingRefUse in recent fuzzer string generation places that I forgot, which should reduce the amount of traps in fuzzer output.
* [Parser] Enable the new text parser by default (#6371)Thomas Lively2024-04-2594-1168/+567
| | | | | | | | | | | | | | 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`
* GUFA: Handle bottom types in filterDataContents() (#6545)Alon Zakai2024-04-252-1/+45
| | | | | | Normally a bottom type cannot reach there, as we ignore unreachable GC operations early on. However, we can infer a bottom type later during the flow, so we need to handle that (just not error on it, and for clarity during debugging we also clear the contents).
* [Strings] Fuzz string.encode (#6539)Alon Zakai2024-04-253-46/+82
| | | | | | | A little trickier than the others due to the risk of trapping, which this handles like the other array operations. Also stop using immutable i16 arrays for string operations - only mutable ones work atm.
* Do not add an extra null character when reading files (#6538)Thomas Lively2024-04-245-11/+5
| | | | | | | | The new wat parser currently considers itself to be at the end of the file whenever it cannot lex another token. This is not quite right, but fixing it causes parser errors because of the extra null character we were appending to files when we read them. This null character is not useful since we can already read files as `std::string`, which always has an implicit null character, so remove it. Clean up some users of `read_file` while we're at it.
* Fuzzer: Update the typeLocals data structure before mutation (#6537)Alon Zakai2024-04-242-2/+20
| | | | | Rather than compute the map of type to locals of that type once, at the start, also update it when relevant, as we can add more locals in some cases. This allows us to local.get from those late-added locals too.