summaryrefslogtreecommitdiff
path: root/src/ir
Commit message (Collapse)AuthorAgeFilesLines
* Stack utils (#3083)Thomas Lively2020-09-073-0/+489
| | | | | | Implement and test utilities for manipulating and analyzing a new stacky form of Binaryen IR that is able to express arbitrary stack machine code. This new Poppy IR will eventually replace Stack IR, and new optimization passes will be built with these utilities. See #3059.
* Optimize MergeBlocks by caching branch results (#3102)Alon Zakai2020-09-031-8/+94
| | | | | | | | | | | BranchSeekerCache caches the set of branches in a node + its children, and helps compute new results by looking in the cache and using data for the children. This avoids quadratic time in the common case of a post-walk on a tower of nested blocks which is common in a switch. Fixes #3090 . On the testcase there this pass goes from over a minute to less than a second.
* MinifyImportsAndExports: Minify the memory and table as well. (#3089)Alon Zakai2020-09-021-0/+8
| | | | | | | | | | | | We were careful not to minify those, as well as the stack pointer, which makes sense in dynamic linking. But we don't run this pass in dynamic linking anyhow - we need the proper names of symbols in that case. So this was not helping us, and was just a leftover from an early state. This both a useful optimization and also important for #3043, as the wasm backend exports the table as __indirect_function_table - a much longer name than emscripten's table. So just changing to that would regress code size on small projects. Once we land this, the name won't matter as it will be minified anyhow.
* Add new compound Signature, Struct and Array types (#3012)Daniel Wirtz2020-08-241-1/+1
| | | | | Extends the `Type` hash-consing infrastructure to handle type-parameterized and constructed types introduced in the typed function references and GC proposals. This should be a non-functional change since the new types are not used anywhere yet. Recursive type construction and canonicalization is also left as future work. Co-authored-by: Thomas Lively <tlively@google.com>
* Prepare for compound types that are single but not basic (#3046)Daniel Wirtz2020-08-173-5/+5
| | | | | | | | | | | | | | As a follow-up to https://github.com/WebAssembly/binaryen/pull/3012#pullrequestreview-459686171 this PR prepares for the new compound Signature, Struct and Array types that are single but not basic. This includes: * Renames `Type::getSingle` to `Type::getBasic` (NFC). Previously, its name was not representing its implementation (`isSingle` excluded `none` and `unreachable` while `getSingle` didn't, i.e. `getSingle` really was `getBasic`). Note that a hypothetical `Type::getSingle` cannot return `ValueType` anyway (new compound types are single but don't map to `ValueType`), so I figured it's best to skip implementing it until we actually need it. * Marks locations where we are (still) assuming that all single types are basic types, as suggested in https://github.com/WebAssembly/binaryen/pull/3012#discussion_r465356708, but using a macro, so we get useful errors once we start implementing the new types and can quickly traverse the affected locations. The macro is added where * there used to be a `switch (type.getSingle())` or similar that handled any basic type (NFC), but in the future will also have to handle single types that are not basic types. * we are not dealing with `Unary`, `Binary`, `Load`, `Store` or `AtomicXY` instructions, since these don't deal with compound types anyway.
* Refactor hashing (#3023)Daniel Wirtz2020-08-124-31/+26
| | | | | | | | | * Unifies internal hashing helpers to naturally integrate with std::hash * Removes the previous custom implementation * Computed hashes are now always size_t * Introduces a hash_combine helper * Fixes an overwritten partial hash in Relooper.cpp
* Added headers to CMake files (#3037)Wouter van Oortmerssen2020-08-101-0/+2
| | | This is needed for headers to show up in IDE projects, and has no other effect on the build.
* Asyncify verbose option (#3022)Alon Zakai2020-08-061-3/+8
| | | | | | | | | | | | | | | | This logs out the decisions made about instrumenting functions, which can help figure out why a function is instrumented, or to get a list of what might need to be. As the test shows, it can print things like this: [asyncify] import is an import that can change the state [asyncify] calls-import can change the state due to import [asyncify] calls-calls-import can change the state due to calls-import [asyncify] calls-calls-calls-import can change the state due to calls-calls-import (the test has calls-calls-calls-import => calls-calls-import => calls-import -> import).
* Refactor getMaxBits() out of OptimizeInstructions and add beginnings of unit ↵Alon Zakai2020-08-041-69/+232
| | | | | | | | | testing for it (#3019) getMaxBits just moves around, no logic is changed. Aside from adding getMaxBits, the change in bits.h is 99% whitespace. helps #2879
* Fix the side effects of data.drop (#2996)Alon Zakai2020-07-281-2/+4
| | | | | | | | | | | | | We marked it as readsMemory so that it could be reordered with various things, except for memory.init. However, the fuzzer found that's not quite right, as it has a global side effect - memory.inits that run later can notice that. So it can't be reordered with anything that might affect global side effects from happening, as in the testcase added here (an instruction that may trap cannot be reordered with a data.drop, as it may prevent the data.drop from happening and changing global state). There may be a way to optimize this more carefully that would allow more optimizations, but as this is a rare instruction I'm not sure it's worth more work.
* Optimize select with const arms (#2869)Max Graey2020-07-221-2/+15
| | | | | x ? 1 : 0 => !!x and so forth.
* Add a builder.makeConst helper template (#2971)Alon Zakai2020-07-213-5/+4
|
* Avoid __popcnt and __popcnt64 intrinsics for MSVC (#2944)Max Graey2020-07-061-3/+3
| | | | We may need to check the CPU ID or something else before using those special things on MSVC. To be safe, avoid them for now.
* More optimizations for pow of two and pos/neg one const on the right (#2870)Max Graey2020-06-221-0/+40
|
* Rename anyref to externref to match proposal change (#2900)Jay Phelps2020-06-101-2/+2
| | | | | | | anyref future semantics were changed to only represent opaque host values, and thus renamed to externref. [Chromium](https://bugs.chromium.org/p/v8/issues/detail?id=7748#c360) was just updated to today (not yet released). I couldn't find a Mozilla bugzilla ticket mentioning externref so I don't immediately know if they've updated yet. https://github.com/WebAssembly/reference-types/pull/87
* Add prototype SIMD rounding instructions (#2895)Thomas Lively2020-06-051-0/+8
| | | As specified in https://github.com/WebAssembly/simd/pull/232.
* DeNaN improvements (#2888)Alon Zakai2020-06-031-1/+22
| | | | | | | | | Instead of instrumenting every local.get, instrument parameters on arrival at a function once on entry. After that, every local will always contain a de-naned value (since we would denan on a local.set). This is more efficient and also less confusing I think. Also avoid doing anything to values that fall through as they have already been fixed up.
* Prevent pops from sinking in SimplifyLocals (#2885)Heejin Ahn2020-06-031-4/+26
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This prevents `exnref.pop`s from being sinked and separated from `catch`. For example, ```wast (try (do) (catch (local.set $0 (exnref.pop)) (call $foo (i32.const 3) (local.get $0) ) ) ) ``` Here, if we sink `exnref.pop` to remove `local.set $0` and `local.get $0`, it becomes this: ```wast (try (do) (catch (nop) (call $foo (i32.const 3) (exnref.pop) ) ) ) ``` This move was possible because `i32.const 3` does not have any side effects. But this is incorrect because now `exnref.pop` does not follow right after `catch`. To prevent this, this patch checks this case in `canSink` in SimplifyLocals. When we encountered a similar case in CodeFolding, we prevented every expression that contains `Pop` anywhere in it from being moved, which was too conservative. This adds `danglingPop` property in `EffectAnalyzer`, so that only pops that are not enclosed within a `catch` count as 'dangling pops` and we only prevent those pops from being moved or sinked.
* Fix SideEffect::Branches to only represent branches (#2886)Heejin Ahn2020-06-021-1/+1
| | | | | | After #2783 `SideEffects::Branches` includes possibly throwing expressions, which can be calls (when EH is enabled). This changes `SideEffects::Branches` back to only include branches, returns, and infinite loops as it was before #2783.
* Refactor Effects (#2873)Alon Zakai2020-05-291-32/+49
| | | | | | | Avoid special work in analyze(). This lets breakTargets always reflect the breaks that we've seen and that might be external, and we check it in hasSideEffects etc. Also do some internal refactoring and renamings for clarity.
* Flat IR: local.set's value should not be a control flow (#2589)Alon Zakai2020-05-271-4/+10
|
* Remove `Push` (#2867)Thomas Lively2020-05-225-8/+0
| | | | | | Push and Pop have been superseded by tuples for their original intended purpose of supporting multivalue. Pop is still used to represent block arguments for exception handling, but there are no plans to use Push for anything now or in the future.
* Add EH support for SimplifyLocals (#2858)Heejin Ahn2020-05-191-1/+9
| | | | | | | - `br_on_exn`'s target block cannot be optimized to have a separate return value. This handles that in `SimplifyLocals`. - `br_on_exn` and `rethrow` can trap (when the arg is null). This handles that in `EffectAnalyzer`. - Fix a few nits
* Implement i64x2.mul (#2860)Thomas Lively2020-05-191-0/+3
| | | | This is the only instruction in the current spec proposal that had not yet been implemnented in the tools.
* Fix br_on_exn handling in ReFinalize (#2854)Heejin Ahn2020-05-151-1/+2
| | | | | | | | | | | | In `ReFinalize`'s branch handling, `updateBreakValueType` is supposed to be executed only when the branch itself is not replaced with its argument (because it is guaranteed not to be taken). Also this moves `visitBrOnExn` from `RuntimeExpressionRunner` to its base class `ExpressionRunner`, because it does not depend on anything on the runtime instance to work. This is effectively NFC for now because `visitTry` is still only implemented only in `RuntimeExpressionRunner` because it relies on multivalue handling of it, and without it we cannot create a valid exception `Literal`.
* Implement pseudo-min/max SIMD instructions (#2847)Thomas Lively2020-05-121-0/+12
| | | As specified in https://github.com/WebAssembly/simd/pull/122.
* Remove --fuzz-binary and simplify round trip (#2799)Thomas Lively2020-04-241-11/+2
| | | Since the --roundtrip pass is more general than --fuzz-binary anyways. Also reimplements `ModuleUtils::clearModule` to use the module destructor and placement new to ensure that no members are missed.
* Remove function index printing (#2742)Thomas Lively2020-04-091-52/+0
| | | | | | | | `BinaryIndexes` was only used in two places (Print.cpp and wasm-binary.h), so it didn't seem to be a great fit for module-utils.h. This change moves it to wasm-binary.h and removes its usage in Print.cpp. This means that function indexes are no longer printed, but those were of limited utility and were the source of annoying noise when updating tests, anyway.
* Tuple globals (#2718)Thomas Lively2020-04-022-2/+30
| | | | | | | Since it wasn't easy to support tuples in Asyncify's call support using temporary functions, we decided to allow tuple-typed globals after all. This PR adds support for parsing, printing, lowering, and interpreting tuple globals and also adds validation ensuring that imported and exported globals do not have tuple types.
* Avoid unnecessary fp$ in side modules (#2717)Alon Zakai2020-03-311-11/+4
| | | | | | | | | | | | | | | | Now that we update the dylink section properly, we can do the same optimization in side modules as in main ones: if the module provides a function, don't call an $fp method during startup, instead add it to the table ourselves and use the relative offset to the table base. Fix an issue when the table has no segments initially: the code just added an offset of 0, but that's not right. Instead, an a __table_base import and use that as the offset. As this is ABI-specific I did it on wasm-emscripten-finalize, leaving TableUtils to just assert on having a singleton segment. Add a test of a wasm file with a dylink section to the lld tests.
* Represent dylink section in IR, so we can update it. (#2715)Alon Zakai2020-03-301-1/+14
| | | | Update it from wasm-emscripten-finalize when we append to the table.
* Avoid fp$ access in MAIN_MODULES (#2704)Alon Zakai2020-03-271-0/+43
| | | | | | | | | | | | | | | | Depends on emscripten-core/emscripten#10741 which ensures that table indexes are unique. With that guarantee, a main module can just add its function pointers into the table, and use them based on that index. The loader will then see them in the table and then give other modules the identical function pointer for a function, ensuring function pointer equality. This avoids calling fp$ functions during startup for the main module's own functions (which are slow). We do still call fp$s of things we import from outside, as we don't have anything to put in the table for them, we depend on the loader for that. I suspect this can also be done with SIDE_MODULES, but did not want to try too much at once.
* SIMD integer abs and bitmask instructions (#2703)Thomas Lively2020-03-201-0/+6
| | | | | | Adds full support for the {i8x16,i16x8,i32x4}.abs instructions merged to the SIMD proposal in https://github.com/WebAssembly/simd/pull/128 as well as the {i8x16,i16x8,i32x4}.bitmask instructions proposed in https://github.com/WebAssembly/simd/pull/201.
* makeConstExpression => makeConstantExpression (#2698)Alon Zakai2020-03-171-1/+1
| | | | | | The meaning we intend is "constant", and not the "Const" node (which contains a number). So I think the full name is less confusing.
* Collect signatures from all block kinds (#2691)Thomas Lively2020-03-163-13/+17
| | | | | | | | | Previously the signature collection mechanism responsible for populating the type section with signatures used by instructions only collected signatures from indirect call and block instructions. This works as long as all other control flow constructs like ifs, loops, and tries contain blocks with the same signature. But it is possible to have an if with non-block children, and we would need to collect its signature as well.
* Interpret tuple locals and tail-calls correctly (#2690)Thomas Lively2020-03-161-7/+3
|
* Update RedundantSetElimination to work with tuples (#2688)Thomas Lively2020-03-111-0/+26
| | | | | | | | Also makes it work with any other constant expression such as a ref.func or ref.null instructions. This optimization may not be very important, but it illustrates how simple it can be to update a pass to handle tuples (and also I was already looking at it because of the prior changes that had to be made to it).
* Update Precompute to handle tuples (#2687)Thomas Lively2020-03-102-2/+13
| | | | | | This involves replacing `Literal::makeZero` with `Literal::makeZeroes` and `Literal::makeSingleZero` and updating `isConstantExpression` to handle constant tuples as well. Also makes `Literals` its own struct and adds convenience methods on it.
* Asyncify: Fix wasm-only instrumentation of unnamed imports (#2682)Alon Zakai2020-03-051-1/+1
| | | | | | | | | | | | | We assumed that the imports were already named (in their internal name) properly. When processing a binary file without names, or if the names don't match in general, that's not true. To fix this, use ModuleUtils::renameFunctions to do a proper renaming up front. Also fix renameFunctions to not assert on the case of renaming a function to the same name it already has. Helps #2680
* Initial multivalue support (#2675)Thomas Lively2020-03-056-1/+29
| | | | | | | | | Implements parsing and emitting of tuple creation and extraction and tuple-typed control flow for both the text and binary formats. TODO: - Extend Precompute/interpreter to handle tuple values - C and JS API support/testing - Figure out how to lower in stack IR - Fuzzing
* Add EH support for CodeFolding (#2665)Heejin Ahn2020-02-261-0/+24
| | | | | | | | | | | This does two things: - Treats the target branch of `br_on_exn` as unoptimizables, because it is a conditional branch. - Makes sure we don't move expressions that contain `exnref.pop`, which should follow right after `catch`. - Adds `containsChild` utility function, which can search all children, optionally with limited depth. This was actually added to be used in CodeFolding but ended up not being used, but wasn't removed in case there will be uses later.
* Add AutoDrop support for Try (#2663)Heejin Ahn2020-02-202-0/+17
| | | | | This adds AutoDrop (+ ReFinalize) support for Try. We don't have `--autodrop` option so I can't add a separate test for this, but this is basically the same as what If does.
* Fix LocalCSE's usable local selection (#2638)Heejin Ahn2020-02-051-19/+0
| | | | | | | | | | | | | | | | Now that we have subtypes, we cannot reuse any local that contains the same expression, because that local's type can be a supertype. For example: ``` (local $0 anyref) (local $1 nullref) ... (local.set $0 (ref.null)) (local.set $1 (ref.null)) ;; cannot be replaced with (local.get $0) ``` This extends `usables` map's key to contain both `HashedExpression` and the local's type, so we can get the right usable local in presence of subtypes.
* Add EH support for OptimizeInstructions (#2608)Heejin Ahn2020-02-052-11/+31
| | | | | | - Adds support for `Try` in `optimizeBoolean` function - Adds support for `Try` in `getFallThrough` function - Adds approximate cost values for instructions in EH and reference types proposals.
* Add EH support for EffectAnalyzer (#2631)Heejin Ahn2020-02-033-25/+92
| | | | | | | | | | | | | | | | | | | | This adds EH support to `EffectAnalyzer`. Before `throw` and `rethrow` conservatively set property. Now `EffectAnalyzer` has a new property `throws` to represent an expression that can throw, and expression that can throw sets `throws` correctly. When EH is enabled, any calls can throw too, so we cannot reorder them with another expression with any side effects, meaning all calls should be treated in the same way as branches when evaluating `invalidate`. This prevents many reorderings, so this patch sets `throws` for calls only when the exception handling features is enabled. This is also why I passed `--disable-exception-handling` to `wasm2js` tests. Most of code changes outside of `EffectAnalyzer` class was made in order to pass `FeatureSet` to it. `throws` isn't always set whenever an expression contains a throwable instruction. When an throwable instruction is within an inner try, it will be caught by the corresponding inner catch, so it does not set `throws`.
* Handle indirect calls in CallGraphPropertyAnalysis (#2624)Alon Zakai2020-01-241-2/+13
| | | | | | | | | | | | | We ignored them, which is a bad default, as typically they imply we can call anything in the table (and the table might change). Instead, notice indirect calls during traversal, and force the user to decide whether to ignore them or not. This was only an issue in PostEmscripten because the other user, Asyncify, already had indirect call analysis because it needed it for other things. Fixes a bug uncovered by #2619 and fixes the current binaryen roll.
* Expose ExpressionAnalyzer in C-/JS-API (#2585)Daniel Wirtz2020-01-171-0/+51
| | | | | | | Instead of reinventing the wheel on our side, this adds ExpressionAnalyzer bindings to the C- and JS-APIs, which can be useful for generators. For example, a generator may decide to simplify a compilation step if a subexpression doesn't have any side effects, or simply skip emitting something that is likely to compile to a drop or an empty block right away.
* Clear Mixedarena in ModuleUtils::clearModule (#2588)Heejin Ahn2020-01-131-0/+1
|
* Remove implicit conversion operators from Type (#2577)Thomas Lively2020-01-084-11/+11
| | | | | | | | | | * Remove implicit conversion operators from Type Now types must be explicitly converted to uint32_t with Type::getID or to ValueType with Type::getVT. This fixes #2572 for switches that use Type::getVT. * getVT => getSingle
* [NFC] Enforce use of `Type::` on type names (#2434)Thomas Lively2020-01-0713-79/+87
|