diff options
author | Ryan Kelly <ryan@rfk.id.au> | 2014-05-20 15:17:18 +1000 |
---|---|---|
committer | Ryan Kelly <ryan@rfk.id.au> | 2014-05-20 15:17:18 +1000 |
commit | 751756ddffdbdf8061b4b73ac6848c0a1f5e61b7 (patch) | |
tree | e843256a528a9c1abaeac19019af0a66fa7465b6 | |
parent | 16d6cb35b4f1a78b1c435999f4081bdc0c566ac8 (diff) |
Fix elimination of conditional expressions in registerizeHarder.
Previously, attempts to eliminate a side-effect-free conditional
expression would corrupt internal block state, because the sub-nodes
belong to a different block than the one containing the expression.
This fixes the problem by not splitting side-effect free conditionals
across multiple blocks.
-rw-r--r-- | tools/js-optimizer.js | 34 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-regs-harder-output.js | 5 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-regs-harder.js | 8 |
3 files changed, 35 insertions, 12 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 088c4f0f..2004efda 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -2237,18 +2237,30 @@ function registerizeHarder(ast) { break; case 'conditional': isInExpr++; - buildFlowGraph(node[1]); - var jEnter = markJunction(); - var jExit = addJunction(); - if (node[2]) { - buildFlowGraph(node[2]); - } - joinJunction(jExit); - setJunction(jEnter); - if (node[3]) { - buildFlowGraph(node[3]); + // If the conditional has no side-effects, we can treat it as a single + // block, which might open up opportunities to remove it entirely. + if (!hasSideEffects(node)) { + buildFlowGraph(node[1]); + if (node[2]) { + buildFlowGraph(node[2]); + } + if (node[3]) { + buildFlowGraph(node[3]); + } + } else { + buildFlowGraph(node[1]); + var jEnter = markJunction(); + var jExit = addJunction(); + if (node[2]) { + buildFlowGraph(node[2]); + } + joinJunction(jExit); + setJunction(jEnter); + if (node[3]) { + buildFlowGraph(node[3]); + } + joinJunction(jExit); } - joinJunction(jExit); isInExpr--; break; case 'while': diff --git a/tools/test-js-optimizer-asm-regs-harder-output.js b/tools/test-js-optimizer-asm-regs-harder-output.js index e1df42cb..c3b326f6 100644 --- a/tools/test-js-optimizer-asm-regs-harder-output.js +++ b/tools/test-js-optimizer-asm-regs-harder-output.js @@ -129,4 +129,9 @@ function linkedVars() { } return i2 + i1; } +function deadCondExpr(i2) { + i2 = i2 | 0; + var i1 = 0; + return i1 | 0; +} diff --git a/tools/test-js-optimizer-asm-regs-harder.js b/tools/test-js-optimizer-asm-regs-harder.js index 0231a215..fa72aab8 100644 --- a/tools/test-js-optimizer-asm-regs-harder.js +++ b/tools/test-js-optimizer-asm-regs-harder.js @@ -149,5 +149,11 @@ function linkedVars() { } return outer1 + outer2; } -// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "_doit", "stackRestore", "switchey", "switchey2", "iffey", "labelledJump", "linkedVars'] +function deadCondExpr(input) { + input = input|0; + var dead = 0, temp = 0; + dead = (!input ? -1 : input)|0; + return temp|0; +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "_doit", "stackRestore", "switchey", "switchey2", "iffey", "labelledJump", "linkedVars", "deadCondExpr"] |