summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
...
* [Simd] Refactoring. Remove middle *Vec* from some simd ops for consistency ↵Max Graey2021-07-273-51/+51
| | | | (#4027)
* [Wasm GC] DeadArgumentElimination: Do not refine return types of tail ↵Alon Zakai2021-07-271-3/+9
| | | | | | callees (#4025) If there is a tail call, we can't change the return type of the function, as it must match in the functions doing a tail call of it.
* [Wasm GC] Refine return types (#4020)Alon Zakai2021-07-261-1/+83
| | | | | | Corresponds to #4014 which did the same for parameter types. This sees whether the return types actually returned from a function allow us to use a more specific type for the function's return. If so, we update that type, as well as calls to the function.
* [Simd] Add extending pairwise adds to interpreter (#4022)Max Graey2021-07-263-4/+33
|
* [SIMD] Add extend + mul simd operations to interpreter (#4021)Max Graey2021-07-261-12/+25
|
* [Simd] Add extension from i32x4 to i64x2 ops to interpreter (#4016)Max Graey2021-07-263-0/+20
|
* [Wasm GC] Handle nondefaultable types in LocalSubtyping (#4019)Alon Zakai2021-07-231-8/+15
| | | | | The pass handled non-nullability, but another case is a tuple with nullable values in it that is assigned non-nullable values, and in general, other stuff that is nondefaultable (but not non-nullable). Ignore those.
* [Wasm GC] Fix Heap2Local + non-nullable locals (#4017)Alon Zakai2021-07-233-11/+35
| | | | | | | | | | | | | | | | | | | | | | | | | | | Given (local $x (ref $foo)) (local.set $x ..) (.. (local.get $x)) If we remove the local.set but not the get, then we end up with (local $x (ref $foo)) (.. (local.get $x)) It looks like the local.get reads the initial value of a non-nullable local, which is not allowed. In practice, this would crash in precompute-propagate which would try to propagate the initial value to the get. Add an assertion there with a clear message, as until we have full validation of non-nullable locals (and the spec for that is in flux), that pass is where bugs will end up being noticed. To fix this, replace the get as well. We can replace it with a null for simplicity; it will never be used anyhow. This also uncovered a small bug with reached not containing all the things we reached - it was missing local.gets.
* [SIMD] Refactor extend helper (#4018)Max Graey2021-07-231-13/+12
|
* [Wasm GC] Local-Subtyping pass (#3765)Alon Zakai2021-07-234-0/+153
| | | | | | | | | | | | | | | | | | | | | | | | | | | | If a local is say anyref, but all values assigned to it are something more specific like funcref, then we can make the type of the local more specific. In principle that might allow further optimizations, as the local.gets of that local will have a more specific type that their users can see, like this: (import .. (func $get-funcref (result funcref))) (func $foo (result i32) (local $x anyref) (local.set $x (call $get-funcref)) (ref.is_func (local.get $x)) ) => (func $foo (result i32) (local $x funcref) ;; updated to a subtype of the original (local.set $x (call $get-funcref)) (ref.is_func (local.get $x)) ;; this can now be optimized to "1" ) A possible downside is that using more specific types may not end up allowing optimizations but may end up increasing the size of the binary (say, replacing lots of anyref with various specific types that compress more poorly; also, for recursive types the LUB may be a unique type appearing nowhere else in the wasm). We should investigate the code size factors more later.
* Clean up and rewrite wasm-reduce element segment logic (#4015)Alon Zakai2021-07-231-16/+19
| | | | | | | | | Practically NFC, but it does reorder some code a little. Previously we would find a "zero", then shrink segments, then use that zero - which might no longer be in the table. That seems weird, so this reorders that, but there should be no significant difference in the output. Also reduce the factor of 100 to 1, which in practice is important on one of the Dart GC benchmarks that has a huge number of table segments.
* [Wasm GC] Refine function parameter types (#4014)Alon Zakai2021-07-231-8/+84
| | | | | | | | If a function is always called with a more specific type than it is declared, we can make the type more specific. DeadArgumentElimination's name is becoming increasingly misleading, and should maybe be renamed. But it is the right place for this as it already does an LTO scan of the call graph and builds up parameter data structures etc.
* 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.