summaryrefslogtreecommitdiff
path: root/src/passes/LocalSubtyping.cpp
Commit message (Collapse)AuthorAgeFilesLines
* [NFC-ish] Remove LocalGraph from LocalSubtyping (#6921)Alon Zakai2024-09-101-69/+42
| | | | | | | | | | | | | | | | The LocalGraph there was used for two purposes: 1. Get the list of gets and sets. 2. Get only the reachable gets and sets. It is trivial to get all the gets and sets in a much faster way, by just walking the code as this PR does. The downside is that we also consider unreachable gets and sets, so unreachable code can prevent us from optimizing, but that seems worthwhile as many passes make that assumption (and they all become maximally effective after --dce). That is the only non-NFC part here. Removing LocalGraph + the fixup code for unreachability makes this significantly shorter, and also 2-3x faster.
* Remove the GCNNLocals feature (#5080)Thomas Lively2023-08-311-21/+5
| | | | | Now that the WasmGC spec has settled on a way of validating non-nullable locals, we no longer need this experimental feature that allowed nonstandard uses of non-nullable locals.
* End the current basic block on a Call (#5823)Alon Zakai2023-07-261-1/+1
| | | | | | | | | | | | | Before this PR, if a call had no paths to a catch in the same function then we skipped creating a new basic block right after it. As a result, we could have a call in the middle of a basic block. If EH is enabled that means we might transfer control flow out of the function from the middle of a block. But it is better to have the property that any transfer of control flow - to another basic block, or outside of the function - can only happen at the end of a basic block. This causes some overhead, but a subsequent PR (#5838) will remove that as a followup, and this PR adds a little code to pass the module and check if EH is enabled, and avoid the overhead if not, which at least avoids regressing the non-EH case until that followup lands.
* Do not special case ref.null in `LUBFinder` (#5307)Thomas Lively2022-12-011-4/+3
| | | | | | | | | | | | Before we implemented bottom heap types, `ref.null` had to be annotated with specific types. The `LUBFinder` utility ignored these types so that it could find the best LUB from all considered non-null expressions, then go back and update the type annotations on the nulls to match that LUB. Now that we have bottom types, however, none of that is necessary, and in fact ignoring nulls can miss possible refinements to bottom types. Update and simplify `LUBFinder` so that it is a simple wrapper around the underlying `Type::getLeastUpperBound` utility with no additional logic. Update tests to account for the more powerful optimizations.
* Refactor interaction between Pass and PassRunner (#5093)Thomas Lively2022-09-301-1/+3
| | | | | | | | | | | | | | Previously only WalkerPasses had access to the `getPassRunner` and `getPassOptions` methods. Move those methods to `Pass` so all passes can use them. As a result, the `PassRunner` passed to `Pass::run` and `Pass::runOnFunction` is no longer necessary, so remove it. Also update `Pass::create` to return a unique_ptr, which is more efficient than having it return a raw pointer only to have the `PassRunner` wrap that raw pointer in a `unique_ptr`. Delete the unused template `PassRunner::getLast()`, which looks like it was intended to enable retrieving previous analyses and has been in the code base since 2015 but is not implemented anywhere.
* [Wasm GC] Support non-nullable locals in the "1a" form (#4959)Alon Zakai2022-08-311-12/+20
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | | An overview of this is in the README in the diff here (conveniently, it is near the top of the diff). Basically, we fix up nn locals after each pass, by default. This keeps things easy to reason about - what validates is what is valid wasm - but there are some minor nuances as mentioned there, in particular, we ignore nameless blocks (which are commonly added by various passes; ignoring them means we can keep more locals non-nullable). The key addition here is LocalStructuralDominance which checks which local indexes have the "structural dominance" property of 1a, that is, that each get has a set in its block or an outer block that precedes it. I optimized that function quite a lot to reduce the overhead of running that logic after each pass. The overhead is something like 2% on J2Wasm and 0% on Dart (0%, because in this mode we shrink code size, so there is less work actually, and it balances out). Since we run fixups after each pass, this PR removes logic to manually call the fixup code from various places we used to call it (like eh-utils and various passes). Various passes are now marked as requiresNonNullableLocalFixups => false. That lets us skip running the fixups after them, which we normally do automatically. This helps avoid overhead. Most passes still need the fixups, though - any pass that adds a local, or a named block, or moves code around, likely does. This removes a hack in SimplifyLocals that is no longer needed. Before we worked to avoid moving a set into a try, as it might not validate. Now, we just do it and let fixups happen automatically if they need to: in the common code they probably don't, so the extra complexity seems not worth it. Also removes a hack from StackIR. That hack tried to avoid roundtrip adding a nondefaultable local. But we have the logic to fix that up now, and opts will likely keep it non-nullable as well. Various tests end up updated here because now a local can be non-nullable - previous fixups are no longer needed. Note that this doesn't remove the gc-nn-locals feature. That has been useful for testing, and may still be useful in the future - it basically just allows nn locals in all positions (that can't read the null default value at the entry). We can consider removing it separately. Fixes #4824
* Modernize code to C++17 (#3104)Max Graey2021-11-221-5/+2
|
* [Wasm GC] Update nulls to allow finding better LUBs (#4340)Alon Zakai2021-11-181-2/+4
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | It is common in GC code to have stuff like this: x = null; .. x = Data(); Nulls in wasm have a type, and if that initial null has say anyref then before this PR we would keep the type of x as anyref. However, while nulls have types, all null values are identical, and so we can in fact change x's type to a nullable reference of Data, by also changing the null's type to something more specific. LUBFinder now has an API that can return the best possible LUB so far, and that can be told to update nulls if we decide that the new LUB is worth using. This updates the passes using LUBFinder to use the new API. Note how TypeRefining becomes simpler because the special logic it had in a subclass of LUBFinder is now part of the main class (it used to remember if there was a null default; LUBFinder now handles both a null default as well as other nulls). This requires some changes to existing tests to avoid them from optimizing using nulls in ways that ends up not testing the original intent. Specifically the dae-gc-refine-params.wast now has calls to get a null of a type, instead of just having a ref.null of that type (which could be optimized now). And dae-gc-refine-return uses locals instead of ref.nulls.
* [Wasm GC] LUBFinder helper. NFC (#4298)Alon Zakai2021-11-011-5/+9
| | | | | | | | | This is a minor refactoring in DAE to have a helper class that does the incremental LUB calculation. The class is also used in LocalSubtyping, where it has the effect of making the work incremental which it was not before (that would have no observable consequence, but it should make us faster in the common case where we fail to find a new LUB). This will allow further optimization in a central place later.
* [Wasm GC] Fix LocalSubtyping on unreachable sets with incompatible values ↵Alon Zakai2021-08-111-1/+28
| | | | | | | | (#4051) We ignore sets in unreachable code, but their values may not be compatible with a new type we specialize a local for. That is, the validator cares about unreachable sets, while logically we don't need to, and this pass doesn't. Fix up such unreachable sets at the end.
* [Wasm GC] Handle unreachability in LocalSubtyping (#4044)Alon Zakai2021-08-021-0/+20
|
* [Wasm GC] Handle uses of default values in LocalSubtyping (#4024)Alon Zakai2021-07-281-27/+52
| | | | | | It is ok to use the default value of a reference even if we refine the type, as it would be a more specifically-typed null, and all nulls compare the same. However, if the default is used then we *cannot* alter the type to be non-nullable, as then we'd use a null where that is not allowed.
* [Wasm GC] DeadArgumentElimination: Update tees after refining param types ↵Alon Zakai2021-07-281-1/+2
| | | | (#4031)
* [Wasm GC] Handle nondefaultable types in LocalSubtyping (#4019)Alon Zakai2021-07-231-8/+15
| | | | | The pass handled non-nullability, but another case is a tuple with nullable values in it that is assigned non-nullable values, and in general, other stuff that is nondefaultable (but not non-nullable). Ignore those.
* [Wasm GC] Local-Subtyping pass (#3765)Alon Zakai2021-07-231-0/+142
If a local is say anyref, but all values assigned to it are something more specific like funcref, then we can make the type of the local more specific. In principle that might allow further optimizations, as the local.gets of that local will have a more specific type that their users can see, like this: (import .. (func $get-funcref (result funcref))) (func $foo (result i32) (local $x anyref) (local.set $x (call $get-funcref)) (ref.is_func (local.get $x)) ) => (func $foo (result i32) (local $x funcref) ;; updated to a subtype of the original (local.set $x (call $get-funcref)) (ref.is_func (local.get $x)) ;; this can now be optimized to "1" ) A possible downside is that using more specific types may not end up allowing optimizations but may end up increasing the size of the binary (say, replacing lots of anyref with various specific types that compress more poorly; also, for recursive types the LUB may be a unique type appearing nowhere else in the wasm). We should investigate the code size factors more later.