diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-03-09 15:37:49 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-03-09 15:37:49 -0800 |
commit | 4c95c34ca8166f49f995ea8fe082cd0aaa70d839 (patch) | |
tree | 5d8ea0f5ac9b9017f74e3da5a0cfd55b0facc5b8 /tools/js-optimizer.js | |
parent | d3d23885170ad1151277e8980d3b41313ed7b9a3 (diff) |
use minified names in registerize for locals
Diffstat (limited to 'tools/js-optimizer.js')
-rw-r--r-- | tools/js-optimizer.js | 65 |
1 files changed, 59 insertions, 6 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index f944eb9b..5b2e6188 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -1445,16 +1445,69 @@ function registerize(ast) { }); vacuum(fun); if (minifierInfo) { - // Fix globals. Note that we know/assume that locals cannot shadow globals. + assert(asm); + var usedGlobals = {}; + var nextLocal = 0; + // Minify globals using the mapping we were given traverse(fun, function(node, type) { if (type == 'name') { - var minified = minifierInfo.globals[node[1]]; - if (minified) node[1] = minified; + var name = node[1]; + var minified = minifierInfo.globals[name]; + if (minified) { + assert(!localVars[name]); // locals must not shadow globals, or else we don't know which is which + if (localVars[minified]) { + // trying to minify a global into a name used locally. rename all the locals + var newName = '$_newLocal_' + (nextLocal++); + assert(!localVars[newName]); + if (params[minified]) { + params[newName] = 1; + delete params[minified]; + } + localVars[newName] = 1; + delete localVars[minified]; + asmData.vars[newName] = asmData.vars[minified]; + delete asmData.vars[minified]; + asmData.params[newName] = asmData.params[minified]; + delete asmData.params[minified]; + traverse(fun, function(node, type) { + if (type == 'name' && node[1] == minified) { + node[1] = newName; + } + }); + if (fun[2]) { + for (var i = 0; i < fun[2].length; i++) { + if (fun[2][i] == minified) fun[2][i] = newName; + } + } + } + node[1] = minified; + usedGlobals[minified] = 1; + } } }); assert(fun[1] in minifierInfo.globals, fun[1]); fun[1] = minifierInfo.globals[fun[1]]; assert(fun[1]); + var nextRegName = 0; + } + var regTypes = {}; + function getNewRegName(num, name) { + if (!asm) return 'r' + num; + var type = asmData.vars[name]; + if (!minifierInfo) { + var ret = (type ? 'd' : 'i') + num; + regTypes[ret] = type; + return ret; + } + // find the next free minified name that is not used by a global that shows up in this function + while (nextRegName < minifierInfo.names.length) { + var ret = minifierInfo.names[nextRegName++]; + if (!usedGlobals[ret]) { + regTypes[ret] = type; + return ret; + } + } + assert('ran out of names'); } // Find the # of uses of each variable. // While doing so, check if all a variable's uses are dominated in a simple @@ -1540,7 +1593,7 @@ function registerize(ast) { saved++; } else { reg = nextReg++; - fullNames[reg] = (asm ? (asmData.vars[name] ? 'd' : 'i') : 'r') + reg; // XXX need to ensure we do not override used globals + fullNames[reg] = getNewRegName(reg, name); if (params[name]) paramRegs[reg] = 1; } varRegs[name] = reg; @@ -1584,7 +1637,7 @@ function registerize(ast) { if (loopRegs[loops]) { if (asm) { loopRegs[loops].forEach(function(loopReg) { - freeRegsClasses[fullNames[loopReg][0] == 'i' ? ASM_INT : ASM_DOUBLE].push(loopReg); + freeRegsClasses[regTypes[fullNames[loopReg]]].push(loopReg); }); } else { freeRegsClasses = freeRegsClasses.concat(loopRegs[loops]); @@ -1620,7 +1673,7 @@ function registerize(ast) { }; for (var i = 1; i < nextReg; i++) { var reg = fullNames[i]; - var type = reg[0] == 'i' ? ASM_INT : ASM_DOUBLE + var type = regTypes[reg]; if (!paramRegs[i]) { finalAsmData.vars[reg] = type; } else { |