diff options
author | Heejin Ahn <aheejin@gmail.com> | 2019-12-12 23:01:56 -0800 |
---|---|---|
committer | GitHub <noreply@github.com> | 2019-12-12 23:01:56 -0800 |
commit | fbce98c6fdeb2a78ef58079ce1c2a385a17357d6 (patch) | |
tree | ce3bcfcb7b9861fc82cdd545146aa19d143876ec /src | |
parent | 16c6b44da64630cd6906433cf35edabcea93cffc (diff) | |
download | binaryen-fbce98c6fdeb2a78ef58079ce1c2a385a17357d6.tar.gz binaryen-fbce98c6fdeb2a78ef58079ce1c2a385a17357d6.tar.bz2 binaryen-fbce98c6fdeb2a78ef58079ce1c2a385a17357d6.zip |
Remove redundant instructions in Flatten (#2524)
When the expression type is none, it does not seem to be necessary to
make it a prelude and insert a nop. This also results in unnecessary
blocks that contains an expression with a nop, which can be reduced to
just the expression. This also adds some newlines to improve
readability.
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/Flatten.cpp | 40 |
1 files changed, 23 insertions, 17 deletions
diff --git a/src/passes/Flatten.cpp b/src/passes/Flatten.cpp index 74788afb5..f5115567b 100644 --- a/src/passes/Flatten.cpp +++ b/src/passes/Flatten.cpp @@ -61,12 +61,17 @@ struct Flatten std::vector<Expression*> ourPreludes; Builder builder(*getModule()); + if (curr->is<Const>() || curr->is<Nop>() || curr->is<Unreachable>()) { + return; + } + if (Flat::isControlFlowStructure(curr)) { // handle control flow explicitly. our children do not have control flow, // but they do have preludes which we need to set up in the right place // no one should have given us preludes, they are on the children assert(preludes.find(curr) == preludes.end()); + if (auto* block = curr->dynCast<Block>()) { // make a new list, where each item's preludes are added before it ExpressionList newList(getModule()->allocator); @@ -106,6 +111,7 @@ struct Flatten } // the block now has no return value, and may have become unreachable block->finalize(none); + } else if (auto* iff = curr->dynCast<If>()) { // condition preludes go before the entire if auto* rep = getPreludesWithExpression(iff->condition, iff); @@ -138,6 +144,7 @@ struct Flatten ourPreludes.push_back(prelude); } replaceCurrent(rep); + } else if (auto* loop = curr->dynCast<Loop>()) { // remove a loop value Expression* rep = loop; @@ -155,15 +162,18 @@ struct Flatten loop->body = getPreludesWithExpression(originalBody, loop->body); loop->finalize(); replaceCurrent(rep); + } else { WASM_UNREACHABLE("unexpected expr type"); } + } else { // for anything else, there may be existing preludes auto iter = preludes.find(curr); if (iter != preludes.end()) { ourPreludes.swap(iter->second); } + // special handling if (auto* set = curr->dynCast<LocalSet>()) { if (set->isTee()) { @@ -178,6 +188,7 @@ struct Flatten replaceCurrent(builder.makeLocalGet(set->index, localType)); } } + } else if (auto* br = curr->dynCast<Break>()) { if (br->value) { auto type = br->value->type; @@ -203,6 +214,7 @@ struct Flatten replaceCurrent(br->value); } } + } else if (auto* sw = curr->dynCast<Switch>()) { if (sw->value) { auto type = sw->value->type; @@ -227,28 +239,22 @@ struct Flatten } } } + // continue for general handling of everything, control flow or otherwise curr = getCurrent(); // we may have replaced it // we have changed children ReFinalizeNode().visit(curr); - // move everything to the prelude, if we need to: anything but constants - if (!curr->is<Const>()) { - if (curr->type == unreachable) { - ourPreludes.push_back(curr); - replaceCurrent(builder.makeUnreachable()); - } else if (curr->type == none) { - if (!curr->is<Nop>()) { - ourPreludes.push_back(curr); - replaceCurrent(builder.makeNop()); - } - } else { - // use a local - auto type = curr->type; - Index temp = builder.addVar(getFunction(), type); - ourPreludes.push_back(builder.makeLocalSet(temp, curr)); - replaceCurrent(builder.makeLocalGet(temp, type)); - } + if (curr->type == unreachable) { + ourPreludes.push_back(curr); + replaceCurrent(builder.makeUnreachable()); + } else if (curr->type.isConcrete()) { + // use a local + auto type = curr->type; + Index temp = builder.addVar(getFunction(), type); + ourPreludes.push_back(builder.makeLocalSet(temp, curr)); + replaceCurrent(builder.makeLocalGet(temp, type)); } + // next, finish up: migrate our preludes if we can if (!ourPreludes.empty()) { auto* parent = getParent(); |