aboutsummaryrefslogtreecommitdiff
path: root/tools/js-optimizer.js
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-05-10 16:39:14 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-05-10 17:33:23 -0700
commit945c2fcf445e0cc1bf62c43383f902d3a7bdb04c (patch)
treef07bdb3c8def3fa256b5bc5c200e4327cbbd4513 /tools/js-optimizer.js
parenta9fd678ff86b79043e59061fe66093f8dccca45f (diff)
recursively remove variables with no uses in eliminator
Diffstat (limited to 'tools/js-optimizer.js')
-rw-r--r--tools/js-optimizer.js27
1 files changed, 26 insertions, 1 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 56ff971c..0bb61eae 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -1837,7 +1837,14 @@ function eliminate(ast, memSafe) {
});
var potentials = {}; // local variables with 1 definition and 1 use
var sideEffectFree = {}; // whether a local variable has no side effects in its definition
- for (var name in locals) {
+
+ function unprocessVariable(name) {
+ if (name in potentials) delete potentials[name];
+ if (name in varsToRemove) delete varsToRemove[name];
+ if (name in sideEffectFree) delete sideEffectFree[name];
+ if (name in varsToTryToRemove) delete varsToTryToRemove[name];
+ }
+ function processVariable(name) {
if (definitions[name] == 1 && uses[name] == 1) {
potentials[name] = 1;
} else if (uses[name] == 0 && (!definitions[name] || definitions[name] <= 1)) { // no uses, no def or 1 def (cannot operate on phis, and the llvm optimizer will remove unneeded phis anyhow)
@@ -1862,11 +1869,29 @@ function eliminate(ast, memSafe) {
if (!hasSideEffects) {
varsToRemove[name] = !definitions[name] ? 2 : 1; // remove it normally
sideEffectFree[name] = true;
+ // Each time we remove a variable with 0 uses, if its value has no
+ // side effects and vanishes too, then we can remove a use from variables
+ // appearing in it, and possibly eliminate again
+ if (value) {
+ traverse(value, function(node, type) {
+ if (type == 'name') {
+ var name = node[1];
+ uses[name]--; // cannot be infinite recursion since we descend an energy function
+ assert(uses[name] >= 0);
+ unprocessVariable(name);
+ processVariable(name);
+ }
+ });
+ }
} else {
varsToTryToRemove[name] = 1; // try to remove it later during scanning
}
}
}
+ for (var name in locals) {
+ processVariable(name);
+ }
+
//printErr('defs: ' + JSON.stringify(definitions));
//printErr('uses: ' + JSON.stringify(uses));
//printErr('values: ' + JSON.stringify(values));