summaryrefslogtreecommitdiff
path: root/src/ir/possible-contents.cpp
Commit message (Collapse)AuthorAgeFilesLines
...
* GUFA: Use SSA-style information (#5121)Alon Zakai2022-10-071-37/+45
| | | | | | | | | | | | | | | | | Previously we treated each local index as a location, and every local.set to that index could be read by every local.get. With this we connect only relevant sets to gets. Practically speaking, this removes LocalLocation which is what was just described, and instead there is ParamLocation for incoming parameter values. And local.get/set use normal ExpressionLocations to connect a set to a get. I was worried this would be slow, since computing LocalGraph takes time, but it actually more than makes up for itself on J2Wasm and we are faster actually rocket I guess since we do less updating after local.sets. This makes a noticeable change on the J2Wasm binary, and perhaps will help with benchmarks.
* Implement bottom heap types (#5115)Thomas Lively2022-10-071-21/+13
| | | | | | | | | | | | | | | | | | | | | | | | | | | | | These types, `none`, `nofunc`, and `noextern` are uninhabited, so references to them can only possibly be null. To simplify the IR and increase type precision, introduce new invariants that all `ref.null` instructions must be typed with one of these new bottom types and that `Literals` have a bottom type iff they represent null values. These new invariants requires several additional changes. First, it is now possible that the `ref` or `target` child of a `StructGet`, `StructSet`, `ArrayGet`, `ArraySet`, or `CallRef` instruction has a bottom reference type, so it is not possible to determine what heap type annotation to emit in the binary or text formats. (The bottom types are not valid type annotations since they do not have indices in the type section.) To fix that problem, update the printer and binary emitter to emit unreachables instead of the instruction with undetermined type annotation. This is a valid transformation because the only possible value that could flow into those instructions in that case is null, and all of those instructions trap on nulls. That fix uncovered a latent bug in the binary parser in which new unreachables within unreachable code were handled incorrectly. This bug was not previously found by the fuzzer because we generally stop emitting code once we encounter an instruction with type `unreachable`. Now, however, it is possible to emit an `unreachable` for instructions that do not have type `unreachable` (but are known to trap at runtime), so we will continue emitting code. See the new test/lit/parse-double-unreachable.wast for details. Update other miscellaneous code that creates `RefNull` expressions and null `Literals` to maintain the new invariants as well.
* [GUFA] Fix call.without.effects's handling of the last parameter (#5111)Alon Zakai2022-10-051-0/+12
| | | | | | | | | The last parameter is the function to call, and we treated it like a normal parameter. This is mostly only an issue during debugging, but in theory sending this extra value could cause us to optimize less later (since it gets added to what the local of that index can contain). Also add assertions which would have caught this before.
* [GUFA] Prepare for cone types [NFC] (#5086)Alon Zakai2022-09-281-13/+13
| | | | | | | | | | | | This does not actually add cone types, but it does NFC refactoring towards that. Specifically it replaces the internal ExactType with ConeType, and the latter has a depth, so a cone type of depth 0 is the old exact type. Cone types with depth > 0 are not possible yet, keeping this NFC. I believe this design with a depth for cone types has little overhead. It does add to the size of ConeType, but the variant there is larger anyhow (it contains a Literal). And things like isSubType need to loop anyhow, so looping up to the depth etc. in checks won't make things slower.
* [GUFA] Fix haveIntersection on comparing nullable with non-nullable (#5089)Alon Zakai2022-09-281-2/+23
| | | | | We compared types and not heap types, so a difference in nullability confused us. But at that point in the code, we've ruled out nulls, so we should focus on heap types only.
* [GUFA] Simplify RefTest logic [NFC] (#5084)Alon Zakai2022-09-271-40/+1
| | | Move the logic to the GUFA pass.
* [GUFA] Optimize functions not taken by reference better (#5085)Alon Zakai2022-09-261-21/+14
| | | | | | | | | This moves the logic to add connections from signatures to functions from the top level into the RefFunc logic. That way we only add those connections to functions that actually have a RefFunc, which avoids us thinking that a function without one can be reached by a call_ref of its type. Has a small but non-zero benefit on j2wasm.
* [GUFA] Infer a RefEq value of 0 when possible (#5081)Alon Zakai2022-09-261-10/+49
| | | | If the PossibleContents for the two sides have no possible intersection then the result must be 0.
* [GUFA] Optimize ref.test (#5067)Alon Zakai2022-09-221-12/+51
| | | | | | Similar to ref.cast slightly, but simpler. Also update some TODO text.
* GUFA: Mutable exported globals are roots (#4935)Alon Zakai2022-08-221-0/+7
| | | | | | | Such globals can be written to from the outside, so we cannot infer anything about their contents. Fixes #4932
* Restore the `extern` heap type (#4898)Thomas Lively2022-08-171-1/+7
| | | | | | | The GC proposal has split `any` and `extern` back into two separate types, so reintroduce `HeapType::ext` to represent `extern`. Before it was originally removed in #4633, externref was a subtype of anyref, but now it is not. Now that we have separate heaptype type hierarchies, make `HeapType::getLeastUpperBound` fallible as well.
* [GUFA] Fix readFromData on a function literal (#4883)Alon Zakai2022-08-081-6/+9
| | | | | | | A function literal (ref.func) should never reach a struct or array get, but if there is a cast then it can look like they might arrive. We filter in ref.cast which avoids that (since casting a function to a data type will trap), but there is also br_on_cast which is not yet optimized. This PR adds code to avoid an assert in readFromData in that case.
* Remove RTTs (#4848)Thomas Lively2022-08-051-5/+2
| | | | | | | RTTs were removed from the GC spec and if they are added back in in the future, they will be heap types rather than value types as in our implementation. Updating our implementation to have RTTs be heap types would have been more work than deleting them for questionable benefit since we don't know how long it will be before they are specced again.
* Update reference type Literal constructors to use HeapType (#4857)Thomas Lively2022-08-011-1/+3
| | | | | | 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.
* [GUFA] Handle GUFA + Intrinsics (#4839)Alon Zakai2022-08-011-16/+49
| | | | | | | | 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.
* Grand Unified Flow Analysis (GUFA) (#4598)Alon Zakai2022-07-221-11/+25
| | | | | | | | | | | | | 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.
* [Strings] stringview_*.slice (#4805)Alon Zakai2022-07-151-0/+8
| | | | | | | 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.
* [Strings] stringview access operations (#4798)Alon Zakai2022-07-131-0/+16
|
* [Strings] string.as (#4797)Alon Zakai2022-07-121-0/+4
|
* [Strings] string.eq (#4781)Alon Zakai2022-07-081-0/+4
|
* [Strings] string.concat (#4777)Alon Zakai2022-07-081-0/+4
|
* [Strings] string.encode (#4776)Alon Zakai2022-07-071-0/+4
|
* [Strings] string.measure (#4775)Alon Zakai2022-07-071-0/+4
|
* [Strings] Add string.const (#4768)Alon Zakai2022-07-061-0/+3
| | | | | 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.
* Fix no-asserts compile warning (#4764)Alon Zakai2022-06-301-0/+1
|
* [Strings] Add string.new* instructions (#4761)Alon Zakai2022-06-291-0/+7
| | | | | | This is the first instruction from the Strings proposal. This includes everything but interpreter support.
* PossibleContents + ContentOracle (#4685)Alon Zakai2022-06-211-0/+1656
This pulls out the core PossibleContents and ContentOracle classes from the very large #4598, making a smaller PR that can be reviewed first. This includes unit tests for the code, but comprehensive testing will only appear in the later PR, when a new pass is added that uses all this. PossibleContents tracks the possible contents at particular locations in the program. It can track constant values as well as "this must contain this exact type", which is more than wasm itself can indicate. *Location structs are provided to declare locations in the wasm, like the location of a local or of a function argument. ContentOracle analyzes the entire program, and can then map a Location to the PossibleContents there, which a later pass will use to optimize.