aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-05-17 14:07:38 -0700
committerAlon Zakai <alonzakai@gmail.com>2012-05-17 14:07:38 -0700
commit6a3ee4ac640e35140be836d6c7485a0d67f0ac47 (patch)
tree8fedc86ea2c4219281e360005e184eb46d80a92c
parent26def19538b82b173d02907ddd5a2a7b94a5bb27 (diff)
do not registerize with switches present
-rw-r--r--tools/js-optimizer.js14
-rw-r--r--tools/test-js-optimizer-regs-output.js30
-rw-r--r--tools/test-js-optimizer-regs.js29
3 files changed, 69 insertions, 4 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index eda85799..2f6b2ff3 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -1143,11 +1143,17 @@ function loopOptimizer(ast) {
}
// Very simple 'registerization', coalescing of variables into a smaller number.
+// We do not optimize when there are switches, so this pass only makes sense with
+// relooping.
+// TODO: Consider how this fits in with the rest of the optimization toolchain. Do
+// we still need the eliminator? Closure? And in what order? Perhaps just
+// closure simple?
function registerize(ast) {
traverseGeneratedFunctions(ast, function(fun) {
// Replace all var definitions with assignments; we will add var definitions at the top after we registerize
// We also mark local variables - i.e., having a var definition
var localVars = {};
+ var hasSwitch = false; // we cannot optimize variables if there is a switch
traverse(fun, function(node, type) {
if (type == 'var') {
node[1].forEach(function(defined) { localVars[defined[0]] = 1 });
@@ -1167,6 +1173,8 @@ function registerize(ast) {
} else {
return emptyNode();
}
+ } else if (type == 'switch') {
+ hasSwitch = true;
}
});
vacuum(fun);
@@ -1215,8 +1223,10 @@ function registerize(ast) {
}
});
var optimizables = {};
- for (var possible in possibles) {
- if (!unoptimizables[possible]) optimizables[possible] = 1;
+ if (!hasSwitch) {
+ for (var possible in possibles) {
+ if (!unoptimizables[possible]) optimizables[possible] = 1;
+ }
}
// Go through the function's code, assigning 'registers'.
// The only tricky bit is to keep variables locked on a register through loops,
diff --git a/tools/test-js-optimizer-regs-output.js b/tools/test-js-optimizer-regs-output.js
index 16d675b8..a5e97f46 100644
--- a/tools/test-js-optimizer-regs-output.js
+++ b/tools/test-js-optimizer-regs-output.js
@@ -197,4 +197,32 @@ function ex() {
}))();
}
}
-// EMSCRIPTEN_GENERATED_FUNCTIONS: ["test", "primes", "atomic", "fcntl_open", "ex"]
+function switchey(x) {
+ var r1, r2, r3, r4, r5, r6, r7, r8;
+ r1 = 5;
+ while (1) {
+ switch (x = f(x, r1)) {
+ case 1:
+ g(r1);
+ r2 = x + 1;
+ x--;
+ break;
+ case 2:
+ g(r1 * 2);
+ r3 = x + 22;
+ r4 = r3 + 5;
+ x -= 20;
+ break;
+ default:
+ r5 = x + 22;
+ r6 = r3 + 5;
+ ch(r5, r6 * r3);
+ throw 99;
+ }
+ }
+ r7 = x + 1;
+ p(r1, r7);
+ r8 = x + 2;
+ pp(r8);
+}
+// EMSCRIPTEN_GENERATED_FUNCTIONS: ["test", "primes", "atomic", "fcntl_open", "ex", "switchey"]
diff --git a/tools/test-js-optimizer-regs.js b/tools/test-js-optimizer-regs.js
index 576e2f8c..2aa95b74 100644
--- a/tools/test-js-optimizer-regs.js
+++ b/tools/test-js-optimizer-regs.js
@@ -203,4 +203,31 @@ function ex() {
}))();
}
}
-// EMSCRIPTEN_GENERATED_FUNCTIONS: ["test", "primes", "atomic", "fcntl_open", "ex"]
+function switchey(x) {
+ var a = 5;
+ while (1) {
+ switch (x = f(x, a)) {
+ case 1:
+ g(a);
+ var b = x+1;
+ x--;
+ break;
+ case 2:
+ g(a*2);
+ var c = x+22;
+ var d = c+5;
+ x -= 20;
+ break;
+ default:
+ var c1 = x+22;
+ var d2 = c+5;
+ ch(c1, d2*c);
+ throw 99;
+ }
+ }
+ var aa = x+1;
+ p(a, aa);
+ var aaa = x+2;
+ pp(aaa);
+}
+// EMSCRIPTEN_GENERATED_FUNCTIONS: ["test", "primes", "atomic", "fcntl_open", "ex", "switchey"]