summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
...
* wasm-reduce: Avoid a crash where function names change after ↵Alon Zakai2021-07-221-3/+4
| | | | | | | | | | | | tryToRemoveFunctions (#4013) tryToRemoveFunctions() will reload the wasm from binary if it fails to optimize, and without the names section we don't have a guarantee on the names being the same after that. And then tryToEmptyFunctions would look for a name, and crash. In the reverse order there is no risk, as tryToEmptyFunctions does not reload the wasm from binary, it carefully undoes what it tried to do when it fails.
* Reduce more carefully when it looks like we are failing (#3996)Alon Zakai2021-07-221-3/+3
| | | | | | Instead of skipping to the end, move quickly towards the end. This is sometimes more efficient (as jumping from a big factor to a factor of 1 can skip over big opportunities to remove code all at once instead of once instruction at a time).
* [Optimize Instructions] Simplify zero/sign extentions (special case) (#4009)Max Graey2021-07-221-9/+25
| | | | | | | For signed or unsigned extension to 64-bits after lowering from partially filled 64-bit arguments: ```rust i64.extend_i32_u(i32.wrap_i64(x)) => x // where maxBits(x) <= 32 i64.extend_i32_s(i32.wrap_i64(x)) => x // where maxBits(x) <= 31 ```
* Do not create a select with multivalue arms in OptimizeInstructions (#4012)Alon Zakai2021-07-223-9/+14
| | | Similar to #4005 but on OptimizeInstructions instead of RemoveUnusedBrs.
* [Wasm GC] Avoid dangerous StackIR opts on GC (#4007)Alon Zakai2021-07-221-4/+40
| | | | | | | | removeUnneededBlocks() can force us to use a local when we load the emitted wasm, which can't work for something nondefaultable like an RTT. For now, just don't run that optimization if GC is enabled. Eventually, perhaps we'll want to enable this optimization in a different way.
* [Optimize Instructions] Combine reinterprets, loads and stores (#4006)Max Graey2021-07-212-0/+37
| | | | | | | | | | | | | | | | | | | | | | | | Fixes #3973 Loads: f32.reinterpret_i32(i32.load(x)) => f32.load(x) f64.reinterpret_i64(i64.load(x)) => f64.load(x) i32.reinterpret_f32(f32.load(x)) => i32.load(x) i64.reinterpret_f64(f64.load(x)) => i64.load(x) Stores: f32.store(y, f32.reinterpret_i32(x)) => i32.store(y, x) f64.store(y, f64.reinterpret_i64(x)) => i64.store(y, x) i32.store(y, i32.reinterpret_f32(x)) => f32.store(y, x) i64.store(y, i64.reinterpret_f64(x)) => f64.store(y, x) Also optimize reinterprets that are undone: i32.reinterpret_f32(f32.reinterpret_i32(x)) => x i64.reinterpret_f64(f64.reinterpret_i64(x)) => x f32.reinterpret_i32(i32.reinterpret_f32(x)) => x f64.reinterpret_i64(i64.reinterpret_f64(x)) => x
* Exponentially empty out function bodies when reducing (#3997)Alon Zakai2021-07-201-45/+75
| | | | | | | | | This removes the code that did so one at a time, and instead adds it in a way that we can do it in an exponentially growing set of functions. On large testcases where other methods do not work, this is very useful. Also adjust the factor to do this 20x more often, which in practice is very useful too.
* [Optimize Instructions] Simplify sign extentions (#4004)Max Graey2021-07-201-0/+51
| | | | | | | | | | | | | | requiring sign-extension: ``` i64(x) << 56 >> 56 ==> i64.extend8_s(x) i64(x) << 48 >> 48 ==> i64.extend16_s(x) i64(x) << 32 >> 32 ==> i64.extend32_s(x) i64.extend_i32_s(i32.wrap_i64(x)) ==> i64.extend32_s(x) ``` general: ``` i32.wrap_i64(i64.extend_i32_s(x)) ==> x i32.wrap_i64(i64.extend_i32_u(x)) ==> x ```
* RemoveUnusedBrs: Do not create a select with a multivalue result (#4005)Alon Zakai2021-07-191-3/+13
| | | | | The spec disallows that. Fixes #3990
* Fix tiny typo (#3995)Alon Zakai2021-07-191-1/+1
|
* [Memory64] Fixed atomics / bulk memory support. (#3992)Wouter van Oortmerssen2021-07-192-5/+15
|
* Revert "Partially fix Precompute on SIMD (#3983)" (#4002)Alon Zakai2021-07-191-9/+9
| | | | | | | | | | | | | This reverts commit b68691e826a46d1b03b27c552b1f5b7f51f92665. Instead of applying the workaround to avoid precomputing SIMD in more places, which prevents things we could optimize before, we should probably focus on making the workaround not needed - that is, implement full SIMD support in the intepreter (the reason for that PR), and the other TODO in the comment here, // Until engines implement v128.const and we have SIMD-aware optimizations // that can break large v128.const instructions into smaller consts and // splats, do not try to precompute v128 expressions.
* [Optimize-Instructions] Simplify sign patterns like x < 0 ? -1 : 1 (#3756)Max Graey2021-07-161-0/+24
| | | | | | i32(x) < 0 ? i32(-1) : i32(1) -> x >> 31 | 1 i64(x) < 0 ? i64(-1) : i64(1) -> x >> 63 | 1 This shrinks 2 bytes.
* [Wasm GC] Fix getSentType() of BrOn with an unreachable input (#3993)Alon Zakai2021-07-161-0/+8
| | | | Without this fix, DCE would end up calling getHeapType() on the unreachable input, which hits an assertion as it has no heap type.
* [Wasm GC] Add Wasm GC support to InstrumentMemory (#3976)Alon Zakai2021-07-151-0/+135
| | | | | | | | This adds calls to imports around every struct load and store, to note their values, and also to arrays (where it also notes the index). This has been very useful in debugging LowerGC (lowering of Wasm GC to wasm MVP).
* Implement q15MulrSatSI16x8 for interpreter (#3984)Max Graey2021-07-142-1/+11
|
* Partially fix Precompute on SIMD (#3983)Alon Zakai2021-07-131-9/+9
| | | We had the logic in only one place.
* Implement interpretation of i64x2.bitmask (#3982)Thomas Lively2021-07-133-1/+12
| | | | | | | Like a few other SIMD operations, this i64x2.bitmask had not been implemented in the interpreter yet. Unlike the others, i64x2.bitmask has type i32 rather than type v128, so Precompute was not skipping it, leading to a crash, as in https://github.com/emscripten-core/emscripten/issues/14629. Fix the problem by implementing i64x2.bitmask in the interpreter.
* Improve NameTypes to keep reasonable names (#3977)Alon Zakai2021-07-121-5/+9
| | | | We only set a name now if there was no name, or the existing name was really really long.
* [Wasm GC] Add a isNonNullable() convenience method. NFC (#3978)Alon Zakai2021-07-128-10/+26
|
* [Memory64] further memory limit fixes (#3865)Wouter van Oortmerssen2021-07-092-3/+13
| | | That were somehow missed.. triggered by emscripten tests
* [Wasm GC] Add support for non-nullable locals in binary reading (#3955)Alon Zakai2021-07-021-7/+11
| | | | | | | We only tested that feature on the text format. For binary support, the reader needs to know that the feature is enabled, so that it allows non-nullable locals in that case (i.e., does not apply the workarounds to remove them). Fixes #3953
* Apply features from the commandline first (#3960)Alon Zakai2021-07-0214-90/+82
| | | | | | | | | | | | | | | | | | | | | | | | | | | As suggested in https://github.com/WebAssembly/binaryen/pull/3955#issuecomment-871016647 This applies commandline features first. If the features section is present, and disallows some of them, then we warn. Otherwise, the features can combine (for example, a wasm may enable feature X because it has to use it, and a user can simply add the flag for feature Y if they want the optimizer to try to use it; both flags will then be enabled). This is important because in some cases we need to know the features before parsing the wasm, in the case that the wasm does not use the features section. In particular, non-nullable GC locals have an effect during parsing. (Typed function references also does, but we found a way to apply its effect all the time, that is, always use the refined type, and that happened to not break the case where the feature is disabled - but such a workaround is not possible with non-nullable locals.) To make this less error-prone, add a FeatureSet input as a parameter to WasmBinaryBuilder. That is, when building a module, we must give it the features to use while doing so. This will unblock #3955 . That PR will also add a test for the actual usage of a feature during loading (the test can only be added there, after that PR unbreaks things).
* Set an absolute maximum inlining limit (#3959)Alon Zakai2021-07-012-0/+27
| | | | | | | | | | | We have seen some cases in both Chrome and Firefox where extremely large modules cause overhead, #3730 (comment) (and link therein) emscripten-core/emscripten#13899 (comment) There is no "right" value to use as a limit here, but pick an arbitrary one that is very high. (This setting is verified to have no effect on the emscripten benchmark suite.)
* Preserve Function HeapTypes (#3952)Thomas Lively2021-06-3048-285/+278
| | | | | | | | | When using nominal types, func.ref of two functions with identical signatures but different HeapTypes will yield different types. To preserve these semantics, Functions need to track their HeapTypes, not just their Signatures. This PR replaces the Signature field in Function with a HeapType field and adds new utility methods to make it almost as simple to update and query the function HeapType as it was to update and query the Function Signature.
* [Wasm GC] Fix LinearExecutionWalker (#3954)Alon Zakai2021-06-292-3/+16
| | | | | | | | | | That traversal did not mention BrOn, which led to it doing incorrect work in SimplifyLocals. Also add assertions at the end, that aim to prevent future issues. The rest of the fix is to make SimplifyLocals not assume that things are a Switch if they are not an If/Block/etc., so that we don't crash on a BrOn.
* Only set `supertype` if nominal typing is enabled (#3958)Thomas Lively2021-06-291-3/+5
| | | | | | | | | | | | | The code for printing and emitting the experimental nominal type constructors added in #3933 assumes that supertypes were only returned from `getSuperType` when nominal typing was enabled. `getSuperType` in turn was assuming that the supertype field would only be set if nominal typing was enabled, but this was not the case. This bug caused use-after-free errors because equirecursive canonicalization left the supertype field pointing to a temporary HeapTypeInfo that would be freed at the end of parsing but then accessed during module writing. To fix the issue, only set `supertype` if nominal typing is enabled, as originally intended.
* Refactor LinearExecutionWalker to a separate file. NFC (#3956)Alon Zakai2021-06-286-113/+143
|
* Handle invokes of invalid function pointers. See #14174 (#3951)Alon Zakai2021-06-241-13/+25
| | | | | | | | | PostEmscripten will turn an invoke of a constant function pointer index into a direct call. However, due to UB it is possible to have invalid function pointers, and we should not crash on that (and do nothing to optimize, of course). Mostly whitespace; to avoid deep nesting, I added more early returns.
* [EH] Make tag attribute's encoding uint8 (#3949)Heejin Ahn2021-06-221-4/+4
| | | | | | | | | | | This changes the encoding of the `attribute` field, which currently only contains the value `0` denoting this tag is for an exception, from `varuint32` to `uint8`. This field is effectively unused at the moment and reserved for future use, and it is not likely to need `varuint32` even in future. See https://github.com/WebAssembly/exception-handling/pull/162. This does not change any encoded binaries because `0` is encoded in the same way both in `varuint32` and `uint8`.
* Preserve function heap types during text parsing (#3935)Thomas Lively2021-06-222-34/+42
| | | | | | | | | | | | | | Previously, ref.func instructions would be assigned the canonical (i.e. first parsed) heap type for the referenced function signature rather than the HeapType actually specified in the type definition. In nominal mode, this could cause validation failures because the types assigned to ref.func instructions would not be correct. Fix the problem by tracking function HeapTypes rather than function Signatures when parsing the text format. There can still be validation failures when round-tripping modules because function HeapTypes are not properly preserved after parsing, but that will be addressed in a follow-up PR.
* [EH] Make tag's attribute encoding detail (#3947)Heejin Ahn2021-06-2110-37/+10
| | | | | | | | | This removes `attribute` field from `Tag` class, making the reserved and unused field known only to binary encoder and decoder. This also removes the `attribute` parameter from `makeTag` and `addTag` methods in wasm-builder.h, C API, and Binaryen JS API. Suggested in https://github.com/WebAssembly/binaryen/pull/3946#pullrequestreview-687756523.
* Remove (attr 0) from tag text format (#3946)Heejin Ahn2021-06-194-26/+2
| | | | | | | | This attribute is always 0 and reserved for future use. In Binayren's unofficial text format we were writing this field as `(attr 0)`, but we have recently come to the conclusion that this is not necessary. Relevant discussion: https://github.com/WebAssembly/exception-handling/pull/160#discussion_r653254680
* [Wasm GC] Fix inlining + non-nullable locals (#3945)Alon Zakai2021-06-181-1/+8
| | | | | | We don't need to assign a zero value for such locals (and we can't, as no default value exists for them). Fixes #3944
* [EH] Replace event with tag (#3937)Heejin Ahn2021-06-1831-498/+484
| | | | | | | | | | | We recently decided to change 'event' to 'tag', and to 'event section' to 'tag section', out of the rationale that the section contains a generalized tag that references a type, which may be used for something other than exceptions, and the name 'event' can be confusing in the web context. See - https://github.com/WebAssembly/exception-handling/issues/159#issuecomment-857910130 - https://github.com/WebAssembly/exception-handling/pull/161
* Rename wasm-delegations[-fields].h to def files (NFC) (#3941)Heejin Ahn2021-06-1812-19/+19
| | | | | | | | | | | These files are special in that they use define symbols that are not defined within those files or other files included in those files; they are supposed to be defined in source files that include these headers. This has caused clang-tidy to fail every time these files have changed because they are not compilable per se. This PR solves the problem by changing their extension to `def`, which is also used in LLVM codebase. LLVM has dozens of files like this whose extension is `def`, which makes these not checked by clang-tidy.
* [Wasm GC] Fix RSE on non-nullable locals (#3943)Alon Zakai2021-06-181-2/+7
| | | | | | | | | | RedundantSetElimination checks if a local already has the default value when we assign the default to it. For a non-nullable local, however, there is no initial value - it cannot be used before it is assigned to. So we just need to skip such locals, and not assume they contain a default value we can compare against (we would assert on trying to create a "zero" for such a non-nullable type). Fixes #3942
* Add a extract-function-index passThomas Lively2021-06-173-28/+55
| | | | | | | | This is a useful alternative to extract-function when you don't know the function's name. Also moves the extract-function tests to be lit tests and re-uses them as extract-function-index tests.
* Add space between options in --help text (#3940)Thomas Lively2021-06-171-0/+1
| | | | | Improve the legibility of the option documentation by adding vertical space between options. This is particularly helpful to delimit the text of options with longer explanations.
* [wasm2js] Refactor assertion parsing (#3938)Thomas Lively2021-06-171-19/+31
| | | | | | | | | | | | | | | Assertions were previously parsed by replacing "invoke" with "call" and using the normal s-expr parser. The parseCall method of the s-expr parser uses the call target to look up the correct signature on the module, but the invoke targets in assertions use export names rather than internal function names, so the signature lookups were inserting new bogus entries with default values. This issue didn't seem to cause any big problems before, but #3935 turns it into a hard error because the default `HeapType` does not have an associated signature. Fix the problem (at least in the common case of trivial arguments and expected results) by manually construction a `Call` expression rather than depending on the s-expr parser to construct it.
* [Wasm GC] rtt.fresh_sub (#3936)Alon Zakai2021-06-1713-11/+72
| | | | | | | | | | This is the same as rtt.sub, but creates a "new" rtt each time. See https://docs.google.com/document/d/1DklC3qVuOdLHSXB5UXghM_syCh-4cMinQ50ICiXnK3Q/edit# The old Literal implementation of rtts becomes a little more complex here, as it was designed for the original spec where only structure matters. It may be worth a complete redesign there, but for now as the spec is in flux I think the approach here is good enough.
* [Wasm GC] Add experimental support for non-nullable locals (#3932)Alon Zakai2021-06-154-7/+33
| | | | | | | | | | | | | | This adds a new feature flag, GCNNLocals that enables support for non-nullable locals. No validation is applied to check that they are actually assigned before their use yet - this just allows experimentation to begin. This feature is not enabled by default even with -all. If we enabled it, then it would take effect in most of our tests and likely confuse current users as well. Instead, the flag must be opted in explicitly using --enable-gc-nn-locals. That is, this is an experimental feature flag, and as such must be explicitly enabled. (Once the spec stabilizes, we will remove the feature anyhow when we implement the final status of non-nullability. )
* Parsing and emitting nominal types (#3933)Thomas Lively2021-06-158-16/+85
| | | | | | | Adds a `--nominal` option to switch the type machinery from equirecursive to nominal. Implements binary and text parsing and emitting of nominal types using new type constructor opcodes and an `(extends $super)` text syntax extension. When not in nominal mode, these extensions will still be parsed but will not have any effect and will not be used when emitting.
* [wasm-split] Add an option to emit a placeholder map (#3931)Thomas Lively2021-06-123-5/+37
| | | | | | The new instruction emits a file containing a map between placeholder index and the name of the split out function that placeholder is replacing in the table. This map is intended to be useful for debugging, as discussed in https://github.com/emscripten-core/emscripten/issues/14330.
* Nominal subtyping (#3927)Thomas Lively2021-06-112-75/+241
| | | | | | | | | | | | | Add methods to the TypeBuilder interface to declare subtyping relationships between the built types. These relationships are validated and recorded globally as part of type building. If the relationships are not valid, a fatal error is produced. In the future, it would be better to report the error to the TypeBuilder client code, but this behavior is sufficient for now. Also updates SubTyper and TypeBounder to be aware of nominal mode so that subtyping and LUBs are correctly calculated. Tests of the failing behavior will be added in a future PR that exposes this functionality to the command line, since the current `example` testing infrastructure cannot handle testing fatal errors.
* [EH] Allow catch/delegate-less trys (#3924)Heejin Ahn2021-06-103-11/+7
| | | | This removes the restriction that `try` should have at least one `catch`/`catch_all`/`delegate`. See WebAssembly/exception-handling#157.
* Store signatures as HeapTypes when parsing binaries (#3929)Thomas Lively2021-06-102-24/+39
| | | | | | | When parsing func.ref instructions, we need to get the HeapType corresponding to the referenced function's signature. Since constructing HeapTypes from Signatures can be expensive under equirecursive typing, keep track of the original function signature HeapTypes directly during parsing rather than storing them as Signatures.
* [Wasm GC] Support struct.new in global initializers (#3930)Alon Zakai2021-06-091-1/+2
|
* [Wasm GC] Properly validate BrOn* (#3928)Alon Zakai2021-06-081-1/+1
| | | | | | The noteBreak call was in the wrong place, causing us to not note breaks from BrOnNull for example, which could make validation miss errors. Noticed in #3926
* Initial nominal typing support (#3919)Thomas Lively2021-06-082-40/+173
| | | | | | | | | | | | | | | | | | | | In nominal mode, HeapType constructors besides the Signature constructor always produce fresh types distinct from any previously created types. The HeapType constructor that takes a Signature maintains its previous behavior of constructing a canonical representative of the given signature because it is used frequently throughout the code base and never in a situation that would benefit from creating a fresh type. It is left as future work to clean up this discrepancy between the Signature HeapType constructor and other HeapType constructors. TypeBuilder skips shape and global canonicalization in nominal mode and always creates a fresh type for each of its entries. For this to work without any canonicalization, the TypeBuilder allocates temporary types on the global Type store and does not support building basic HeapTypes in nominal mode. The new mode is not available in any of the Binaryen tools yet because it is still missing critical functionality like the ability to declare subtyping relations and correctly calculate LUBs. This functionality will be implemented in future PRs.