summaryrefslogtreecommitdiff
path: root/test
Commit message (Collapse)AuthorAgeFilesLines
...
* [Wasm GC] Add a method to traverse subtypes (#5131)Alon Zakai2022-10-121-0/+51
| | | This will be useful in further cone type optimizations.
* [Wasm GC] Fix the intersection of a bottom type null (#5128)Alon Zakai2022-10-121-0/+9
| | | | | When the heap types are not subtypes of each other, but a null is possible, the intersection exists and is a null. That null must be the shared bottom type.
* [Wasm GC] [GUFA] Add initial ConeType support (#5116)Alon Zakai2022-10-112-92/+711
| | | | | | | | | | | A cone type is a PossibleContents that has a base type and a depth, and it contains all subtypes up to that depth. So depth 0 is an exact type from before, etc. This only adds cone type computations when combining types, that is, when we combine two exact types we might get a cone, etc. This does not yet use the cone info in all places (like struct gets and sets), and it does not yet define roots of cone types, all of which is left for later. IOW this is the MVP of cone types that is just enough to add them + pass tests + test the new functionality.
* Support null characters in string.const expressions (#5123)Thomas Lively2022-10-111-3/+7
| | | | Remove an obsolete error about null characters and test both binary and text round tripping of a string constant containing an escaped zero byte.
* Make `Name` a pointer, length pair (#5122)Thomas Lively2022-10-111-2/+2
| | | | | | | | | | | | | | | | | | | | | | | With the goal of supporting null characters (i.e. zero bytes) in strings. Rewrite the underlying interned `IString` to store a `std::string_view` rather than a `const char*`, reduce the number of map lookups necessary to intern a string, and present a more immutable interface. Most importantly, replace the `c_str()` method that returned a `const char*` with a `toString()` method that returns a `std::string`. This new method can correctly handle strings containing null characters. A `const char*` can still be had by calling `data()` on the `std::string_view`, although this usage should be discouraged. This change is NFC in spirit, although not in practice. It does not intend to support any particular new functionality, but it is probably now possible to use strings containing null characters in at least some cases. At least one parser bug is also incidentally fixed. Follow-on PRs will explicitly support and test strings containing nulls for particular use cases. The C API still uses `const char*` to represent strings. As strings containing nulls become better supported by the rest of Binaryen, this will no longer be sufficient. Updating the C and JS APIs to use pointer, length pairs is left as future work.
* [Parser] Parse folded instructions (#5124)Thomas Lively2022-10-111-0/+60
| | | | | | | | | | | | | | | Parse folded expressions as described in the spec: https://webassembly.github.io/spec/core/text/instructions.html#folded-instructions. The old binaryen parser _only_ parses folded expressions, and furthermore requires them to be folded such that a parent instruction consumes the values produced by its children and only those values. The standard format is much more general and allows folded instructions to have an arbitrary number of children independent of dataflow. To prevent the rest of the parser from having to know or care about the difference between folded and unfolded instructions, parse folded instructions after their children have been parsed. This means that a sequence of instructions is always parsed in the order they would appear in a binary no matter how they are folded (or not folded).
* GUFA: Use SSA-style information (#5121)Alon Zakai2022-10-074-51/+147
| | | | | | | | | | | | | | | | | Previously we treated each local index as a location, and every local.set to that index could be read by every local.get. With this we connect only relevant sets to gets. Practically speaking, this removes LocalLocation which is what was just described, and instead there is ParamLocation for incoming parameter values. And local.get/set use normal ExpressionLocations to connect a set to a get. I was worried this would be slow, since computing LocalGraph takes time, but it actually more than makes up for itself on J2Wasm and we are faster actually rocket I guess since we do less updating after local.sets. This makes a noticeable change on the J2Wasm binary, and perhaps will help with benchmarks.
* Implement bottom heap types (#5115)Thomas Lively2022-10-0790-1760/+1946
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | These types, `none`, `nofunc`, and `noextern` are uninhabited, so references to them can only possibly be null. To simplify the IR and increase type precision, introduce new invariants that all `ref.null` instructions must be typed with one of these new bottom types and that `Literals` have a bottom type iff they represent null values. These new invariants requires several additional changes. First, it is now possible that the `ref` or `target` child of a `StructGet`, `StructSet`, `ArrayGet`, `ArraySet`, or `CallRef` instruction has a bottom reference type, so it is not possible to determine what heap type annotation to emit in the binary or text formats. (The bottom types are not valid type annotations since they do not have indices in the type section.) To fix that problem, update the printer and binary emitter to emit unreachables instead of the instruction with undetermined type annotation. This is a valid transformation because the only possible value that could flow into those instructions in that case is null, and all of those instructions trap on nulls. That fix uncovered a latent bug in the binary parser in which new unreachables within unreachable code were handled incorrectly. This bug was not previously found by the fuzzer because we generally stop emitting code once we encounter an instruction with type `unreachable`. Now, however, it is possible to emit an `unreachable` for instructions that do not have type `unreachable` (but are known to trap at runtime), so we will continue emitting code. See the new test/lit/parse-double-unreachable.wast for details. Update other miscellaneous code that creates `RefNull` expressions and null `Literals` to maintain the new invariants as well.
* Warn on too many parameters for Web VMs (#5119)Alon Zakai2022-10-061-0/+22
| | | Fixes emscripten-core/emscripten#17988
* wasm2js: Support for flexible module import naming (#5114)Sam Clegg2022-10-05118-410/+327
| | | | | | | | The previous code was making emscripten-specific assumptions about imports basically all coming from the `env` module. I can't find a way to make this backwards compatible so may do a combined roll with the emscripten-side change: https://github.com/emscripten-core/emscripten/pull/17806
* Strip em_js_deps exports (#5109)Sam Clegg2022-10-041-12/+28
| | | These are only needed for the metadata extraction in emcc.
* Simplify and fix heap type counting (#5110)Thomas Lively2022-10-0411-34/+40
| | | | | Annotations on array.get and array.set were not being counted and the code could generally be simplified since `count` already ignores types that don't need to be counted.
* Make Asyncify work with wasm64 (#5105)Sam Clegg2022-10-041-0/+1335
| | | | | The emscripten side is a little tricky but I've got some tests passing. Currently blocked on: https://github.com/emscripten-core/emscripten/issues/17969
* Fix ordering of visit() in MemoryGrow interpretation (#5108)Alon Zakai2022-10-031-0/+26
| | | | | | | This is a pretty subtle point that was missed in #4811 - we need to first visit the child, then compute the size, as the child may alter that size. Found by the fuzzer.
* Fix compiler warnings under emcc. NFC (#5104)Sam Clegg2022-10-031-3/+3
| | | | | These comparisons were showing up as warnings with the latest emcc/clang. I only noticed because I ran `ninja` to build everything whereas we only test the `binaryen` target under emscripten normally.
* [Wasm GC] Fix .depth() and add testing (#5102)Alon Zakai2022-09-301-0/+38
|
* Fix handling of unreachable selects in Directize (#5098)Alon Zakai2022-09-301-0/+36
| | | | We ignored only unreachable conditions, but we must ignore the arms as well, or else we could error.
* [GUFA] Test that combined things intersect with the combination. (#5094)Alon Zakai2022-09-291-0/+113
| | | | Just an automatic test that A has an intersection with A + B for the contents in our unit test.
* [GUFA] Improve hashing (#5091)Alon Zakai2022-09-281-0/+22
| | | | Avoid manually doing bitshifts etc. - leave combining to the core hash logic, which can do a better job.
* [GUFA] Add some tests (#5090)Alon Zakai2022-09-281-2/+197
| | | | | | | These just add more test coverage of situations I've seen during some recent debugging, that I realized we lack coverage for. The first function here would have detected the bug fixed in #5089
* [GUFA] Fix haveIntersection on comparing nullable with non-nullable (#5089)Alon Zakai2022-09-282-0/+18
| | | | | We compared types and not heap types, so a difference in nullability confused us. But at that point in the code, we've ruled out nulls, so we should focus on heap types only.
* Memory64Lowering: Ignore data segments with non-const iniital offset (#5074)Sam Clegg2022-09-282-0/+5
| | | | This is the case for dynamic linking where the segment offset are derived from he `__memory_base` import.
* [GUFA] Optimize functions not taken by reference better (#5085)Alon Zakai2022-09-261-2/+34
| | | | | | | | | This moves the logic to add connections from signatures to functions from the top level into the RefFunc logic. That way we only add those connections to functions that actually have a RefFunc, which avoids us thinking that a function without one can be reached by a call_ref of its type. Has a small but non-zero benefit on j2wasm.
* [GUFA] Infer a RefEq value of 0 when possible (#5081)Alon Zakai2022-09-262-0/+341
| | | | If the PossibleContents for the two sides have no possible intersection then the result must be 0.
* Emit call_ref with a type annotation (#5079)Thomas Lively2022-09-2315-59/+61
| | | | | | | Emit call_ref instructions with type annotations and a temporary opcode. Also implement support for parsing optional type annotations on call_ref in the text and binary formats. This is part of a multi-part graceful update to switch Binaryen and all of its users over to using the type-annotated version of call_ref without there being any breakage.
* [C API] Make TypeBuilderSetSubType take a heap type (#5045)dcode2022-09-232-1/+87
| | | Fixes #5041
* Add a type annotation to return_call_ref (#5068)Thomas Lively2022-09-224-26/+38
| | | | | | The GC spec has been updated to have heap type annotations on call_ref and return_call_ref. To avoid breaking users, we will have a graceful, multi-step upgrade to the annotated version of call_ref, but since return_call_ref has no users yet, update it in a single step.
* Correctly handle escapes in string constants (#5070)Thomas Lively2022-09-224-7/+7
| | | | | | | Previously when we parsed `string.const` payloads in the text format we were using the text strings directly instead of un-escaping them. Fix that parsing, and while we're editing the code, also add support for the `\r` escape allowed by the spec. Remove a spurious nested anonymous namespace and spurious `static`s in Print.cpp as well.
* [GUFA] Optimize ref.test (#5067)Alon Zakai2022-09-221-2/+166
| | | | | | Similar to ref.cast slightly, but simpler. Also update some TODO text.
* [OptimizeInstruction] Prevent reordering for rule in #5034 (#5066)Max Graey2022-09-211-0/+12
|
* Add wasm64 support in OptimizeAddedConstants (#5043)Axis2022-09-211-0/+57
| | | This lets that pass optimize 64-bit offsets on memory64 loads and stores.
* [OptimizeInstructions] Simplify add / sub with negative on LHS or RHS for ↵Max Graey2022-09-202-51/+455
| | | | | | | | | floating points (#5034) ``` (-x) + y -> y - x x + (-y) -> x - y x - (-y) -> x + y ```
* [C-/JS-Api] Expose the multi memories feature (#4973)Max Graey2022-09-202-0/+2
| | | This finalizes the multi memories feature introduced in #4968.
* [Strings] Add missing String effects + tests (#5057)Alon Zakai2022-09-191-0/+549
| | | Also fix some formatting issue in the file.
* Vacuum: Ignore effects at the entire function scope when possible (#5053)Alon Zakai2022-09-199-24/+124
| | | | | | | | | | | | | | | Recently we added logic to ignore effects that don't "escape" past the function call. That is, e.g. local.set only affects the current function scope, and once the call stack is unwound it no longer matters as an effect. This moves that logic to a shared place, and uses it in the core Vacuum logic. The new constructor in EffectAnalyzer receives a function and then scans it as a whole. This works just like e.g. scanning a Block as a whole (if we see a break in the block, that has an effect only inside it, and the Block + children doesn't have a branch effect). Various tests are updated so they don't optimize away trivially, by adding new return values for them.
* [Wasm64] The binary format offset of load/store should be u64leb in wasm64 ↵Axis2022-09-191-4/+30
| | | | (#5038)
* Effects: Clarify trap effect meaning, and consider infinite loops to trap ↵Alon Zakai2022-09-164-34/+193
| | | | | | | | | | | | | | | | | | | | | due to timeout (#5039) I think this simplifies the logic behind what we consider to trap. Before we had kind of a hack in visitLoop that now has a more clear reasoning behind it: we consider as trapping things that trap in all VMs all the time, or will eventually. So a single allocation doesn't trap, but an unbounded amount can, and an infinite loop is considered to trap as well (a timeout in a VM will be hit eventually, somehow). This means we cannot optimize way a trivial infinite loop with no effects in it, while (1) {} But we can optimize it out in trapsNeverHappen mode. In any event, such a loop is not a realistic situation; an infinite loop with some other effect in it, like a call to an import, will not be optimized out, of course. Also clarify some other things regarding traps and trapsNeverHappen following recent discussions in https://github.com/emscripten-core/emscripten/issues/17732 Specifically, TNH will never be allowed to remove calls to imports.
* JPSI - Support re-entering a suspended Wasm module. (#5044)Brendan Dahl2022-09-161-3/+45
| | | | | | | | | | | | | Fixes: https://github.com/emscripten-core/emscripten/issues/17846 More detailed explanation of the issue from Thibaud: - A promising export is entered, generating a suspender s1, which is stored in the global - The wasm code calls a wrapped import, passing it the value in the global (s1) and suspends - Another export is entered, generating suspender s2, which is stored in the global - We call another wrapped import, which suspends s2 (so far so good) - We return to the event loop and s1 is resumed And now we are in an inconsistent state: the active suspender is "s1", but the object in the global is "s2". So the next time we call a wrapped import, there is a mismatch, which is what this runtime error reports.
* Temporarily restore the typed-function-references flags as no-ops (#5050)Thomas Lively2022-09-169-606/+658
| | | | | This allows a three-step upgrade process where binaryen is updated with this change, then users remove their use of these flags, then binaryen can remove the flags permanently.
* wasm2js: Don't assume that `env.abort` can always be impored. (#5049)Sam Clegg2022-09-16119-541/+373
| | | | | | This import was being injected and then used to implement trapping. Rather than injecting an import that doesn't exist in the original module we instead use the existing mechanism to implement this as an internal helper.
* Vacuum trivial trys (#5046)Alon Zakai2022-09-161-0/+39
| | | | A try whose body throws, and does nothing else, and the try catches that exception, can be removed.
* Allow optimizing with global function effects (#5040)Alon Zakai2022-09-163-0/+333
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This adds a map of function name => the effects of that function to the PassOptions structure. That lets us compute those effects once and then use them in multiple passes afterwards. For example, that lets us optimize away a call to a function that has no effects: (drop (call $nothing)) [..] (func $nothing ;; .. lots of stuff but no effects, only a returned value .. ) Vacuum will remove that dropped call if we tell it that the called function has no effects. Note that a nice result of adding this to the PassOptions struct is that all passes will use the extra info automatically. This is not enabled by default as the benefits seem rather minor, though it does help in a small but noticeable way on J2Wasm code, where we use call.without.effects and have situations like this: (func $foo (call $bar) ) (func $bar (call.without.effects ..) ) The call to bar looks like it has effects, normally, but with global effect info we know it actually doesn't. To use this, one would do --generate-global-effects [.. some passes that use the effects ..] --discard-global-effects Discarding is not necessary, but if there is a pass later that adds effects, then not discarding could lead to bugs, since we'd think there are fewer effects than there are. (However, normal optimization passes never add effects, only remove them.) It's also possible to call this multiple times: --generate-global-effects -O3 --generate-global-effects -O3 That computes affects after the first -O3, and may find fewer effects than earlier. This doesn't compute the full transitive closure of the effects across functions. That is, when computing a function's effects, we don't look into its own calls. The simple case so far is enough to handle the call.without.effects example from before (though it may take multiple optimization cycles).
* Multi-Memories wasm-split (#4977)Ashley Nelson2022-09-154-10/+148
| | | Adds an --in-secondary-memory switch to the wasm-split tool that allows profile data to be stored in a separate memory from module main memory. With this option, users do not need to reserve the initial memory region for profile data and the data can be shared between multiple threads.
* [OptimizeInstructions] More canonizations for floating points (#5033)Max Graey2022-09-152-30/+107
| | | | | | | | x - C -> x + (-C) min(C, x) -> min(x, C) max(C, x) -> max(x, C) And remove redundant rules
* wasm2js: Have instantiate function take standard import object (#5018)Sam Clegg2022-09-14118-162/+312
| | | | | | | | | | | Previously we were assuming asmLibraryArg which is what emscripten passes as the `env` import object but using this method is more flexible and should allow wasm2js to work with import that are not all form a single object. The slight size increase here is just temporary until emscripten gets updated. See https://github.com/emscripten-core/emscripten/pull/17737
* [Exceptions] Optimize in CodePushing even with exceptions thrown (#5028)Alon Zakai2022-09-131-1/+70
| | | | | | | | | | We had some concerns about this not working in the past, but thinking about it now, I believe it is safe to do. Specifically, a throw is either like a break or a return - either it jumps out to an outer scope (like a break) or it jumps out of the function (like a return), and both breaks and returns have already been handled here. This change has some nice effects on J2Wasm output, where there are quite a lot of throws, which we can now optimize around.
* OptimizeInstructions: Use min/max bits in comparisons (#5035)Alon Zakai2022-09-132-57/+444
| | | | | | | When we see e.g. x < y and x has fewer bits set, we can infer a result. Helps #5010. As mentioned there, this is one of the top superoptimizer findings. On j2wasm it ends up removing a few hundred binary operations for example.
* [OptimizeInstructions] Simplify floating point ops with NaN on right side ↵Max Graey2022-09-122-24/+200
| | | | | | | | | | | | | | | | | | | (#4985) x + nan -> nan' x - nan -> nan' x * nan -> nan' x / nan -> nan' min(x, nan) -> nan' max(x, nan) -> nan' where nan' is canonicalized nan of rhs x != nan -> 1 x == nan -> 0 x >= nan -> 0 x <= nan -> 0 x > nan -> 0 x < nan -> 0
* [C-/JS-API] Add new BinaryenMemoryIs64 API + add memory64 argument for ↵Max Graey2022-09-1213-13/+19
| | | | BinaryenSetMemory (#4963)
* Remove typed-function-references feature (#5030)Thomas Lively2022-09-0919-711/+636
| | | | | | | | | | | | | | | | In practice typed function references will not ship before GC and is not independently useful, so it's not necessary to have a separate feature for it. Roll the functionality previously enabled by --enable-typed-function-references into --enable-gc instead. This also avoids a problem with the ongoing implementation of the new GC bottom heap types. That change will make all ref.null instructions in Binaryen IR refer to one of the bottom heap types. But since those bottom types are introduced in GC, it's not valid to emit them in binaries unless unless GC is enabled. The fix if only reference types is enabled is to emit (ref.null func) instead of (ref.null nofunc), but that doesn't always work if typed function references are enabled because a function type more specific than func may be required. Getting rid of typed function references as a separate feature makes this a nonissue.