diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-03-15 15:44:14 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-03-17 17:56:17 -0700 |
commit | 6c31546ced32fd968ae50da7803964c9195ebd62 (patch) | |
tree | 46ddb131a57a612e83f5d00efe847d3794725c94 | |
parent | f6c2bcd2a3058b4b36518aa4cabec2baa7222970 (diff) |
uncommaify between ifs that can potentially be simplified
-rwxr-xr-x | emcc | 4 | ||||
-rw-r--r-- | tools/js-optimizer.js | 27 | ||||
-rw-r--r-- | tools/test-js-optimizer-si-output.js | 17 | ||||
-rw-r--r-- | tools/test-js-optimizer-si.js | 21 |
4 files changed, 60 insertions, 9 deletions
@@ -1689,7 +1689,9 @@ try: js_optimizer_queue += ['simplifyExpressions'] - if debug_level == 0 or profiling: js_optimizer_queue += ['simplifyIfs'] + # simplify ifs if it is ok to make the code somewhat unreadable, and unless outlining (simplified ifs + # with commaified code breaks late aggressive variable elimination) + if (debug_level == 0 or profiling) and shared.Settings.OUTLINING_LIMIT == 0: js_optimizer_queue += ['simplifyIfs'] if opt_level >= 3 and shared.Settings.PRECISE_F32: js_optimizer_queue += ['optimizeFrounds'] diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index b746489a..bb6acf73 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -140,6 +140,8 @@ var ALTER_FLOW = set('break', 'continue', 'return'); var BREAK_CAPTURERS = set('do', 'while', 'for', 'switch'); var CONTINUE_CAPTURERS = LOOP; +var COMMABLE = set('assign', 'binary', 'unary-prefix', 'unary-postfix', 'name', 'num', 'call', 'seq', 'conditional', 'sub'); + var FUNCTIONS_THAT_ALWAYS_THROW = set('abort', '___resumeException', '___cxa_throw', '___cxa_rethrow'); var NULL_NODE = ['name', 'null']; @@ -832,8 +834,29 @@ function simplifyIfs(ast) { var body = node[2]; // recurse to handle chains while (body[0] === 'block') { - if (body[1].length !== 1) break; - var singleton = body[1][0]; + var stats = body[1]; + if (stats.length > 1) { + var last = stats[stats.length-1]; + if (last[0] === 'if' && !last[3]) { + // try to commaify - turn everything between the ifs into a comma operator inside the second if + var ok = true; + for (var i = 0; i < stats.length-1; i++) { + var curr = stats[i]; + if (curr[0] === 'stat') curr = curr[1]; + if (!(curr[0] in COMMABLE)) ok = false; + } + if (ok) { + for (var i = stats.length-2; i >= 0; i--) { + var curr = stats[i]; + if (curr[0] === 'stat') curr = curr[1]; + last[1] = ['seq', curr, last[1]]; + } + stats = body[1] = [last]; + } + } + } + if (stats.length !== 1) break; + var singleton = stats[0]; if (singleton[0] === 'if' && !singleton[3]) { node[1] = ['conditional', node[1], singleton[1], ['num', 0]]; body = node[2] = singleton[2]; diff --git a/tools/test-js-optimizer-si-output.js b/tools/test-js-optimizer-si-output.js index 9a55281d..bd36ef10 100644 --- a/tools/test-js-optimizer-si-output.js +++ b/tools/test-js-optimizer-si-output.js @@ -23,7 +23,7 @@ function a() { h(); } if (x) { - f(); + return; if (y) { g(); } @@ -32,13 +32,13 @@ function a() { g(); } if (x) { - f(); + return; if (y ? z : 0) { g(); } } if (x ? y : 0) { - f(); + return; if (z) { g(); } @@ -55,5 +55,16 @@ function a() { } f(); } + if (x ? (f(), x = x + 2 | 0, y) : 0) { + g(); + } + if (x) { + f(); + x = x + 2 | 0; + return; + if (y) { + g(); + } + } } diff --git a/tools/test-js-optimizer-si.js b/tools/test-js-optimizer-si.js index 1d214386..5f6b334f 100644 --- a/tools/test-js-optimizer-si.js +++ b/tools/test-js-optimizer-si.js @@ -25,7 +25,7 @@ function a() { h(); } if (x) { - f(); + return; if (y) { g(); } @@ -38,7 +38,7 @@ function a() { } } if (x) { - f(); + return; if (y) { if (z) { g(); @@ -47,7 +47,7 @@ function a() { } if (x) { if (y) { - f(); + return; if (z) { g(); } @@ -69,5 +69,20 @@ function a() { } f(); } + if (x) { + f(); + x = x + 2 | 0; + if (y) { + g(); + } + } + if (x) { + f(); + x = x + 2 | 0; + return; + if (y) { + g(); + } + } } |