| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
|
|
|
|
|
|
| |
`--debug`. NFC (#4874)
For example I found it useful to able to do something like this:
```
$ BINARYEN_DEBUG=post-emscripten ./test/runner sometest
```
|
|
|
| |
Introduces the necessary APIs to use the type builder from C. Enables construction of compound heap types (arrays, structs and signatures) that may be recursive, including assigning concrete names to the built types and, in case of structs, their fields.
|
| |
|
|
|
|
|
|
|
|
| |
We already remove `__start_em_asm` and `__stop_em_asm`. This change
is needed since I want to start exporting `__start_em_js` and
`__stop_em_js` from emscripten without causing regressions.
As a followup I'm planning on moving all of the em_js and em_asm
stripping code it PostEmscripten.cpp.
|
|
|
|
|
| |
It has been removed from the typed function references proposal, so we no longer
need to support it. Maintaining the test for `let` was difficult because
Binaryen could not emit either text or binary that actually used it.
|
|
|
|
|
|
|
|
|
|
|
|
| |
+ Move these rules to separate function;
+ Refactor them to use matches;
+ Add comments;
+ Handle rotational shifts as well;
+ Handle overflows for `<<`, `>>`, `>>>` shifts;
+ Add mixed rotate rules:
```rust
rotl(rotr(x, C1), C2) => rotr(x, C1 - C2)
rotr(rotl(x, C1), C2) => rotl(x, C1 - C2)
```
|
|
|
| |
Avoids a "may fall through" warning.
|
| |
|
|
|
|
|
|
| |
We already require non-null literals to have non-null types, but with this
change we can enforce that constraint by construction. Also remove the default
behavior of creating a function reference literal with heap type `func`, since
there is always a more specific function type to use.
|
|
|
| |
This can give us some chance to catch bugs like #4839 in the fuzzer.
|
|
|
|
|
|
|
|
| |
Like RemoveUnusedModuleElements, places that build graphs of function
reachability must special-case the call-without-effects intrinsic. Without that,
it looks like a call to an import. Normally a call to an import is fine - it makes us
be super-pessimistic, as we think things escape all the way out - but in GC
for now we are assuming a closed world, and so we end up broken. To fix that,
properly handle the intrinsic case.
|
|
|
|
|
|
| |
It was wasted work to see a drop and then check if we can replace it with
a drop of its child, which is identical to the original state. This didn't cause
any harm (we'd not reduce code size, and stop eventually) but it did slow us
down.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Refactor everywhere from:
```c++
for (size_t i = 0; i < indent; i++) {
o << ' ';
}
```
to:
```c++
o << std::string(indent, ' ');
```
### Motivation
It is much simpler and should produce smaller code.See godbolt:
https://godbolt.org/z/KMYMdn7z5
|
|
|
| |
Make the C API match the JS API and fix an old bug where extra newlines were emitted.
|
| |
|
|
|
|
|
|
|
|
|
| |
The stubs let precompute skip over them without erroring. With this PR we can
run the optimizer on strings code. We still can't run --fuzz-exec though, so we
can't run the fuzzer.
Also simplify the error strings in the earlier part of the file. All other code just
has "unimp" so we might as well do the same and not mention full names
there.
|
|
|
|
|
|
|
| |
The previous code assumes if `last`'s type is unreachable it traps. But
it's not always the case because it can be other instructions like `br`
whose type is unreachable but doesn't necessarily trap.
Context:
https://github.com/WebAssembly/binaryen/pull/4827#discussion_r929395477
|
|
|
|
|
| |
This lets wasm-reduce --enable-FOO work. Usually this is not needed as we do
enable all features by default, but sometimes it is nice to disable features (e.g. to
avoid reducing into a testcase that uses something the original wasm did not use).
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There are two new potential problems that `GlobalTypeRewriter` can run into when
working with isorecursive types instead of nominal types. First, the refined
types may have replaced generic references with references to specific other
types, potentially creating new recursions and making the existing recursion
groups insufficient. Second, distinct types may be refined to structurally
identical types and those distinct input types may map the same output type,
potentially changing cast behavior.
Both of these problems are solved by putting all the new types in a single large
recursion group.
We do not currently account for the fact that types may be used in the external
interface of the module, but when we do, externalized types will be excluded
from optimizations and will not be affected by the creation of this single large
rec group.
Fixes #4816.
|
|
|
|
|
|
|
|
|
|
|
| |
* Changing ref maps in wasm-binary to use a value of a vector of Name*
* clang-format
* Update src/wasm/wasm-binary.cpp
Co-authored-by: Thomas Lively <7121787+tlively@users.noreply.github.com>
Co-authored-by: Thomas Lively <7121787+tlively@users.noreply.github.com>
|
| |
|
|
|
|
|
|
| |
constants on RHS (#4808)
(x * C1) << C2 -> x * (C1 << C2)
(x << C1) * C2 -> x * (C2 << C1)
|
|
|
|
|
|
|
|
|
| |
Add support for emitting the string type reference shorthands, which had
previously been omitted accidentally due to the `default` case in that switch.
Also avoid emitting shorthands for non-nullable reference types as a first step
towards transitioning the shorthands to represent nullable types instead. Not
emitting these shorthands at all will give V8 the flexibility it needs to change
its interpretation of the shorthands without breaking any workflows using
Binaryen.
|
|
|
|
|
|
|
|
|
|
|
|
| |
Now that we have `getDroppedUnconditionalChildrenAndAppend`, all passes
need to use it rather than the old `getDroppedChildrenAndAppend`, which
is used within the new method
`getDroppedUnconditionalChildrenAndAppend`.
This creates `drop.cpp` and move method implementations in drop.h there,
and merge two methods given that the old method is not supposed to be
used from outside anyway, and drops `Unconditional` from the new method
name because this is the only method and doesn't have to be specific
about that.
|
|
|
|
|
|
| |
This is not observable in practice atm since call_ref also does a call,
which has even more effects. However, future optimizations might benefit
from this, and it is more consistent to avoid marking the instruction as
trapping if it can't.
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
There are several reasons why a function may not be trained in deterministically.
So to perform quick validation we need to inspect profile.data (another ways requires split to be performed). However as profile.data is a binary file and is not self sufficient, so we cannot currently use it to perform such validation.
Therefore to allow quick check on whether a particular function has been trained in, we need to dump profile.data in a more readable format.
This PR, allows us to output, the list of functions to be kept (in main wasm) and those split functions (to be moved to deferred.wasm) in a readable format, to console.
Added a new option `--print-profile`
- input path to orig.wasm (its the original wasm file that will be used later during split)
- input path to profile.data that we need to output
optionally pass `--unescape`
to unescape the function names
Usage:
```
binaryen\build>bin\wasm-split.exe test\profile_data\MY.orig.wasm --print-profile=test\profile_data\profile.data > test\profile_data\out.log
```
note: meaning of prefixes
`+` => fn to be kept in main wasm
`-` => fn to be split and moved to deferred wasm
|
|
|
|
|
| |
The encoding here is simple: we store i31 values in the literal.i32
field. The top bit says if a value exists, which means literal.i32 == 0 is the
same as null.
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
This tracks the possible contents in the entire program all at once using a single IR.
That is in contrast to say DeadArgumentElimination of LocalRefining etc., all of whom
look at one particular aspect of the program (function params and returns in DAE,
locals in LocalRefining). The cost is to build up an entire new IR, which takes a lot
of new code (mostly in the already-landed PossibleContents). Another cost
is this new IR is very big and requires a lot of time and memory to process.
The benefit is that this can find opportunities that are only obvious when looking
at the entire program, and also it can track information that is more specialized
than the normal type system in the IR - in particular, this can track an ExactType,
which is the case where we know the value is of a particular type exactly and not
a subtype.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
| |
Basic reference types like `Type::funcref`, `Type::anyref`, etc. made it easy to
accidentally forget to handle reference types with the same basic HeapTypes but
the opposite nullability. In principle there is nothing special about the types
with shorthands except in the binary and text formats. Removing these shorthands
from the internal type representation by removing all basic reference types
makes some code more complicated locally, but simplifies code globally and
encourages properly handling both nullable and non-nullable reference types.
|
| |
|
|
|
|
| |
This measures the length of a view, so it seems simplest to make it a
sub-operation of the existing measure instruction.
|
|
|
|
|
|
|
| |
Unfortunately one slice is the same as python [start:end], using 2 params,
and the other slice is one param, [CURR:CURR+num] (where CURR is implied
by the current state in the iter). So we can't use a single class here. Perhaps
a different name would be good, like slice vs substring (like JS does), but
I picked names to match the current spec.
|
|
|
|
|
| |
For them to be the same we must have a value that can appear on both
sides. If the heap types disallow that, then only null is possible, and if
that is impossible as well then the result must be 0.
|
| |
|
|
|
|
|
| |
Minor fuzz bug. When we replace a struct.set with its children we also
add a ref.as_non_null on the reference, but that must not occur before
effects in the other child.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
The parser functions previously both parsed the input and controlled what was
done with the results using `constexpr` if-else chains. As the number of parsing
contexts grew, these if-else chains became increasingly complex and distracting
from the core parsing logic of the parsing functions.
To simplify the code, refactor the parsing functions to replace the `constexpr`
if-else chains with unconditional calls to methods on the context. To avoid
duplicating most method definitions for multiple parsing contexts, introduce new
utility contexts that implement common methods and (ab)use inheritance and
multiple inheritance to reuse their methods from the main parsing contexts.
This change will also make it easier to reuse the parser code for entirely
different purposes in the future by providing new context implementations. For
example, V8 could reuse the code and provide different parser contexts that
construct V8-internal data structures rather than Binaryen data structures.
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
Update gen-s-parser.py to produce a second version of its parsing code that
works with the new wat parser. The new version automatically replaces the `s`
element argument in the existing parser with the `ctx` and `in` arguments used
by the new parser, so adding new instructions will not require any additional
work in gen-s-parser.py after this change.
Also add stub `make***` functions to the new wat parser, with a few filled out,
namely `makeNop`, `makeUnreachable`, `makeConst`, and `makeRefNull`. Update the
`global` parser to parse global initializer instructions and update
wat-kitchen-sink.wast to demonstrate that the instructions are parsed correctly.
Adding new instruction classes will require adding a new `make***` function to
wat-parser.cpp in additional to wasm-s-parser.{h,cpp} after this change, but
adding a trivial failing implementation is good enough for the time being, so I
don't expect this to appreciably increase our maintenance burden in the near
term.
The infrastructure for parsing folded instructions, instructions with operands,
and control flow instructions will be implemented in future PRs.
|
|
|
|
|
|
|
|
|
|
|
|
| |
This marks all reference operations that return 0/1 as doing so. This
allows various bitwise operations to be optimized on them.
This also marks StringEq as a boolean, though we can't test that fully yet
as Strings support is wip (no interpreter or other stuff yet).
As a driveby this moves emitsBoolean to its own file, and uses it
in getMaxBits to avoid redundancy (the redundant code paths now have
a WASM_UNREACHABLE).
|
| |
|
|
|
|
|
|
|
| |
This implements it as a StringMeasure opcode. They do have the same number of
operands, same trapping behavior, and same return type. They both get a string and
do some inspection of it to return an i32. Perhaps the name could be StringInspect
or something like that, rather than StringMeasure..? But I think for now this might be
good enough, and the spec may change anyhow later.
|
| |
|
|
|
|
| |
Parse type definitions with the format `(type $t (sub $super ...))`. Update the
test to use hybrid types so that the subtypes are reflected in the test output.
|
| |
|