diff options
author | Alon Zakai <alonzakai@gmail.com> | 2017-05-17 11:29:11 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2017-05-17 11:29:11 -0700 |
commit | bb1c44a3f975bf8fb72216b9c04bcd34e31bd815 (patch) | |
tree | 90c6dc049931981ef28bc4728113528b1627595b /src | |
parent | 443cfe929d094e34d8d84270965c738743d06585 (diff) | |
download | binaryen-bb1c44a3f975bf8fb72216b9c04bcd34e31bd815.tar.gz binaryen-bb1c44a3f975bf8fb72216b9c04bcd34e31bd815.tar.bz2 binaryen-bb1c44a3f975bf8fb72216b9c04bcd34e31bd815.zip |
optimize if and select in the case their values are identical (#1013)
Diffstat (limited to 'src')
-rw-r--r-- | src/passes/OptimizeInstructions.cpp | 39 |
1 files changed, 39 insertions, 0 deletions
diff --git a/src/passes/OptimizeInstructions.cpp b/src/passes/OptimizeInstructions.cpp index c1787b57d..50a7c5589 100644 --- a/src/passes/OptimizeInstructions.cpp +++ b/src/passes/OptimizeInstructions.cpp @@ -596,6 +596,18 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions, std::swap(iff->ifTrue, iff->ifFalse); } } + if (ExpressionAnalyzer::equal(iff->ifTrue, iff->ifFalse)) { + // sides are identical, fold + if (!EffectAnalyzer(getPassOptions(), iff->condition).hasSideEffects()) { + return iff->ifTrue; + } else { + Builder builder(*getModule()); + return builder.makeSequence( + builder.makeDrop(iff->condition), + iff->ifTrue + ); + } + } } } else if (auto* select = curr->dynCast<Select>()) { select->condition = optimizeBoolean(select->condition); @@ -609,6 +621,33 @@ struct OptimizeInstructions : public WalkerPass<PostWalker<OptimizeInstructions, std::swap(select->ifTrue, select->ifFalse); } } + if (ExpressionAnalyzer::equal(select->ifTrue, select->ifFalse)) { + // sides are identical, fold + EffectAnalyzer value(getPassOptions(), select->ifTrue); + if (value.hasSideEffects()) { + // at best we don't need the condition, but need to execute the value + // twice. a block is larger than a select by 2 bytes, and + // we must drop one value, so 3, while we save the condition, + // so it's not clear this is worth it, TODO + } else { + // value has no side effects + EffectAnalyzer condition(getPassOptions(), select->condition); + if (!condition.hasSideEffects()) { + return select->ifTrue; + } else { + // the condition is last, so we need a new local, and it may be + // a bad idea to use a block like we do for an if. Do it only if we + // can reorder + if (!condition.invalidates(value)) { + Builder builder(*getModule()); + return builder.makeSequence( + builder.makeDrop(select->condition), + select->ifTrue + ); + } + } + } + } } else if (auto* br = curr->dynCast<Break>()) { if (br->condition) { br->condition = optimizeBoolean(br->condition); |