summaryrefslogtreecommitdiff
path: root/src/ir
Commit message (Collapse)AuthorAgeFilesLines
* Set an absolute maximum inlining limit (#3959)Alon Zakai2021-07-011-0/+6
| | | | | | | | | | | 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-308-24/+24
| | | | | | | | | 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-291-0/+11
| | | | | | | | | | 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.
* Refactor LinearExecutionWalker to a separate file. NFC (#3956)Alon Zakai2021-06-281-0/+139
|
* [EH] Make tag's attribute encoding detail (#3947)Heejin Ahn2021-06-212-2/+0
| | | | | | | | | 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.
* [EH] Replace event with tag (#3937)Heejin Ahn2021-06-186-36/+34
| | | | | | | | | | | 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-185-8/+8
| | | | | | | | | | | 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] Add experimental support for non-nullable locals (#3932)Alon Zakai2021-06-151-0/+3
| | | | | | | | | | | | | | 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-151-0/+7
| | | | | | | 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-122-3/+13
| | | | | | 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.
* [Wasm GC] Support struct.new in global initializers (#3930)Alon Zakai2021-06-091-1/+2
|
* [OptimizeInstructions] Handle post-MVP sign extended operations (#3910)Max Graey2021-06-032-3/+37
| | | fixes part of #3906
* [Wasm GC] Add negated BrOn* operations (#3913)Alon Zakai2021-06-023-3/+21
| | | | | | They are basically the flip versions. The only interesting part in the impl is that their returned typed and sent types are different. Spec: https://docs.google.com/document/d/1DklC3qVuOdLHSXB5UXghM_syCh-4cMinQ50ICiXnK3Q/edit
* [wasm-split] Minimize names of newly created exports (#3905)Thomas Lively2021-06-012-2/+14
| | | | | | | | | wasm-split would previously use internal function names to create the external names of the functions that are newly exported from the primary module to be imported into the secondary module. When the input module contains full function names (as is commonly the case when emitting symbol maps), this caused the function names to be preserved as the export names, even when names are otherwise being stripped. To save on code size and properly anonymize functions, generate minimal export names when debuginfo is disabled instead.
* [NFC] Factor out and simplify minified name generation (#3909)Thomas Lively2021-05-273-1/+86
| | | | Simplifies the public API to not unnecessarily take an index and simplifies the implementation to use a single integer as state rather than a vector of indices.
* [Wasm GC] Add experimental array.copy (#3911)Alon Zakai2021-05-273-0/+11
| | | | | | | | Spec for it is here: https://docs.google.com/document/d/1DklC3qVuOdLHSXB5UXghM_syCh-4cMinQ50ICiXnK3Q/edit# Also reorder some things in wasm.h that were not in the canonical order (that has no effect, but it is confusing to read).
* Remove Type ordering (#3793)Thomas Lively2021-05-181-13/+13
| | | | | | | | | 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.
* [Wasm GC] Heap2Local: Handle branches (#3881)Alon Zakai2021-05-121-5/+38
| | | | | | | | | | | | | | | | | | If we branch to a block, and there are no other branches or a final value on the block either, then there is no mixing, and we may be able to optimize the allocation. Before this PR, all branches stopped us. To do this, add some helpers in BranchUtils. The main flow logic in Heap2Local used to stop when we reached a child for the second time. With branches, however, a child can flow both to its immediate parent, and to branch targets, and so the proper thing to look at is when we reach a parent for the second time (which would definitely indicate mixing). Tests are added for the new functionality. Note that some existing tests already covered some things we should not optimize, and so no tests were needed for them. The existing ones are: $get-through-block, $branch-to-block.
* BranchUtils additions (#3860)Alon Zakai2021-05-061-0/+40
| | | | | | | | | | Add operateOnScopeNameUsesAndSentValues which is like the existing utilities, but provides the child expression that is sent as a value on the branch. Also provide a BranchTargets utility that maps target names to the control flow structure for them. Both will be used and tested in escape analysis.
* Refactor getFallthrough() to use a loop instead of recursion. NFC (#3859)Alon Zakai2021-05-051-13/+33
| | | | | | A new getImmediateFallthrough is called in the loop. Aside from this being more efficient than recursion, the new method will be used in escape analysis.
* Allow only computing necessary influences in LocalGraph. NFC (#3861)Alon Zakai2021-05-052-7/+19
| | | | | | | Some passes need setInfluences but not getInfluences, but were computing them nonetheless. This makes e.g. MergeLocals 12% faster. It will also help use LocalGraph in new passes with less worries about speed.
* Use standard type traversal in module-utils.h (#3851)Thomas Lively2021-04-291-45/+22
| | | | | | | | | | | Add new public `getHeapTypeChildren` methods to Type and HeapType, implemented in using the standard machinery from #3844, and use them to simplify `ModuleUtils::collectHeapTypes`. Now that the type traversal code in wasm-type.cpp is not just used in canonicalization, move it to a more appropriate place in the file. Also, since the only users of `HeapTypePathWalker` were using it to visit top-level children only, replace that with a more specialized `HeapTypeChildWalker` to reduce code duplication.
* Add LocalGraph::equivalent (#3848)Alon Zakai2021-04-292-1/+43
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | This compares two local.gets and checks whether we are sure they are equivalent, that is, they contain the same value. This does not solve the general problem, but uses the existing info to get a positive answer for the common case where two gets only receive values by a single set, like (local.set $x ..) (a use.. (local.get $x)) (another use.. (local.get $x)) If they only receive values from the same single set, then we know it must dominate them. The only risk is that the set is "in between" the gets, that is, that the set occurs after one get and before the other. That can happen in a loop in theory, (loop $loop (use (local.get $x)) (local.set $x ..some new value each iteration..) (use (local.get $x)) (br_if $loop ..) ) Both of those gets receive a value from the set, and they may be different values, from different loop iterations. But as mentioned in the source code, this is not a problem since wasm always has a zero-initialization value, and so the first local.get in that loop would have another set from which it can receive a value, the function entry. (The only way to avoid that is for this entire code to be unreachable, in which case nothing matters.) This will be useful in dead store elimination, which has to use this to reason about references and pointers in order to be able to do anything useful with GC and memory.
* Generalize moving of identical code from if/select arms (#3833)Alon Zakai2021-04-211-0/+14
| | | | | | | | | | | | | | | Effects are fine in the moved code, if we are doing so on an if (which runs just one arm anyhow). Allow unreachable, which lets us hoist returns for example. Allow none, which lets us hoist drop and call for example. For this we also need to be careful with subtyping, as at least drop is polymorphic, so the child types may not have an LUB (see example in code). Adds a small ShallowEffectAnalyzer child of EffectAnalyzer that calls visit to just do a shallow analysis (instead of walk which walks the children).
* [Wasm GC] Fix handleNonDefaultableLocals on tees (#3830)Alon Zakai2021-04-211-1/+22
| | | | | | | When we change a local's type, as we do in that method when we turn a non-nullable (invalid) local into a nullable (valid) one, we must update tees as well as gets - their type must match the changed local type, and we must cast them so that their users do not see a change.
* Refactor Child*Iterator for simplicity and to allow modifications. NFC (#3826)Alon Zakai2021-04-201-36/+66
| | | | | | | | | | | | | | | | | | | Instead of creating a class and doing a traversal, simply use wasm-delegates-fields to get the children directly. This is simpler and faster. This requires a new way to override the behavior by ChildValueIterator. I ended up using CRTP. This stores pointers to the children instead of the children. This will allow modifying the children using these classes (which is the reason I started this refactoring - next PR will use it). This is also slightly faster in theory as we avoid doing loads from memory to find the children (which maybe we never get to doing if the iteration is stopped early). Not the goal here, but this speeds up roundtripping by 12%. This is NFC as nothing uses the new ability to modify things yet.
* Minor wasm-split improvements (#3825)Thomas Lively2021-04-202-42/+36
| | | | | | | | | | | - Support functions appearing more than once in the table. It turns out we were assuming and asserting that functions would appear at most once, but we weren't making use of that assumption in any way. - Make TableSlotManager::getSlot take a function Name rather than a RefFunc expression to avoid allocating and leaking unnecessary expressions. - Add and use a Builder interface for building TableElementSegments to make them more similar to other module-level items.
* [Wasm GC] Optimize reference identity checks (#3814)Alon Zakai2021-04-192-0/+7
| | | | | * Note that ref.cast has a fallthrough value. * Optimize ref.eq on identical inputs.
* [Wasm GC] Do not inline a function with an RTT parameter (#3808)Alon Zakai2021-04-142-2/+13
| | | | | Inlined parameters become locals, and rtts cannot be handled as locals, unlike non-nullable values which we can at least fix up. So do not inline functions with rtt params.
* [Wasm GC] Full precompute support for GC (#3803)Alon Zakai2021-04-131-0/+4
| | | | | | | | | | | | The precompute pass ignored all reference types, but that was overly pessimistic: we can precompute some of them, namely a null and a reference to a function are fully precomputable, etc. To allow that to work, add missing integration in getFallthrough as well. With this, we can precompute quite a lot of field accesses in the existing -Oz testcase, as can be seen from the output. That testcase runs --fuzz-exec so it prints out all those logged values, proving they have not changed.
* wasm-split: Update dylink section when growing table (#3791)Sam Clegg2021-04-092-1/+4
|
* RefFunc: Validate that the type is non-nullable, and avoid possible bugs in ↵Alon Zakai2021-04-082-5/+2
| | | | | | | | the builder (#3790) The builder can receive a HeapType so that callers don't need to set non-nullability themselves. Not NFC as some of the callers were in fact still making it nullable.
* [GC] Do not crash on unreasonable GC array allocations in interpreter; trap ↵Alon Zakai2021-04-071-2/+15
| | | | | | | | | | (#3559) The spec does not mention traps here, but this is like a JS VM trapping on OOM - a runtime limitation is reached. As these are not specced traps, I did not add them to effects.h. Note how as a result the optimizer happily optimizes into a nop an unused allocation of an array of size unsigned(-1), which is the behavior we want.
* [RT] Add type to tables and element segments (#3763)Abbas Mashayekh2021-04-064-9/+28
|
* Update SIMD names and opcodes (#3771)Thomas Lively2021-04-054-53/+21
| | | | Also removes experimental SIMD instructions that were not included in the final spec proposal.
* Scan all module-level code in collectHeapTypes() (#3752)Alon Zakai2021-03-301-44/+42
| | | | | The key fix here is to call walkModuleCode so that we pick up on types that appear only in the table and nowhere else. The rest of the patch refactors the code so that that is practical.
* [Wasm GC] Optimize RefIs and RefAs when the type lets us (#3725)Alon Zakai2021-03-301-1/+37
| | | | | | | | | This is similar to the optimization of BrOn in #3719 and #3724. When the type tells us the kind of input we have, we can tell at compile time what result we'll get, like ref.is_func of something with type (ref func) will always return 1, etc. There are some code size and perf tradeoffs that should be looked into more and are marked as TODOs.
* [Wasm GC] Heap reads/writes are reads/writes of global state (#3755)Alon Zakai2021-03-301-2/+3
| | | | | | We missed that in effects.h, with the result that sets could look like they had no side effects. Fixes #3754
* LUBs (#3731)Thomas Lively2021-03-294-7/+101
| | | | | | | This is a partial revert of #3669, which removed the old implementation of Type::getLeastUpperBound that did not correctly handle recursive types. The new implementation in this PR uses a TypeBuilder to construct LUBs and for recursive types, it returns a temporary HeapType that has not yet been fully constructed to break what would otherwise be infinite recursions.
* handleNonNullableLocals(): Do not modify params (#3740)Alon Zakai2021-03-291-0/+4
| | | | Parameters can be non-nullable, and must stay so if they began as such. By mistake we modified them with the vars.
* Flat IR: Allow ref.as_non_null in nested positions (#3732)Alon Zakai2021-03-251-3/+10
| | | | | | We can't disallow it, as its result is non-null which we can't spill to a local. This may cause issues eventually in the combination of GC + flatten, but I don't expect it to. If it does we may need to revisit.
* [Wasm GC] Optimize BrOn* of the wrong kind (#3724)Alon Zakai2021-03-241-0/+94
| | | | | | | | | | | | #3719 optimized the case where the kind is what we want, like br_on_func of a function. This handles the opposite case, where we know the kind is wrong, and so the break is not taken. This seems equally useful for "polymorphic" code that does a bunch of checks and routes to different code for each case, as after inlining or other optimizations we may see which paths are taken and which are not. Also refactor the checking code to a shared location as RefIs/As will also want to use it.
* [RT] Support expressions in element segments (#3666)Abbas Mashayekh2021-03-245-51/+124
| | | | | | This PR adds support for `ref.null t` as a valid element segment item. The abbreviated format of `(elem ... func $f $g...)` is kept in both printing and binary emitting if all items are `ref.func`s. Public APIs aren't updated in this PR.
* [Wasm GC] Fix canMakeZero on tuples (#3721)Alon Zakai2021-03-241-3/+11
|
* [Wasm GC] Add support for non-nullable types, all except for locals (#3710)Alon Zakai2021-03-234-0/+76
| | | | | | | | | | | | | | | | | | | | | | After this PR we still do not support non-nullable locals. But we no longer turn all types into nullable upon load. In particular, we support non-nullable types on function parameters and struct fields, etc. This should be enough to experiment with optimizations in both binaryen and in VMs regarding non- nullability (since we expect that optimizing VMs can do well inside functions anyhow; it's non-nullability across calls and from data that the VM can't be expected to think about). Let is handled as before, by lowering it into gets and sets. In addition, we turn non-nullable locals into nullable ones, and add a ref.as_non_null on all their gets (to keep the type identical there). This is used not just for loading code with a let but also is needed after inlining. Most of the code changes here are removing FIXMEs for allowing non-nullable types. But there is also code to handle the issues mentioned above. Most of the test updates are removing extra nulls that we added before when we turned all types nullable. A few tests had actual issues, though, and also some new tests are added to cover the code changes here.
* Add missing fields in ModuleUtils::copyModule (#3692)Alon Zakai2021-03-161-0/+2
| | | We were missing type names and the features section.
* Remove unused 'Module' param from Names::getValidName. NFC (#3691)Alon Zakai2021-03-161-14/+12
|
* Fix fuzz issue with ElementSegment name collisions (#3674)Alon Zakai2021-03-121-0/+5
| | | | | Now that they have names they can collide. All the fuzzer wants is to ensure there is a segment to add to, so if there is one, do not add another.
* Remove LUB calculation (#3669)Thomas Lively2021-03-115-117/+15
| | | | | | | | Since correct LUB calculation for recursive types is complicated, stop depending on LUBs throughout the code base. This also fixes a validation bug in which the validator required blocks to be typed with the LUB of all the branch types, when in fact any upper bound should have been valid. In addition to fixing that bug, this PR simplifies the code for break handling by not storing redundant information about the arity of types.
* [reference-types] Support passive elem segments (#3572)Abbas Mashayekh2021-03-056-96/+152
| | | | | | | | | | | Passive element segments do not belong to any table, so the link between Table and elem needs to be weaker; i.e. an elem may have a table in case of active segments, or simply be a collection of function references in case of passive/declarative segments. This PR takes Table::Segment out and turns it into a first class module element just like tables and functions. It also implements early support for parsing, printing, encoding and decoding passive/declarative elem segments.