aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-03-15 15:44:14 -0700
committerAlon Zakai <alonzakai@gmail.com>2014-03-17 17:56:17 -0700
commit6c31546ced32fd968ae50da7803964c9195ebd62 (patch)
tree46ddb131a57a612e83f5d00efe847d3794725c94
parentf6c2bcd2a3058b4b36518aa4cabec2baa7222970 (diff)
uncommaify between ifs that can potentially be simplified
-rwxr-xr-xemcc4
-rw-r--r--tools/js-optimizer.js27
-rw-r--r--tools/test-js-optimizer-si-output.js17
-rw-r--r--tools/test-js-optimizer-si.js21
4 files changed, 60 insertions, 9 deletions
diff --git a/emcc b/emcc
index 3845beb1..471cbb76 100755
--- a/emcc
+++ b/emcc
@@ -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();
+ }
+ }
}