Skip to content

Commit e006ccc

Browse files
authored
Asyncify: Allow specifying the external memory (#7125)
This is important for multi-memory.
1 parent 09300e4 commit e006ccc

File tree

2 files changed

+147
-2
lines changed

2 files changed

+147
-2
lines changed

src/passes/Asyncify.cpp

Lines changed: 23 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -244,6 +244,10 @@
244244
// Logs out instrumentation decisions to the console. This can help figure
245245
// out why a certain function was instrumented.
246246
//
247+
// --pass-arg=asyncify-memory@memory
248+
// Picks which exported memory of the module to store and load data from
249+
// and to (useful if the module contains multiple memories).
250+
//
247251
// For manual fine-tuning of the list of instrumented functions, there are lists
248252
// that you can set. These must be used carefully, as misuse can break your
249253
// application - for example, if a function is called that should be
@@ -1648,14 +1652,31 @@ struct Asyncify : public Pass {
16481652
auto propagateAddList = hasArgument("asyncify-propagate-addlist");
16491653

16501654
// Ensure there is a memory, as we need it.
1655+
16511656
if (secondaryMemory) {
16521657
auto secondaryMemorySizeString =
16531658
getArgumentOrDefault("asyncify-secondary-memory-size", "1");
16541659
Address secondaryMemorySize = std::stoi(secondaryMemorySizeString);
16551660
asyncifyMemory = createSecondaryMemory(module, secondaryMemorySize);
16561661
} else {
1657-
MemoryUtils::ensureExists(module);
1658-
asyncifyMemory = module->memories[0]->name;
1662+
if (module->memories.size() <= 1) {
1663+
MemoryUtils::ensureExists(module);
1664+
asyncifyMemory = module->memories[0]->name;
1665+
} else {
1666+
auto asyncifyMemoryValue =
1667+
getArgumentOrDefault("asyncify-memory", "memory");
1668+
for (auto& theExport : module->exports) {
1669+
if (theExport->kind == ExternalKind::Memory &&
1670+
theExport->name == asyncifyMemoryValue) {
1671+
asyncifyMemory = theExport->value;
1672+
break;
1673+
}
1674+
}
1675+
if (!asyncifyMemory) {
1676+
Fatal() << "Please specify which of the multiple memories to use, "
1677+
"with --pass-arg=asyncify-memory@memory";
1678+
}
1679+
}
16591680
}
16601681
pointerType =
16611682
module->getMemory(asyncifyMemory)->is64() ? Type::i64 : Type::i32;

test/lit/passes/[email protected]

Lines changed: 124 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,124 @@
1+
;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited.
2+
3+
;; RUN: foreach %s %t wasm-opt --enable-multimemory --enable-mutable-globals --asyncify --pass-arg=asyncify-memory@memory -S -o - | filecheck %s
4+
5+
;; This test checks that the asyncify-memory argument can pick which memory to use in asyncify.
6+
(module
7+
;; CHECK: (type $0 (func (param i32)))
8+
9+
;; CHECK: (type $1 (func))
10+
11+
;; CHECK: (type $2 (func (result i32)))
12+
13+
;; CHECK: (global $__asyncify_state (mut i32) (i32.const 0))
14+
15+
;; CHECK: (global $__asyncify_data (mut i32) (i32.const 0))
16+
17+
;; CHECK: (memory $unused0 1 1)
18+
(memory $unused0 (export "unused0") 1 1)
19+
;; CHECK: (memory $mem 1 1)
20+
(memory $mem (export "memory") 1 1)
21+
;; CHECK: (memory $ignore 1 1)
22+
(memory $ignore (export "unused") 1 1)
23+
)
24+
;; CHECK: (export "unused0" (memory $unused0))
25+
26+
;; CHECK: (export "memory" (memory $mem))
27+
28+
;; CHECK: (export "unused" (memory $ignore))
29+
30+
;; CHECK: (export "asyncify_start_unwind" (func $asyncify_start_unwind))
31+
32+
;; CHECK: (export "asyncify_stop_unwind" (func $asyncify_stop_unwind))
33+
34+
;; CHECK: (export "asyncify_start_rewind" (func $asyncify_start_rewind))
35+
36+
;; CHECK: (export "asyncify_stop_rewind" (func $asyncify_stop_rewind))
37+
38+
;; CHECK: (export "asyncify_get_state" (func $asyncify_get_state))
39+
40+
;; CHECK: (func $asyncify_start_unwind (param $0 i32)
41+
;; CHECK-NEXT: (global.set $__asyncify_state
42+
;; CHECK-NEXT: (i32.const 1)
43+
;; CHECK-NEXT: )
44+
;; CHECK-NEXT: (global.set $__asyncify_data
45+
;; CHECK-NEXT: (local.get $0)
46+
;; CHECK-NEXT: )
47+
;; CHECK-NEXT: (if
48+
;; CHECK-NEXT: (i32.gt_u
49+
;; CHECK-NEXT: (i32.load $mem
50+
;; CHECK-NEXT: (global.get $__asyncify_data)
51+
;; CHECK-NEXT: )
52+
;; CHECK-NEXT: (i32.load $mem offset=4
53+
;; CHECK-NEXT: (global.get $__asyncify_data)
54+
;; CHECK-NEXT: )
55+
;; CHECK-NEXT: )
56+
;; CHECK-NEXT: (then
57+
;; CHECK-NEXT: (unreachable)
58+
;; CHECK-NEXT: )
59+
;; CHECK-NEXT: )
60+
;; CHECK-NEXT: )
61+
62+
;; CHECK: (func $asyncify_stop_unwind
63+
;; CHECK-NEXT: (global.set $__asyncify_state
64+
;; CHECK-NEXT: (i32.const 0)
65+
;; CHECK-NEXT: )
66+
;; CHECK-NEXT: (if
67+
;; CHECK-NEXT: (i32.gt_u
68+
;; CHECK-NEXT: (i32.load $mem
69+
;; CHECK-NEXT: (global.get $__asyncify_data)
70+
;; CHECK-NEXT: )
71+
;; CHECK-NEXT: (i32.load $mem offset=4
72+
;; CHECK-NEXT: (global.get $__asyncify_data)
73+
;; CHECK-NEXT: )
74+
;; CHECK-NEXT: )
75+
;; CHECK-NEXT: (then
76+
;; CHECK-NEXT: (unreachable)
77+
;; CHECK-NEXT: )
78+
;; CHECK-NEXT: )
79+
;; CHECK-NEXT: )
80+
81+
;; CHECK: (func $asyncify_start_rewind (param $0 i32)
82+
;; CHECK-NEXT: (global.set $__asyncify_state
83+
;; CHECK-NEXT: (i32.const 2)
84+
;; CHECK-NEXT: )
85+
;; CHECK-NEXT: (global.set $__asyncify_data
86+
;; CHECK-NEXT: (local.get $0)
87+
;; CHECK-NEXT: )
88+
;; CHECK-NEXT: (if
89+
;; CHECK-NEXT: (i32.gt_u
90+
;; CHECK-NEXT: (i32.load $mem
91+
;; CHECK-NEXT: (global.get $__asyncify_data)
92+
;; CHECK-NEXT: )
93+
;; CHECK-NEXT: (i32.load $mem offset=4
94+
;; CHECK-NEXT: (global.get $__asyncify_data)
95+
;; CHECK-NEXT: )
96+
;; CHECK-NEXT: )
97+
;; CHECK-NEXT: (then
98+
;; CHECK-NEXT: (unreachable)
99+
;; CHECK-NEXT: )
100+
;; CHECK-NEXT: )
101+
;; CHECK-NEXT: )
102+
103+
;; CHECK: (func $asyncify_stop_rewind
104+
;; CHECK-NEXT: (global.set $__asyncify_state
105+
;; CHECK-NEXT: (i32.const 0)
106+
;; CHECK-NEXT: )
107+
;; CHECK-NEXT: (if
108+
;; CHECK-NEXT: (i32.gt_u
109+
;; CHECK-NEXT: (i32.load $mem
110+
;; CHECK-NEXT: (global.get $__asyncify_data)
111+
;; CHECK-NEXT: )
112+
;; CHECK-NEXT: (i32.load $mem offset=4
113+
;; CHECK-NEXT: (global.get $__asyncify_data)
114+
;; CHECK-NEXT: )
115+
;; CHECK-NEXT: )
116+
;; CHECK-NEXT: (then
117+
;; CHECK-NEXT: (unreachable)
118+
;; CHECK-NEXT: )
119+
;; CHECK-NEXT: )
120+
;; CHECK-NEXT: )
121+
122+
;; CHECK: (func $asyncify_get_state (result i32)
123+
;; CHECK-NEXT: (global.get $__asyncify_state)
124+
;; CHECK-NEXT: )

0 commit comments

Comments
 (0)