Skip to content

Commit d1cd2cf

Browse files
authored
Skip continuation types in SignatureRefining (#8438)
SignatureRefining has no knowledge of stack switching instructions or types, so it would go ahead and optimize function types used in stack switching instructions even if that made the stack switching usage invalid. Simplify avoid optimizing those types for now.
1 parent a349643 commit d1cd2cf

File tree

2 files changed

+87
-0
lines changed

2 files changed

+87
-0
lines changed

src/passes/SignatureRefining.cpp

Lines changed: 11 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -168,6 +168,17 @@ struct SignatureRefining : public Pass {
168168
false;
169169
}
170170

171+
// Continuations must not have params refined, because we do not update
172+
// their users (e.g. cont.bind, resume) with new types.
173+
// TODO: support refining continuations
174+
if (module->features.hasStackSwitching()) {
175+
for (auto type : ModuleUtils::collectHeapTypes(*module)) {
176+
if (type.isContinuation()) {
177+
allInfo[type.getContinuation().type].canModifyParams = false;
178+
}
179+
}
180+
}
181+
171182
// Also skip modifying types used in tags, even private tags, since we don't
172183
// analyze exception handling or stack switching instructions. TODO: Analyze
173184
// and optimize exception handling and stack switching instructions.

test/lit/passes/signature-refining.wast

Lines changed: 76 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1180,3 +1180,79 @@
11801180
)
11811181
)
11821182
)
1183+
1184+
(module
1185+
;; If a signature is used in a continuation, we cannot refine its parameters,
1186+
;; as we do not yet support updating continuation instructions with new types.
1187+
(rec
1188+
;; CHECK: (rec
1189+
;; CHECK-NEXT: (type $cont (cont $sig))
1190+
1191+
;; CHECK: (type $1 (func))
1192+
1193+
;; CHECK: (type $other (func (param nullref)))
1194+
1195+
;; CHECK: (type $sig (func (param anyref)))
1196+
(type $sig (func (param anyref)))
1197+
(type $other (func (param anyref)))
1198+
(type $cont (cont $sig))
1199+
)
1200+
;; CHECK: (elem declare func $cont $not-cont $other)
1201+
1202+
;; CHECK: (func $cont (type $sig) (param $0 anyref)
1203+
;; CHECK-NEXT: (nop)
1204+
;; CHECK-NEXT: )
1205+
(func $cont (type $sig) (param anyref)
1206+
(nop)
1207+
)
1208+
1209+
;; CHECK: (func $not-cont (type $sig) (param $0 anyref)
1210+
;; CHECK-NEXT: (nop)
1211+
;; CHECK-NEXT: )
1212+
(func $not-cont (type $sig) (param anyref)
1213+
;; This function cannot be optimized even though it is not used in a
1214+
;; continuation. It is enough that it shares a type with a continuation
1215+
;;function.
1216+
(nop)
1217+
)
1218+
1219+
;; CHECK: (func $other (type $other) (param $0 nullref)
1220+
;; CHECK-NEXT: (nop)
1221+
;; CHECK-NEXT: )
1222+
(func $other (type $other) (param anyref)
1223+
;; This function uses a different type, so it can be optimized.
1224+
(nop)
1225+
)
1226+
1227+
1228+
;; CHECK: (func $test (type $1)
1229+
;; CHECK-NEXT: (drop
1230+
;; CHECK-NEXT: (cont.new $cont
1231+
;; CHECK-NEXT: (ref.func $cont)
1232+
;; CHECK-NEXT: )
1233+
;; CHECK-NEXT: )
1234+
;; CHECK-NEXT: (call_ref $sig
1235+
;; CHECK-NEXT: (ref.null none)
1236+
;; CHECK-NEXT: (ref.func $not-cont)
1237+
;; CHECK-NEXT: )
1238+
;; CHECK-NEXT: (call_ref $other
1239+
;; CHECK-NEXT: (ref.null none)
1240+
;; CHECK-NEXT: (ref.func $other)
1241+
;; CHECK-NEXT: )
1242+
;; CHECK-NEXT: )
1243+
(func $test
1244+
(drop
1245+
(cont.new $cont
1246+
(ref.func $cont)
1247+
)
1248+
)
1249+
(call_ref $sig
1250+
(ref.null none)
1251+
(ref.func $not-cont)
1252+
)
1253+
(call_ref $other
1254+
(ref.null none)
1255+
(ref.func $other)
1256+
)
1257+
)
1258+
)

0 commit comments

Comments
 (0)