summaryrefslogtreecommitdiff
path: root/src/passes/OptimizeAddedConstants.cpp
diff options
context:
space:
mode:
authorAlon Zakai <azakai@google.com>2019-03-06 11:15:42 -0800
committerAlon Zakai <alonzakai@gmail.com>2019-03-06 16:34:34 -0800
commit22fe3269f79c38c7954967ec303642b5168844c3 (patch)
tree7a49400f32d013eb7ce72e15ac8a9ec71f1e2d77 /src/passes/OptimizeAddedConstants.cpp
parent56fc114121716c672d4a16f92e8323eada557177 (diff)
downloadbinaryen-22fe3269f79c38c7954967ec303642b5168844c3.tar.gz
binaryen-22fe3269f79c38c7954967ec303642b5168844c3.tar.bz2
binaryen-22fe3269f79c38c7954967ec303642b5168844c3.zip
Run multiple iterations in OptimizeAddedConstants
Multiple propagations may be possible in some cases, like nested structs in C.
Diffstat (limited to 'src/passes/OptimizeAddedConstants.cpp')
-rw-r--r--src/passes/OptimizeAddedConstants.cpp46
1 files changed, 33 insertions, 13 deletions
diff --git a/src/passes/OptimizeAddedConstants.cpp b/src/passes/OptimizeAddedConstants.cpp
index 9e339ed38..f6158cb2d 100644
--- a/src/passes/OptimizeAddedConstants.cpp
+++ b/src/passes/OptimizeAddedConstants.cpp
@@ -41,19 +41,22 @@ template<typename P, typename T>
class MemoryAccessOptimizer {
public:
MemoryAccessOptimizer(P* parent, T* curr, Module* module, LocalGraph* localGraph) :
- parent(parent), curr(curr), module(module), localGraph(localGraph) {
+ parent(parent), curr(curr), module(module), localGraph(localGraph) {}
+
+ // Tries to optimize, and returns whether we propagated a change.
+ bool optimize() {
// The pointer itself may be a constant, if e.g. it was precomputed or
// a get that we propagated.
if (curr->ptr->template is<Const>()) {
optimizeConstantPointer();
- return;
+ return false;
}
if (auto* add = curr->ptr->template dynCast<Binary>()) {
if (add->op == AddInt32) {
// Look for a constant on both sides.
if (tryToOptimizeConstant(add->right, add->left) ||
tryToOptimizeConstant(add->left, add->right)) {
- return;
+ return false;
}
}
}
@@ -84,7 +87,7 @@ public:
// old value.
if (tryToOptimizePropagatedAdd(add->right, add->left, get, set) ||
tryToOptimizePropagatedAdd(add->left, add->right, get, set)) {
- return;
+ return true;
}
}
}
@@ -92,6 +95,7 @@ public:
}
}
}
+ return false;
}
private:
@@ -233,23 +237,37 @@ struct OptimizeAddedConstants : public WalkerPass<PostWalker<OptimizeAddedConsta
std::unique_ptr<LocalGraph> localGraph;
void visitLoad(Load* curr) {
- MemoryAccessOptimizer<OptimizeAddedConstants, Load>(this, curr, getModule(), localGraph.get());
+ MemoryAccessOptimizer<OptimizeAddedConstants, Load> optimizer(this, curr, getModule(), localGraph.get());
+ if (optimizer.optimize()) {
+ propagated = true;
+ }
}
void visitStore(Store* curr) {
- MemoryAccessOptimizer<OptimizeAddedConstants, Store>(this, curr, getModule(), localGraph.get());
+ MemoryAccessOptimizer<OptimizeAddedConstants, Store> optimizer(this, curr, getModule(), localGraph.get());
+ if (optimizer.optimize()) {
+ propagated = true;
+ }
}
void doWalkFunction(Function* func) {
// This pass is only valid under the assumption of unused low memory.
assert(getPassOptions().lowMemoryUnused);
- if (propagate) {
- localGraph = make_unique<LocalGraph>(func);
- localGraph->computeSSAIndexes();
- }
- super::doWalkFunction(func);
- if (!helperIndexes.empty()) {
- createHelperIndexes();
+ // Multiple passes may be needed if we have x + 4 + 8 etc. (nested structs in C
+ // can cause this, but it's rare). Note that we only need that for the propagation
+ // case (as 4 + 8 would be optimized directly if it were adjacent).
+ while (1) {
+ propagated = false;
+ if (propagate) {
+ localGraph = make_unique<LocalGraph>(func);
+ localGraph->computeSSAIndexes();
+ }
+ super::doWalkFunction(func);
+ if (!helperIndexes.empty()) {
+ createHelperIndexes();
+ helperIndexes.clear();
+ }
+ if (!propagated) return;
}
}
@@ -269,6 +287,8 @@ struct OptimizeAddedConstants : public WalkerPass<PostWalker<OptimizeAddedConsta
private:
std::map<SetLocal*, Index> helperIndexes;
+ bool propagated;
+
void createHelperIndexes() {
struct Creator : public PostWalker<Creator> {
std::map<SetLocal*, Index>& helperIndexes;