summaryrefslogtreecommitdiff
path: root/src/passes/RemoveNonJSOps.cpp
Commit message (Collapse)AuthorAgeFilesLines
* Remove obsolete parser code (#6607)Thomas Lively2024-05-291-1/+0
| | | | | Remove `SExpressionParser`, `SExpressionWasmBuilder`, and `cashew::Parser`. Simplify gen-s-parser.py. Remove the --new-wat-parser and --deprecated-wat-parser flags.
* [NFC] Use the new wat parser in RemoveNonJSOps (#6554)Thomas Lively2024-04-291-5/+4
|
* [NFC] Remove our bespoke `make_unique` implementation (#5613)Thomas Lively2023-03-311-3/+3
| | | | This code predates our adoption of C++14 and can now be removed in favor of `std::make_unique`, which should be more efficient.
* Refactor interaction between Pass and PassRunner (#5093)Thomas Lively2022-09-301-2/+6
| | | | | | | | | | | | | | Previously only WalkerPasses had access to the `getPassRunner` and `getPassOptions` methods. Move those methods to `Pass` so all passes can use them. As a result, the `PassRunner` passed to `Pass::run` and `Pass::runOnFunction` is no longer necessary, so remove it. Also update `Pass::create` to return a unique_ptr, which is more efficient than having it return a raw pointer only to have the `PassRunner` wrap that raw pointer in a `unique_ptr`. Delete the unused template `PassRunner::getLast()`, which looks like it was intended to enable retrieving previous analyses and has been in the code base since 2015 but is not implemented anywhere.
* Mutli-Memories Support in IR (#4811)Ashley Nelson2022-08-171-1/+1
| | | | | | | This PR removes the single memory restriction in IR, adding support for a single module to reference multiple memories. To support this change, a new memory name field was added to 13 memory instructions in order to identify the memory for the instruction. It is a goal of this PR to maintain backwards compatibility with existing text and binary wasm modules, so memory indexes remain optional for memory instructions. Similarly, the JS API makes assumptions about which memory is intended when only one memory is present in the module. Another goal of this PR is that existing tests behavior be unaffected. That said, tests must now explicitly define a memory before invoking memory instructions or exporting a memory, and memory names are now printed for each memory instruction in the text format. There remain quite a few places where a hardcoded reference to the first memory persist (memory flattening, for example, will return early if more than one memory is present in the module). Many of these call-sites, particularly within passes, will require us to rethink how the optimization works in a multi-memories world. Other call-sites may necessitate more invasive code restructuring to fully convert away from relying on a globally available, single memory pointer.
* Modernize code to C++17 (#3104)Max Graey2021-11-221-6/+3
|
* [JS] Add a new OptimizeForJS pass (#4033)Max Graey2021-08-021-4/+16
| | | | | Add a new OptimizeForJS pass which contains rewriting rules specific to JavaScript. LLVM usually lowers x != 0 && (x & (x - 1)) == 0 (isPowerOf2) to popcnt(x) == 1 which is ok for wasm and other targets but is quite expensive for JavaScript. In this PR we lower the popcnt pattern back to the isPowerOf2 pattern.
* Remove Type ordering (#3793)Thomas Lively2021-05-181-1/+2
| | | | | | | | | As found in #3682, the current implementation of type ordering is not correct, and although the immediate issue would be easy to fix, I don't think the current intended comparison algorithm is correct in the first place. Rather than try to switch to using a correct algorithm (which I am not sure I know how to implement, although I have an idea) this PR removes Type ordering entirely. In places that used Type ordering with std::set or std::map because they require deterministic iteration order, this PR uses InsertOrdered{Set,Map} instead.
* [wasm2js] Use native JavaScript Math.trunc (#3329)Max Graey2020-11-101-7/+0
|
* Poppy IR wast parsing and validation (#3105)Thomas Lively2020-09-091-1/+2
| | | | | Adds an IR profile to each function so the validator can determine which validation rules to apply and adds a flag to have the wast parser set the profile to Poppy for testing purposes.
* Prepare for compound types that are single but not basic (#3046)Daniel Wirtz2020-08-171-2/+2
| | | | | | | | | | | | | | 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.
* StubUnsupportedJSOps: Remove CallIndirects (#3027)Alon Zakai2020-08-061-6/+23
| | | | | | wasm2js does not have full call_indirect support as we don't trap if the type is incorrect, which wasm does. Therefore the StubUnsupportedJSOps pass needs to remove those operations so that the fuzzer doesn't find spurious issues.
* Add StubUnsupportedJSOps to remove operations that JS does not support (#3024)Alon Zakai2020-08-051-1/+46
| | | | | | | | This doesn't lower them - it just replaces the unsupported operation with a drop. This will be useful for fuzzing, where to compare JS to the correct semantics we must avoid operations where JS is not always accurate. Also fully document the i64 -> f32 conversion issue in JS.
* wasm2js: Avoid 64-bit scratch memory helpers in wasm-intrinsics (#2926)Alon Zakai2020-06-231-0/+5
| | | | | | | | | | | | | | That code originally used memory location 1024 to save 64 bits of data (as that is what rust does apparently). We refactored it manually to instead use a scratch memory helper, which is safer. However, that 64-bit function ends up legalized, which actually changes the interface between the module and the outside, which is confusing and causes problems with optimizations that can remove the getTempRet0 imports, see emscripten-core/emscripten#11456 Instead, just use a global i64 to stash those bits. This requires adding support for copying globals from the intrinsics module, but otherwise seems simpler overall.
* wasm2js: Bulk memory support (#2923)Alon Zakai2020-06-221-1/+1
| | | | | | | | | | | | | | Adds a special helper functions for data.drop etc., as unlike most wasm instructions these are too big to emit inline. Track passive segments at runtime in var memorySegments whose indexes are the segment indexes. Emit var bufferView even if the memory exists even without memory segments, as we do still need the view in order to operate on it. Also adds a few constants for atomics that will be useful in future PRs (as this PR updates the constant lists anyhow).
* Remove implicit conversion operators from Type (#2577)Thomas Lively2020-01-081-2/+2
| | | | | | | | | | * 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-8/+8
|
* Use wat over wast for text format filenames (#2518)Sam Clegg2019-12-081-2/+2
|
* Reflect instruction renaming in code (#2128)Heejin Ahn2019-05-211-1/+1
| | | | | | | | | | | | | | | | | | | | | | | | | | | | - 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-2/+4
| | | 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-43/+33
| | | 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
* wasm2js: use scratch memory properly (#2033)Alon Zakai2019-04-221-0/+4
| | | | | | | This replaces all uses of __tempMemory__, the old scratch space location, with calls to function imports for scratch memory access. This lets us then implement those in a way that does not use the same heap as main memory. This avoids possible bugs with scratch memory overwriting something, or just in general that it has observable side effects, which can confuse fuzzing etc. The intrinsics are currently implemented in the glue. We could perhaps emit them inline instead (but that might limit asm.js optimizations, so I wanted to keep our options open for now - easy to change later). Also fixes some places where we used 0 as the scratch space address.
* wasm2js2 import fixes (#2031)Alon Zakai2019-04-191-1/+4
| | | | | | * Don't assume function types exist in legalize-js-interface. * Properly handle (ignore) imports in RemoveNonJSOps - do not try to recurse into them. * Run legalize-js-interface and remove-unused-module-elements in wasm2js, the first is necessary, the last is nice to have.
* Wasm2js memory fixes (#2003)Alon Zakai2019-04-121-6/+26
| | | | | | | | * I64ToI32Lowering - don't assume address 0 is a hardcoded location for scratch memory. Import __tempMemory__ for that. * RemoveNonJSOps - also use __tempMemory__. Oddly here the address was a hardcoded 1024 (perhaps where the rust program put a static global?). * Support imported ints in wasm2js, coercing them as needed. * Add "env" import support in the tests, since now we emit imports from there. * Make wasm2js tests split out multi-module tests using split_wast which is more robust and avoids emitting multiple outputs in one file (which makes no sense for ES6 modules)
* Update test/spec/memory.wast to latest upstream (#1801)Alon Zakai2019-04-031-0/+4
| | | | | | | Minus multi-memory which we don't support yet. Improve validator. Fix some minor validation issues in our tests.
* Dead return value elimination in DeadArgumentElimination (#1917)Alon Zakai2019-02-261-1/+1
| | | | | | | * Finds functions whose return value is always dropped, and removes the return. * Run multiple iterations of the pass, as one can enable others. * Do not run DeadArgumentElimination at all if debug info is present (with these improvements, it became much more likely to destroy debug info). Saves 2.5% on hello world, because of some simple libc calls.
* Stack IR (#1623)Alon Zakai2018-07-301-1/+5
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | This adds a new IR, "Stack IR". This represents wasm at a very low level, as a simple stream of instructions, basically the same as wasm's binary format. This is unlike Binaryen IR which is structured and in a tree format. This gives some small wins on binary sizes, less than 1% in most cases, usually 0.25-0.50% or so. That's not much by itself, but looking forward this prepares us for multi-value, which we really need an IR like this to be able to optimize well. Also, it's possible there is more we can do already - currently there are just a few stack IR optimizations implemented, DCE local2stack - check if a set_local/get_local pair can be removed, which keeps the set's value on the stack, which if the stars align it can be popped instead of the get. Block removal - remove any blocks with no branches, as they are valid in wasm binary format. Implementation-wise, the IR is defined in wasm-stack.h. A new StackInst is defined, representing a single instruction. Most are simple reflections of Binaryen IR (an add, a load, etc.), and just pointers to them. Control flow constructs are expanded into multiple instructions, like a block turns into a block begin and end, and we may also emit extra unreachables to handle the fact Binaryen IR has unreachable blocks/ifs/loops but wasm does not. Overall, all the Binaryen IR differences with wasm vanish on the way to stack IR. Where this IR lives: Each Function now has a unique_ptr to stack IR, that is, a function may have stack IR alongside the main IR. If the stack IR is present, we write it out during binary writing; if not, we do the same binaryen IR => wasm binary process as before (this PR should not affect speed there). This design lets us use normal Passes on stack IR, in particular this PR defines 3 passes: Generate stack IR Optimize stack IR (might be worth splitting out into separate passes eventually) Print stack IR for debugging purposes Having these as normal passes is convenient as then they can run in parallel across functions and all the other conveniences of our current Pass system. However, a downside of keeping the second IR as an option on Functions, and using normal Passes to operate on it, means that we may get out of sync: if you generate stack IR, then modify binaryen IR, then the stack IR may no longer be valid (for example, maybe you removed locals or modified instructions in place etc.). To avoid that, Passes now define if they modify Binaryen IR or not; if they do, we throw away the stack IR. Miscellaneous notes: Just writing Stack IR, then writing to binary - no optimizations - is 20% slower than going directly to binary, which is one reason why we still support direct writing. This does lead to some "fun" C++ template code to make that convenient: there is a single StackWriter class, templated over the "mode", which is either Binaryen2Binary (direct writing), Binaryen2Stack, or Stack2Binary. This avoids a lot of boilerplate as the 3 modes share a lot of code in overlapping ways. Stack IR does not support source maps / debug info. We just don't use that IR if debug info is present. A tiny text format comment (if emitting non-minified text) indicates stack IR is present, if it is ((; has Stack IR ;)). This may help with debugging, just in case people forget. There is also a pass to print out the stack IR for debug purposes, as mentioned above. The sieve binaryen.js test was actually not validating all along - these new opts broke it in a more noticeable manner. Fixed. Added extra checks in pass-debug mode, to verify that if stack IR should have been thrown out, it was. This should help avoid any confusion with the IR being invalid. Added a comment about the possible future of stack IR as the main IR, depending on optimization results, following some discussion earlier today.
* wasm2asm: Fix and enable a large number of spec tests (#1558)Alex Crichton2018-05-291-0/+44
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | * Import `abort` from the environment * Add passing spec tests * Bind the abort function * wasm2asm: Fix name collisions Currently function names and local names can collide in namespaces, causing buggy results when a function intends to call another function but ends up using a local value as the target! This fix was required to enable the `fac` spec test * wasm2asm: Get multiple modules in one file working The spec tests seem to have multiple modules defined in some tests and the invocations all use the most recently defined module. This commit updates the `--allow-asserts` mode of wasm2asm to work with this mode of tests, enabling us to enable more spec tests for wasm2asm. * wasm2asm: Enable the float_literals spec test This needed to be modified to account for how JS engines don't work with NaN bits the same way, but it's otherwise largely the same test. Additionally it turns out that asm.js doesn't accept either `Infinity` or `NaN` ambient globals so they needed to get imported through the `global` variable rather than defined as literals in code * wasm2asm: Fix function pointer invocations This commit fixes invocations of functions through function pointers as previously the table names on lookup and definition were mismatched. Both tables now go through signature-based namification rather than athe name of the type itself. Overall this enables a slew of spec tests * wasm2asm: Enable the left-to-right spec test There were two small bugs in the order of evaluation of operators with wasm2asm. The `select` instruction would sometimes evaluate the condition first when it was supposed to be last. Similarly a `call_indirect` instruction would evaluate the function pointer first when it was supposed to be evaluated last. The `select` instruction case was a relatively small fix but the one for `call_indirect` was a bit more pessimized to generate some temporaries. Hopefully if this becomes up a problem it can be tightened up. * wasm2asm: Fix signed load promotions of 64-bit ints This commit enables the `endianness` spec test which revealed a bug in 64-bit loads from smaller sizes which were signed. Previously the upper bits of the 64-bit number were all set to zero but the fix was for signed loads to have all the upper bits match the highest bit of the low 32 bits that we load. * wasm2asm: Enable the `stack` spec test Internally the spec test uses a mixture of the s-expression syntax and the wat syntax, so this is copied over into the `wasm2asm` folder after going through `wat2wasm` to ensure it's consistent for binaryen. * wasm2asm: Fix unaligned loads/stores of floats Replace these operations in `RemoveNonJSOps` by using reinterpretation to translate floats to integers and then use the existing code for unaligned loads/stores of integers. * wasm2asm: Fix a tricky grow_memory codegen bug This commit fixes a tricky codegen bug found in the `grow_memory` instruction. Specifically if you stored the result of `grow_memory` immediately into memory it would look like: HEAP32[..] = __wasm_grow_memory(..); Here though it looks like JS evaluates the destination *before* the grow function is called, but the grow function will invalidate the destination! Furthermore this is actually generalizable to all function calls: HEAP32[..] = foo(..); Because any function could transitively call `grow_memory`. This commit fixes the issue by ensuring that store instructions are always considered statements, unconditionally evaluating the value into a temporary and then storing that into the destination. While a bit of a pessmimization for now it should hopefully fix the bug here. * wasm2asm: Handle offsets in tables This commit fixes initializing tables whose elements have an initial offset. This should hopefully help fix some more Rust code which has all function pointers offset by default! * Update tests * Tweak * location on types * Rename entries of NameScope and document fromName * Comment on lowercase names * Update compiled JS * Update js test output expectation * Rename NameScope::Global to NameScope::Top * Switch to `enum class` * Switch to `Fatal()` * Add TODO for when asm.js is no longer generated
* wasm2asm: Finish i64 lowering operations (#1563)Alex Crichton2018-05-251-316/+90
| | | | | | | | | | | | | | | | | * wasm2asm: Finish i64 lowering operations This commit finishes out lowering i64 operations to JS with implementations of division and remainder for JS. The primary change here is to have these compiled from Rust to wasm and then have them "linked in" via intrinsics. The `RemoveNonJSOps` pass has been updated to include some of what `I64ToI32Lowering` was previously doing, basically replacing some instructions with calls to intrinsics. The intrinsics are now all tracked in one location. Hopefully the intrinsics don't need to be regenerated too much, but for posterity the source currently [lives in a gist][gist], although I suspect that gist won't continue to compile and work as-is for all of time. [gist]: https://gist.github.com/alexcrichton/e7ea67bcdd17ce4b6254e66f77165690
* wasm2asm: Finish f32/f64 operations (#1554)Alex Crichton2018-05-191-0/+479