summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2020-06-23 09:20:50 -0700
committerGitHub <noreply@github.com>2020-06-23 09:20:50 -0700
commit92423bebfc267373b28f5cf8c28e5711767adb4c (patch)
tree8676095dabcaeda54da8dc9c01871e525f5ba5ce
parent63e580f737352d877fb90b4efca2eee89d780755 (diff)
downloadbinaryen-92423bebfc267373b28f5cf8c28e5711767adb4c.tar.gz
binaryen-92423bebfc267373b28f5cf8c28e5711767adb4c.tar.bz2
binaryen-92423bebfc267373b28f5cf8c28e5711767adb4c.zip
Asyncify liveness analysis (#2890)
This finds out which locals are live at call sites that might pause/resume, which is the set of locals we need to actually save/load. That is, if a local is not alive at any call site in the function, then it's value doesn't need to stay alive while sleeping. This saves about 10% of locals that are saved/loaded, and about 1.5% in final code size.
-rwxr-xr-xscripts/fuzz_opt.py4
-rw-r--r--src/passes/Asyncify.cpp70
-rw-r--r--test/passes/asyncify.txt1261
-rw-r--r--test/passes/asyncify.wast53
-rw-r--r--test/passes/asyncify_enable-multivalue.txt413
-rw-r--r--test/passes/asyncify_mod-asyncify-always-and-only-unwind.txt42
-rw-r--r--test/passes/asyncify_mod-asyncify-never-unwind.txt42
-rw-r--r--test/passes/asyncify_optimize-level=1.txt200
-rw-r--r--test/passes/asyncify_pass-arg=asyncify-ignore-imports.txt15
-rw-r--r--test/passes/asyncify_pass-arg=asyncify-ignore-indirect.txt24
-rw-r--r--test/passes/asyncify_pass-arg=asyncify-imports@env.import,env.import2.txt183
11 files changed, 1453 insertions, 854 deletions
diff --git a/scripts/fuzz_opt.py b/scripts/fuzz_opt.py
index 76d97bd2e..9c8af1106 100755
--- a/scripts/fuzz_opt.py
+++ b/scripts/fuzz_opt.py
@@ -545,10 +545,6 @@ class Asyncify(TestCaseHandler):
print('ignoring due to pre-asyncify difference')
return
- # TODO: also something that actually does async sleeps in the code, say
- # on the logging commands?
- # --remove-unused-module-elements removes the asyncify intrinsics, which are not valid to call
-
def do_asyncify(wasm):
cmd = [in_bin('wasm-opt'), wasm, '--asyncify', '-o', 'async.t.wasm']
# if we allow NaNs, running binaryen optimizations and then
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp
index 2708ae4e0..d4a788adb 100644
--- a/src/passes/Asyncify.cpp
+++ b/src/passes/Asyncify.cpp
@@ -291,6 +291,7 @@
// of their original range.
//
+#include "cfg/liveness-traversal.h"
#include "ir/effects.h"
#include "ir/find_all.h"
#include "ir/literal-utils.h"
@@ -1149,8 +1150,9 @@ struct AsyncifyLocals : public WalkerPass<PostWalker<AsyncifyLocals>> {
if (!analyzer->needsInstrumentation(func)) {
return;
}
- // Note the locals we want to preserve, before we add any more helpers.
- numPreservableLocals = func->getNumLocals();
+ // Find the locals that we actually need to load and save: any local that is
+ // alive at a relevant call site must be handled, but others can be ignored.
+ findRelevantLiveLocals(func);
// The new function body has a prelude to load locals if rewinding,
// then the actual main body, which does all its unwindings by breaking
// to the unwind block, which then handles pushing the call index, as
@@ -1198,16 +1200,61 @@ private:
std::unique_ptr<AsyncifyBuilder> builder;
Index rewindIndex;
- Index numPreservableLocals;
std::map<Type, Index> fakeCallLocals;
+ std::set<Index> relevantLiveLocals;
+
+ void findRelevantLiveLocals(Function* func) {
+ struct RelevantLiveLocalsWalker
+ : public LivenessWalker<RelevantLiveLocalsWalker,
+ Visitor<RelevantLiveLocalsWalker>> {
+ // Basic blocks that have a possible unwind/rewind in them.
+ std::set<BasicBlock*> relevantBasicBlocks;
+
+ void visitCall(Call* curr) {
+ if (!currBasicBlock) {
+ return;
+ }
+ // Note blocks where we might unwind/rewind, all of which have a
+ // possible call to ASYNCIFY_CHECK_CALL_INDEX emitted right before the
+ // actual call.
+ // Note that each relevant original call was turned into a sequence of
+ // instructions, one of which is an if and then a call to this special
+ // intrinsic. We rely on the fact that if a local was live at the
+ // original call, it also would be in all that sequence of instructions,
+ // and in particular at the call we look for here (which is right before
+ // the call, and so anything that has its final use at the call is still
+ // live here).
+ if (curr->target == ASYNCIFY_CHECK_CALL_INDEX) {
+ relevantBasicBlocks.insert(currBasicBlock);
+ }
+ }
+ };
+
+ RelevantLiveLocalsWalker walker;
+ walker.walkFunctionInModule(func, getModule());
+ // The relevant live locals are ones that are alive at an unwind/rewind
+ // location. TODO look more precisely inside basic blocks, as one might stop
+ // being live in the middle
+ for (auto* block : walker.liveBlocks) {
+ if (walker.relevantBasicBlocks.count(block)) {
+ for (auto local : block->contents.start) {
+ relevantLiveLocals.insert(local);
+ }
+ }
+ }
+ }
Expression* makeLocalLoading() {
- if (numPreservableLocals == 0) {
+ if (relevantLiveLocals.empty()) {
return builder->makeNop();
}
auto* func = getFunction();
+ auto numLocals = func->getNumLocals();
Index total = 0;
- for (Index i = 0; i < numPreservableLocals; i++) {
+ for (Index i = 0; i < numLocals; i++) {
+ if (!relevantLiveLocals.count(i)) {
+ continue;
+ }
total += func->getLocalType(i).getByteSize();
}
auto* block = builder->makeBlock();
@@ -1216,7 +1263,10 @@ private:
block->list.push_back(
builder->makeLocalSet(tempIndex, builder->makeGetStackPos()));
Index offset = 0;
- for (Index i = 0; i < numPreservableLocals; i++) {
+ for (Index i = 0; i < numLocals; i++) {
+ if (!relevantLiveLocals.count(i)) {
+ continue;
+ }
const auto& types = func->getLocalType(i).expand();
SmallVector<Expression*, 1> loads;
for (Index j = 0; j < types.size(); j++) {
@@ -1248,16 +1298,20 @@ private:
}
Expression* makeLocalSaving() {
- if (numPreservableLocals == 0) {
+ if (relevantLiveLocals.empty()) {
return builder->makeNop();
}
auto* func = getFunction();
+ auto numLocals = func->getNumLocals();
auto* block = builder->makeBlock();
auto tempIndex = builder->addVar(func, Type::i32);
block->list.push_back(
builder->makeLocalSet(tempIndex, builder->makeGetStackPos()));
Index offset = 0;
- for (Index i = 0; i < numPreservableLocals; i++) {
+ for (Index i = 0; i < numLocals; i++) {
+ if (!relevantLiveLocals.count(i)) {
+ continue;
+ }
auto localType = func->getLocalType(i);
const auto& types = localType.expand();
for (Index j = 0; j < types.size(); j++) {
diff --git a/test/passes/asyncify.txt b/test/passes/asyncify.txt
new file mode 100644
index 000000000..4137c946c
--- /dev/null
+++ b/test/passes/asyncify.txt
@@ -0,0 +1,1261 @@
+(module
+ (type $i32_=>_none (func (param i32)))
+ (type $i32_i32_=>_none (func (param i32 i32)))
+ (type $none_=>_none (func))
+ (type $none_=>_i32 (func (result i32)))
+ (import "env" "import" (func $import))
+ (import "env" "import2" (func $import2 (param i32)))
+ (memory $0 1 2)
+ (table $0 2 2 funcref)
+ (elem (i32.const 0) $liveness2 $liveness2)
+ (global $__asyncify_state (mut i32) (i32.const 0))
+ (global $__asyncify_data (mut i32) (i32.const 0))
+ (export "asyncify_start_unwind" (func $asyncify_start_unwind))
+ (export "asyncify_stop_unwind" (func $asyncify_stop_unwind))
+ (export "asyncify_start_rewind" (func $asyncify_start_rewind))
+ (export "asyncify_stop_rewind" (func $asyncify_stop_rewind))
+ (export "asyncify_get_state" (func $asyncify_get_state))
+ (func $liveness1 (param $live0 i32) (param $dead0 i32)
+ (local $live1 i32)
+ (local $dead1 i32)
+ (local $4 i32)
+ (local $5 i32)
+ (local $6 i32)
+ (local $7 i32)
+ (local $8 i32)
+ (local $9 i32)
+ (local $10 i32)
+ (local $11 i32)
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (block
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const -8)
+ )
+ )
+ (local.set $10
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ (local.set $live0
+ (i32.load
+ (local.get $10)
+ )
+ )
+ (local.set $live1
+ (i32.load offset=4
+ (local.get $10)
+ )
+ )
+ )
+ )
+ (local.set $8
+ (block $__asyncify_unwind (result i32)
+ (block
+ (block
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (block
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const -4)
+ )
+ )
+ (local.set $9
+ (i32.load
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (block
+ (local.set $4
+ (local.get $dead0)
+ )
+ (drop
+ (local.get $4)
+ )
+ (local.set $5
+ (local.get $dead1)
+ )
+ (drop
+ (local.get $5)
+ )
+ )
+ )
+ (nop)
+ (nop)
+ (nop)
+ (if
+ (if (result i32)
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (i32.const 1)
+ (i32.eq
+ (local.get $9)
+ (i32.const 0)
+ )
+ )
+ (block
+ (call $import)
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 1)
+ )
+ (br $__asyncify_unwind
+ (i32.const 0)
+ )
+ )
+ )
+ )
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (block
+ (local.set $6
+ (local.get $live0)
+ )
+ (drop
+ (local.get $6)
+ )
+ (local.set $7
+ (local.get $live1)
+ )
+ (drop
+ (local.get $7)
+ )
+ )
+ )
+ (nop)
+ (nop)
+ (nop)
+ )
+ )
+ (return)
+ )
+ )
+ )
+ (block
+ (i32.store
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (local.get $8)
+ )
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const 4)
+ )
+ )
+ )
+ (block
+ (local.set $11
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ (i32.store
+ (local.get $11)
+ (local.get $live0)
+ )
+ (i32.store offset=4
+ (local.get $11)
+ (local.get $live1)
+ )
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const 8)
+ )
+ )
+ )
+ )
+ (func $liveness2 (param $live0 i32) (param $dead0 i32)
+ (local $live1 i32)
+ (local $dead1 i32)
+ (local $4 i32)
+ (local $5 i32)
+ (local $6 i32)
+ (local $7 i32)
+ (local $8 i32)
+ (local $9 i32)
+ (local $10 i32)
+ (local $11 i32)
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (block
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const -8)
+ )
+ )
+ (local.set $10
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ (local.set $live0
+ (i32.load
+ (local.get $10)
+ )
+ )
+ (local.set $live1
+ (i32.load offset=4
+ (local.get $10)
+ )
+ )
+ )
+ )
+ (local.set $8
+ (block $__asyncify_unwind (result i32)
+ (block
+ (block
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (block
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const -4)
+ )
+ )
+ (local.set $9
+ (i32.load
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (block
+ (local.set $4
+ (local.get $dead0)
+ )
+ (drop
+ (local.get $4)
+ )
+ (local.set $5
+ (local.get $dead1)
+ )
+ (drop
+ (local.get $5)
+ )
+ )
+ )
+ (nop)
+ (nop)
+ (nop)
+ (if
+ (if (result i32)
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (i32.const 1)
+ (i32.eq
+ (local.get $9)
+ (i32.const 0)
+ )
+ )
+ (block
+ (call $import)
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 1)
+ )
+ (br $__asyncify_unwind
+ (i32.const 0)
+ )
+ )
+ )
+ )
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (block
+ (local.set $6
+ (local.get $live0)
+ )
+ (drop
+ (local.get $6)
+ )
+ (local.set $7
+ (local.get $live1)
+ )
+ (drop
+ (local.get $7)
+ )
+ )
+ )
+ (nop)
+ (nop)
+ (nop)
+ )
+ )
+ (return)
+ )
+ )
+ )
+ (block
+ (i32.store
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (local.get $8)
+ )
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const 4)
+ )
+ )
+ )
+ (block
+ (local.set $11
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ (i32.store
+ (local.get $11)
+ (local.get $live0)
+ )
+ (i32.store offset=4
+ (local.get $11)
+ (local.get $live1)
+ )
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const 8)
+ )
+ )
+ )
+ )
+ (func $liveness3 (param $live0 i32) (param $dead0 i32)
+ (local $live1 i32)
+ (local $dead1 i32)
+ (local $4 i32)
+ (local $5 i32)
+ (local $6 i32)
+ (local $7 i32)
+ (local $8 i32)
+ (local $9 i32)
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (block
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const -8)
+ )
+ )
+ (local.set $8
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ (local.set $live0
+ (i32.load
+ (local.get $8)
+ )
+ )
+ (local.set $live1
+ (i32.load offset=4
+ (local.get $8)
+ )
+ )
+ )
+ )
+ (local.set $6
+ (block $__asyncify_unwind (result i32)
+ (block
+ (block
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (block
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const -4)
+ )
+ )
+ (local.set $7
+ (i32.load
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (if
+ (if (result i32)
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (i32.const 1)
+ (i32.eq
+ (local.get $7)
+ (i32.const 0)
+ )
+ )
+ (block
+ (call $import)
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 1)
+ )
+ (br $__asyncify_unwind
+ (i32.const 0)
+ )
+ )
+ )
+ )
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (block
+ (local.set $4
+ (local.get $live0)
+ )
+ (drop
+ (local.get $4)
+ )
+ )
+ )
+ (nop)
+ (if
+ (if (result i32)
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (i32.const 1)
+ (i32.eq
+ (local.get $7)
+ (i32.const 1)
+ )
+ )
+ (block
+ (call $import)
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 1)
+ )
+ (br $__asyncify_unwind
+ (i32.const 1)
+ )
+ )
+ )
+ )
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (block
+ (local.set $5
+ (local.get $live1)
+ )
+ (drop
+ (local.get $5)
+ )
+ )
+ )
+ (nop)
+ )
+ )
+ (return)
+ )
+ )
+ )
+ (block
+ (i32.store
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (local.get $6)
+ )
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const 4)
+ )
+ )
+ )
+ (block
+ (local.set $9
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ (i32.store
+ (local.get $9)
+ (local.get $live0)
+ )
+ (i32.store offset=4
+ (local.get $9)
+ (local.get $live1)
+ )
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const 8)
+ )
+ )
+ )
+ )
+ (func $liveness4 (param $live0 i32) (param $dead0 i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local $4 i32)
+ (local $5 i32)
+ (local $6 i32)
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (block
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const -4)
+ )
+ )
+ (local.set $5
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ (local.set $live0
+ (i32.load
+ (local.get $5)
+ )
+ )
+ )
+ )
+ (local.set $3
+ (block $__asyncify_unwind (result i32)
+ (block
+ (block
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (block
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const -4)
+ )
+ )
+ (local.set $4
+ (i32.load
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (if
+ (i32.or
+ (i32.const 0)
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ )
+ (if
+ (if (result i32)
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (i32.const 1)
+ (i32.eq
+ (local.get $4)
+ (i32.const 0)
+ )
+ )
+ (block
+ (call $import)
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 1)
+ )
+ (br $__asyncify_unwind
+ (i32.const 0)
+ )
+ )
+ )
+ )
+ )
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (block
+ (local.set $2
+ (local.get $live0)
+ )
+ (drop
+ (local.get $2)
+ )
+ )
+ )
+ (nop)
+ )
+ )
+ (return)
+ )
+ )
+ )
+ (block
+ (i32.store
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (local.get $3)
+ )
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const 4)
+ )
+ )
+ )
+ (block
+ (local.set $6
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ (i32.store
+ (local.get $6)
+ (local.get $live0)
+ )
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const 4)
+ )
+ )
+ )
+ )
+ (func $liveness5 (param $dead0 i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local $4 i32)
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (nop)
+ )
+ (local.set $3
+ (block $__asyncify_unwind (result i32)
+ (block
+ (block
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (block
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const -4)
+ )
+ )
+ (local.set $4
+ (i32.load
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (block
+ (local.set $1
+ (local.get $dead0)
+ )
+ (drop
+ (local.get $1)
+ )
+ )
+ )
+ (nop)
+ (if
+ (i32.or
+ (i32.const 0)
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ )
+ (if
+ (if (result i32)
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (i32.const 1)
+ (i32.eq
+ (local.get $4)
+ (i32.const 0)
+ )
+ )
+ (block
+ (call $import)
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 1)
+ )
+ (br $__asyncify_unwind
+ (i32.const 0)
+ )
+ )
+ )
+ )
+ )
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (block
+ (local.set $dead0
+ (i32.const 1)
+ )
+ (local.set $2
+ (local.get $dead0)
+ )
+ (drop
+ (local.get $2)
+ )
+ )
+ )
+ (nop)
+ (nop)
+ )
+ )
+ (return)
+ )
+ )
+ )
+ (block
+ (i32.store
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (local.get $3)
+ )
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const 4)
+ )
+ )
+ )
+ (nop)
+ )
+ (func $liveness-call-kills (param $live i32)
+ (local $1 i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local $4 i32)
+ (local $5 i32)
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (block
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const -4)
+ )
+ )
+ (local.set $4
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ (local.set $1
+ (i32.load
+ (local.get $4)
+ )
+ )
+ )
+ )
+ (local.set $2
+ (block $__asyncify_unwind (result i32)
+ (block
+ (block
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (block
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const -4)
+ )
+ )
+ (local.set $3
+ (i32.load
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (local.set $1
+ (local.get $live)
+ )
+ )
+ (if
+ (if (result i32)
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (i32.const 1)
+ (i32.eq
+ (local.get $3)
+ (i32.const 0)
+ )
+ )
+ (block
+ (call $import2
+ (local.get $1)
+ )
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 1)
+ )
+ (br $__asyncify_unwind
+ (i32.const 0)
+ )
+ )
+ )
+ )
+ )
+ )
+ (return)
+ )
+ )
+ )
+ (block
+ (i32.store
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (local.get $2)
+ )
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const 4)
+ )
+ )
+ )
+ (block
+ (local.set $5
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ (i32.store
+ (local.get $5)
+ (local.get $1)
+ )
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const 4)
+ )
+ )
+ )
+ )
+ (func $liveness-indirect-kills (param $live0 i32) (param $live1 i32)
+ (local $2 i32)
+ (local $3 i32)
+ (local $4 i32)
+ (local $5 i32)
+ (local $6 i32)
+ (local $7 i32)
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (block
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const -8)
+ )
+ )
+ (local.set $6
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ (local.set $2
+ (i32.load
+ (local.get $6)
+ )
+ )
+ (local.set $3
+ (i32.load offset=4
+ (local.get $6)
+ )
+ )
+ )
+ )
+ (local.set $4
+ (block $__asyncify_unwind (result i32)
+ (block
+ (block
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 2)
+ )
+ (block
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const -4)
+ )
+ )
+ (local.set $5
+ (i32.load
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ )
+ )
+ )
+ (block
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (block
+ (local.set $2
+ (local.get $live0)
+ )
+ (local.set $3
+ (local.get $live1)
+ )
+ )
+ )
+ (nop)
+ (if
+ (if (result i32)
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 0)
+ )
+ (i32.const 1)
+ (i32.eq
+ (local.get $5)
+ (i32.const 0)
+ )
+ )
+ (block
+ (call_indirect (type $i32_=>_none)
+ (local.get $2)
+ (local.get $3)
+ )
+ (if
+ (i32.eq
+ (global.get $__asyncify_state)
+ (i32.const 1)
+ )
+ (br $__asyncify_unwind
+ (i32.const 0)
+ )
+ )
+ )
+ )
+ )
+ )
+ (return)
+ )
+ )
+ )
+ (block
+ (i32.store
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (local.get $4)
+ )
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const 4)
+ )
+ )
+ )
+ (block
+ (local.set $7
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ )
+ (i32.store
+ (local.get $7)
+ (local.get $2)
+ )
+ (i32.store offset=4
+ (local.get $7)
+ (local.get $3)
+ )
+ (i32.store
+ (global.get $__asyncify_data)
+ (i32.add
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.const 8)
+ )
+ )
+ )
+ )
+ (func $asyncify_start_unwind (param $0 i32)
+ (global.set $__asyncify_state
+ (i32.const 1)
+ )
+ (global.set $__asyncify_data
+ (local.get $0)
+ )
+ (if
+ (i32.gt_u
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.load offset=4
+ (global.get $__asyncify_data)
+ )
+ )
+ (unreachable)
+ )
+ )
+ (func $asyncify_stop_unwind
+ (global.set $__asyncify_state
+ (i32.const 0)
+ )
+ (if
+ (i32.gt_u
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.load offset=4
+ (global.get $__asyncify_data)
+ )
+ )
+ (unreachable)
+ )
+ )
+ (func $asyncify_start_rewind (param $0 i32)
+ (global.set $__asyncify_state
+ (i32.const 2)
+ )
+ (global.set $__asyncify_data
+ (local.get $0)
+ )
+ (if
+ (i32.gt_u
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.load offset=4
+ (global.get $__asyncify_data)
+ )
+ )
+ (unreachable)
+ )
+ )
+ (func $asyncify_stop_rewind
+ (global.set $__asyncify_state
+ (i32.const 0)
+ )
+ (if
+ (i32.gt_u
+ (i32.load
+ (global.get $__asyncify_data)
+ )
+ (i32.load offset=4
+ (global.get $__asyncify_data)
+ )
+ )
+ (unreachable)
+ )
+ )
+ (func $asyncify_get_state (result i32)
+ (global.get $__asyncify_state)
+ )
+)
diff --git a/test/passes/asyncify.wast b/test/passes/asyncify.wast
new file mode 100644
index 000000000..281934aea
--- /dev/null
+++ b/test/passes/asyncify.wast
@@ -0,0 +1,53 @@
+(module
+ (type $f (func (param i32)))
+ (memory 1 2)
+ (import "env" "import" (func $import))
+ (import "env" "import2" (func $import2 (param i32)))
+ (table 1 1)
+ (func $liveness1 (param $live0 i32) (param $dead0 i32)
+ (local $live1 i32)
+ (local $dead1 i32)
+ (drop (local.get $dead0))
+ (drop (local.get $dead1))
+ (call $import)
+ (drop (local.get $live0))
+ (drop (local.get $live1))
+ )
+ (func $liveness2 (param $live0 i32) (param $dead0 i32)
+ (local $live1 i32)
+ (local $dead1 i32)
+ (drop (local.get $dead0))
+ (drop (local.get $dead1))
+ (call $import)
+ (drop (local.get $live0))
+ (drop (local.get $live1))
+ )
+ (func $liveness3 (param $live0 i32) (param $dead0 i32)
+ (local $live1 i32)
+ (local $dead1 i32)
+ (call $import)
+ (drop (local.get $live0))
+ (call $import)
+ (drop (local.get $live1))
+ )
+ (func $liveness4 (param $live0 i32) (param $dead0 i32)
+ (if (i32.const 0)
+ (call $import)
+ )
+ (drop (local.get $live0))
+ )
+ (func $liveness5 (param $dead0 i32)
+ (drop (local.get $dead0))
+ (if (i32.const 0)
+ (call $import) ;; live before and after call, but not during
+ )
+ (local.set $dead0 (i32.const 1))
+ (drop (local.get $dead0))
+ )
+ (func $liveness-call-kills (param $live i32)
+ (call $import2 (local.get $live))
+ )
+ (func $liveness-indirect-kills (param $live0 i32) (param $live1 i32)
+ (call_indirect (type $f) (local.get $live0) (local.get $live1))
+ )
+)
diff --git a/test/passes/asyncify_enable-multivalue.txt b/test/passes/asyncify_enable-multivalue.txt
index 5aee73c7a..08d0d7bf9 100644
--- a/test/passes/asyncify_enable-multivalue.txt
+++ b/test/passes/asyncify_enable-multivalue.txt
@@ -447,7 +447,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -20)
+ (i32.const -4)
)
)
(local.set $8
@@ -455,28 +455,8 @@
(global.get $__asyncify_data)
)
)
- (local.set $temp
- (i32.load
- (local.get $8)
- )
- )
(local.set $1
- (i32.load offset=4
- (local.get $8)
- )
- )
- (local.set $2
- (i32.load offset=8
- (local.get $8)
- )
- )
- (local.set $3
- (i32.load offset=12
- (local.get $8)
- )
- )
- (local.set $4
- (i32.load offset=16
+ (i32.load
(local.get $8)
)
)
@@ -592,31 +572,15 @@
)
(i32.store
(local.get $9)
- (local.get $temp)
- )
- (i32.store offset=4
- (local.get $9)
(local.get $1)
)
- (i32.store offset=8
- (local.get $9)
- (local.get $2)
- )
- (i32.store offset=12
- (local.get $9)
- (local.get $3)
- )
- (i32.store offset=16
- (local.get $9)
- (local.get $4)
- )
(i32.store
(global.get $__asyncify_data)
(i32.add
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 20)
+ (i32.const 4)
)
)
)
@@ -806,7 +770,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -52)
+ (i32.const -4)
)
)
(local.set $13
@@ -814,63 +778,8 @@
(global.get $__asyncify_data)
)
)
- (local.set $x
- (i32.load
- (local.get $13)
- )
- )
(local.set $y
- (i32.load offset=4
- (local.get $13)
- )
- )
- (local.set $z
- (tuple.make
- (f32.load offset=8
- (local.get $13)
- )
- (i64.load offset=12 align=4
- (local.get $13)
- )
- )
- )
- (local.set $3
- (i32.load offset=20
- (local.get $13)
- )
- )
- (local.set $4
- (i32.load offset=24
- (local.get $13)
- )
- )
- (local.set $5
- (i32.load offset=28
- (local.get $13)
- )
- )
- (local.set $6
- (i32.load offset=32
- (local.get $13)
- )
- )
- (local.set $7
- (i32.load offset=36
- (local.get $13)
- )
- )
- (local.set $8
- (i32.load offset=40
- (local.get $13)
- )
- )
- (local.set $9
- (i32.load offset=44
- (local.get $13)
- )
- )
- (local.set $10
- (i32.load offset=48
+ (i32.load
(local.get $13)
)
)
@@ -1015,63 +924,15 @@
)
(i32.store
(local.get $14)
- (local.get $x)
- )
- (i32.store offset=4
- (local.get $14)
(local.get $y)
)
- (f32.store offset=8
- (local.get $14)
- (tuple.extract 0
- (local.get $z)
- )
- )
- (i64.store offset=12 align=4
- (local.get $14)
- (tuple.extract 1
- (local.get $z)
- )
- )
- (i32.store offset=20
- (local.get $14)
- (local.get $3)
- )
- (i32.store offset=24
- (local.get $14)
- (local.get $4)
- )
- (i32.store offset=28
- (local.get $14)
- (local.get $5)
- )
- (i32.store offset=32
- (local.get $14)
- (local.get $6)
- )
- (i32.store offset=36
- (local.get $14)
- (local.get $7)
- )
- (i32.store offset=40
- (local.get $14)
- (local.get $8)
- )
- (i32.store offset=44
- (local.get $14)
- (local.get $9)
- )
- (i32.store offset=48
- (local.get $14)
- (local.get $10)
- )
(i32.store
(global.get $__asyncify_data)
(i32.add
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 52)
+ (i32.const 4)
)
)
)
@@ -1081,39 +942,12 @@
(local $1 i32)
(local $2 i32)
(local $3 i32)
- (local $4 i32)
- (local $5 i32)
(if
(i32.eq
(global.get $__asyncify_state)
(i32.const 2)
)
- (block
- (i32.store
- (global.get $__asyncify_data)
- (i32.add
- (i32.load
- (global.get $__asyncify_data)
- )
- (i32.const -8)
- )
- )
- (local.set $4
- (i32.load
- (global.get $__asyncify_data)
- )
- )
- (local.set $x
- (i32.load
- (local.get $4)
- )
- )
- (local.set $1
- (i32.load offset=4
- (local.get $4)
- )
- )
- )
+ (nop)
)
(local.set $2
(block $__asyncify_unwind (result i32)
@@ -1210,30 +1044,7 @@
)
)
)
- (block
- (local.set $5
- (i32.load
- (global.get $__asyncify_data)
- )
- )
- (i32.store
- (local.get $5)
- (local.get $x)
- )
- (i32.store offset=4
- (local.get $5)
- (local.get $1)
- )
- (i32.store
- (global.get $__asyncify_data)
- (i32.add
- (i32.load
- (global.get $__asyncify_data)
- )
- (i32.const 8)
- )
- )
- )
+ (nop)
)
(func $calls-import2-if-else (param $x i32)
(local $1 i32)
@@ -1254,7 +1065,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -12)
+ (i32.const -4)
)
)
(local.set $5
@@ -1262,18 +1073,8 @@
(global.get $__asyncify_data)
)
)
- (local.set $x
- (i32.load
- (local.get $5)
- )
- )
- (local.set $1
- (i32.load offset=4
- (local.get $5)
- )
- )
(local.set $2
- (i32.load offset=8
+ (i32.load
(local.get $5)
)
)
@@ -1433,14 +1234,6 @@
)
(i32.store
(local.get $6)
- (local.get $x)
- )
- (i32.store offset=4
- (local.get $6)
- (local.get $1)
- )
- (i32.store offset=8
- (local.get $6)
(local.get $2)
)
(i32.store
@@ -1449,7 +1242,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 12)
+ (i32.const 4)
)
)
)
@@ -1461,54 +1254,12 @@
(local $4 i32)
(local $5 i32)
(local $6 i32)
- (local $7 i32)
- (local $8 i32)
(if
(i32.eq
(global.get $__asyncify_state)
(i32.const 2)
)
- (block
- (i32.store
- (global.get $__asyncify_data)
- (i32.add
- (i32.load
- (global.get $__asyncify_data)
- )
- (i32.const -20)
- )
- )
- (local.set $7
- (i32.load
- (global.get $__asyncify_data)
- )
- )
- (local.set $x
- (i32.load
- (local.get $7)
- )
- )
- (local.set $1
- (i32.load offset=4
- (local.get $7)
- )
- )
- (local.set $2
- (i32.load offset=8
- (local.get $7)
- )
- )
- (local.set $3
- (i32.load offset=12
- (local.get $7)
- )
- )
- (local.set $4
- (i32.load offset=16
- (local.get $7)
- )
- )
- )
+ (nop)
)
(local.set $5
(block $__asyncify_unwind (result i32)
@@ -1650,42 +1401,7 @@
)
)
)
- (block
- (local.set $8
- (i32.load
- (global.get $__asyncify_data)
- )
- )
- (i32.store
- (local.get $8)
- (local.get $x)
- )
- (i32.store offset=4
- (local.get $8)
- (local.get $1)
- )
- (i32.store offset=8
- (local.get $8)
- (local.get $2)
- )
- (i32.store offset=12
- (local.get $8)
- (local.get $3)
- )
- (i32.store offset=16
- (local.get $8)
- (local.get $4)
- )
- (i32.store
- (global.get $__asyncify_data)
- (i32.add
- (i32.load
- (global.get $__asyncify_data)
- )
- (i32.const 20)
- )
- )
- )
+ (nop)
(i32.const 0)
)
(func $calls-import2-if-else-oneside2 (param $x i32) (result i32)
@@ -1709,7 +1425,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -20)
+ (i32.const -4)
)
)
(local.set $7
@@ -1717,28 +1433,8 @@
(global.get $__asyncify_data)
)
)
- (local.set $x
- (i32.load
- (local.get $7)
- )
- )
- (local.set $1
- (i32.load offset=4
- (local.get $7)
- )
- )
- (local.set $2
- (i32.load offset=8
- (local.get $7)
- )
- )
- (local.set $3
- (i32.load offset=12
- (local.get $7)
- )
- )
(local.set $4
- (i32.load offset=16
+ (i32.load
(local.get $7)
)
)
@@ -1892,22 +1588,6 @@
)
(i32.store
(local.get $8)
- (local.get $x)
- )
- (i32.store offset=4
- (local.get $8)
- (local.get $1)
- )
- (i32.store offset=8
- (local.get $8)
- (local.get $2)
- )
- (i32.store offset=12
- (local.get $8)
- (local.get $3)
- )
- (i32.store offset=16
- (local.get $8)
(local.get $4)
)
(i32.store
@@ -1916,7 +1596,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 20)
+ (i32.const 4)
)
)
)
@@ -1942,7 +1622,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -24)
+ (i32.const -12)
)
)
(local.set $5
@@ -1950,7 +1630,7 @@
(global.get $__asyncify_data)
)
)
- (local.set $x
+ (local.set $1
(tuple.make
(i32.load
(local.get $5)
@@ -1960,16 +1640,6 @@
)
)
)
- (local.set $1
- (tuple.make
- (i32.load offset=12
- (local.get $5)
- )
- (i64.load offset=16 align=4
- (local.get $5)
- )
- )
- )
)
)
(local.set $2
@@ -2072,22 +1742,10 @@
(i32.store
(local.get $6)
(tuple.extract 0
- (local.get $x)
- )
- )
- (i64.store offset=4 align=4
- (local.get $6)
- (tuple.extract 1
- (local.get $x)
- )
- )
- (i32.store offset=12
- (local.get $6)
- (tuple.extract 0
(local.get $1)
)
)
- (i64.store offset=16 align=4
+ (i64.store offset=4 align=4
(local.get $6)
(tuple.extract 1
(local.get $1)
@@ -2099,7 +1757,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 24)
+ (i32.const 12)
)
)
)
@@ -2124,7 +1782,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -16)
+ (i32.const -4)
)
)
(local.set $6
@@ -2137,21 +1795,6 @@
(local.get $6)
)
)
- (local.set $1
- (i32.load offset=4
- (local.get $6)
- )
- )
- (local.set $2
- (i32.load offset=8
- (local.get $6)
- )
- )
- (local.set $3
- (i32.load offset=12
- (local.get $6)
- )
- )
)
)
(local.set $4
@@ -2273,25 +1916,13 @@
(local.get $7)
(local.get $x)
)
- (i32.store offset=4
- (local.get $7)
- (local.get $1)
- )
- (i32.store offset=8
- (local.get $7)
- (local.get $2)
- )
- (i32.store offset=12
- (local.get $7)
- (local.get $3)
- )
(i32.store
(global.get $__asyncify_data)
(i32.add
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 16)
+ (i32.const 4)
)
)
)
diff --git a/test/passes/asyncify_mod-asyncify-always-and-only-unwind.txt b/test/passes/asyncify_mod-asyncify-always-and-only-unwind.txt
index 7be0eed18..62c3ba33f 100644
--- a/test/passes/asyncify_mod-asyncify-always-and-only-unwind.txt
+++ b/test/passes/asyncify_mod-asyncify-always-and-only-unwind.txt
@@ -111,7 +111,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -20)
+ (i32.const -4)
)
)
(local.set $8
@@ -119,28 +119,8 @@
(global.get $__asyncify_data)
)
)
- (local.set $temp
- (i32.load
- (local.get $8)
- )
- )
(local.set $1
- (i32.load offset=4
- (local.get $8)
- )
- )
- (local.set $2
- (i32.load offset=8
- (local.get $8)
- )
- )
- (local.set $3
- (i32.load offset=12
- (local.get $8)
- )
- )
- (local.set $4
- (i32.load offset=16
+ (i32.load
(local.get $8)
)
)
@@ -250,31 +230,15 @@
)
(i32.store
(local.get $9)
- (local.get $temp)
- )
- (i32.store offset=4
- (local.get $9)
(local.get $1)
)
- (i32.store offset=8
- (local.get $9)
- (local.get $2)
- )
- (i32.store offset=12
- (local.get $9)
- (local.get $3)
- )
- (i32.store offset=16
- (local.get $9)
- (local.get $4)
- )
(i32.store
(global.get $__asyncify_data)
(i32.add
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 20)
+ (i32.const 4)
)
)
)
diff --git a/test/passes/asyncify_mod-asyncify-never-unwind.txt b/test/passes/asyncify_mod-asyncify-never-unwind.txt
index 264760759..eaf2794cf 100644
--- a/test/passes/asyncify_mod-asyncify-never-unwind.txt
+++ b/test/passes/asyncify_mod-asyncify-never-unwind.txt
@@ -120,7 +120,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -20)
+ (i32.const -4)
)
)
(local.set $8
@@ -128,28 +128,8 @@
(global.get $__asyncify_data)
)
)
- (local.set $temp
- (i32.load
- (local.get $8)
- )
- )
(local.set $1
- (i32.load offset=4
- (local.get $8)
- )
- )
- (local.set $2
- (i32.load offset=8
- (local.get $8)
- )
- )
- (local.set $3
- (i32.load offset=12
- (local.get $8)
- )
- )
- (local.set $4
- (i32.load offset=16
+ (i32.load
(local.get $8)
)
)
@@ -262,31 +242,15 @@
)
(i32.store
(local.get $9)
- (local.get $temp)
- )
- (i32.store offset=4
- (local.get $9)
(local.get $1)
)
- (i32.store offset=8
- (local.get $9)
- (local.get $2)
- )
- (i32.store offset=12
- (local.get $9)
- (local.get $3)
- )
- (i32.store offset=16
- (local.get $9)
- (local.get $4)
- )
(i32.store
(global.get $__asyncify_data)
(i32.add
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 20)
+ (i32.const 4)
)
)
)
diff --git a/test/passes/asyncify_optimize-level=1.txt b/test/passes/asyncify_optimize-level=1.txt
index 1946a7f96..19e0cd160 100644
--- a/test/passes/asyncify_optimize-level=1.txt
+++ b/test/passes/asyncify_optimize-level=1.txt
@@ -286,26 +286,19 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -8)
+ (i32.const -4)
)
)
- (local.set $0
+ (local.set $1
(i32.load
- (local.tee $1
- (i32.load
- (global.get $__asyncify_data)
- )
+ (i32.load
+ (global.get $__asyncify_data)
)
)
)
- (local.set $1
- (i32.load offset=4
- (local.get $1)
- )
- )
)
)
- (local.set $2
+ (local.set $0
(block $__asyncify_unwind (result i32)
(if
(i32.eq
@@ -385,7 +378,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (local.get $2)
+ (local.get $0)
)
(i32.store
(global.get $__asyncify_data)
@@ -397,15 +390,9 @@
)
)
(i32.store
- (local.tee $2
- (i32.load
- (global.get $__asyncify_data)
- )
+ (i32.load
+ (global.get $__asyncify_data)
)
- (local.get $0)
- )
- (i32.store offset=4
- (local.get $2)
(local.get $1)
)
(i32.store
@@ -414,38 +401,14 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 8)
+ (i32.const 4)
)
)
(i32.const 0)
)
(func $calls-import2-if (param $0 i32)
(local $1 i32)
- (if
- (i32.eq
- (global.get $__asyncify_state)
- (i32.const 2)
- )
- (block
- (i32.store
- (global.get $__asyncify_data)
- (i32.add
- (i32.load
- (global.get $__asyncify_data)
- )
- (i32.const -4)
- )
- )
- (local.set $0
- (i32.load
- (i32.load
- (global.get $__asyncify_data)
- )
- )
- )
- )
- )
- (local.set $1
+ (local.set $0
(block $__asyncify_unwind (result i32)
(if
(i32.eq
@@ -508,21 +471,6 @@
(i32.load
(global.get $__asyncify_data)
)
- (local.get $1)
- )
- (i32.store
- (global.get $__asyncify_data)
- (i32.add
- (i32.load
- (global.get $__asyncify_data)
- )
- (i32.const 4)
- )
- )
- (i32.store
- (i32.load
- (global.get $__asyncify_data)
- )
(local.get $0)
)
(i32.store
@@ -550,26 +498,19 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -8)
+ (i32.const -4)
)
)
- (local.set $0
+ (local.set $1
(i32.load
- (local.tee $1
- (i32.load
- (global.get $__asyncify_data)
- )
+ (i32.load
+ (global.get $__asyncify_data)
)
)
)
- (local.set $1
- (i32.load offset=4
- (local.get $1)
- )
- )
)
)
- (local.set $2
+ (local.set $0
(block $__asyncify_unwind (result i32)
(if
(i32.eq
@@ -675,7 +616,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (local.get $2)
+ (local.get $0)
)
(i32.store
(global.get $__asyncify_data)
@@ -687,15 +628,9 @@
)
)
(i32.store
- (local.tee $2
- (i32.load
- (global.get $__asyncify_data)
- )
+ (i32.load
+ (global.get $__asyncify_data)
)
- (local.get $0)
- )
- (i32.store offset=4
- (local.get $2)
(local.get $1)
)
(i32.store
@@ -704,45 +639,14 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 8)
+ (i32.const 4)
)
)
)
(func $calls-import2-if-else-oneside (param $0 i32) (result i32)
(local $1 i32)
(local $2 i32)
- (if
- (i32.eq
- (global.get $__asyncify_state)
- (i32.const 2)
- )
- (block
- (i32.store
- (global.get $__asyncify_data)
- (i32.add
- (i32.load
- (global.get $__asyncify_data)
- )
- (i32.const -8)
- )
- )
- (local.set $0
- (i32.load
- (local.tee $1
- (i32.load
- (global.get $__asyncify_data)
- )
- )
- )
- )
- (local.set $1
- (i32.load offset=4
- (local.get $1)
- )
- )
- )
- )
- (local.set $2
+ (local.set $0
(block $__asyncify_unwind (result i32)
(if
(i32.eq
@@ -759,7 +663,7 @@
(i32.const -4)
)
)
- (local.set $2
+ (local.set $1
(i32.load
(i32.load
(global.get $__asyncify_data)
@@ -770,9 +674,9 @@
)
(if
(i32.or
- (local.tee $1
+ (local.tee $2
(select
- (local.get $1)
+ (local.get $2)
(local.get $0)
(global.get $__asyncify_state)
)
@@ -794,7 +698,7 @@
(if
(i32.or
(i32.eqz
- (local.get $1)
+ (local.get $2)
)
(i32.eq
(global.get $__asyncify_state)
@@ -804,7 +708,7 @@
(if
(select
(i32.eqz
- (local.get $2)
+ (local.get $1)
)
(i32.const 1)
(global.get $__asyncify_state)
@@ -840,36 +744,15 @@
(i32.load
(global.get $__asyncify_data)
)
- (local.get $2)
- )
- (i32.store
- (global.get $__asyncify_data)
- (i32.add
- (i32.load
- (global.get $__asyncify_data)
- )
- (i32.const 4)
- )
- )
- (i32.store
- (local.tee $2
- (i32.load
- (global.get $__asyncify_data)
- )
- )
(local.get $0)
)
- (i32.store offset=4
- (local.get $2)
- (local.get $1)
- )
(i32.store
(global.get $__asyncify_data)
(i32.add
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 8)
+ (i32.const 4)
)
)
(i32.const 0)
@@ -889,26 +772,19 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -8)
+ (i32.const -4)
)
)
- (local.set $0
+ (local.set $1
(i32.load
- (local.tee $1
- (i32.load
- (global.get $__asyncify_data)
- )
+ (i32.load
+ (global.get $__asyncify_data)
)
)
)
- (local.set $1
- (i32.load offset=4
- (local.get $1)
- )
- )
)
)
- (local.set $2
+ (local.set $0
(block $__asyncify_unwind (result i32)
(if
(i32.eq
@@ -1006,7 +882,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (local.get $2)
+ (local.get $0)
)
(i32.store
(global.get $__asyncify_data)
@@ -1018,15 +894,9 @@
)
)
(i32.store
- (local.tee $2
- (i32.load
- (global.get $__asyncify_data)
- )
+ (i32.load
+ (global.get $__asyncify_data)
)
- (local.get $0)
- )
- (i32.store offset=4
- (local.get $2)
(local.get $1)
)
(i32.store
@@ -1035,7 +905,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 8)
+ (i32.const 4)
)
)
(i32.const 0)
diff --git a/test/passes/asyncify_pass-arg=asyncify-ignore-imports.txt b/test/passes/asyncify_pass-arg=asyncify-ignore-imports.txt
index b1854fb5d..f9ae663fd 100644
--- a/test/passes/asyncify_pass-arg=asyncify-ignore-imports.txt
+++ b/test/passes/asyncify_pass-arg=asyncify-ignore-imports.txt
@@ -60,7 +60,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -8)
+ (i32.const -4)
)
)
(local.set $4
@@ -68,13 +68,8 @@
(global.get $__asyncify_data)
)
)
- (local.set $x
- (i32.load
- (local.get $4)
- )
- )
(local.set $1
- (i32.load offset=4
+ (i32.load
(local.get $4)
)
)
@@ -176,10 +171,6 @@
)
(i32.store
(local.get $5)
- (local.get $x)
- )
- (i32.store offset=4
- (local.get $5)
(local.get $1)
)
(i32.store
@@ -188,7 +179,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 8)
+ (i32.const 4)
)
)
)
diff --git a/test/passes/asyncify_pass-arg=asyncify-ignore-indirect.txt b/test/passes/asyncify_pass-arg=asyncify-ignore-indirect.txt
index a48f3b3eb..690c96030 100644
--- a/test/passes/asyncify_pass-arg=asyncify-ignore-indirect.txt
+++ b/test/passes/asyncify_pass-arg=asyncify-ignore-indirect.txt
@@ -267,7 +267,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -12)
+ (i32.const -4)
)
)
(local.set $5
@@ -275,18 +275,8 @@
(global.get $__asyncify_data)
)
)
- (local.set $x
- (i32.load
- (local.get $5)
- )
- )
- (local.set $1
- (i32.load offset=4
- (local.get $5)
- )
- )
(local.set $2
- (i32.load offset=8
+ (i32.load
(local.get $5)
)
)
@@ -446,14 +436,6 @@
)
(i32.store
(local.get $6)
- (local.get $x)
- )
- (i32.store offset=4
- (local.get $6)
- (local.get $1)
- )
- (i32.store offset=8
- (local.get $6)
(local.get $2)
)
(i32.store
@@ -462,7 +444,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 12)
+ (i32.const 4)
)
)
)
diff --git a/test/passes/asyncify_pass-arg=asyncify-imports@env.import,env.import2.txt b/test/passes/asyncify_pass-arg=asyncify-imports@env.import,env.import2.txt
index 48187bef3..defef94ed 100644
--- a/test/passes/asyncify_pass-arg=asyncify-imports@env.import,env.import2.txt
+++ b/test/passes/asyncify_pass-arg=asyncify-imports@env.import,env.import2.txt
@@ -444,7 +444,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -20)
+ (i32.const -4)
)
)
(local.set $8
@@ -452,28 +452,8 @@
(global.get $__asyncify_data)
)
)
- (local.set $temp
- (i32.load
- (local.get $8)
- )
- )
(local.set $1
- (i32.load offset=4
- (local.get $8)
- )
- )
- (local.set $2
- (i32.load offset=8
- (local.get $8)
- )
- )
- (local.set $3
- (i32.load offset=12
- (local.get $8)
- )
- )
- (local.set $4
- (i32.load offset=16
+ (i32.load
(local.get $8)
)
)
@@ -589,31 +569,15 @@
)
(i32.store
(local.get $9)
- (local.get $temp)
- )
- (i32.store offset=4
- (local.get $9)
(local.get $1)
)
- (i32.store offset=8
- (local.get $9)
- (local.get $2)
- )
- (i32.store offset=12
- (local.get $9)
- (local.get $3)
- )
- (i32.store offset=16
- (local.get $9)
- (local.get $4)
- )
(i32.store
(global.get $__asyncify_data)
(i32.add
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 20)
+ (i32.const 4)
)
)
)
@@ -802,7 +766,7 @@
(i32.load
(global.get $__asyncify_data)
)
- (i32.const -40)
+ (i32.const -4)
)
)
(local.set $12
@@ -810,53 +774,8 @@
(global.get $__asyncify_data)
)
)
- (local.set $x
- (i32.load
- (local.get $12)
- )
- )
(local.set $y
- (i32.load offset=4
- (local.get $12)
- )
- )
- (local.set $2
- (i32.load offset=8
- (local.get $12)
- )
- )
- (local.set $3
- (i32.load offset=12
- (local.get $12)
- )
- )
- (local.set $4
- (i32.load offset=16
- (local.get $12)
- )
- )
- (local.set $5
- (i32.load offset=20
- (local.get $12)
- )
- )
- (local.set $6
- (i32.load offset=24
- (local.get $12)
- )
- )
- (local.set $7
- (i32.load offset=28
- (local.get $12)
- )
- )
- (local.set $8
- (i32.load offset=32
- (local.get $12)
- )
- )
- (local.set $9
- (i32.load offset=36
+ (i32.load
(local.get $12)
)
)
@@ -1001,51 +920,15 @@
)
(i32.store
(local.get $13)
- (local.get $x)
- )
- (i32.store offset=4
- (local.get $13)
(local.get $y)
)
- (i32.store offset=8
- (local.get $13)
- (local.get $2)
- )
- (i32.store offset=12
- (local.get $13)
- (local.get $3)
- )
- (i32.store offset=16
- (local.get $13)
- (local.get $4)
- )
- (i32.store offset=20
- (local.get $13)
- (local.get $5)
- )
- (i32.store offset=24
- (local.get $13)
- (local.get $6)
- )
- (i32.store offset=28
- (local.get $13)
- (local.get $7)
- )
- (i32.store offset=32
- (local.get $13)
- (local.get $8)
- )
- (i32.store offset=36
- (local.get $13)
- (local.get $9)
- )
(i32.store
(global.get $__asyncify_data)
(i32.add
(i32.load
(global.get $__asyncify_data)
)
- (i32.const 40)
+ (i32.const 4)
)
)
)
@@ -1055,39 +938,12 @@
(local $1 i32)
(local $2 i32)
(local $3 i32)
- (local $4 i32)
- (local $5 i32)
(if
(i32.eq
(global.get $__asyncify_state)
(i32.const 2)
)
- (block
- (i32.store
- (global.get $__asyncify_data)
- (i32.add
- (i32.load
- (global.get $__asyncify_data)
- )
- (i32.const -8)
- )
- )
- (local.set $4
- (i32.load
- (global.get $__asyncify_data)
- )
- )
- (local.set $x
- (i32.load
- (local.get $4)
- )
- )
- (local.set $1
- (i32.load offset=4
- (local.get $4)
- )
- )
- )
+ (nop)
)
(local.set $2
(block $__asyncify_unwind (result i32)
@@ -1184,30 +1040,7 @@
)
)
)
- (block
- (local.set $5
- (i32.load
- (global.get $__asyncify_data)
- )
- )
- (i32.store
- (local.get $5)
- (local.get $x)
- )
- (i32.store offset=4
- (local.get $5)
- (local.get $1)
- )
- (i32.store
- (global.get $__asyncify_data)
- (i32.add
- (i32.load
- (global.get $__asyncify_data)
- )
- (i32.const 8)
- )
- )
- )
+ (nop)
)
(func $calls-import2-if-else (param $x i32)
(local $1 i32)