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.js32
1 files changed, 23 insertions, 9 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index d04807a7..1de06e4c 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -405,13 +405,16 @@ function removeUnneededLabelSettings(ast) {
// Various expression simplifications. Pre run before closure (where we still have metadata), Post run after.
var USEFUL_BINARY_OPS = set('<<', '>>', '|', '&', '^');
+var COMPARE_OPS = set('<', '<=', '>', '>=', '==', '===', '!=');
function simplifyExpressionsPre(ast) {
- // Look for (x&A)<<B>>B and replace it with X&A if possible.
- function simplifySignExtends(ast) {
+ // Simplify common expressions used to perform integer conversion operations
+ // in cases where no conversion is needed.
+ function simplifyIntegerConversions(ast) {
traverse(ast, function(node, type) {
if (type === 'binary' && node[1] === '>>' && node[3][0] === 'num' &&
node[2][0] === 'binary' && node[2][1] === '<<' && node[2][3][0] === 'num' && node[3][1] === node[2][3][1]) {
+ // Transform (x&A)<<B>>B to X&A.
var innerNode = node[2][2];
var shifts = node[3][1];
if (innerNode[0] === 'binary' && innerNode[1] === '&' && innerNode[3][0] === 'num') {
@@ -420,6 +423,15 @@ function simplifyExpressionsPre(ast) {
return innerNode;
}
}
+ } else if (type === 'binary' && node[1] === '&' && node[3][0] === 'num') {
+ // Rewrite (X < Y) & 1 to (X < Y)|0. (Subsequent passes will eliminate
+ // the |0 if possible.)
+ var input = node[2];
+ var amount = node[3][1];
+ if (input[0] === 'binary' && (input[1] in COMPARE_OPS) && amount == 1) {
+ node[1] = '|';
+ node[3][1] = 0;
+ }
}
});
}
@@ -763,7 +775,7 @@ function simplifyExpressionsPre(ast) {
}
traverseGeneratedFunctions(ast, function(func) {
- simplifySignExtends(func);
+ simplifyIntegerConversions(func);
simplifyBitops(func);
joinAdditions(func);
// simplifyZeroComp(func); TODO: investigate performance
@@ -2730,8 +2742,9 @@ function relocate(ast) {
assert(asm); // we also assume we are normalized
var replacements = extraInfo.replacements;
- var fBase = extraInfo.fBase;
+ var fBases = extraInfo.fBases;
var hBase = extraInfo.hBase;
+ var m;
traverse(ast, function(node, type) {
switch(type) {
@@ -2743,13 +2756,14 @@ function relocate(ast) {
case 'binary': {
if (node[1] == '+' && node[2][0] == 'name') {
var base = null;
- if (node[2][1] == 'F_BASE') {
- base = fBase;
- } else if (node[2][1] == 'H_BASE') {
+ if (node[2][1] == 'H_BASE') {
base = hBase;
+ } else if (m = /^F_BASE_(\w+)$/.exec(node[2][1])) {
+ base = fBases[m[1]] || 0; // 0 if the parent has no function table for this, but the child does. so no relocation needed
}
- if (base) {
+ if (base !== null) {
var other = node[3];
+ if (base === 0) return other;
if (other[0] == 'num') {
other[1] += base;
return other;
@@ -2887,7 +2901,7 @@ arguments_.slice(1).forEach(function(arg) {
passes[arg](ast);
});
if (asm && last) {
- asmLoopOptimizer(ast);
+ asmLoopOptimizer(ast); // TODO: move out of last, to make last faster when done later (as in side modules)
prepDotZero(ast);
}
var js = astToSrc(ast, minifyWhitespace), old;