summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2018-04-27 14:49:02 -0700
committerGitHub <noreply@github.com>2018-04-27 14:49:02 -0700
commit7e8a47add58ebf5f39523fe70461aa7119ee490d (patch)
treea88fb6058ea1f61a7a0db8b80113d9cf39377e1d /src
parent52d14d008a6a836c2cdbfe68852d274840e5de14 (diff)
downloadbinaryen-7e8a47add58ebf5f39523fe70461aa7119ee490d.tar.gz
binaryen-7e8a47add58ebf5f39523fe70461aa7119ee490d.tar.bz2
binaryen-7e8a47add58ebf5f39523fe70461aa7119ee490d.zip
precompute-propagate may benefit from multiple passes (#1518)
One pass may remove code that includes a tee which then makes more optimization possible. Found by the Souper investigations.
Diffstat (limited to 'src')
-rw-r--r--src/passes/Precompute.cpp27
1 files changed, 19 insertions, 8 deletions
diff --git a/src/passes/Precompute.cpp b/src/passes/Precompute.cpp
index db7d8b772..32f54721d 100644
--- a/src/passes/Precompute.cpp
+++ b/src/passes/Precompute.cpp
@@ -130,15 +130,24 @@ struct Precompute : public WalkerPass<PostWalker<Precompute, UnifiedExpressionVi
GetValues getValues;
+ bool worked;
+
void doWalkFunction(Function* func) {
- // with extra effort, we can utilize the get-set graph to precompute
- // things that use locals that are known to be constant. otherwise,
- // we just look at what is immediately before us
- if (propagate) {
- optimizeLocals(func);
- }
- // do the main and final walk over everything
- super::doWalkFunction(func);
+ // if propagating, we may need multiple rounds: each propagation can
+ // lead to the main walk removing code, which might open up more
+ // propagation opportunities
+ do {
+ getValues.clear();
+ // with extra effort, we can utilize the get-set graph to precompute
+ // things that use locals that are known to be constant. otherwise,
+ // we just look at what is immediately before us
+ if (propagate) {
+ optimizeLocals(func);
+ }
+ // do the main walk over everything
+ worked = false;
+ super::doWalkFunction(func);
+ } while (propagate && worked);
}
void visitExpression(Expression* curr) {
@@ -198,6 +207,7 @@ struct Precompute : public WalkerPass<PostWalker<Precompute, UnifiedExpressionVi
// this was precomputed
if (isConcreteType(flow.value.type)) {
replaceCurrent(Builder(*getModule()).makeConst(flow.value));
+ worked = true;
} else {
ExpressionManipulator::nop(curr);
}
@@ -236,6 +246,7 @@ private:
return flow.value;
}
+ // Propagates values around. Returns whether we propagated.
void optimizeLocals(Function* func) {
// using the graph of get-set interactions, do a constant-propagation type
// operation: note which sets are assigned locals, then see if that lets us