Skip to content

Commit fc6a797

Browse files
authored
[Custom Descriptors] Consider desc effects in HeapStoreOptimization (#7772)
HeapStoreOptimization moves subsequent sets back into initial allocations, so it must ensure the set values can be reordered before all of the original set values that it will precede. If the allocation has a descriptor operand, then the set value must be reordered before that as well, but we were not checking that operand for effects. Fix it.
1 parent 15b4ffd commit fc6a797

File tree

2 files changed

+62
-9
lines changed

2 files changed

+62
-9
lines changed

src/passes/HeapStoreOptimization.cpp

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -248,6 +248,16 @@ struct HeapStoreOptimization
248248
}
249249
}
250250

251+
// Similarly, we must move the set's value past the allocation's descriptor,
252+
// if it exists.
253+
if (new_->desc) {
254+
auto descEffects = effects(new_->desc);
255+
if (descEffects.invalidates(setValueEffects)) {
256+
// TODO: we could use locals to reorder everything
257+
return false;
258+
}
259+
}
260+
251261
// We also cannot reorder if the struct.new itself has effects (which it can
252262
// in the case of a descriptor) that interact with X' (from the comment
253263
// above), as e.g. a struct.new trap happens before effects in X', but after

test/lit/passes/heap-store-optimization-desc.wast

Lines changed: 52 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,15 +6,17 @@
66
(rec
77
;; CHECK: (rec
88
;; CHECK-NEXT: (type $struct (descriptor $desc (struct (field (mut i32)))))
9-
(type $struct (sub final (descriptor $desc (struct (field (mut i32))))))
10-
;; CHECK: (type $desc (sub (describes $struct (struct))))
11-
(type $desc (sub (describes $struct (struct))))
9+
(type $struct (descriptor $desc (struct (field (mut i32)))))
10+
;; CHECK: (type $desc (describes $struct (descriptor $meta (struct))))
11+
(type $desc (describes $struct (descriptor $meta (struct))))
12+
;; CHECK: (type $meta (describes $desc (struct)))
13+
(type $meta (describes $desc (struct)))
1214
)
1315

14-
;; CHECK: (import "" "" (func $effect (type $2)))
16+
;; CHECK: (import "" "" (func $effect (type $3)))
1517
(import "" "" (func $effect))
1618

17-
;; CHECK: (func $no-reorder (type $2)
19+
;; CHECK: (func $no-reorder (type $3)
1820
;; CHECK-NEXT: (local $struct (ref $struct))
1921
;; CHECK-NEXT: (local.set $struct
2022
;; CHECK-NEXT: (struct.new_default $struct
@@ -47,25 +49,66 @@
4749
)
4850
)
4951

50-
;; CHECK: (func $yes-reorder (type $2)
52+
;; CHECK: (func $no-reorder-nested (type $3)
53+
;; CHECK-NEXT: (local $struct (ref $struct))
54+
;; CHECK-NEXT: (local.set $struct
55+
;; CHECK-NEXT: (struct.new_default $struct
56+
;; CHECK-NEXT: (struct.new_default $desc
57+
;; CHECK-NEXT: (ref.null none)
58+
;; CHECK-NEXT: )
59+
;; CHECK-NEXT: )
60+
;; CHECK-NEXT: )
61+
;; CHECK-NEXT: (struct.set $struct 0
62+
;; CHECK-NEXT: (local.get $struct)
63+
;; CHECK-NEXT: (block $block (result i32)
64+
;; CHECK-NEXT: (call $effect)
65+
;; CHECK-NEXT: (i32.const 0)
66+
;; CHECK-NEXT: )
67+
;; CHECK-NEXT: )
68+
;; CHECK-NEXT: )
69+
(func $no-reorder-nested
70+
(local $struct (ref $struct))
71+
;; As above, but now it is not the top-level allocation that traps, but
72+
;; rather its descriptor operand. We still cannot optimize.
73+
(local.set $struct
74+
(struct.new_default $struct
75+
(struct.new $desc
76+
(ref.null none)
77+
)
78+
)
79+
)
80+
(struct.set $struct 0
81+
(local.get $struct)
82+
(block $block (result i32)
83+
(call $effect)
84+
(i32.const 0)
85+
)
86+
)
87+
)
88+
89+
;; CHECK: (func $yes-reorder (type $3)
5190
;; CHECK-NEXT: (local $struct (ref $struct))
5291
;; CHECK-NEXT: (local.set $struct
5392
;; CHECK-NEXT: (struct.new $struct
5493
;; CHECK-NEXT: (block $block (result i32)
5594
;; CHECK-NEXT: (call $effect)
5695
;; CHECK-NEXT: (i32.const 0)
5796
;; CHECK-NEXT: )
58-
;; CHECK-NEXT: (struct.new_default $desc)
97+
;; CHECK-NEXT: (struct.new_default $desc
98+
;; CHECK-NEXT: (struct.new_default $meta)
99+
;; CHECK-NEXT: )
59100
;; CHECK-NEXT: )
60101
;; CHECK-NEXT: )
61102
;; CHECK-NEXT: (nop)
62103
;; CHECK-NEXT: )
63104
(func $yes-reorder
64105
(local $struct (ref $struct))
65-
;; As above, but now the descriptor does not trap, so we optimize.
106+
;; Nothing traps, so we can reorder.
66107
(local.set $struct
67108
(struct.new_default $struct
68-
(struct.new $desc)
109+
(struct.new $desc
110+
(struct.new $meta)
111+
)
69112
)
70113
)
71114
(struct.set $struct 0

0 commit comments

Comments
 (0)