-
Notifications
You must be signed in to change notification settings - Fork 830
[WasmGC] Heap2Local: Optimize RefCast failures #6727
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
Merged
Merged
Changes from all commits
Commits
Show all changes
28 commits
Select commit
Hold shift + click to select a range
a4e1778
almost
kripken 38f2297
work
kripken 3009f94
work
kripken 10a8b9d
work
kripken 43e5381
Undo.opt
kripken d36281b
re-do
kripken 1c11a1e
Revert "re-do"
kripken 19823a6
format
kripken 078b813
almost
kripken 090af2d
work
kripken 49d7545
Merge remote-tracking branch 'origin/main' into heap2local.ref.eq
kripken 60050be
fix
kripken dea6db5
add two more tests
kripken 9029ba2
improve test
kripken f305e4f
more
kripken 8d26f56
test
kripken cffde15
todo
kripken 66f8b13
work
kripken 72c9b60
test
kripken fd71b16
formt
kripken 4193d58
test
kripken 1eb9848
fix
kripken 56d5e98
merge
kripken 584b750
yolo
kripken 3488e5d
fix
kripken f5a998c
Merge remote-tracking branch 'myself/heap2local.ref.is' into heap2loc…
kripken d6d4d12
Merge remote-tracking branch 'origin/main' into heap2local.castfailz
kripken 6df1b8b
clarify in a comment
kripken File filter
Filter by extension
Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
There are no files selected for viewing
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
| Original file line number | Diff line number | Diff line change |
|---|---|---|
|
|
@@ -2640,24 +2640,34 @@ | |
| (type $A (sub (struct (field (ref null $A))))) | ||
| ;; CHECK: (type $1 (func (result anyref))) | ||
|
|
||
| ;; CHECK: (type $B (sub $A (struct (field (ref $A))))) | ||
| (type $B (sub $A (struct (field (ref $A))))) | ||
| ;; CHECK: (type $B (sub $A (struct (field (ref $A)) (field i32)))) | ||
| (type $B (sub $A (struct (field (ref $A)) (field i32)))) | ||
|
|
||
| ;; CHECK: (type $3 (func (result i32))) | ||
|
|
||
| ;; CHECK: (func $func (type $1) (result anyref) | ||
| ;; CHECK-NEXT: (local $a (ref $A)) | ||
| ;; CHECK-NEXT: (local $1 (ref $A)) | ||
| ;; CHECK-NEXT: (local $2 (ref $A)) | ||
| ;; CHECK-NEXT: (local $2 i32) | ||
| ;; CHECK-NEXT: (local $3 (ref $A)) | ||
| ;; CHECK-NEXT: (local $4 i32) | ||
| ;; CHECK-NEXT: (ref.cast (ref $B) | ||
| ;; CHECK-NEXT: (block (result (ref $A)) | ||
| ;; CHECK-NEXT: (drop | ||
| ;; CHECK-NEXT: (block (result nullref) | ||
| ;; CHECK-NEXT: (local.set $2 | ||
| ;; CHECK-NEXT: (local.set $3 | ||
| ;; CHECK-NEXT: (struct.new $A | ||
| ;; CHECK-NEXT: (ref.null none) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (local.set $4 | ||
| ;; CHECK-NEXT: (i32.const 1) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (local.set $1 | ||
| ;; CHECK-NEXT: (local.get $2) | ||
| ;; CHECK-NEXT: (local.get $3) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (local.set $2 | ||
| ;; CHECK-NEXT: (local.get $4) | ||
|
Member
Author
There was a problem hiding this comment. Choose a reason for hiding this commentThe reason will be displayed to describe this comment to others. Learn more. These changes are what I meant in the second paragraph - |
||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (ref.null none) | ||
| ;; CHECK-NEXT: ) | ||
|
|
@@ -2680,6 +2690,7 @@ | |
| (struct.new $A | ||
| (ref.null none) | ||
| ) | ||
| (i32.const 1) | ||
| ) | ||
| ) | ||
| ) | ||
|
|
@@ -2688,16 +2699,24 @@ | |
|
|
||
| ;; CHECK: (func $cast-success (type $1) (result anyref) | ||
| ;; CHECK-NEXT: (local $0 (ref $A)) | ||
| ;; CHECK-NEXT: (local $1 (ref $A)) | ||
| ;; CHECK-NEXT: (local $1 i32) | ||
| ;; CHECK-NEXT: (local $2 (ref $A)) | ||
| ;; CHECK-NEXT: (local $3 i32) | ||
| ;; CHECK-NEXT: (drop | ||
| ;; CHECK-NEXT: (block (result nullref) | ||
| ;; CHECK-NEXT: (local.set $1 | ||
| ;; CHECK-NEXT: (local.set $2 | ||
| ;; CHECK-NEXT: (struct.new $A | ||
| ;; CHECK-NEXT: (ref.null none) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (local.set $3 | ||
| ;; CHECK-NEXT: (i32.const 1) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (local.set $0 | ||
| ;; CHECK-NEXT: (local.get $1) | ||
| ;; CHECK-NEXT: (local.get $2) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (local.set $1 | ||
| ;; CHECK-NEXT: (local.get $3) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (ref.null none) | ||
| ;; CHECK-NEXT: ) | ||
|
|
@@ -2711,25 +2730,80 @@ | |
| (struct.new $A | ||
| (ref.null none) | ||
| ) | ||
| (i32.const 1) | ||
| ) | ||
| ) | ||
| ) | ||
| ) | ||
| ;; CHECK: (func $cast-failure (type $1) (result anyref) | ||
| ;; CHECK-NEXT: (struct.get $B 0 | ||
| ;; CHECK-NEXT: (ref.cast (ref $B) | ||
| ;; CHECK-NEXT: (struct.new $A | ||
| ;; CHECK-NEXT: (struct.new $A | ||
| ;; CHECK-NEXT: (ref.null none) | ||
| ;; CHECK-NEXT: (local $0 (ref null $A)) | ||
| ;; CHECK-NEXT: (local $1 (ref null $A)) | ||
| ;; CHECK-NEXT: (block ;; (replaces unreachable StructGet we can't emit) | ||
| ;; CHECK-NEXT: (drop | ||
| ;; CHECK-NEXT: (block | ||
| ;; CHECK-NEXT: (drop | ||
| ;; CHECK-NEXT: (block (result nullref) | ||
| ;; CHECK-NEXT: (local.set $1 | ||
| ;; CHECK-NEXT: (struct.new $A | ||
| ;; CHECK-NEXT: (ref.null none) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (local.set $0 | ||
| ;; CHECK-NEXT: (local.get $1) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (ref.null none) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (unreachable) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (unreachable) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: ) | ||
| (func $cast-failure (result anyref) | ||
| (struct.get $B 0 | ||
| ;; The allocated $A arrives here, but the cast will fail, so we do not | ||
| ;; optimize. | ||
| ;; The allocated $A arrives here, but the cast will fail. We can remove | ||
| ;; the allocation and put an unreachable here. (Note that the inner | ||
| ;; struct.new survives, which would take another cycle to remove.) | ||
| (ref.cast (ref $B) | ||
| (struct.new $A | ||
| (struct.new $A | ||
| (ref.null none) | ||
| ) | ||
| ) | ||
| ) | ||
| ) | ||
| ) | ||
|
|
||
| ;; CHECK: (func $cast-failure-nofield (type $3) (result i32) | ||
| ;; CHECK-NEXT: (local $0 (ref null $A)) | ||
| ;; CHECK-NEXT: (local $1 (ref null $A)) | ||
| ;; CHECK-NEXT: (block ;; (replaces unreachable StructGet we can't emit) | ||
| ;; CHECK-NEXT: (drop | ||
| ;; CHECK-NEXT: (block | ||
| ;; CHECK-NEXT: (drop | ||
| ;; CHECK-NEXT: (block (result nullref) | ||
| ;; CHECK-NEXT: (local.set $1 | ||
| ;; CHECK-NEXT: (struct.new $A | ||
| ;; CHECK-NEXT: (ref.null none) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (local.set $0 | ||
| ;; CHECK-NEXT: (local.get $1) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (ref.null none) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (unreachable) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: (unreachable) | ||
| ;; CHECK-NEXT: ) | ||
| ;; CHECK-NEXT: ) | ||
| (func $cast-failure-nofield (result i32) | ||
| ;; As above, but we read from a field that only exists in $B, despite the | ||
| ;; allocation that flows here being an $A. We should not error on that. | ||
| (struct.get $B 1 ;; this changes from 0 to 1 | ||
| (ref.cast (ref $B) | ||
| (struct.new $A | ||
| (struct.new $A | ||
|
|
||
Add this suggestion to a batch that can be applied as a single commit.
This suggestion is invalid because no changes were made to the code.
Suggestions cannot be applied while the pull request is closed.
Suggestions cannot be applied while viewing a subset of changes.
Only one suggestion per line can be applied in a batch.
Add this suggestion to a batch that can be applied as a single commit.
Applying suggestions on deleted lines is not supported.
You must change the existing code in this line in order to create a valid suggestion.
Outdated suggestions cannot be applied.
This suggestion has been applied or marked resolved.
Suggestions cannot be applied from pending reviews.
Suggestions cannot be applied on multi-line comments.
Suggestions cannot be applied while the pull request is queued to merge.
Suggestion cannot be applied right now. Please check back later.
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Even if the cast is known to succeed, we might still need it to make the static types work out, right? This replacement is only valid ifcurr->ref->typeis a subtype ofcurr->type, not necessarily ifallocation->typeis a subtype.This isn't a new issue, so I must be missing something that makes this safe.Aha, it's because we're going to remove the allocation entirely. This is worth a comment!
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Sounds good, I added a comment.