From 3c961d1383629e9907bc8d4c5b6f1f566d13a3f2 Mon Sep 17 00:00:00 2001 From: Alon Zakai Date: Mon, 11 Apr 2016 20:27:35 -0700 Subject: continue simplifying locals while opportunities present themselves --- src/passes/SimplifyLocals.cpp | 60 ++++++++++++++++++++++++++----------------- 1 file changed, 37 insertions(+), 23 deletions(-) (limited to 'src/passes/SimplifyLocals.cpp') diff --git a/src/passes/SimplifyLocals.cpp b/src/passes/SimplifyLocals.cpp index 77e4f788a..faf6e3a6e 100644 --- a/src/passes/SimplifyLocals.cpp +++ b/src/passes/SimplifyLocals.cpp @@ -41,6 +41,8 @@ struct SimplifyLocals : public WalkerPass> // locals in current linear execution trace, which we try to sink std::map sinkables; + bool sunk; + // name => # of get_locals for it std::map numGetLocals; @@ -60,6 +62,7 @@ struct SimplifyLocals : public WalkerPass> *found->second.item = curr; ExpressionManipulator::nop(curr); sinkables.erase(found); + sunk = true; } else { numGetLocals[curr->name]++; } @@ -150,31 +153,42 @@ struct SimplifyLocals : public WalkerPass> self->pushTask(visitPre, currp); } - void visitFunction(Function *curr) { - // after optimizing a function, we can see if we have set_locals - // for a local with no remaining gets, in which case, we can - // remove the set. - std::vector optimizables; - for (auto pair : setLocalOrigins) { - SetLocal* curr = pair.first; - if (numGetLocals[curr->name] == 0) { - // no gets, can remove the set and leave just the value - optimizables.push_back(curr); + void startWalk(Function *func) { + // multiple passes may be required per function, consider this: + // x = load + // y = store + // c(x, y) + // the load cannot cross the store, but y can be sunk, after which so can x + do { + sunk = false; + // main operation + walk(func->body); + // after optimizing a function, we can see if we have set_locals + // for a local with no remaining gets, in which case, we can + // remove the set. + std::vector optimizables; + for (auto pair : setLocalOrigins) { + SetLocal* curr = pair.first; + if (numGetLocals[curr->name] == 0) { + // no gets, can remove the set and leave just the value + optimizables.push_back(curr); + } } - } - for (auto* curr : optimizables) { - Expression** origin = setLocalOrigins[curr]; - *origin = curr->value; - // nested set_values need to be handled properly. - // consider (set_local x (set_local y (..)), where both can be - // reduced to their values, and we might do it in either - // order. - if (curr->value->is()) { - setLocalOrigins[curr->value->cast()] = origin; + for (auto* curr : optimizables) { + Expression** origin = setLocalOrigins[curr]; + *origin = curr->value; + // nested set_values need to be handled properly. + // consider (set_local x (set_local y (..)), where both can be + // reduced to their values, and we might do it in either + // order. + if (curr->value->is()) { + setLocalOrigins[curr->value->cast()] = origin; + } } - } - numGetLocals.clear(); - setLocalOrigins.clear(); + // clean up + numGetLocals.clear(); + setLocalOrigins.clear(); + } while (sunk); } }; -- cgit v1.2.3