aboutsummaryrefslogtreecommitdiff
path: root/tools/js-optimizer.js
diff options
context:
space:
mode:
Diffstat (limited to 'tools/js-optimizer.js')
-rw-r--r--tools/js-optimizer.js50
1 files changed, 41 insertions, 9 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 95d9b82f..29b36cad 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -3001,7 +3001,7 @@ function outline(ast) {
// Try to flatten out code as much as possible, to make outlining more feasible.
function flatten(func, asmData) {
- var minSize = sizeToOutline/3;
+ var minSize = sizeToOutline;
var helperId = 0;
function getHelper() {
while (1) {
@@ -3012,18 +3012,22 @@ function outline(ast) {
}
}
}
+ var ignore = [];
traverse(func, function(node) {
var stats = getStatements(node);
if (stats) {
for (var i = 0; i < stats.length; i++) {
var node = stats[i]; // step over param
+ if (ignore.indexOf(node) >= 0) continue;
+ if (node[0] == 'stat') node = node[1];
+ if (ignore.indexOf(node) >= 0) continue;
var type = node[0];
if (measureSize(node) >= minSize) {
if (type === 'if' && node[3]) {
var reps = [];
var helper = getHelper();
// clear helper
- reps.push(['stat', ['assign', true, ['name', helper], ['num', 1]]]);
+ reps.push(['stat', ['assign', true, ['name', helper], ['num', 1]]]); // 1 means continue in ifs
// gather parts
var parts = [];
var curr = node;
@@ -3036,13 +3040,41 @@ function outline(ast) {
break;
}
}
- // generate flattened code
+ // chunkify. Each chunk is a chain of if-elses, with the new overhead just on entry and exit
+ var chunks = [];
+ var currSize = 0;
+ var currChunk = [];
parts.forEach(function(part) {
- var condition = ['name', helper];
- if (part.condition) condition = ['conditional', condition, part.condition, ['num', 0]];
- assert(part.body[0] == 'block');
- reps.push(makeIf(condition, part.body[1]));
- getStatements(part.body).unshift(['stat', ['assign', true, ['name', helper], ['num', 0]]]);
+ var size = (part.condition ? measureSize(part.condition) : 0) + measureSize(part.body) + 5; // add constant for overhead of extra code
+ assert(size > 0);
+ if (size + currSize >= minSize && currSize) {
+ chunks.push(currChunk);
+ currChunk = [];
+ currSize = 0;
+ }
+ currChunk.push(part);
+ currSize += size;
+ });
+ assert(currSize);
+ chunks.push(currChunk);
+ // generate flattened code
+ chunks.forEach(function(chunk) {
+ var pre = ['stat', ['assign', true, ['name', helper], ['num', 0]]];
+ var chain = null, tail = null;
+ chunk.forEach(function(part) {
+ // add to chain
+ var contents = makeIf(part.condition || ['num', 1], part.body[1]);
+ if (chain) {
+ tail[3] = contents;
+ } else {
+ chain = contents;
+ ignore.push(contents);
+ }
+ tail = contents;
+ });
+ // if none of the ifs were entered, in the final else note that we need to continue
+ tail[3] = ['block', [['stat', ['assign', true, ['name', helper], ['num', 1]]]]];
+ reps.push(makeIf(['name', helper], [pre, chain]));
});
// replace code and update i
stats.splice.apply(stats, [i, 1].concat(reps));
@@ -3504,7 +3536,7 @@ function outline(ast) {
var newFuncs = doOutline(func, asmData, stats, i, end); // outline [i, .. ,end] inclusive
if (newFuncs.length) {
ret.push.apply(ret, newFuncs);
- printErr('performed outline on ' + func[1] + ' of ' + sizeSeen + ', func is now size ' + measureSize(func));
+ printErr('performed outline on ' + func[1] + ' of ' + sizeSeen + ', func is now size ' + measureSize(func) + ' ==> ' + newFuncs[0][1]);
}
sizeSeen = 0;
end = i-1;