Skip to content

Commit b89d65a

Browse files
authored
[Custom Descriptors] Optimize struct.new (#7691)
Optimize struct.new instructions that are known to trap due to having null descriptors. Also optimize out non-null casts of descriptors, since struct.new will implicitly perform that cast.
1 parent 48d11fd commit b89d65a

File tree

3 files changed

+64
-1
lines changed

3 files changed

+64
-1
lines changed

scripts/test/fuzzing.py

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -126,6 +126,7 @@
126126
'precompute-desc.wast',
127127
'gc-desc.wast',
128128
'simplify-locals-desc.wast',
129+
'optimize-instructions-desc.wast',
129130
# TODO: fix split_wast() on tricky escaping situations like a string ending
130131
# in \\" (the " is not escaped - there is an escaped \ before it)
131132
'string-lifting-section.wast',

src/passes/OptimizeInstructions.cpp

Lines changed: 10 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -1830,9 +1830,18 @@ struct OptimizeInstructions
18301830
}
18311831

18321832
void visitStructNew(StructNew* curr) {
1833+
if (curr->type == Type::unreachable) {
1834+
// Leave this for DCE.
1835+
return;
1836+
}
1837+
if (curr->desc) {
1838+
skipNonNullCast(curr->desc, curr);
1839+
trapOnNull(curr, curr->desc);
1840+
}
1841+
18331842
// If values are provided, but they are all the default, then we can remove
18341843
// them (in reachable code).
1835-
if (curr->type == Type::unreachable || curr->isWithDefault()) {
1844+
if (curr->isWithDefault()) {
18361845
return;
18371846
}
18381847

Lines changed: 53 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,53 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py and should not be edited.
2+
3+
;; RUN: wasm-opt %s -all --optimize-instructions -S -o - | filecheck %s
4+
5+
(module
6+
(rec
7+
;; CHECK: (rec
8+
;; CHECK-NEXT: (type $struct (descriptor $desc (struct)))
9+
(type $struct (descriptor $desc (struct)))
10+
;; CHECK: (type $desc (describes $struct (struct)))
11+
(type $desc (describes $struct (struct)))
12+
)
13+
14+
;; CHECK: (func $trap-null-desc (type $2) (result (ref (exact $struct)))
15+
;; CHECK-NEXT: (unreachable)
16+
;; CHECK-NEXT: )
17+
(func $trap-null-desc (result (ref (exact $struct)))
18+
(struct.new $struct
19+
(ref.null none)
20+
)
21+
)
22+
23+
;; CHECK: (func $trap-null-desc-fallthrough (type $2) (result (ref (exact $struct)))
24+
;; CHECK-NEXT: (local $desc (ref null (exact $desc)))
25+
;; CHECK-NEXT: (drop
26+
;; CHECK-NEXT: (local.tee $desc
27+
;; CHECK-NEXT: (ref.null none)
28+
;; CHECK-NEXT: )
29+
;; CHECK-NEXT: )
30+
;; CHECK-NEXT: (unreachable)
31+
;; CHECK-NEXT: )
32+
(func $trap-null-desc-fallthrough (result (ref (exact $struct)))
33+
(local $desc (ref null (exact $desc)))
34+
(struct.new $struct
35+
(local.tee $desc
36+
(ref.null none)
37+
)
38+
)
39+
)
40+
41+
;; CHECK: (func $nonnull-cast-desc (type $3) (param $desc (ref null (exact $desc))) (result (ref (exact $struct)))
42+
;; CHECK-NEXT: (struct.new_default $struct
43+
;; CHECK-NEXT: (local.get $desc)
44+
;; CHECK-NEXT: )
45+
;; CHECK-NEXT: )
46+
(func $nonnull-cast-desc (param $desc (ref null (exact $desc))) (result (ref (exact $struct)))
47+
(struct.new $struct
48+
(ref.as_non_null
49+
(local.get $desc)
50+
)
51+
)
52+
)
53+
)

0 commit comments

Comments
 (0)