aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2012-12-10 10:33:15 -0800
committerAlon Zakai <alonzakai@gmail.com>2012-12-10 10:33:15 -0800
commit762e6535d1753b0d23b12dd300916fad20f785d6 (patch)
treedea118eaec6e4e2237e2bb3c018609d4765b8bec
parent89426bedcdf71b6ce5bc48b3ec584532be66fc86 (diff)
never share parameter registers
-rw-r--r--tools/js-optimizer.js15
-rw-r--r--tools/test-js-optimizer-asm-regs-output.js9
-rw-r--r--tools/test-js-optimizer-asm-regs.js12
3 files changed, 29 insertions, 7 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 193556f9..518e451a 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -1345,7 +1345,7 @@ function registerize(ast, asm) {
traverseGeneratedFunctions(ast, function(fun) {
if (asm) var asmData = normalizeAsm(fun);
// Add parameters as a first (fake) var (with assignment), so they get taken into consideration
- var params = {};
+ var params = {}; // note: params are special, they can never share a register between them (see later)
if (fun[2] && fun[2].length) {
var assign = ['num', 0];
fun[3].unshift(['var', fun[2].map(function(param) {
@@ -1356,6 +1356,7 @@ function registerize(ast, asm) {
if (asm) {
// copy params into vars
for (var p in asmData.params) asmData.vars[p] = asmData.params[p];
+ //printErr('fake params: \n\n' + astToSrc(fun) + '\n\n');
}
// 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
@@ -1443,6 +1444,8 @@ function registerize(ast, asm) {
var saved = 0;
var activeOptimizables = {};
var optimizableLoops = {};
+ var paramRegs = {}; // true if the register is used by a parameter (and so needs no def at start of function; also cannot
+ // be shared with another param, each needs its own)
function decUse(name) {
if (!varUses[name]) return false; // no uses left, or not a relevant variable
if (optimizables[name]) activeOptimizables[name] = 1;
@@ -1451,12 +1454,14 @@ function registerize(ast, asm) {
var freeRegs = asm ? freeRegsClasses[asmData.vars[name]] : freeRegsClasses;
if (!reg) {
// acquire register
- if (optimizables[name] && freeRegs.length > 0) {
+ if (optimizables[name] && freeRegs.length > 0 &&
+ !(params[name] && paramRegs[freeRegs[freeRegs.length-1]])) { // do not share registers between parameters
reg = freeRegs.pop();
saved++;
} else {
reg = nextReg++;
fullNames[reg] = (asm ? (asmData.vars[name] ? 'd' : 'i') : 'r') + reg; // TODO: even smaller names
+ if (params[name]) paramRegs[reg] = 1;
}
varRegs[name] = reg;
}
@@ -1509,14 +1514,11 @@ function registerize(ast, asm) {
loops--;
}
});
- var paramRegs = {}; // true if the register is used by a parameter (and so needs no def at start of function)
if (fun[2] && fun[2].length) {
- for (var p in params) {
- paramRegs[varRegs[p]] = 1;
- }
fun[2].length = 0; // clear params, we will fill with registers
fun[3].shift(); // remove fake initial var
}
+ //printErr('var regs: ' + JSON.stringify(varRegs) + '\n\nparam regs: ' + JSON.stringify(paramRegs));
if (!asm) {
if (nextReg > 1) {
var vars = [];
@@ -1531,6 +1533,7 @@ function registerize(ast, asm) {
getStatements(fun).unshift(['var', vars]);
}
} else {
+ //printErr('unfake params: \n\n' + astToSrc(fun) + '\n\n');
var finalAsmData = {
params: {},
vars: {},
diff --git a/tools/test-js-optimizer-asm-regs-output.js b/tools/test-js-optimizer-asm-regs-output.js
index 00f032f7..d9aa5c0c 100644
--- a/tools/test-js-optimizer-asm-regs-output.js
+++ b/tools/test-js-optimizer-asm-regs-output.js
@@ -9,4 +9,13 @@ function asm(d1, i2) {
d4 = d1 * 5;
return d4;
}
+function _doit(i1, i2, i3) {
+ i1 = i1 | 0;
+ i2 = i2 | 0;
+ i3 = i3 | 0;
+ i1 = STACKTOP;
+ _printf(__str | 0, (tempInt = STACKTOP, STACKTOP = STACKTOP + 8 | 0, HEAP32[(tempInt & 16777215) >> 2] = i2, HEAP32[(tempInt + 4 & 16777215) >> 2] = i3, tempInt));
+ STACKTOP = i1;
+ return 0 | 0;
+}
diff --git a/tools/test-js-optimizer-asm-regs.js b/tools/test-js-optimizer-asm-regs.js
index 2ae21f5e..6ae7f7d0 100644
--- a/tools/test-js-optimizer-asm-regs.js
+++ b/tools/test-js-optimizer-asm-regs.js
@@ -10,5 +10,15 @@ function asm(x, y) {
double2 = double1*5;
return double2;
}
-// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "__Z11printResultPiS_j"]
+function _doit($x, $y$0, $y$1) {
+ $x = $x | 0;
+ $y$0 = $y$0 | 0;
+ $y$1 = $y$1 | 0;
+ var __stackBase__ = 0;
+ __stackBase__ = STACKTOP;
+ _printf(__str | 0, (tempInt = STACKTOP, STACKTOP = STACKTOP + 8 | 0, HEAP32[(tempInt & 16777215) >> 2] = $y$0, HEAP32[(tempInt + 4 & 16777215) >> 2] = $y$1, tempInt));
+ STACKTOP = __stackBase__;
+ return 0 | 0;
+}
+// EMSCRIPTEN_GENERATED_FUNCTIONS: ["asm", "_doit"]