diff options
author | Alon Zakai <alonzakai@gmail.com> | 2018-04-27 14:49:02 -0700 |
---|---|---|
committer | GitHub <noreply@github.com> | 2018-04-27 14:49:02 -0700 |
commit | 7e8a47add58ebf5f39523fe70461aa7119ee490d (patch) | |
tree | a88fb6058ea1f61a7a0db8b80113d9cf39377e1d /src | |
parent | 52d14d008a6a836c2cdbfe68852d274840e5de14 (diff) | |
download | binaryen-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.cpp | 27 |
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 |