| Commit message (Collapse) | Author | Age | Files | Lines |
|
|
| |
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.
|
|
|
|
|
| |
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)
```
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
|
|
|
| |
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.
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
|
|
|
|
|
| |
constants on RHS (#4808)
(x * C1) << C2 -> x * (C1 << C2)
(x << C1) * C2 -> x * (C2 << C1)
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
| |
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| |
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.
|
| |
|
| |
|
| |
|
|
|
|
|
|
|
|
|
|
|
|
| |
Grouping all references together makes it easier for baseline compilers to
zero out memory (as the zeroing out may be different for MVP types vs.
references).
This puts all references together, either at the start or the end. As a
heuristic for that we see if the first local is a reference. As the optimizer
will sort locals by frequency, this ensures that the most-frequent local
stays in index 0.
Fixes #4773. See more details there
|
| |
|
|
|
|
|
| |
This is more work than a typical instruction because it also adds a new section:
all the (string.const "foo") strings are put in a new "strings" section in the binary, and
the instructions refer to them by index.
|
| |
|
| |
|
|
|
|
|
|
| |
This is the first instruction from the Strings proposal.
This includes everything but interpreter support.
|
|
|
|
|
|
|
|
| |
This starts to implement the Wasm Strings proposal
https://github.com/WebAssembly/stringref/blob/main/proposals/stringref/Overview.md
This just adds the types.
|
|
|
|
|
|
|
|
|
|
|
| |
Nominal types don't make much sense without GC, and in particular trying to emit
them with typed function references but not GC enabled can result in invalid
binaries because nominal types do not respect the type ordering constraints
required by the typed function references proposal. Making this change was
mostly straightforward, but required fixing the fuzzer to use --nominal only
when GC is enabled and required exiting early from nominal-only optimizations
when GC was not enabled.
Fixes #4756.
|
|
|
|
|
|
|
| |
`controlFlowDepth` is a variable used to print `delegate`'s target. When
printing nested blocks, we increase `controlFlowDepth` by the number of
nested blocks at once. But we should decrement it as we finish each
block, rather than decrease by the number of nested blocks at once,
because we need correct `controlFlowDepth` within nested blocks.
|