summaryrefslogtreecommitdiff
path: root/src
Commit message (Collapse)AuthorAgeFilesLines
...
* Add SubTypes::getAllSubTypes variant which includes the type itself (#4649)Alon Zakai2022-05-133-17/+15
| | | | This also includes the type itself in the returned vector. This will be useful in a future PR.
* [NFC] Make Literal::makeNull take a HeapType (#4664)Alon Zakai2022-05-134-8/+7
| | | | | | | | Taking a Type is redundant as we only care about the heap type - the nullability must be Nullable. This avoids needing an assertion in the function, that is, it makes the API more type-safe.
* Make RefCast safe by default (#4663)Thomas Lively2022-05-121-1/+1
| | | | This prevents new `RefCast` expressions that don't explicitly have their safety set from getting an unitialized safety value.
* Costs: Increase cost of casts (#4661)Alon Zakai2022-05-122-13/+27
| | | | | Casts involve branches in the VM, so adding a cast in return for removing a branch (like If=>Select) is not beneficial. We don't want to ever do any more casts than we already are.
* Add ref.cast_nop_static (#4656)Thomas Lively2022-05-119-9/+44
| | | | | | This unsafe experimental instruction is semantically equivalent to ref.cast_static, but V8 will unsafely turn it into a nop. This is meant to help us measure cast overhead more precisely than we can by globally turning all casts into nops.
* [NominalFuzzing] Fix SignaturePruning on types with a super (#4657)Alon Zakai2022-05-111-0/+9
| | | | | | | Do not prune parameters if there is a supertype that is a signature. Without this we crash on an assertion in TypeBuilder when we try to recreate the types (as we try to make a a subtype with fewer fields than the super).
* [Fuzzer] Fix another reference types vs gc types issue (#4647)Alon Zakai2022-05-061-36/+37
| | | | | | | | | | Diff without whitespace is smaller. We can't emit HeapType::data without GC. Fixing that by switching to func, another problem was uncovered: makeRefFuncConst had a TODO to handle the case where we need a function to refer to but have created none yet. In fact that TODO was done at the end of the function. Fix up the logic in between to actually get there.
* [NFC] Avoid scanning code in hasBranchTarget if the target is null (#4648)Alon Zakai2022-05-061-0/+4
| | | | | | | | A null target is not a valid name so nothing can branch to there. This just saves the wasted work. No existing code in the codebase benefits from this atm, but a later PR will. In particular this lets callers call this without checking if the name is non-null, which is more concise.
* Add CMake flag JS_OF_OCAML for js_of_ocaml (#4637)Blaine Bublitz2022-05-061-0/+6
|
* Revert "Reduce iterations required for DeadArgumentElimination convergence ↵arsnyder162022-05-051-16/+44
| | | | | (#4629)" (#4646) This reverts commit 4bcfba261cb8ee182261d26064453cab787d0df4.
* Fix fuzzer's choosing of reference types (#4642)Alon Zakai2022-05-051-7/+18
| | | | | | * Don't emit "i31" or "data" if GC is not enabled, as only the GC feature adds those. * Don't emit "any" without GC either. While it is allowed, fuzzer limitations prevent this atm (see details in comment - it's fixable).
* Parse the prototype nominal binary format (#4644)Thomas Lively2022-05-042-9/+44
| | | | | | In f124a11ca3 we removed support for the prototype nominal binary format entirely, but that means that we can no longer parse older binary modules that used that format. Fix this regression by restoring the ability to parse the prototype binary format.
* Reduce iterations required for DeadArgumentElimination convergence (#4629)arsnyder162022-05-041-44/+16
| | | | | | If we do not remove a param, we can try to remove the return value. We can do that on a per-function basis, and not only if we removed no params from anywhere. Also simplify tail call logic.
* Update StackCheck for memory64 (#4636)Sam Clegg2022-05-041-7/+11
|
* Remove externref (#4633)Thomas Lively2022-05-0421-158/+35
| | | | | | Remove `Type::externref` and `HeapType::ext` and replace them with uses of anyref and any, respectively, now that we have unified these types in the GC proposal. For backwards compatibility, continue to parse `extern` and `externref` and maintain their relevant C API functions.
* Update nominal type ordering (#4631)Thomas Lively2022-05-031-14/+33
| | | | | | V8 requires that supertypes come before subtypes when it parses isorecursive (i.e. standards-track) type definitions. Since 2268f2a we are emitting nominal types using the standard isorecursive format, so respect the ordering requirement.
* Add missing include for windows (#4627)martinRenou2022-05-021-0/+2
| | | | | Without this Windows fails with: 'isdigit': is not a member of 'std'
* Handle call.without.effects in RemoveUnusedModuleElements (#4624)Alon Zakai2022-05-021-5/+39
| | | | | | | | | | | | | | | | | We assume a closed world atm in the GC space, but the call.without.effects intrinsic sort of breaks that: that intrinsic looks like an import, but we really need to care about what is sent to it even in a closed world: (call $call-without-effects (ref.func $target-keep) ) That reference cannot be ignored, as logically it is called just as if there were a call_ref there. This adds support for that, fixing the combination of #4621 and using call.without.effects. Also flip the vector of ref.func names to a set. I realized that in a very large program we might see the same name many times.
* Update the type section binary format (#4625)Thomas Lively2022-05-022-71/+67
| | | | | | | | | | Print subtype declarations using the standards-track format with a vector of supertypes followed by a normal type declaration rather than our interim nominal format that used alternative versions of the func, struct, and array forms. Desugar the nominal format to additionally emit all the types into a single large recursion group. Currently V8 is performing this desugaring, but after this change and a future change that fixes the order of nominal types to ensure supertypes precede subtypes, it will no longer need to.
* Lift the restriction in liveness-traversal.h that supported max 65535 locals ↵juj2022-04-284-59/+114
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | in a function. (#4567) * Lift the restriction in liveness-traversal.h that supported max 65535 locals in a function. * Lint * Fix typo * Fix static * Lint * Lint * Lint * Add needed canRun function * lint * Use either a sparse or a dense matrix for tracking liveness copies, depending on the locals count. * Lint * Fix lint * Lint * Implement sparse_square_matrix class and use that as a backing. * Lint * Lint * Lint #includes * Lint * Lint includes * Remove unnecessary code * Fix canonical accesses to copies matrix * Lint * Add missing variable update * Remove canRun() function * Address review * Update expected test results * Update test name * Add asserts to sparse_square_matrix set and get functions that they are not out of bound. * Lint includes * Update test expectation * Use .clear() + .resize() to reset totalCopies vector
* RemoveUnusedModuleElements: Track CallRef/RefFunc more precisely (#4621)Alon Zakai2022-04-281-3/+91
| | | | | | | | | | | | | | | | | | If we see (ref.func $foo) that does not mean that $foo is reachable - we must also see a (call_ref ..) of the proper type. Only after seeing both should we mark the function as reachable, which this PR does. This adds some complexity as we need to track intermediate state as we go, since we could see the RefFunc before the CallRef or vice versa. We also need to handle the case of a RefFunc without a CallRef properly: We cannot remove the function, as the RefFunc must refer to it, but at least we can empty out the body since we know it is never reached. This removes an old wasm-opt test which is now superseded by a new lit test. On J2Wasm output this removes 3% of all functions, which account for 2.5% of total code size.
* [NominalFuzzing] SignatureRefining can modify the IR while running a ↵Alon Zakai2022-04-283-7/+13
| | | | | | | | | parallel analysis (#4620) Normally ParallelFunctionAnalysis is just an analysis, and has no effects. However, in SignatureRefining we actually do have side effects, due to an internal limitation of the helper code it runs. This adds a template parameter to the class so users can note that they do modify the IR. The parameter is added in the middle as it is easier to add this param than to add the last one (the map).
* Fix some outdated comments (#4617)Alon Zakai2022-04-262-6/+2
| | | | * We implemented specialization of field types (the TypeRefining pass). * LUBFinder now handles nulls, so we need nothing extra for it in TypeRefining.
* wasm-reduce: Try to remove functions from a random place (#4612)Alon Zakai2022-04-251-7/+32
| | | | | | Previously we'd only try to remove functions from index 0, so we missed some opportunities. With this change we still go through all the functions if things go well, but we start from a deterministic random location in the vector.
* SmallSet: Mark iterator parent as const (#4613)Alon Zakai2022-04-251-2/+2
| | | | | | | | | | | | | | | | | | | We already assume the parent does not change, binaryen/src/support/small_set.h Lines 202 to 208 in 94d77ef // std::set allows changes while iterating. For us here, though, it would // be nontrivial to support that given we have two iterators that we // generalize over (switching "in the middle" would not be easy or fast), // so error on that. if (usingFixed != other.usingFixed) { Fatal() << "SmallSet does not support changes while iterating"; } This also marks the parent as const to reflect that. This fixed a weird C++ compilation error I had when working on something unrelated, but seems worth landing independently.
* OptimizeInstructions: Refinalize after a cast removal (#4611)Alon Zakai2022-04-251-0/+26
| | | | | | | | | Casts can replace a type with a subtype, which normally has no downsides, but in a corner case of struct types it can lead to us needing to refinalize higher up too, see details in the comment. We have avoided any Refinalize calls in OptimizeInstructions, but the case handled here requires it sadly. I considered moving it to another pass, but this is a peephole optimization so there isn't really a better place.
* [NominalFuzzing] SignatureRefining: Ignore exported functions (#4601)Alon Zakai2022-04-222-1/+60
| | | This hits the fuzzer when it tries to call reference exports with a null.
* [NominalFuzzing] Fix getHeapTypeCounts() on unreachable casts (#4609)Alon Zakai2022-04-221-53/+53
| | | | | | | | | | | The cast instruction may be unreachable but the intended type for the cast still needs to be collected. Otherwise we end up with problems both during optimizations that look at heap types and in printing (which will use the heap type in code but not declare it). Diff without whitespace is much smaller: this just moves code around so that we can use a template to avoid code duplication. The actual change is just to scan ->intendedType unconditionally, and not ignore it if the cast is unreachable.
* [NominalFuzzing] GTO: trap on null ref in removed struct.set (#4607)Alon Zakai2022-04-211-3/+5
| | | | | | | | | | | | | | When a field has no reads, we remove all its writes, but we did this: (struct.set $foo A B) => (drop A) (drop B) We also need to trap if A, the reference, is null, which this PR fixes, (struct.set $foo A B) => (drop (ref.as_non_null A)) (drop B)
* [NominalFuzzing] Add a validation error on ref.cast's etc. intended type (#4606)Alon Zakai2022-04-211-0/+7
|
* [NominalFuzzing] MergeSimilarFunctions: handle nominal types properly (#4602)Alon Zakai2022-04-211-2/+2
| | | | | | This fixes two bugs: First, we need to compare the nominal types of function constants when looking for constants to "merge", not just their structure. Second, when creating the new function we must use the proper type of those constants, and not just another type.
* [NominalFuzzing] Fix TranslateToFuzzReader::getSubType(Rtt) (#4604)Alon Zakai2022-04-211-0/+6
| | | | Randomly selecting a depth is ok for structural typing, but in nominal it must match the actual hierarchy of types.
* [NominalFuzzing] Don't compare nominal types in the fuzzer (#4603)Alon Zakai2022-04-211-3/+8
| | | | | The same module will have a different type after some transformations, even though that is not observable, like --roundtrip. Basically, we should not be comparing types between separate modules, which is what the fuzzer does.
* [NominalFuzzing] Fix replaceWithIdenticalType() on nondefaultable tuples (#4605)Alon Zakai2022-04-211-1/+1
|
* Rename asyncify-side-module to asyncify-relocatable (#4596)かめのこにょこにょこ2022-04-181-3/+3
| | | | | | | Related: emscripten-core/emscripten#15893 (comment) --pass-arg=asyncify-side-module option will be used not only from side modules, but also from main modules.
* Implement relaxed SIMD dot product instructions (#4586)Thomas Lively2022-04-1111-12/+118
| | | As proposed in https://github.com/WebAssembly/relaxed-simd/issues/52.
* [Inlining] Preserve return_calls when possible (#4589)Thomas Lively2022-04-111-0/+10
| | | | | | | | | We can preserve return_calls in inlined functions when the inlined call site is itself a return_call, since the call result types must transitively match in that case. This solves a problem where the previous inlining logic could introduce stack exhaustion by downgrading recursive return_calls to normal calls. Fixes #4587.
* [SIMD] Make swizzle's opcode name consistent (NFC) (#4585)Heejin Ahn2022-04-0912-21/+21
| | | | Other opcode ends with `Inxm` or `Fnxm` (where n and m are integers), while `i8x16.swizzle`'s opcode name doesn't have an `I` in there.
* Implement i16x8.relaxed_q15mulr_s (#4583)Thomas Lively2022-04-079-7/+31
| | | As proposed in https://github.com/WebAssembly/relaxed-simd/issues/40.
* Avoid a code pattern of vec.resize() followed by std::fill() as suboptimal. ↵juj2022-04-054-9/+8
| | | | Instead do a clear()+resize() (#4580)
* Fix MemoryPacking bug (#4579)Thomas Lively2022-04-051-2/+1
| | | | | | | | 247f4c20a1 introduced a bug that caused expressions that refer to data segments to be associated with the wrong segments in the presence of other segments that have no referring expressions at all. Fixes #4569. Fixes #4571.
* [Wasm GC] Fix unreachable local.gets of non-nullable locals in ↵Alon Zakai2022-04-051-1/+21
| | | | | | | | CoalesceLocals (#4574) Normally we just replace unreachable local.gets with a constant (0, or null), but if the local is non-nullable we can't do that. Fixes #4573
* Use LiteralUtils::canMakeZero before calling makeZero (#4568)Alon Zakai2022-04-013-9/+10
| | | | | Fixes #4562 Fixes #4564
* [NFC] Refactor Feature::All to match FeatureSet.setAll() (#4557)Alon Zakai2022-03-312-9/+13
| | | | | | | | | | | As we recently noted in #4555, that Feature::All and FeatureSet.setAll() are different is potentially confusing... I think the best thing is to make them identical. This does that, and adds a new Feature::AllPossible which is everything possible and not just the set of all features that are enabled by -all. This undoes part of #4555 as now the old/simpler code works properly.
* [Wasm GC] Fix stacky non-nullable tuples (#4561)Alon Zakai2022-03-311-7/+8
| | | | | #4555 fixed validation for such tuples, but we also did not handle them in "stacky" code using pops etc., due to a logic bug in the binary reading code.
* [MemoryPacking] Remove workaround for old V8 bug (#4558)Thomas Lively2022-03-311-10/+1
| | | | | | | V8 used to incorrectly parse the segment index on bulk memory instructions as a signed LEB rather than an unsigned LEB, which meant it only worked correctly with up to 63 data segments. That bug has been fixed for over two years now, so lift the maximum number of segments generated by memory packing from 63 to the specified max, 100k.
* [Wasm GC] Fix non-nullable tuples (#4555)Alon Zakai2022-03-304-7/+26
| | | | | | Apply the same logic to tuple fields as we do for all other fields, when checking whether a non-nullable value is valid. Fixes #4554
* [NFC][MemoryPacking] Avoid unnecessarily enormous memory allocations (#4556)Thomas Lively2022-03-301-26/+33
| | | | | | | | | | | The memory packing pass previously used vectors with a slot for each data segment to easily map segment indices to lists of "referrers," i.e. bulk memory expressions that referred to the segments. The parallel analysis pass to collect these referrers allocated one of these vectors for each function in a module. Unfortunately, for a particularly large module with over 200k functions and over 75k data segments, this resulted in hundreds of gigabytes of memory allocations. The vast majority of functions contain no referrers, so using a std::unordered_map makes much more sense than using a vector to perform this mapping.
* [Wasm GC] GlobalTypeOptimization: Remove fields from end based on subtypes ↵Alon Zakai2022-03-303-20/+74
| | | | | | | | | | | | | | (#4553) Previously we'd remove a field from a type if that field has no uses in any sub- or super-type. In that case we'd remove it from all the types at once. However, there is a case where we can remove a field only from a parent but not from its children, if the field is at the end: if A has fields {x, y, z} and its subtype B has fields {x, y, z, w}, and A pointers only access field y while B pointers access all the fields, then we can remove z from A. Removing it from the end is safe, and then B will not only add w as it did before but also add z. Note that we cannot remove x, because it is not at the end: removing it from just A but not B would shift the indexes, making them incompatible.
* [Wasm GC] Signature Pruning: Remove params passed constant values (#4551)Alon Zakai2022-03-281-13/+34
| | | | | This basically just adds a call to ParamUtils::applyConstantValues, however, we also need to be careful to not optimize in the presence of imports or exports, so this adds a boolean that indicates unoptimizability.