diff options
author | Heejin Ahn <aheejin@gmail.com> | 2023-10-03 15:17:31 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2023-10-03 15:17:31 -0700 |
commit | 5854873dfbf291018853f9da62c9cdb55007b27f (patch) | |
tree | 63c8d80153ddeb96e6ca5c47997abf7ae2568c61 /src/passes/Asyncify.cpp | |
parent | b14b2e3e931d421da1738da70369451402495c42 (diff) | |
download | binaryen-5854873dfbf291018853f9da62c9cdb55007b27f.tar.gz binaryen-5854873dfbf291018853f9da62c9cdb55007b27f.tar.bz2 binaryen-5854873dfbf291018853f9da62c9cdb55007b27f.zip |
Asyncify: Simpify if into i32.or (#5988)
```wast
(if (result i32)
(expr0)
(i32.const 1)
(expr1)
)
```
can be written as
```wast
(i32.or
(expr0)
(expr1)
)
```
Also this removes some unused variables and methods.
This also adds an optimization for
```wast
(i32.eqz
(global.get $__asyncify_state)
)
```
in `--mod-asyncify-always-and-only-unwind` to fix an unexpected
regression caused by this.
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) { |