diff options
Diffstat (limited to 'src/passes/Asyncify.cpp')
-rw-r--r-- | src/passes/Asyncify.cpp | 43 |
1 files changed, 26 insertions, 17 deletions
diff --git a/src/passes/Asyncify.cpp b/src/passes/Asyncify.cpp index 9ed201c45..7d0b72964 100644 --- a/src/passes/Asyncify.cpp +++ b/src/passes/Asyncify.cpp @@ -530,10 +530,9 @@ public: const String::Split& removeListInput, const String::Split& addListInput, const String::Split& onlyListInput, - bool asserts, bool verbose) : module(module), canIndirectChangeState(canIndirectChangeState), - fakeGlobals(module), asserts(asserts), verbose(verbose) { + fakeGlobals(module), verbose(verbose) { PatternMatcher removeList("remove", module, removeListInput); PatternMatcher addList("add", module, addListInput); @@ -784,7 +783,6 @@ public: } FakeGlobalHelper fakeGlobals; - bool asserts; bool verbose; }; @@ -841,11 +839,6 @@ public: makeGlobalGet(ASYNCIFY_STATE, Type::i32), makeConst(Literal(int32_t(value)))); } - - Expression* makeNegatedStateCheck(State value) { - return makeUnary(Abstract::getUnary(pointerType, Abstract::EqZ), - makeStateCheck(value)); - } }; // Proxy that runs wrapped pass for instrumented functions only @@ -1180,9 +1173,9 @@ private: // TODO: we can read the next call index once in each function (but should // avoid saving/restoring that local later) curr = builder->makeIf( - builder->makeIf(builder->makeStateCheck(State::Normal), - builder->makeConst(int32_t(1)), - makeCallIndexPeek(index)), + builder->makeBinary(OrInt32, + builder->makeStateCheck(State::Normal), + makeCallIndexPeek(index)), builder->makeSequence(curr, makePossibleUnwind(index, set))); return curr; } @@ -1347,11 +1340,10 @@ struct AsyncifyLocals : public WalkerPass<PostWalker<AsyncifyLocals>> { Type::i32, asyncifyMemory)))); } else if (curr->target == ASYNCIFY_CHECK_CALL_INDEX) { - replaceCurrent(builder->makeBinary( - EqInt32, - builder->makeLocalGet(rewindIndex, Type::i32), - builder->makeConst( - Literal(int32_t(curr->operands[0]->cast<Const>()->value.geti32()))))); + replaceCurrent( + builder->makeBinary(EqInt32, + builder->makeLocalGet(rewindIndex, Type::i32), + curr->operands[0])); } } @@ -1688,7 +1680,6 @@ struct Asyncify : public Pass { removeList, addList, onlyList, - asserts, verbose); // Add necessary globals before we emit code to use them. @@ -1936,6 +1927,24 @@ struct ModAsyncify } } + void visitUnary(Unary* curr) { + if (curr->op != EqZInt32) { + return; + } + auto* get = curr->value->dynCast<GlobalGet>(); + if (!get || get->name != asyncifyStateName) { + return; + } + // This is a comparison of the state to zero, which means we are checking + // "if running normally, run this code, but if rewinding, ignore it". If + // we know we'll never rewind, we can optimize this. + if (neverRewind) { + Builder builder(*this->getModule()); + // The whole expression will be 1 because it is (i32.eqz (i32.const 0)) + this->replaceCurrent(builder.makeConst(int32_t(1))); + } + } + void visitCall(Call* curr) { unsetUnwinding(); if (!importsAlwaysUnwind) { |