diff options
-rw-r--r-- | tools/eliminator/asm-eliminator-test-output.js | 4 | ||||
-rw-r--r-- | tools/eliminator/asm-eliminator-test.js | 10 | ||||
-rw-r--r-- | tools/js-optimizer.js | 23 |
3 files changed, 29 insertions, 8 deletions
diff --git a/tools/eliminator/asm-eliminator-test-output.js b/tools/eliminator/asm-eliminator-test-output.js index 4cd9cbaa..b519cdf9 100644 --- a/tools/eliminator/asm-eliminator-test-output.js +++ b/tools/eliminator/asm-eliminator-test-output.js @@ -129,4 +129,8 @@ function confuusion() { j = i; func2(+j); } +function tempDouble(a) { + a = +a; + f(a * a); +} diff --git a/tools/eliminator/asm-eliminator-test.js b/tools/eliminator/asm-eliminator-test.js index 9dc71835..ff67af47 100644 --- a/tools/eliminator/asm-eliminator-test.js +++ b/tools/eliminator/asm-eliminator-test.js @@ -162,5 +162,13 @@ function confuusion() { var j = i; // add this var in the middle. should show up with right type later, auto-inferred from i's type func2(+j); } -// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "__Z11printResultPiS_j", "_segment_holding", "__ZN5identC2EiPKcPci", "_vec2Length", "exc", "label", "confuusion"] +function tempDouble(a) { + a = +a; + var x = +0, y = +0; + // CastAway can leave things like this as variables no longer needed. We need to identify that x's value has no side effects so it can be completely cleaned up + x = (HEAP32[((tempDoublePtr)>>2)]=((HEAP32[(($_sroa_0_0__idx1)>>2)])|0),HEAP32[(((tempDoublePtr)+(4))>>2)]=((HEAP32[((($_sroa_0_0__idx1)+(4))>>2)])|0),(+(HEAPF64[(tempDoublePtr)>>3]))); + y = a*a; + f(y); +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "__Z11printResultPiS_j", "_segment_holding", "__ZN5identC2EiPKcPci", "_vec2Length", "exc", "label", "confuusion", "tempDouble"] diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 815baed8..56ff971c 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -1842,13 +1842,22 @@ function eliminate(ast, memSafe) { 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) var hasSideEffects = false; - if (values[name]) { - traverse(values[name], function(node, type) { - if (!(type in NODES_WITHOUT_ELIMINATION_SIDE_EFFECTS)) { - hasSideEffects = true; // cannot remove this unused variable, constructing it has side effects - return true; - } - }); + var value = values[name]; + if (value) { + // TODO: merge with other side effect code + // First, pattern-match + // (HEAP32[((tempDoublePtr)>>2)]=((HEAP32[(($_sroa_0_0__idx1)>>2)])|0),HEAP32[(((tempDoublePtr)+(4))>>2)]=((HEAP32[((($_sroa_0_0__idx1)+(4))>>2)])|0),(+(HEAPF64[(tempDoublePtr)>>3]))) + // which has no side effects and is the special form of converting double to i64. + if (!(value[0] == 'seq' && value[1][0] == 'assign' && value[1][2][0] == 'sub' && value[1][2][2][0] == 'binary' && value[1][2][2][1] == '>>' && + value[1][2][2][2][0] == 'name' && value[1][2][2][2][1] == 'tempDoublePtr')) { + // If not that, then traverse and scan normally. + traverse(value, function(node, type) { + if (!(type in NODES_WITHOUT_ELIMINATION_SIDE_EFFECTS)) { + hasSideEffects = true; // cannot remove this unused variable, constructing it has side effects + return true; + } + }); + } } if (!hasSideEffects) { varsToRemove[name] = !definitions[name] ? 2 : 1; // remove it normally |