summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
* Multi-Memories wasm-split (#4977)Ashley Nelson2022-09-156-28/+122
| | | 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-14/+9
| | | | | | | | x - C -> x + (-C) min(C, x) -> min(x, C) max(C, x) -> max(x, C) And remove redundant rules
* [C API] Add getters and setters for various GC/Strings expressions (#5037)dcode2022-09-142-0/+1297
| | | Covers CallRef, RefTest, RefCast, BrOn, StructNew, StructGet, StructSet, ArrayNew, ArrayInit, ArrayGet, ArraySet, ArrayLen, ArrayCopy, StringNew, StringConst, StringMeasure, StringEncode, StringConcat, StringEq, StringAs, StringWTF8Advance, StringWTF16Get, StringIterNext, StringIterMove, StringSliceWTF, StringSliceIter.
* wasm2js: Have instantiate function take standard import object (#5018)Sam Clegg2022-09-141-3/+19
| | | | | | | | | | | 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-132-6/+26
| | | | | | | | | | 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.
* Improve ExtractFunction pass error printing (#4747)juj2022-09-131-2/+3
| | | | | * Improve ExtractFunction pass error printing. * Update lint
* Move relational-optimizing code to optimizeRelational [NFC] (#5036)Alon Zakai2022-09-131-33/+35
| | | | | | This just moves the code from #5025 to the right function, which I did not realize existed. optimizeRelational is where we optimize binary operations that do comparisons, and it's nice to put all that code together. Avoids repeated checks of isRelational() in separate places.
* The name of the import object might not always be "env" (e.g. when ↵juj2022-09-131-1/+20
| | | | Emscripten minifies the import name to a shorter string "a"). Adjust LogExecution pass to discover the import name that is used. (#4746)
* OptimizeInstructions: Use min/max bits in comparisons (#5035)Alon Zakai2022-09-132-6/+95
| | | | | | | 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-124-28/+71
| | | | | | | | | | | | | | | | | | | (#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-123-2/+20
| | | | BinaryenSetMemory (#4963)
* Remove typed-function-references feature (#5030)Thomas Lively2022-09-0911-55/+19
| | | | | | | | | | | | | | | | 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.
* Changing Fatal() to assert() (#4982)Ashley Nelson2022-09-092-45/+15
| | | Replacing Fatal() call sites in src/shell-interface.h & src/tools/wasm-ctor-eval.cpp that were added in the Multi-Memories PR with assert()
* OptimizeInstructions: Optimize comparisons with an added offset (#5025)Alon Zakai2022-09-091-19/+81
| | | | | | | | | | | | | | E.g. x + C1 > C2 ==> x > (C2-C1) We do need to be careful of overflows in either the add on the left or the proposed subtract on the right. In the latter case, we can at least do x + C1 > C2 ==> x + (C1-C2) > 0 Helps #5008 (but more patterns remain). Found by the superoptimizer #4994. This was the top suggestion for Java and Dart.
* [Effects] Fix hasAnything on mutable global state (#5026)Alon Zakai2022-09-081-2/+1
| | | | | We explicitly wrote out memory, table, and globals, but did not add structs. This switches us to use readsMutableGlobalState which has the full list of all relevant global state, including the memory, table, and globals as well as structs.
* [NFC] Remove unused code in type fuzzer (#5023)Thomas Lively2022-09-071-67/+0
| | | | | The only call to `generateSubBasic` was removed as part of a bug fix in #4346, but the function itself was not removed. Remove it and other unused functions it depends on now.
* Switch to i32 operations when heading to a wrap anyhow (#5022)Alon Zakai2022-09-071-8/+119
| | | | | | | | | | | | | | | E.g. if we just do addition etc., then any higher bits will be wrapped out anyhow: int32_t(int64_t(x) + int64_t(10)) => x + int32_t(10) Found by the superoptimizer #4994 . This is by far the most promising suggestion it had. Interestingly, it mainly helps Go, where it removes 20% of all Unary operations (the extends and wraps), and Rust, where it removes 3%. Helps #5004. This handles the common cases I see in the superoptimizer output, but there are more that could be handled.
* [Wasm GC] Fix GlobalTypeOptimization fuzz bug on replacing unreachable ↵Alon Zakai2022-09-062-1/+15
| | | | | | struct.set (#5021) We replaced an unreachable struct.set with something reachable, which can break validation in corner cases.
* [OptimizeInstructions] Simplify two binary expressions with asymmetric ↵Max Graey2022-09-061-0/+49
| | | | | | | | | | | | shifts and same constant (#4996) (x >> C) << C -> x & -(1 << C) (x >>> C) << C -> x & -(1 << C) (x << C) >>> C -> x & (-1 >>> C) // (x << C) >> C doesn't support Found by the superoptimizer #4994 Fixes #5012
* Add JavaScript promise integration (JSPI) pass. (#4961)Brendan Dahl2022-09-027-0/+185
| | | | | | | Add a pass that wraps all imports and exports with functions that handle storing and passing along the suspender externref needed for JSPI. https://github.com/WebAssembly/js-promise-integration/blob/main/proposals/js-promise-integration/Overview.md
* OptimizeInstructions: Select => and/or in more cases (#4154)Alon Zakai2022-09-011-1/+25
| | | | | | | | | | | | | | | | | | | | | | | | | | x ? 0 : y ==> z & y where z = !x x ? y : 1 ==> z | y where z = !x Only do this when we have z = !x, that is, we can invert x without adding an actual eqz (which would add work). To do this, canonicalize selects to prefer to flip the arms, when possible, if it would move a constant to a location that the existing optimizations already turn into an and/or. That is, x >= 5 ? 0 : y != 42 would be canonicalized into x < 5 ? y != 42 : 0 and existing opts turn that into (x < 5) & (y != 42) The canonicalization does not always help this optimization, as we need the values to be boolean to do this, but canonicalizing is still nice to get more regular code which might compress slightly better.
* [Wasm GC] Fix evaluateKindCheck() on new externalize/internalize operations ↵Alon Zakai2022-09-011-2/+6
| | | | | | | | | | (#5000) Also add testing that they pass through the full optimizer. Fixes #4999 Drive-by fixes to the text in the assertions, which was copy-pasted.
* Add remaining GC and string instructions to C API (#4998)dcode2022-08-313-25/+471
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | Adds C-API bindings for the following expression classes: RefTest RefCast BrOn with operations BrOnNull, BrOnNonNull, BrOnCast, BrOnCastFail, BrOnFunc, BrOnNonFunc, BrOnData, BrOnNonData, BrOnI31, BrOnNonI31 StructNew with operations StringNewUTF8, StringNewWTF8, StringNewReplace, StringNewWTF16, StringNewUTF8Array, StringNewWTF8Array, StringNewReplaceArray, StringNewWTF16Array StructGet StructSet ArrayNew ArrayInit ArrayGet ArraySet ArrayLen ArrayCopy StringNew StringConst StringMeasure with operations StringMeasureUTF8, StringMeasureWTF8, StringMeasureWTF16, StringMeasureIsUSV, StringMeasureWTF16View StringEncode with operations StringEncodeUTF8, StringEncodeWTF8, StringEncodeWTF16, StringEncodeUTF8Array, StringEncodeWTF8Array, StringEncodeWTF16Array StringConcat StringEq StringAs with operations StringAsWTF8, StringAsWTF16, StringAsIter StringWTF8Advance StringWTF16Get StringIterNext StringIterMove with operations StringIterMoveAdvance, StringIterMoveRewind StringSliceWTF with operations StringSliceWTF8, StringSliceWTF16 StringSliceIter
* Update fuzzer to newer GC spec regarding JS interop (#4965)Alon Zakai2022-08-311-7/+24
| | | | Do not export functions that have types not allowed in the rules for JS interop. Only very few GC types can be on the JS boundary atm.
* [NFC] Simplify binary reading logic for data segments (#4990)Alon Zakai2022-08-312-10/+4
| | | Similar to #4969 but for data segments.
* [Wasm GC] Support non-nullable locals in the "1a" form (#4959)Alon Zakai2022-08-3145-192/+622
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | An overview of this is in the README in the diff here (conveniently, it is near the top of the diff). Basically, we fix up nn locals after each pass, by default. This keeps things easy to reason about - what validates is what is valid wasm - but there are some minor nuances as mentioned there, in particular, we ignore nameless blocks (which are commonly added by various passes; ignoring them means we can keep more locals non-nullable). The key addition here is LocalStructuralDominance which checks which local indexes have the "structural dominance" property of 1a, that is, that each get has a set in its block or an outer block that precedes it. I optimized that function quite a lot to reduce the overhead of running that logic after each pass. The overhead is something like 2% on J2Wasm and 0% on Dart (0%, because in this mode we shrink code size, so there is less work actually, and it balances out). Since we run fixups after each pass, this PR removes logic to manually call the fixup code from various places we used to call it (like eh-utils and various passes). Various passes are now marked as requiresNonNullableLocalFixups => false. That lets us skip running the fixups after them, which we normally do automatically. This helps avoid overhead. Most passes still need the fixups, though - any pass that adds a local, or a named block, or moves code around, likely does. This removes a hack in SimplifyLocals that is no longer needed. Before we worked to avoid moving a set into a try, as it might not validate. Now, we just do it and let fixups happen automatically if they need to: in the common code they probably don't, so the extra complexity seems not worth it. Also removes a hack from StackIR. That hack tried to avoid roundtrip adding a nondefaultable local. But we have the logic to fix that up now, and opts will likely keep it non-nullable as well. Various tests end up updated here because now a local can be non-nullable - previous fixups are no longer needed. Note that this doesn't remove the gc-nn-locals feature. That has been useful for testing, and may still be useful in the future - it basically just allows nn locals in all positions (that can't read the null default value at the entry). We can consider removing it separately. Fixes #4824
* [C/JS API] Avoid erroring in BinaryenSetMemoryImport etc. if the entity ↵Max Graey2022-08-302-30/+70
| | | | | | exists (#4991) If it exists, just turn it into an import. If not, then as before we create it + turn it into an import.
* Fix ModuleUtils::renameFunctions on RefFunc (#4978)Alon Zakai2022-08-291-26/+29
| | | | | It had hardcoded handling of the table, but was missing RefFunc (and maybe more?) Also some cleanups around that code.
* [NFC] Simplify binary reading logic for element segments (#4989)Alon Zakai2022-08-292-11/+4
| | | Similar to #4969 but for element segments.
* Implement `extern.externalize` and `extern.internalize` (#4975)Thomas Lively2022-08-2910-10/+132
| | | | These new GC instructions infallibly convert between `extern` and `any` references now that those types are not in the same hierarchy.
* [NFC] Simplify binary reading logic for memories (#4987)Alon Zakai2022-08-292-29/+7
| | | Similar to #4969 but for memories.
* Remvoe extra space after rec beginning (#4981)Alon Zakai2022-08-291-1/+1
|
* Fix SmallVector's resize() method (#4979)Alon Zakai2022-08-291-0/+2
| | | | A resize from a large amount to a small amount would sometimes not clear the flexible storage, if we used it before but not after.
* [OptimizeInstruction] Reorder rules in optimizeSelect (#4984)Max Graey2022-08-291-32/+32
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | To unblock some optimizations. For example this: ```wat (select (i32.eqz (local.get $x)) (i32.const 0) (i32.eqz (local.get $y)) ) ``` Was previously optimized as: ```wat (i32.eqz (select (i32.const 1) (local.get $x) (local.get $y) ) ) ``` Because `optimizeSelect` applied `!x ? !y : 0 -> x ? 0 : !y` then `!(x ? 1 : y)`, blocking the next rules which could have folded this to `or` or `and`. After this PR the same example optimizes better: ```wat (i32.eqz (i32.or (local.get $x) (local.get $y) ) ) ```
* [NFC] Simplify binary reading logic for globals (#4980)Alon Zakai2022-08-292-36/+11
| | | Similar to #4969 but for globals.
* [OptimizeInstructions] Canonicalize relational ops near min/max values (#4282)Max Graey2022-08-261-0/+61
| | | | | | | | | | | | | A continuation of #4272. ``` (signed)x < s_min + 1 ==> x == s_min (signed)x >= s_min + 1 ==> x != s_min (signed)x > s_max - 1 ==> x == s_max (signed)x <= s_max - 1 ==> x != s_max (unsigned)x <= u_max - 1 ==> x != u_max (unsigned)x > u_max - 1 ==> x == u_max ```
* [NFC] Simplify binary reading logic for tables (#4974)Alon Zakai2022-08-262-32/+11
| | | Similar to #4969 but for tables.
* Emit `i31ref` and `dataref` binary shorthands (#4844)Thomas Lively2022-08-261-6/+4
|
* Make `i31ref` and `dataref` nullable (#4843)Thomas Lively2022-08-265-58/+40
| | | | | | | Match the latest version of the GC spec. This change does not depend on V8 changing its interpretation of the shorthands because we are still temporarily not emitting the binary shorthands, but all Binaryen users will have to update their interpretations along with this change if they use the text or binary shorthands.
* [Parser] Parse functions and implicit types (#4972)Thomas Lively2022-08-262-20/+397
| | | | | | | | | Implement function parsing, including parsing of locals and type uses. Also add a new phase of parsing that iterates through type uses that do not have explicit types to create any implicitly defined types and append them to the type index space. This is important because the implicitly defined types may be referred to by index elsewhere and because the legacy parser does not handle these implicitly defined types correctly. Finally, maintain a map of implicit type use locations to corresponding types for use in later phases of parsing.
* Add support for Tag names in the Names section (#4970)Alon Zakai2022-08-262-4/+61
|
* [NFC] Simplify binary reading logic for functions (#4969)Alon Zakai2022-08-262-23/+9
| | | | | | | We do a call to updateMaps() at the end of processNames anyhow, and so we may as well call addFunction immediately (and the names will get fixed up in that updateMaps later). The old code for some reason did that for function imports, but not normal functions. It also stored them separately in temporary storage for some unclear reason...
* Adding Multi-Memories Wasm Feature (#4968)Ashley Nelson2022-08-256-2/+20
| | | Adding multi-memories to the the list of wasm-features.
* Fix order of local names in Names section (#4964)Congcong Cai2022-08-251-17/+19
| | | | | | The wasm spec requires the order of local names in that section to be in increasing order: https://webassembly.github.io/spec/core/appendix/custom.html#binary-namemap
* [TNH Fuzzing] Fix some equality checks that ignored effects (#4951)Alon Zakai2022-08-241-8/+20
| | | | | | | | | | | | | Fuzzing with TrapsNeverHappen found a bug, and then reading similar code I found another, where we check structural equality but ignored effects. Some things look equal but may have different values at runtime: (foo (call $x) (call $y) ) The arms are identical structurally but due to side effects may not be identical in value.
* Fuzzer simplification: Remove trap-ignoring logic (#4958)Alon Zakai2022-08-242-16/+3
| | | | | | | | | | | | | The "ignore trap" logic there is not close to enough for what we'd need to actually fuzz in a way that ignores traps, so this removes it. Atm that logic just allows a trap to happen without causing an error (that is, when comparing two results, one might trap and the other not, but they'd still be considered "equal"). But due to how we optimize traps in TrapsNeverHappens mode, the optimizer is free to assume the trap never occurs, which might remove side effects that are noticeable later. To actually handle that, we'd need to refactor the code to retain results per function (including the Loggings) and then to ignore everything from the very first trapping function. That is somewhat complicated to do, and a simpler thing is done in #4936, so we won't need it here.
* Only look at the relevant parameter in param-utils:removeParameter (#4937)Alon Zakai2022-08-231-5/+2
| | | Followup to #4910.
* Fix multi-memory + C API for MemoryGrow and MemorySize (#4953)Alon Zakai2022-08-234-19/+44
| | | | | | | | | | | | | | | | Those instructions need to know if the memory is 64-bit or not. We looked that up on the module globally, which is convenient, but in the C API this was actually a breaking change, it turns out. To keep things working, provide that information when creating a MemoryGrow or MemorySize, as another parameter in the C API. In the C++ API (wasm-builder), support both modes, and default to the automatic lookup. We already require a bunch of other explicit info when creating expressions, like making a Call requires the return type (we don't look it up globally), and even a LocalGet requires the local type (we don't look it up on the function), so this is consistent with those. Fixes #4946
* Multi-Memories Validate (#4945)Ashley Nelson2022-08-231-37/+43
| | | This change loops through memories to validate each meets wasm spec. Also factors data segment validation out from memory validation, as it makes more sense for data segments to stand alone like the other module-level elements.
* Separate `func` into a separate type hierarchy (#4955)Thomas Lively2022-08-223-37/+18
| | | | | Just like `extern` is no longer a subtype of `any` in the new GC type system, `func` is no longer a subtype of `any`, either. Make that change in our type system implementation and update tests and fuzzers accordingly.