aboutsummaryrefslogtreecommitdiff
path: root/tools
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-05-25 18:52:57 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-05-25 18:52:57 -0700
commitd5299a3bbf2a9fb71b9ffae102d5acd273ae28c8 (patch)
treed021812a1503744d06cff5625a24962fc7457484 /tools
parent7011aa3831041920d5269d873b0c16acaa042360 (diff)
fix registerize semantics to treat each arm of ifs and switches separately
Diffstat (limited to 'tools')
-rw-r--r--tools/js-optimizer.js65
-rw-r--r--tools/test-js-optimizer-asm-regs-output.js65
-rw-r--r--tools/test-js-optimizer-asm-regs.js67
3 files changed, 186 insertions, 11 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index a52ad6b7..9e0307da 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -1596,7 +1596,15 @@ function registerize(ast) {
var varLevels = {};
var possibles = {};
var unoptimizables = {};
- traverse(fun, function(node, type) {
+ function purgeLevel() {
+ // Invalidate all dominating on this level, further users make it unoptimizable
+ for (var name in levelDominations[level]) {
+ varLevels[name] = 0;
+ }
+ levelDominations[level] = null;
+ level--;
+ }
+ traverse(fun, function possibilifier(node, type) {
if (type == 'name') {
var name = node[1];
if (localVars[name]) {
@@ -1617,16 +1625,49 @@ function registerize(ast) {
}
}
} else if (type in CONTROL_FLOW) {
- level++;
- }
- }, function(node, type) {
- if (type in CONTROL_FLOW) {
- // Invalidate all dominating on this level, further users make it unoptimizable
- for (var name in levelDominations[level]) {
- varLevels[name] = 0;
+ // recurse children, in the context of a loop
+ switch(type) {
+ case 'while': case 'do': {
+ traverse(node[1], possibilifier);
+ level++;
+ traverse(node[2], possibilifier);
+ purgeLevel();
+ break;
+ }
+ case 'for': {
+ traverse(node[1], possibilifier);
+ for (var i = 2; i <= 4; i++) {
+ level++;
+ traverse(node[i], possibilifier);
+ purgeLevel();
+ }
+ break;
+ }
+ case 'if': {
+ traverse(node[1], possibilifier);
+ level++;
+ traverse(node[2], possibilifier);
+ purgeLevel();
+ if (node[3]) {
+ level++;
+ traverse(node[3], possibilifier);
+ purgeLevel();
+ }
+ break;
+ }
+ case 'switch': {
+ traverse(node[1], possibilifier);
+ var cases = node[2];
+ for (var i = 0; i < cases.length; i++) {
+ level++;
+ traverse(cases[i][1], possibilifier);
+ purgeLevel();
+ }
+ break;
+ }
+ default: throw dumpAst(node);
}
- levelDominations[level] = null;
- level--;
+ return null; // prevent recursion into children, which we already did
}
});
var optimizables = {};
@@ -1635,6 +1676,10 @@ function registerize(ast) {
if (!unoptimizables[possible]) optimizables[possible] = 1;
}
}
+
+ //printErr('optimizables: ' + JSON.stringify(optimizables));
+ //printErr('unoptimizables: ' + JSON.stringify(unoptimizables));
+
// Go through the function's code, assigning 'registers'.
// The only tricky bit is to keep variables locked on a register through loops,
// since they can potentially be returned to. Optimizable variables lock onto
diff --git a/tools/test-js-optimizer-asm-regs-output.js b/tools/test-js-optimizer-asm-regs-output.js
index ba2316ea..c2efa506 100644
--- a/tools/test-js-optimizer-asm-regs-output.js
+++ b/tools/test-js-optimizer-asm-regs-output.js
@@ -38,4 +38,69 @@ function switchey(d1, i2) {
return 20;
}
}
+function switchey2() {
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, d6 = +0, d7 = +0, i8 = 0, i9 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 8 | 0;
+ i2 = 1;
+ while (1) switch (i2 | 0) {
+ case 1:
+ i3 = i1 | 0;
+ __ZN6RandomC1Ev(i3);
+ i4 = 0;
+ i5 = 0;
+ i2 = 2;
+ break;
+ case 2:
+ d6 = +__ZN6Random3getEf(8, +1);
+ d7 = +__ZN6Random3getEf(i3, +1);
+ _printf(24, (tempInt = STACKTOP, STACKTOP = STACKTOP + 16 | 0, HEAPF64[CHECK_ALIGN_8(tempInt | 0) >> 3] = d6, HEAPF64[CHECK_ALIGN_8(tempInt + 8 | 0) >> 3] = d7, tempInt) | 0);
+ i8 = (d6 != d7 & 1) + i5 | 0;
+ i9 = i4 + 1 | 0;
+ if ((i9 | 0) < 100) {
+ i4 = i9;
+ i5 = i8;
+ i2 = 2;
+ break;
+ } else {
+ i2 = 3;
+ break;
+ }
+ case 3:
+ _printf(16, (tempInt = STACKTOP, STACKTOP = STACKTOP + 8 | 0, HEAP32[CHECK_ALIGN_4(tempInt | 0) >> 2] = i8, tempInt) | 0);
+ STACKTOP = i1;
+ return 0;
+ }
+ return 0;
+}
+function iffey() {
+ var i1 = 0, i2 = 0, i3 = 0, i4 = 0, i5 = 0, d6 = +0, d7 = +0, i8 = 0, i9 = 0;
+ i1 = STACKTOP;
+ STACKTOP = STACKTOP + 8 | 0;
+ i2 = 1;
+ while (1) {
+ if (i2 | 0) {
+ i3 = i1 | 0;
+ __ZN6RandomC1Ev(i3);
+ i4 = 0;
+ i5 = 0;
+ i2 = 2;
+ } else {
+ d6 = +__ZN6Random3getEf(8, +1);
+ d7 = +__ZN6Random3getEf(i3, +1);
+ _printf(24, (tempInt = STACKTOP, STACKTOP = STACKTOP + 16 | 0, HEAPF64[CHECK_ALIGN_8(tempInt | 0) >> 3] = d6, HEAPF64[CHECK_ALIGN_8(tempInt + 8 | 0) >> 3] = d7, tempInt) | 0);
+ i8 = (d6 != d7 & 1) + i5 | 0;
+ i9 = i4 + 1 | 0;
+ if ((i9 | 0) < 100) {
+ i4 = i9;
+ i5 = i8;
+ i2 = 2;
+ } else {
+ i2 = 3;
+ return 10;
+ }
+ }
+ }
+ return 0;
+}
diff --git a/tools/test-js-optimizer-asm-regs.js b/tools/test-js-optimizer-asm-regs.js
index 64797e38..8c3a1c98 100644
--- a/tools/test-js-optimizer-asm-regs.js
+++ b/tools/test-js-optimizer-asm-regs.js
@@ -41,5 +41,70 @@ function switchey(x, y) {
return 20;
}
}
-// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "_doit", "stackRestore", "switchey"]
+function switchey2() {
+ var $rng2 = 0, $count_06 = 0, $i_05 = 0, $2 = +0, $3 = +0, $count_1 = 0, $9 = 0, label = 0, __stackBase__ = 0;
+ __stackBase__ = STACKTOP;
+ STACKTOP = STACKTOP + 8 | 0;
+ label = 1;
+ while (1) switch (label | 0) {
+ case 1:
+ $rng2 = __stackBase__ | 0;
+ __ZN6RandomC1Ev($rng2);
+ $i_05 = 0;
+ $count_06 = 0;
+ label = 2;
+ break;
+ case 2:
+ $2 = +__ZN6Random3getEf(8, +1);
+ $3 = +__ZN6Random3getEf($rng2, +1);
+ _printf(24, (tempInt = STACKTOP, STACKTOP = STACKTOP + 16 | 0, HEAPF64[CHECK_ALIGN_8(tempInt | 0) >> 3] = $2, HEAPF64[CHECK_ALIGN_8(tempInt + 8 | 0) >> 3] = $3, tempInt) | 0);
+ $count_1 = ($2 != $3 & 1) + $count_06 | 0;
+ $9 = $i_05 + 1 | 0;
+ if (($9 | 0) < 100) {
+ $i_05 = $9;
+ $count_06 = $count_1;
+ label = 2;
+ break;
+ } else {
+ label = 3;
+ break;
+ }
+ case 3:
+ _printf(16, (tempInt = STACKTOP, STACKTOP = STACKTOP + 8 | 0, HEAP32[CHECK_ALIGN_4(tempInt | 0) >> 2] = $count_1, tempInt) | 0);
+ STACKTOP = __stackBase__;
+ return 0;
+ }
+ return 0;
+}
+function iffey() {
+ var $rng2 = 0, $count_06 = 0, $i_05 = 0, $2 = +0, $3 = +0, $count_1 = 0, $9 = 0, label = 0, __stackBase__ = 0;
+ __stackBase__ = STACKTOP;
+ STACKTOP = STACKTOP + 8 | 0;
+ label = 1;
+ while (1) {
+ if (label | 0) {
+ $rng2 = __stackBase__ | 0;
+ __ZN6RandomC1Ev($rng2);
+ $i_05 = 0;
+ $count_06 = 0;
+ label = 2;
+ } else {
+ $2 = +__ZN6Random3getEf(8, +1);
+ $3 = +__ZN6Random3getEf($rng2, +1);
+ _printf(24, (tempInt = STACKTOP, STACKTOP = STACKTOP + 16 | 0, HEAPF64[CHECK_ALIGN_8(tempInt | 0) >> 3] = $2, HEAPF64[CHECK_ALIGN_8(tempInt + 8 | 0) >> 3] = $3, tempInt) | 0);
+ $count_1 = ($2 != $3 & 1) + $count_06 | 0;
+ $9 = $i_05 + 1 | 0;
+ if (($9 | 0) < 100) {
+ $i_05 = $9;
+ $count_06 = $count_1;
+ label = 2;
+ } else {
+ label = 3;
+ return 10;
+ }
+ }
+ }
+ return 0;
+}
+// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "_doit", "stackRestore", "switchey", "switchey2", "iffey"]