summaryrefslogtreecommitdiff
path: root/src/passes/OptimizeInstructions.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Improve partial evaluation (#3236)Max Graey2020-10-141-2/+11
|
* Optimize power of two float divisions (#3018)Max Graey2020-10-131-5/+44
|
* Optimize unsigned divisions when rhs is negative constant (#2991)Max Graey2020-10-131-7/+22
| | | | | | | | `(uint32_t)x / C` --> `x >= C`, where `C > 2^31` `(uint32_t)x / -1` --> `x != -1` and for `shrinkLevel == 0`: `(uint64_t)x / C` --> `uint64_t(x >= C)`, where `C > 2^63` `(uint64_t)x / -1` --> `x != -1`
* Refactor naming convention for functions handling tuples (#3196)Max Graey2020-10-091-7/+7
| | | When there are two versions of a function, one handling tuples and the other handling non-tuple values, the previous naming convention was to have "Single" in the name of the non-tuple handling function. This PR simplifies the convention and shortens function names by making the names plural for the tuple-handling version and singular for the non-tuple-handling version.
* Remove old attempted DSL beginnings from OptimizeInstructions (#3200)Alon Zakai2020-10-081-23/+0
| | | | | | Wasm turned out to not be that good for a DSL for such peephole optimizations, so that never made progress. Meanwhile we have the new matcher stuff which works well.
* Add optimization rules for some shift operations (#3099)Max Graey2020-10-071-0/+35
| | | Specifically, truncates constant shift values that are greater than the number of bits available and optimizes out explicit masking of the shift value that is redundant with the implicit masking performed by shift operations.
* Revert some changes for #3193 (#3197)Max Graey2020-10-061-15/+14
| | | `(signed)x % (i32|i64).min_s ==> (x & (i32|i64).max_s)` is not valid unless compared to zero.
* fast-math: Fold `fp * -1` to `-fp` (#3189)Max Graey2020-10-051-2/+5
|
* Generalize transforms for #3153 (#3193)Max Graey2020-10-051-6/+17
| | | | | | | | | | | | | | Implement a more general (additional) version of #3153 which also handles negative constant divisors: `(int32)x % -4 == 0` --> `(x & 3) == 0` `x % -C_pot == 0` --> `(x & (abs(C_pot) - 1)) == 0` and special two-complement values as well: `(int32)x % 0x80000000 == 0` --> `(x & 0x7fffffff) == 0` `(int64)x % 0x8000000000000000 == 0` --> `(x & 0x7fffffffffffffff) == 0` as separete rules: `(int32)x % 0x80000000` --> `x & 0x7fffffff` `(int64)x % 0x8000000000000000` --> `x & 0x7fffffffffffffff` The [previous pr](https://github.com/WebAssembly/binaryen/pull/3153) didn't use these possibilities.
* Ordering correction fix in OptimizeInstructions for #3047 (#3195)Alon Zakai2020-10-051-2/+12
| | | | | | | | | | | | (found by the fuzzer) It is not valid to replace x | (y | x) ==> y | x, if x, y cannot be reordered. It is also not valid to replace x ^ (y ^ x) ==> y, if x, y cannot be reordered, for a more subtle reason: if they cannot be reordered then y can affect the value of x (the opposite is not possible as we checked x for side effects so that we could remove one copy). If so, then the second appearance of x could be different, if e.g. it reads a local y writes to. Whereas, if it's ok to reorder, then it's ok to do x ^ (y ^ x) ==> x ^ (x ^ y) ==> y.
* Optimize "clear bit mask" combination to cyclic rotation over preinverted ↵Max Graey2020-10-011-0/+14
| | | | mask (#3184)
* Add comment about signed => unsigned lowering (#3187)Max Graey2020-10-011-0/+5
|
* Clean up support/bits.h (#3177)Thomas Lively2020-09-301-9/+9
| | | | | Use overloads instead of templates where applicable and change function names from PascalCase to camelCase. Also puts the functions in the Bits namespace to avoid naming conflicts.
* Add --fast-math mode (#3155)Alon Zakai2020-09-301-8/+11
| | | | | | | | | | | | Similar to clang and gcc, --fast-math makes us ignore corner cases of floating-point math like NaN changes and (not done yet) lack of associativity and so forth. In the future we may want to have separate fast math flags for each specific thing, like gcc and clang do. This undoes some changes (#2958 and #3096) where we assumed it was ok to not change NaN bits, but @binji corrected us. We can only do such things in fast math mode. This puts those optimizations behind that flag, adds tests for it, and restores the interpreter to the simpler code from before with no special cases.
* Fold i32.eqz(wrap_i64(x)) -> i64.eqz(x) where possible (#3181)Max Graey2020-09-301-0/+12
| | | Specifically, when `x` has at most 32 bits so that wrapping doesn't change its value.
* Simplify signed remainders compared with zero (#3153)Max Graey2020-09-291-9/+29
| | | | | | Specifically when the divisor is a power of two. `eqz((signed)x % C_pot)` -> `eqz(x & (C_pot - 1))` `(signed)x % C_pot != 0` -> `x & (C_pot - 1) != 0`
* Add also non-equal with zero simplification for boolean context (#3178)Max Graey2020-09-291-2/+3
|
* Lower signed binops to unsigned binops when possible (#2988)Max Graey2020-09-281-10/+59
| | | This can unlock further instruction optimizations that do not apply to signed operations.
* Expression matching API (#3134)Thomas Lively2020-09-181-352/+368
| | | | | | | | | | | Provides an easily extensible layered API for matching expression patterns and extracting their components. The low-level API provides modular building blocks for creating matchers for any data type and the high-level API provides a succinct and flexible interface for matching expressions and extracting useful information from them. Matchers are currently provided for Const, Unary, Binary, and Select instructions. Adding a matcher for a new type of expression is straightforward enough that I expect to add them as they become useful as part of other changes.
* Initial implementation of "Memory64" proposal (#3130)Wouter van Oortmerssen2020-09-181-6/+12
| | | Also includes a lot of new spec tests that eventually need to go into the spec repo
* Optimize binary operations with 1-bit on lhs and 1 const on rhs (#2948)Max Graey2020-09-171-10/+45
| | | | | | | `expr | 1` --> `1` `expr & 1` --> `expr` `expr == 1` --> `expr` `expr != 1` --> `!expr` where `maxBits(expr) == 1` i.e `expr` is boolean
* Unary and binary duplicate expression elimination (#3047)Max Graey2020-09-171-15/+139
| | | | | | | | | | | | | | | | | | Simplifies patterns in which an expression is applied twice to its operands. `abs(abs(x))` -> `abs(x)` `ceil(ceil(x))` -> `ceil(x)` `floor(floor(x))` -> `floor(x)` `trunc(trunc(x))` -> `trunc(x)` `nearest(nearest(x))` -> `nearest(x)` `eqz(eqz(bool(x)))` -> `bool(x)` `sext(sext(x))` -> `sext(x)` `neg(neg(x))` -> `x` `y - (y - x)` -> `x` `(x ^ y) ^ y` -> `x` `(x | y) | y` -> `x | y` `(x & y) & y` -> `x & y` `(x % y) % y` -> `x % y`
* Add float operations for isSymmetric util (#3127)Max Graey2020-09-141-2/+25
| | | Add floating point Eq and Ne operators to Properties::isSymmetric. Also treat additional float ops as symmetric specifically in OptimizeInstructions when their operands are known to be non-NaN.
* Simplify subtracting zero from float expressions (#3125)Max Graey2020-09-131-0/+21
| | | | | | | `x - 0.0` -> `x` `x + (-0.0)` -> `x` `x - (-0.0)` -> `x + 0.0` where `x` is `f32` or `f64`.
* also drop size for memory.copy(x, x, y) (#3075)Max Graey2020-08-241-2/+5
| | | This fixes a bug in which a side effect in the calculation of the size could be lost.
* memory.copy: use nop reductions only for ignoreImplicitTraps (#3074)Max Graey2020-08-241-3/+15
| | | | | | | | | According to changes in spec: WebAssembly/bulk-memory-operations#124 WebAssembly/bulk-memory-operations#145 we unfortunately can't fold to nop even for memory.copy(x, y, 0). So this PR revert all reductions to nop but do this only under ignoreImplicitTraps flag
* Remove optimization for memory.copy(x, x, C) (#3073)Max Graey2020-08-231-11/+1
| | | | | That can trap, so we can only remove it if traps are ignored, which was not handled properly. Revert it as we consider the options.
* OptimizeInstructions on memory.copy: check size for side effect as well (#3072)Max Graey2020-08-231-0/+2
| | | Fix issue found by fuzzer: #3038 (comment)
* Optimize bulk memory.copy (#3038)Max Graey2020-08-221-0/+68
| | | Replace it with a load and a store when the size is a small constant and remove it entirely when it would be a nop.
* Prepare for compound types that are single but not basic (#3046)Daniel Wirtz2020-08-171-2/+4
| | | | | | | | | | | | | | 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 getMaxBits() out of OptimizeInstructions and add beginnings of unit ↵Alon Zakai2020-08-041-149/+4
| | | | | | | | | 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
* Optimize select with const arms (#2869)Max Graey2020-07-221-97/+124
| | | | | x ? 1 : 0 => !!x and so forth.
* Optimize booleans when argument is negative integer (#2930)Max Graey2020-07-081-0/+8
| | | bool(-x) ==> bool(x)
* More optimizations for pow of two and pos/neg one const on the right (#2870)Max Graey2020-06-221-18/+101
|
* Add EH support for OptimizeInstructions (#2608)Heejin Ahn2020-02-051-4/+16
| | | | | | - 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-031-22/+40
| | | | | | | | | | | | | | | | | | | | 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`.
* Remove implicit conversion operators from Type (#2577)Thomas Lively2020-01-081-3/+3
| | | | | | | | | | * 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-071-18/+18
|
* Add support for reference types proposal (#2451)Heejin Ahn2019-12-301-3/+3
| | | | | | | | | | | | This adds support for the reference type proposal. This includes support for all reference types (`anyref`, `funcref`(=`anyfunc`), and `nullref`) and four new instructions: `ref.null`, `ref.is_null`, `ref.func`, and new typed `select`. This also adds subtype relationship support between reference types. This does not include table instructions yet. This also does not include wasm2js support. Fixes #2444 and fixes #2447.
* Add string parameter to WASM_UNREACHABLE (#2499)Sam Clegg2019-12-051-2/+2
| | | | | This works more like llvm's unreachable handler in that is preserves information even in release builds.
* Multivalue type creation and inspection (#2459)Thomas Lively2019-11-221-5/+5
| | | | | | | | | | | | | Adds the ability to create multivalue types from vectors of concrete value types. All types are transparently interned, so their representation is still a single uint32_t. Types can be extracted into vectors of their component parts, and all the single value types expand into vectors containing themselves. Multivalue types are not yet used in the IR, but their creation and inspection functionality is exposed and tested in the C and JS APIs. Also makes common type predicates methods of Type and improves the ergonomics of type printing.
* OptimizeInstructions: Eq64 of 0 => Eqz64 (#2421)Alon Zakai2019-11-041-0/+2
| | | Fixes #2417
* Optimize select fallthrough values (#2220)Alon Zakai2019-07-111-0/+4
| | | This became noticeable after #2216 which led to some eqz eqz pairs in the test suite.
* Fix comparison signedness errors in optimizeMemoryAccess() (#2211)Sean Stangl2019-07-101-3/+3
|
* Un-recursify OptimizeInstructions::optimizeAddedConstants (#2157)Alon Zakai2019-05-311-16/+27
| | | | | This helps avoid issues with smaller stack sizes on some OSes. Should fix the last Mac test failure on emscripten-releases CI (other.test_js_function_names_are_minified, which happens to have massively-nested additions of constants).
* Reflect instruction renaming in code (#2128)Heejin Ahn2019-05-211-11/+11
| | | | | | | | | | | | | | | | | | | | | | | | | | | | - Reflected new renamed instruction names in code and tests: - `get_local` -> `local.get` - `set_local` -> `local.set` - `tee_local` -> `local.tee` - `get_global` -> `global.get` - `set_global` -> `global.set` - `current_memory` -> `memory.size` - `grow_memory` -> `memory.grow` - Removed APIs related to old instruction names in Binaryen.js and added APIs with new names if they are missing. - Renamed `typedef SortedVector LocalSet` to `SetsOfLocals` to prevent name clashes. - Resolved several TODO renaming items in wasm-binary.h: - `TableSwitch` -> `BrTable` - `I32ConvertI64` -> `I32WrapI64` - `I64STruncI32` -> `I64SExtendI32` - `I64UTruncI32` -> `I64UExtendI32` - `F32ConvertF64` -> `F32DemoteI64` - `F64ConvertF32` -> `F64PromoteF32` - Renamed `BinaryenGetFeatures` and `BinaryenSetFeatures` to `BinaryenModuleGetFeatures` and `BinaryenModuleSetFeatures` for consistency.
* clang-tidy braces changes (#2075)Alon Zakai2019-05-011-18/+36
| | | Applies the changes in #2065, and temprarily disables the hook since it's too slow to run on a change this large. We should re-enable it in a later commit.
* Apply format changes from #2048 (#2059)Alon Zakai2019-04-261-212/+391
| | | Mass change to apply clang-format to everything. We are applying this in a PR by me so the (git) blame is all mine ;) but @aheejin did all the work to get clang-format set up and all the manual work to tidy up some things to make the output nicer in #2048
* avoid signed overflow undefined behavior in OptimizeInstructions constant ↵Alon Zakai2019-04-091-2/+2
| | | | computations (#1990)
* Massive renaming (#1855)Thomas Lively2019-01-071-1/+1
| | | | | | Automated renaming according to https://github.com/WebAssembly/spec/issues/884#issuecomment-426433329.