summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2016-04-25 20:08:24 -0700
committerAlon Zakai <alonzakai@gmail.com>2016-04-25 20:16:36 -0700
commit791c765cda070e47d90577de2d798f046431d095 (patch)
treea3d3868d21e6a3c599f16f3847ff227d15116409 /src
parentcb35ee67868bdc2b8839766b7e10b65e8fcc122a (diff)
downloadbinaryen-791c765cda070e47d90577de2d798f046431d095.tar.gz
binaryen-791c765cda070e47d90577de2d798f046431d095.tar.bz2
binaryen-791c765cda070e47d90577de2d798f046431d095.zip
selectify if-elses with no control flow in them
Diffstat (limited to 'src')
-rw-r--r--src/ast_utils.h2
-rw-r--r--src/passes/RemoveUnusedBrs.cpp30
2 files changed, 31 insertions, 1 deletions
diff --git a/src/ast_utils.h b/src/ast_utils.h
index 36895ac51..5cda48578 100644
--- a/src/ast_utils.h
+++ b/src/ast_utils.h
@@ -52,7 +52,7 @@ struct EffectAnalyzer : public PostWalker<EffectAnalyzer, Visitor<EffectAnalyzer
bool accessesLocal() { return localsRead.size() + localsWritten.size() > 0; }
bool accessesMemory() { return calls || readsMemory || writesMemory; }
- bool hasSideEffects() { return calls || localsWritten.size() > 0 || writesMemory; }
+ bool hasSideEffects() { return calls || localsWritten.size() > 0 || writesMemory || branches; }
bool hasAnything() { return branches || calls || accessesLocal() || readsMemory || writesMemory; }
// checks if these effects would invalidate another set (e.g., if we write, we invalidate someone that reads, they can't be moved past us)
diff --git a/src/passes/RemoveUnusedBrs.cpp b/src/passes/RemoveUnusedBrs.cpp
index 1dd16d07b..f4efef173 100644
--- a/src/passes/RemoveUnusedBrs.cpp
+++ b/src/passes/RemoveUnusedBrs.cpp
@@ -175,6 +175,36 @@ struct RemoveUnusedBrs : public WalkerPass<PostWalker<RemoveUnusedBrs, Visitor<R
}
flows.clear();
} while (anotherCycle);
+ // finally, we may have simplified ifs enough to turn them into selects
+ struct Selectifier : public WalkerPass<PostWalker<Selectifier, Visitor<Selectifier>>> {
+ void visitIf(If* curr) {
+ if (curr->ifFalse) {
+ // if with else, consider turning it into a select if there is no control flow
+ // TODO: estimate cost
+ EffectAnalyzer condition;
+ condition.walk(curr->condition);
+ if (!condition.hasSideEffects()) {
+ EffectAnalyzer ifTrue;
+ ifTrue.walk(curr->ifTrue);
+ if (!ifTrue.hasSideEffects()) {
+ EffectAnalyzer ifFalse;
+ ifFalse.walk(curr->ifFalse);
+ if (!ifFalse.hasSideEffects()) {
+ auto* select = getModule()->allocator.alloc<Select>();
+ select->condition = curr->condition;
+ select->ifTrue = curr->ifTrue;
+ select->ifFalse = curr->ifFalse;
+ select->finalize();
+ replaceCurrent(select);
+ }
+ }
+ }
+ }
+ }
+ };
+ Selectifier selectifier;
+ selectifier.setModule(getModule());
+ selectifier.walk(root);
}
};