diff options
author | Alon Zakai <alonzakai@gmail.com> | 2012-12-06 17:39:59 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2012-12-07 14:23:24 -0800 |
commit | 556924460a93c8d7218225b8c52c4de1fef3c730 (patch) | |
tree | 3c15b765c5cfee6ad3fee95f83785d52f1c15fb0 /tools | |
parent | f3a52489d4316b25ee35dea49ff818b851460dc4 (diff) |
remove unneeded single assignments to otherwise-unused variables in eliminator
Diffstat (limited to 'tools')
-rw-r--r-- | tools/eliminator/asm-eliminator-test-output.js | 10 | ||||
-rw-r--r-- | tools/eliminator/asm-eliminator-test.js | 18 | ||||
-rw-r--r-- | tools/js-optimizer.js | 65 |
3 files changed, 68 insertions, 25 deletions
diff --git a/tools/eliminator/asm-eliminator-test-output.js b/tools/eliminator/asm-eliminator-test-output.js index 15d3a74c..70eca01a 100644 --- a/tools/eliminator/asm-eliminator-test-output.js +++ b/tools/eliminator/asm-eliminator-test-output.js @@ -64,4 +64,14 @@ function __ZN5identC2EiPKcPci($this, $n, $a) { HEAP32[($this + 40 & 16777215) >> 2] = 1; return; } +function _vec2Length($this) { + $this = $this | 0; + var $__first_addr_i = 0, $__last_addr_i = 0, __stackBase__ = 0; + __stackBase__ = STACKTOP; + STACKTOP = STACKTOP + 8 | 0; + $__first_addr_i = __stackBase__; + $__last_addr_i = __stackBase__ + 4; + STACKTOP = __stackBase__; + return 0; +} diff --git a/tools/eliminator/asm-eliminator-test.js b/tools/eliminator/asm-eliminator-test.js index 67cdf2a0..2fcf90d4 100644 --- a/tools/eliminator/asm-eliminator-test.js +++ b/tools/eliminator/asm-eliminator-test.js @@ -83,5 +83,21 @@ function __ZN5identC2EiPKcPci($this, $n, $a) { HEAP32[($this + 40 & 16777215) >> 2] = 1; return; } -// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "__Z11printResultPiS_j", "_segment_holding", "__ZN5identC2EiPKcPci"] +function _vec2Length($this) { + $this = $this | 0; + var $__first_addr_i = 0, $__last_addr_i = 0, $__comp_addr_i = 0, $a13 = 0, $a14 = 0, $a18 = 0, $a19 = 0; + var label = 0; + var __stackBase__ = 0; + __stackBase__ = STACKTOP; + STACKTOP = STACKTOP + 8 | 0; + $__first_addr_i = __stackBase__; + $__last_addr_i = __stackBase__ + 4; + $a13 = $__first_addr_i; + $a14 = $__last_addr_i; + $a18 = $__first_addr_i; + $a19 = $__last_addr_i; + STACKTOP = __stackBase__; + return 0; +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "__Z11printResultPiS_j", "_segment_holding", "__ZN5identC2EiPKcPci", "_vec2Length"] diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 222ebba0..daa08fe5 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -1260,7 +1260,7 @@ function normalizeAsm(func) { if (node[0] != 'var') break; node[1].forEach(function(v) { data.vars[v[0]] = detectAsmCoercion(v[1]); - v[1] = null; // make an un-assigning var + v.length = 1; // make an un-assigning var }); i++; } @@ -1273,12 +1273,12 @@ function normalizeAsm(func) { }); i++; } - //printErr('normalized \n\n' + astToSrc(func) + '\n\n'); + //printErr('normalized \n\n' + astToSrc(func) + '\n\nwith: ' + JSON.stringify(data)); return data; } function denormalizeAsm(func, data) { - //printErr('pre-denormalize \n\n' + astToSrc(func) + '\n\n'); + //printErr('pre-denormalize \n\n' + astToSrc(func) + '\n\nwith: ' + JSON.stringify(data)); var stats = func[3]; // Remove var definitions, if any for (var i = 0; i < stats.length; i++) { @@ -1556,7 +1556,7 @@ function eliminate(ast, memSafe, asm) { var uses = {}; var values = {}; var locals = {}; - var varsToRemove = {}; // variables being removed, that we can eliminate all 'var x;' of + var varsToRemove = {}; // variables being removed, that we can eliminate all 'var x;' of (this refers to 'var' nodes we should remove) var varsToTryToRemove = {}; // variables that have 0 uses, but have side effects - when we scan we can try to remove them // add arguments as locals if (func[2]) { @@ -1599,6 +1599,7 @@ function eliminate(ast, memSafe, asm) { } }); 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) { if (definitions[name] == 1 && uses[name] == 1) { potentials[name] = 1; @@ -1614,6 +1615,7 @@ function eliminate(ast, memSafe, asm) { } if (!hasSideEffects) { varsToRemove[name] = 1; // remove it normally + sideEffectFree[name] = true; } else { varsToTryToRemove[name] = 1; // try to remove it later during scanning } @@ -1621,10 +1623,11 @@ function eliminate(ast, memSafe, asm) { } //printErr('defs: ' + JSON.stringify(definitions)); //printErr('uses: ' + JSON.stringify(uses)); + //printErr('values: ' + JSON.stringify(values)); //printErr('locals: ' + JSON.stringify(locals)); //printErr('varsToRemove: ' + JSON.stringify(varsToRemove)); - //printErr('2varsToTryToRemove: ' + JSON.stringify(varsToTryToRemove)); - definitions = uses = values = null; + //printErr('varsToTryToRemove: ' + JSON.stringify(varsToTryToRemove)); + definitions = values = null; //printErr('potentials: ' + JSON.stringify(potentials)); // We can now proceed through the function. In each list of statements, we try to eliminate var tracked = {}; @@ -1756,6 +1759,12 @@ function eliminate(ast, memSafe, asm) { invalidateGlobals(); globalsInvalidated = true; } + // if we can track this name (that we assign into), and it has 0 uses and we want to remove its 'var' + // definition - then remove it right now, there is no later chance + if (allowTracking && (name in varsToRemove) && uses[name] == 0) { + track(name, node[3], node); + doEliminate(name, node); + } } else { // replace it in-place node.length = value.length; @@ -1906,24 +1915,31 @@ function eliminate(ast, memSafe, asm) { var info = tracked[name]; delete tracked[name]; var defNode = info.defNode; - if (defNode[0] == 'var') { - defNode[1].forEach(function(pair) { - if (pair[0] == name) { - value = pair[1]; - } - }); - assert(value); - } else { // assign - value = defNode[3]; - // wipe out the assign - defNode[0] = 'toplevel'; - defNode[1] = []; - defNode.length = 2; - } - // replace this node in-place - node.length = 0; - for (var i = 0; i < value.length; i++) { - node[i] = value[i]; + if (!sideEffectFree[name]) { + if (defNode[0] == 'var') { + defNode[1].forEach(function(pair) { + if (pair[0] == name) { + value = pair[1]; + } + }); + assert(value); + } else { // assign + value = defNode[3]; + // wipe out the assign + defNode[0] = 'toplevel'; + defNode[1] = []; + defNode.length = 2; + } + // replace this node in-place + node.length = 0; + for (var i = 0; i < value.length; i++) { + node[i] = value[i]; + } + } else { + // empty it out in-place + node.length = 0; + node[0] = 'toplevel'; + node[1] = []; } } traverse(func, function(block) { @@ -1946,6 +1962,7 @@ function eliminate(ast, memSafe, asm) { tracked = {}; // not a var or assign, break all potential elimination so far } } + //printErr('delete StatBlock'); }); // clean up vars |