diff options
-rw-r--r-- | src/passes/Asyncify.cpp | 119 | ||||
-rw-r--r-- | test/lit/passes/asyncify-wasm64_pass-arg=in-secondary-memory.wast | 312 | ||||
-rw-r--r-- | test/lit/passes/asyncify_pass-arg=in-secondary-memory.wast | 609 |
3 files changed, 999 insertions, 41 deletions
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp index 3cc57158a..9be731d06 100644 --- a/src/passes/Asyncify.cpp +++ b/src/passes/Asyncify.cpp @@ -150,7 +150,7 @@ // which means it will keep unwinding in a meaningless way. // // * asyncify_start_rewind(data : iPTR): call this to start rewinding the -// stack vack up to the location stored in the provided data. This prepares +// stack back up to the location stored in the provided data. This prepares // for the rewind; to start it, you must call the first function in the // call stack to be unwound. // @@ -234,7 +234,7 @@ // // --pass-arg=asyncify-asserts // -// This enables extra asserts in the output, like checking if we in +// This enables extra asserts in the output, like checking if we put in // an unwind/rewind in an invalid place (this can be helpful for manual // tweaking of the only-list / remove-list, see later). // @@ -311,6 +311,7 @@ #include "ir/literal-utils.h" #include "ir/memory-utils.h" #include "ir/module-utils.h" +#include "ir/names.h" #include "ir/utils.h" #include "pass.h" #include "support/file.h" @@ -803,9 +804,11 @@ class AsyncifyBuilder : public Builder { public: Module& wasm; Type pointerType; + Name asyncifyMemory; - AsyncifyBuilder(Module& wasm) - : Builder(wasm), wasm(wasm), pointerType(wasm.memories[0]->indexType) {} + AsyncifyBuilder(Module& wasm, Type pointerType, Name asyncifyMemory) + : Builder(wasm), wasm(wasm), pointerType(pointerType), + asyncifyMemory(asyncifyMemory) {} Expression* makeGetStackPos() { return makeLoad(pointerType.getByteSize(), @@ -814,7 +817,7 @@ public: pointerType.getByteSize(), makeGlobalGet(ASYNCIFY_DATA, pointerType), pointerType, - wasm.memories[0]->name); + asyncifyMemory); } Expression* makeIncStackPos(int32_t by) { @@ -830,7 +833,7 @@ public: makeGetStackPos(), makeConst(literal)), pointerType, - wasm.memories[0]->name); + asyncifyMemory); } Expression* makeStateCheck(State value) { @@ -850,17 +853,23 @@ struct AsyncifyFlow : public Pass { bool isFunctionParallel() override { return true; } ModuleAnalyzer* analyzer; + Type pointerType; + Name asyncifyMemory; std::unique_ptr<Pass> create() override { - return std::make_unique<AsyncifyFlow>(analyzer); + return std::make_unique<AsyncifyFlow>( + analyzer, pointerType, asyncifyMemory); } - AsyncifyFlow(ModuleAnalyzer* analyzer) : analyzer(analyzer) {} + AsyncifyFlow(ModuleAnalyzer* analyzer, Type pointerType, Name asyncifyMemory) + : analyzer(analyzer), pointerType(pointerType), + asyncifyMemory(asyncifyMemory) {} void runOnFunction(Module* module_, Function* func_) override { module = module_; func = func_; - builder = make_unique<AsyncifyBuilder>(*module); + builder = + make_unique<AsyncifyBuilder>(*module, pointerType, asyncifyMemory); // If the function cannot change our state, we have nothing to do - // we will never unwind or rewind the stack here. if (!analyzer->needsInstrumentation(func)) { @@ -1225,12 +1234,19 @@ struct AsyncifyLocals : public WalkerPass<PostWalker<AsyncifyLocals>> { bool isFunctionParallel() override { return true; } ModuleAnalyzer* analyzer; + Type pointerType; + Name asyncifyMemory; std::unique_ptr<Pass> create() override { - return std::make_unique<AsyncifyLocals>(analyzer); + return std::make_unique<AsyncifyLocals>( + analyzer, pointerType, asyncifyMemory); } - AsyncifyLocals(ModuleAnalyzer* analyzer) : analyzer(analyzer) {} + AsyncifyLocals(ModuleAnalyzer* analyzer, + Type pointerType, + Name asyncifyMemory) + : analyzer(analyzer), pointerType(pointerType), + asyncifyMemory(asyncifyMemory) {} void visitCall(Call* curr) { // Replace calls to the fake intrinsics. @@ -1239,15 +1255,14 @@ struct AsyncifyLocals : public WalkerPass<PostWalker<AsyncifyLocals>> { } else if (curr->target == ASYNCIFY_GET_CALL_INDEX) { replaceCurrent(builder->makeSequence( builder->makeIncStackPos(-4), - builder->makeLocalSet( - rewindIndex, - builder->makeLoad(4, - false, - 0, - 4, - builder->makeGetStackPos(), - Type::i32, - getModule()->memories[0]->name)))); + builder->makeLocalSet(rewindIndex, + builder->makeLoad(4, + false, + 0, + 4, + builder->makeGetStackPos(), + Type::i32, + asyncifyMemory)))); } else if (curr->target == ASYNCIFY_CHECK_CALL_INDEX) { replaceCurrent(builder->makeBinary( EqInt32, @@ -1298,7 +1313,8 @@ struct AsyncifyLocals : public WalkerPass<PostWalker<AsyncifyLocals>> { auto unwindIndex = builder->addVar(func, Type::i32); rewindIndex = builder->addVar(func, Type::i32); // Rewrite the function body. - builder = make_unique<AsyncifyBuilder>(*getModule()); + builder = + make_unique<AsyncifyBuilder>(*getModule(), pointerType, asyncifyMemory); walk(func->body); // After the normal function body, emit a barrier before the postamble. Expression* barrier; @@ -1417,7 +1433,7 @@ private: STACK_ALIGN, builder->makeLocalGet(tempIndex, builder->pointerType), type, - getModule()->memories[0]->name)); + asyncifyMemory)); offset += size; } Expression* load; @@ -1466,7 +1482,7 @@ private: builder->makeLocalGet(tempIndex, builder->pointerType), localGet, type, - getModule()->memories[0]->name)); + asyncifyMemory)); offset += size; ++j; } @@ -1485,7 +1501,7 @@ private: builder->makeGetStackPos(), builder->makeLocalGet(tempIndex, Type::i32), Type::i32, - getModule()->memories[0]->name), + asyncifyMemory), builder->makeIncStackPos(4)); } @@ -1509,11 +1525,6 @@ struct Asyncify : public Pass { void run(Module* module) override { auto& options = getPassOptions(); bool optimize = options.optimizeLevel > 0; - is64 = module->memories.size() && module->memories[0]->is64(); - pointerType = is64 ? Type::i64 : Type::i32; - - // Ensure there is a memory, as we need it. - MemoryUtils::ensureExists(module); // Find which things can change the state. auto stateChangingImports = String::trim(read_possible_response_file( @@ -1551,6 +1562,21 @@ struct Asyncify : public Pass { auto verbose = options.getArgumentOrDefault("asyncify-verbose", "") != ""; auto relocatable = options.getArgumentOrDefault("asyncify-relocatable", "") != ""; + auto secondaryMemory = + options.getArgumentOrDefault("asyncify-in-secondary-memory", "") != ""; + + // Ensure there is a memory, as we need it. + if (secondaryMemory) { + auto secondaryMemorySizeString = + options.getArgumentOrDefault("asyncify-secondary-memory-size", "1"); + Address secondaryMemorySize = std::stoi(secondaryMemorySizeString); + asyncifyMemory = createSecondaryMemory(module, secondaryMemorySize); + } else { + MemoryUtils::ensureExists(module); + asyncifyMemory = module->memories[0]->name; + } + pointerType = + module->getMemory(asyncifyMemory)->is64() ? Type::i64 : Type::i32; removeList = handleBracketingOperators(removeList); addList = handleBracketingOperators(addList); @@ -1611,7 +1637,8 @@ struct Asyncify : public Pass { runner.add("reorder-locals"); runner.add("merge-blocks"); } - runner.add(make_unique<AsyncifyFlow>(&analyzer)); + runner.add( + make_unique<AsyncifyFlow>(&analyzer, pointerType, asyncifyMemory)); runner.setIsNested(true); runner.setValidateGlobally(false); runner.run(); @@ -1626,7 +1653,8 @@ struct Asyncify : public Pass { if (optimize) { runner.addDefaultFunctionOptimizationPasses(); } - runner.add(make_unique<AsyncifyLocals>(&analyzer)); + runner.add( + make_unique<AsyncifyLocals>(&analyzer, pointerType, asyncifyMemory)); if (optimize) { runner.addDefaultFunctionOptimizationPasses(); } @@ -1686,15 +1714,16 @@ private: pointerType.getByteSize(), builder.makeGlobalGet(ASYNCIFY_DATA, pointerType), pointerType, - module->memories[0]->name); - auto* stackEnd = builder.makeLoad( - pointerType.getByteSize(), - false, - int(is64 ? DataOffset::BStackEnd64 : DataOffset::BStackEnd), - pointerType.getByteSize(), - builder.makeGlobalGet(ASYNCIFY_DATA, pointerType), - pointerType, - module->memories[0]->name); + asyncifyMemory); + auto* stackEnd = + builder.makeLoad(pointerType.getByteSize(), + false, + int(pointerType == Type::i64 ? DataOffset::BStackEnd64 + : DataOffset::BStackEnd), + pointerType.getByteSize(), + builder.makeGlobalGet(ASYNCIFY_DATA, pointerType), + pointerType, + asyncifyMemory); body->list.push_back(builder.makeIf( builder.makeBinary( Abstract::getBinary(pointerType, Abstract::GtU), stackPos, stackEnd), @@ -1720,8 +1749,16 @@ private: ASYNCIFY_GET_STATE, ASYNCIFY_GET_STATE, ExternalKind::Function)); } - bool is64; + Name createSecondaryMemory(Module* module, Address secondaryMemorySize) { + Name name = Names::getValidMemoryName(*module, "asyncify_memory"); + auto secondaryMemory = + Builder::makeMemory(name, secondaryMemorySize, secondaryMemorySize); + module->addMemory(std::move(secondaryMemory)); + return name; + } + Type pointerType; + Name asyncifyMemory; }; Pass* createAsyncifyPass() { return new Asyncify(); } diff --git a/test/lit/passes/asyncify-wasm64_pass-arg=in-secondary-memory.wast b/test/lit/passes/asyncify-wasm64_pass-arg=in-secondary-memory.wast new file mode 100644 index 000000000..7342365cb --- /dev/null +++ b/test/lit/passes/asyncify-wasm64_pass-arg=in-secondary-memory.wast @@ -0,0 +1,312 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt --enable-memory64 --enable-multi-memories --asyncify --pass-arg=asyncify-in-secondary-memory %s -S -o - | filecheck %s + +(module + (memory i64 1 2) + ;; CHECK: (type $none_=>_none (func)) + + ;; CHECK: (type $i32_=>_none (func (param i32))) + + ;; CHECK: (type $i32_i32_=>_none (func (param i32 i32))) + + ;; CHECK: (type $none_=>_i32 (func (result i32))) + + ;; CHECK: (import "env" "import" (func $import)) + (import "env" "import" (func $import)) + ;; CHECK: (global $__asyncify_state (mut i32) (i32.const 0)) + + ;; CHECK: (global $__asyncify_data (mut i32) (i32.const 0)) + + ;; CHECK: (memory $0 i64 1 2) + + ;; CHECK: (memory $asyncify_memory 1 1) + + ;; CHECK: (export "asyncify_start_unwind" (func $asyncify_start_unwind)) + + ;; CHECK: (export "asyncify_stop_unwind" (func $asyncify_stop_unwind)) + + ;; CHECK: (export "asyncify_start_rewind" (func $asyncify_start_rewind)) + + ;; CHECK: (export "asyncify_stop_rewind" (func $asyncify_stop_rewind)) + + ;; CHECK: (export "asyncify_get_state" (func $asyncify_get_state)) + + ;; CHECK: (func $liveness1 (param $live0 i32) (param $dead0 i32) + ;; CHECK-NEXT: (local $live1 i32) + ;; CHECK-NEXT: (local $dead1 i32) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 i32) + ;; CHECK-NEXT: (local $6 i32) + ;; CHECK-NEXT: (local $7 i32) + ;; CHECK-NEXT: (local $8 i32) + ;; CHECK-NEXT: (local $9 i32) + ;; CHECK-NEXT: (local $10 i32) + ;; CHECK-NEXT: (local $11 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (i32.store $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $live0 + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $live1 + ;; CHECK-NEXT: (i32.load $asyncify_memory offset=4 + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (i32.store $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $dead0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $dead1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $live0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.get $live1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (i32.store $asyncify_memory + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store $asyncify_memory + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $live0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store $asyncify_memory offset=4 + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $live1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + (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)) + ) +) +;; CHECK: (func $asyncify_start_unwind (param $0 i32) +;; CHECK-NEXT: (global.set $__asyncify_state +;; CHECK-NEXT: (i32.const 1) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (global.set $__asyncify_data +;; CHECK-NEXT: (local.get $0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (if +;; CHECK-NEXT: (i32.gt_u +;; CHECK-NEXT: (i32.load $asyncify_memory +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (i32.load $asyncify_memory offset=4 +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) + +;; CHECK: (func $asyncify_stop_unwind +;; CHECK-NEXT: (global.set $__asyncify_state +;; CHECK-NEXT: (i32.const 0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (if +;; CHECK-NEXT: (i32.gt_u +;; CHECK-NEXT: (i32.load $asyncify_memory +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (i32.load $asyncify_memory offset=4 +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) + +;; CHECK: (func $asyncify_start_rewind (param $0 i32) +;; CHECK-NEXT: (global.set $__asyncify_state +;; CHECK-NEXT: (i32.const 2) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (global.set $__asyncify_data +;; CHECK-NEXT: (local.get $0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (if +;; CHECK-NEXT: (i32.gt_u +;; CHECK-NEXT: (i32.load $asyncify_memory +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (i32.load $asyncify_memory offset=4 +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) + +;; CHECK: (func $asyncify_stop_rewind +;; CHECK-NEXT: (global.set $__asyncify_state +;; CHECK-NEXT: (i32.const 0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (if +;; CHECK-NEXT: (i32.gt_u +;; CHECK-NEXT: (i32.load $asyncify_memory +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (i32.load $asyncify_memory offset=4 +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) + +;; CHECK: (func $asyncify_get_state (result i32) +;; CHECK-NEXT: (global.get $__asyncify_state) +;; CHECK-NEXT: ) diff --git a/test/lit/passes/asyncify_pass-arg=in-secondary-memory.wast b/test/lit/passes/asyncify_pass-arg=in-secondary-memory.wast new file mode 100644 index 000000000..961c6d72c --- /dev/null +++ b/test/lit/passes/asyncify_pass-arg=in-secondary-memory.wast @@ -0,0 +1,609 @@ +;; NOTE: Assertions have been generated by update_lit_checks.py --all-items and should not be edited. + +;; RUN: wasm-opt --enable-multi-memories --asyncify --pass-arg=asyncify-in-secondary-memory %s -S -o - | filecheck %s +;; RUN: wasm-opt --enable-multi-memories --asyncify --pass-arg=asyncify-in-secondary-memory --pass-arg=asyncify-secondary-memory-size@3 %s -S -o - | filecheck %s --check-prefix SIZE + +(module + (memory 1 2) + ;; CHECK: (type $none_=>_none (func)) + + ;; CHECK: (type $i32_=>_none (func (param i32))) + + ;; CHECK: (type $i32_i32_=>_none (func (param i32 i32))) + + ;; CHECK: (type $none_=>_i32 (func (result i32))) + + ;; CHECK: (import "env" "import" (func $import)) + ;; SIZE: (type $none_=>_none (func)) + + ;; SIZE: (type $i32_=>_none (func (param i32))) + + ;; SIZE: (type $i32_i32_=>_none (func (param i32 i32))) + + ;; SIZE: (type $none_=>_i32 (func (result i32))) + + ;; SIZE: (import "env" "import" (func $import)) + (import "env" "import" (func $import)) + ;; CHECK: (global $__asyncify_state (mut i32) (i32.const 0)) + + ;; CHECK: (global $__asyncify_data (mut i32) (i32.const 0)) + + ;; CHECK: (memory $0 1 2) + + ;; CHECK: (memory $asyncify_memory 1 1) + + ;; CHECK: (export "asyncify_start_unwind" (func $asyncify_start_unwind)) + + ;; CHECK: (export "asyncify_stop_unwind" (func $asyncify_stop_unwind)) + + ;; CHECK: (export "asyncify_start_rewind" (func $asyncify_start_rewind)) + + ;; CHECK: (export "asyncify_stop_rewind" (func $asyncify_stop_rewind)) + + ;; CHECK: (export "asyncify_get_state" (func $asyncify_get_state)) + + ;; CHECK: (func $liveness1 (param $live0 i32) (param $dead0 i32) + ;; CHECK-NEXT: (local $live1 i32) + ;; CHECK-NEXT: (local $dead1 i32) + ;; CHECK-NEXT: (local $4 i32) + ;; CHECK-NEXT: (local $5 i32) + ;; CHECK-NEXT: (local $6 i32) + ;; CHECK-NEXT: (local $7 i32) + ;; CHECK-NEXT: (local $8 i32) + ;; CHECK-NEXT: (local $9 i32) + ;; CHECK-NEXT: (local $10 i32) + ;; CHECK-NEXT: (local $11 i32) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (i32.store $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $10 + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $live0 + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $live1 + ;; CHECK-NEXT: (i32.load $asyncify_memory offset=4 + ;; CHECK-NEXT: (local.get $10) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $8 + ;; CHECK-NEXT: (block $__asyncify_unwind (result i32) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 2) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (i32.store $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const -4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $9 + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $4 + ;; CHECK-NEXT: (local.get $dead0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $5 + ;; CHECK-NEXT: (local.get $dead1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $5) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (if (result i32) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (local.get $9) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (call $import) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (br $__asyncify_unwind + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (if + ;; CHECK-NEXT: (i32.eq + ;; CHECK-NEXT: (global.get $__asyncify_state) + ;; CHECK-NEXT: (i32.const 0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $6 + ;; CHECK-NEXT: (local.get $live0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $6) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.set $7 + ;; CHECK-NEXT: (local.get $live1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (drop + ;; CHECK-NEXT: (local.get $7) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: (nop) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (return) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (i32.store $asyncify_memory + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (local.get $8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 4) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (block + ;; CHECK-NEXT: (local.set $11 + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store $asyncify_memory + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $live0) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store $asyncify_memory offset=4 + ;; CHECK-NEXT: (local.get $11) + ;; CHECK-NEXT: (local.get $live1) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.store $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: (i32.add + ;; CHECK-NEXT: (i32.load $asyncify_memory + ;; CHECK-NEXT: (global.get $__asyncify_data) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: (i32.const 8) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; CHECK-NEXT: ) + ;; SIZE: (global $__asyncify_state (mut i32) (i32.const 0)) + + ;; SIZE: (global $__asyncify_data (mut i32) (i32.const 0)) + + ;; SIZE: (memory $0 1 2) + + ;; SIZE: (memory $asyncify_memory 3 3) + + ;; SIZE: (export "asyncify_start_unwind" (func $asyncify_start_unwind)) + + ;; SIZE: (export "asyncify_stop_unwind" (func $asyncify_stop_unwind)) + + ;; SIZE: (export "asyncify_start_rewind" (func $asyncify_start_rewind)) + + ;; SIZE: (export "asyncify_stop_rewind" (func $asyncify_stop_rewind)) + + ;; SIZE: (export "asyncify_get_state" (func $asyncify_get_state)) + + ;; SIZE: (func $liveness1 (param $live0 i32) (param $dead0 i32) + ;; SIZE-NEXT: (local $live1 i32) + ;; SIZE-NEXT: (local $dead1 i32) + ;; SIZE-NEXT: (local $4 i32) + ;; SIZE-NEXT: (local $5 i32) + ;; SIZE-NEXT: (local $6 i32) + ;; SIZE-NEXT: (local $7 i32) + ;; SIZE-NEXT: (local $8 i32) + ;; SIZE-NEXT: (local $9 i32) + ;; SIZE-NEXT: (local $10 i32) + ;; SIZE-NEXT: (local $11 i32) + ;; SIZE-NEXT: (if + ;; SIZE-NEXT: (i32.eq + ;; SIZE-NEXT: (global.get $__asyncify_state) + ;; SIZE-NEXT: (i32.const 2) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (i32.store $asyncify_memory + ;; SIZE-NEXT: (global.get $__asyncify_data) + ;; SIZE-NEXT: (i32.add + ;; SIZE-NEXT: (i32.load $asyncify_memory + ;; SIZE-NEXT: (global.get $__asyncify_data) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (i32.const -8) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (local.set $10 + ;; SIZE-NEXT: (i32.load $asyncify_memory + ;; SIZE-NEXT: (global.get $__asyncify_data) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (local.set $live0 + ;; SIZE-NEXT: (i32.load $asyncify_memory + ;; SIZE-NEXT: (local.get $10) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (local.set $live1 + ;; SIZE-NEXT: (i32.load $asyncify_memory offset=4 + ;; SIZE-NEXT: (local.get $10) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (local.set $8 + ;; SIZE-NEXT: (block $__asyncify_unwind (result i32) + ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (if + ;; SIZE-NEXT: (i32.eq + ;; SIZE-NEXT: (global.get $__asyncify_state) + ;; SIZE-NEXT: (i32.const 2) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (i32.store $asyncify_memory + ;; SIZE-NEXT: (global.get $__asyncify_data) + ;; SIZE-NEXT: (i32.add + ;; SIZE-NEXT: (i32.load $asyncify_memory + ;; SIZE-NEXT: (global.get $__asyncify_data) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (i32.const -4) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (local.set $9 + ;; SIZE-NEXT: (i32.load $asyncify_memory + ;; SIZE-NEXT: (i32.load $asyncify_memory + ;; SIZE-NEXT: (global.get $__asyncify_data) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (if + ;; SIZE-NEXT: (i32.eq + ;; SIZE-NEXT: (global.get $__asyncify_state) + ;; SIZE-NEXT: (i32.const 0) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (local.set $4 + ;; SIZE-NEXT: (local.get $dead0) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (drop + ;; SIZE-NEXT: (local.get $4) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (local.set $5 + ;; SIZE-NEXT: (local.get $dead1) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (drop + ;; SIZE-NEXT: (local.get $5) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (nop) + ;; SIZE-NEXT: (nop) + ;; SIZE-NEXT: (nop) + ;; SIZE-NEXT: (if + ;; SIZE-NEXT: (if (result i32) + ;; SIZE-NEXT: (i32.eq + ;; SIZE-NEXT: (global.get $__asyncify_state) + ;; SIZE-NEXT: (i32.const 0) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (i32.const 1) + ;; SIZE-NEXT: (i32.eq + ;; SIZE-NEXT: (local.get $9) + ;; SIZE-NEXT: (i32.const 0) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (call $import) + ;; SIZE-NEXT: (if + ;; SIZE-NEXT: (i32.eq + ;; SIZE-NEXT: (global.get $__asyncify_state) + ;; SIZE-NEXT: (i32.const 1) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (br $__asyncify_unwind + ;; SIZE-NEXT: (i32.const 0) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (if + ;; SIZE-NEXT: (i32.eq + ;; SIZE-NEXT: (global.get $__asyncify_state) + ;; SIZE-NEXT: (i32.const 0) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (local.set $6 + ;; SIZE-NEXT: (local.get $live0) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (drop + ;; SIZE-NEXT: (local.get $6) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (local.set $7 + ;; SIZE-NEXT: (local.get $live1) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (drop + ;; SIZE-NEXT: (local.get $7) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (nop) + ;; SIZE-NEXT: (nop) + ;; SIZE-NEXT: (nop) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (return) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (i32.store $asyncify_memory + ;; SIZE-NEXT: (i32.load $asyncify_memory + ;; SIZE-NEXT: (global.get $__asyncify_data) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (local.get $8) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (i32.store $asyncify_memory + ;; SIZE-NEXT: (global.get $__asyncify_data) + ;; SIZE-NEXT: (i32.add + ;; SIZE-NEXT: (i32.load $asyncify_memory + ;; SIZE-NEXT: (global.get $__asyncify_data) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (i32.const 4) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (block + ;; SIZE-NEXT: (local.set $11 + ;; SIZE-NEXT: (i32.load $asyncify_memory + ;; SIZE-NEXT: (global.get $__asyncify_data) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (i32.store $asyncify_memory + ;; SIZE-NEXT: (local.get $11) + ;; SIZE-NEXT: (local.get $live0) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (i32.store $asyncify_memory offset=4 + ;; SIZE-NEXT: (local.get $11) + ;; SIZE-NEXT: (local.get $live1) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (i32.store $asyncify_memory + ;; SIZE-NEXT: (global.get $__asyncify_data) + ;; SIZE-NEXT: (i32.add + ;; SIZE-NEXT: (i32.load $asyncify_memory + ;; SIZE-NEXT: (global.get $__asyncify_data) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: (i32.const 8) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + ;; SIZE-NEXT: ) + (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)) + ) +) +;; CHECK: (func $asyncify_start_unwind (param $0 i32) +;; CHECK-NEXT: (global.set $__asyncify_state +;; CHECK-NEXT: (i32.const 1) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (global.set $__asyncify_data +;; CHECK-NEXT: (local.get $0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (if +;; CHECK-NEXT: (i32.gt_u +;; CHECK-NEXT: (i32.load $asyncify_memory +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (i32.load $asyncify_memory offset=4 +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) + +;; CHECK: (func $asyncify_stop_unwind +;; CHECK-NEXT: (global.set $__asyncify_state +;; CHECK-NEXT: (i32.const 0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (if +;; CHECK-NEXT: (i32.gt_u +;; CHECK-NEXT: (i32.load $asyncify_memory +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (i32.load $asyncify_memory offset=4 +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) + +;; CHECK: (func $asyncify_start_rewind (param $0 i32) +;; CHECK-NEXT: (global.set $__asyncify_state +;; CHECK-NEXT: (i32.const 2) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (global.set $__asyncify_data +;; CHECK-NEXT: (local.get $0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (if +;; CHECK-NEXT: (i32.gt_u +;; CHECK-NEXT: (i32.load $asyncify_memory +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (i32.load $asyncify_memory offset=4 +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) + +;; CHECK: (func $asyncify_stop_rewind +;; CHECK-NEXT: (global.set $__asyncify_state +;; CHECK-NEXT: (i32.const 0) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (if +;; CHECK-NEXT: (i32.gt_u +;; CHECK-NEXT: (i32.load $asyncify_memory +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (i32.load $asyncify_memory offset=4 +;; CHECK-NEXT: (global.get $__asyncify_data) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) +;; CHECK-NEXT: (unreachable) +;; CHECK-NEXT: ) +;; CHECK-NEXT: ) + +;; CHECK: (func $asyncify_get_state (result i32) +;; CHECK-NEXT: (global.get $__asyncify_state) +;; CHECK-NEXT: ) + +;; SIZE: (func $asyncify_start_unwind (param $0 i32) +;; SIZE-NEXT: (global.set $__asyncify_state +;; SIZE-NEXT: (i32.const 1) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (global.set $__asyncify_data +;; SIZE-NEXT: (local.get $0) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (if +;; SIZE-NEXT: (i32.gt_u +;; SIZE-NEXT: (i32.load $asyncify_memory +;; SIZE-NEXT: (global.get $__asyncify_data) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (i32.load $asyncify_memory offset=4 +;; SIZE-NEXT: (global.get $__asyncify_data) +;; SIZE-NEXT: ) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (unreachable) +;; SIZE-NEXT: ) +;; SIZE-NEXT: ) + +;; SIZE: (func $asyncify_stop_unwind +;; SIZE-NEXT: (global.set $__asyncify_state +;; SIZE-NEXT: (i32.const 0) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (if +;; SIZE-NEXT: (i32.gt_u +;; SIZE-NEXT: (i32.load $asyncify_memory +;; SIZE-NEXT: (global.get $__asyncify_data) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (i32.load $asyncify_memory offset=4 +;; SIZE-NEXT: (global.get $__asyncify_data) +;; SIZE-NEXT: ) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (unreachable) +;; SIZE-NEXT: ) +;; SIZE-NEXT: ) + +;; SIZE: (func $asyncify_start_rewind (param $0 i32) +;; SIZE-NEXT: (global.set $__asyncify_state +;; SIZE-NEXT: (i32.const 2) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (global.set $__asyncify_data +;; SIZE-NEXT: (local.get $0) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (if +;; SIZE-NEXT: (i32.gt_u +;; SIZE-NEXT: (i32.load $asyncify_memory +;; SIZE-NEXT: (global.get $__asyncify_data) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (i32.load $asyncify_memory offset=4 +;; SIZE-NEXT: (global.get $__asyncify_data) +;; SIZE-NEXT: ) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (unreachable) +;; SIZE-NEXT: ) +;; SIZE-NEXT: ) + +;; SIZE: (func $asyncify_stop_rewind +;; SIZE-NEXT: (global.set $__asyncify_state +;; SIZE-NEXT: (i32.const 0) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (if +;; SIZE-NEXT: (i32.gt_u +;; SIZE-NEXT: (i32.load $asyncify_memory +;; SIZE-NEXT: (global.get $__asyncify_data) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (i32.load $asyncify_memory offset=4 +;; SIZE-NEXT: (global.get $__asyncify_data) +;; SIZE-NEXT: ) +;; SIZE-NEXT: ) +;; SIZE-NEXT: (unreachable) +;; SIZE-NEXT: ) +;; SIZE-NEXT: ) + +;; SIZE: (func $asyncify_get_state (result i32) +;; SIZE-NEXT: (global.get $__asyncify_state) +;; SIZE-NEXT: ) |