| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
| |
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
|
|
|
|
| |
uses of the original add, as otherwise we may just be adding work (both an offset, and an add). Refactor local-utils.h, and make UnneededSetRemover also check for side effects, so it cleanly removes all traces of unneeded sets.
|
|
|
|
|
| |
Trying to refactor the code to be simpler and less redundant, I ran into some perf issues that it seems like a small vector, with fixed-size storage and optional additional storage as needed, might help with. This implements that class and uses it in a few places.
This seems to help, I see some 1-2% fewer instructions and cycles in `perf stat`, but it's hard to tell if it really makes a noticeable difference.
|
|
|
|
|
|
| |
Automated renaming according to
https://github.com/WebAssembly/spec/issues/884#issuecomment-426433329.
|
|
|
| |
Remove the existing hack, and optimize them just like we do for ifs and blocks. This is now able to handle a few more cases than before.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
an if-else.
If an if sets a local,
(if
(..condition..)
(set_local $x (..value..))
)
we can turn it into
(set_local $x
(if
(..condition..)
(..value..)
(get_local $x)
)
)
This increases code size and adds a branch in the if, but allows
the set to be optimized into a tee or optimized out entirely. In
the worst case, other optimizations can break up an if with a copy
in one of its arms later.
Includes a determinism fix for EquivalentSets, which this patch
triggered.
|
|
|
|
|
|
| |
* Switch optimizations in remove-unused-brs: thread switch jumps, and turn a switch with all identical targets into a br
* refinalize in interm operations in remove-unused-brs, as we can be confused by it
|
|
|
|
|
| |
This makes it much more effective, by rewriting it to depend on flatten. In flattened IR, it is very simple to check if an expression is equivalent to one already available for use in a local, and use that one instead, basically we just track values in locals.
Helps with #1521
|
|
|
| |
Don't skip through flowing tee values, just drop the current outermost which we find is redundant. the child tees may still be necessary.
|
|
|
|
|
|
|
|
|
| |
If locals are known to contain the same value, we can
* Pick which local to use for a get_local of any of them. Makes sense to prefer the most common, to increase the chance of one dropping to zero uses.
* Remove copies between a local and one that we know contains the same value.
This is a consistent win, small though, around 0.1-0.2%.
|
|
|
|
|
| |
* remove-unused-brs: handle an if declared as returning a value despite having an unreachable condition
* simplify-locals: don't work on loops while the main pass is making changes, as set_locals are being tracked and modified.
|
| |
|
|
|
|
|
|
| |
* Use an if return value when one side is unreachable.
* Undo an if return value if we can use a br_if instead
|
|
|
|
|
| |
Add a version of simplify-locals which does not create nesting. This keeps the IR flat (in the sense of --flatten).
Also refactor simpify-locals to be a template, so the various modes are all template parameters.
|
|
|
| |
The IR is indeed a tree, but not an "abstract syntax tree" since there is no language for which it is the syntax (except in the most trivial and meaningless sense).
|
|
|
|
| |
we are moving code out of the br_if's condition - the value executes before (#1213)
|
| |
|
|
|
|
| |
validation that was from when we differentiated reachable from unreachable breaks (#1166)
|
|
|
|
|
|
|
|
| |
* if a block has a concrete final element (or a break with a value), then even if it has an unreachable child, keep it with that concrete type. this means we no longe allow the silly case of a block with an unreachable in the middle and a concrete as the final element while the block is unreachable - after this change, the block would have the type of the final element
* if an if has a concrete element in one arm, make it have that type as a result, even if the if condition is unreachable, to parallel block
* make type rules for brs and switches simpler, ignore whether they are reachable or not. whether they are dead code should not affect how they influence other types in our IR.
|
|
|
|
| |
to make this practical
|
| |
|
|
|
|
|
|
|
| |
* validate that types are properly finalized, when in pass-debug mode (BINARYEN_PASS_DEBUG env var): check after each pass is run that the type of each node is equal to the proper type (when finalizing it, i.e., fully recomputing the type).
* fix many fuzz bugs found by that.
* in particular, fix dce bugs with type changes not being fully updated during code removal. add a new TypeUpdater helper class that lets a pass update types efficiently, by the helper tracking deps between blocks and branches etc., and updating/propagating type changes only as necessary.
|
|
|
|
| |
Most module walkers use PostWalker<T, Visitor<T>>, let that pattern be
expressed as simply PostWalker<T>
|
|
|
|
|
|
|
|
| |
* add --ignore-implicit-traps option, and by default do not ignore them, to properly preserve semantics
* implicit traps can be reordered, but are side effects and should not be removed
* add testing for --ignore-implicit-traps
|
|
|
|
| |
before coalesce, so that coalesce can remove all copies, then do another pass of full simplification after it
|
| |
|
| |
|
|
|
|
| |
must be dropped
|
|
|
|
| |
value
|
|
|
|
| |
is only possible if the break is unconditional; if it is condition, we must tee the value so that if the break condition is false and we do not jump, then we have the new value in the local on the line after it
|
| |
|
| |
|
|
|
|
| |
due to linker dead code elimination. Fixes #577.
|
|
|
|
| |
efficient parallel execution (#564)
|
|
|
|
| |
that is clearer where it should be overridden (#551)
|
| |
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
| |
function, to avoid confusion with having both visit* and visitExpression in a single pass (#357)
|
| |
|
|
|
|
| |
names are kept on the Function object (#354)
|
|
|
|
| |
* allow traversals to mark themselves as function-parallel, in which case we run them using a thread pool. also mark some thread-safety risks (interned strings, arena allocators) with assertions they modify only on the main thread
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
* refactor core walking to not recurse
* add a simplify-locals test
* reuse parent's non-branchey scan logic in SimpleExecutionWalker, reduce code duplication
* update wasm.js
* rename things following comments
|