diff options
author | Alon Zakai <alonzakai@gmail.com> | 2011-12-15 19:12:48 -0800 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2011-12-15 19:12:48 -0800 |
commit | cad9b242be49d551f07e1df803594164eb4a7e57 (patch) | |
tree | e22fca437ff29f88294e65847b83cd84cc584417 /tools | |
parent | 680e9c48bac764ba57c8a5c8dfa6981041caf480 (diff) |
js optimizer pass to join together additions
Diffstat (limited to 'tools')
-rw-r--r-- | tools/js-optimizer.js | 32 | ||||
-rw-r--r-- | tools/test-js-optimizer-output.js | 4 | ||||
-rw-r--r-- | tools/test-js-optimizer.js | 2 |
3 files changed, 36 insertions, 2 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 010739d3..bf971951 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -78,6 +78,7 @@ function traverse(node, pre, post, stack) { if (stack) len = stack.length; var result = pre(node, type, stack); if (result == true) return true; + if (typeof result == 'object') node = result; // Continue processing on this node if (stack && len == stack.length) stack.push(0); } for (var i = 0; i < node.length; i++) { @@ -259,7 +260,8 @@ function removeUnneededLabelSettings(ast) { }); } -// Various expression simplifications +// Various expression simplifications. Pre run before closure (where we still have metadata), Post run after. + function simplifyExpressionsPre(ast) { // When there is a bunch of math like (((8+5)|0)+12)|0, only the external |0 is needed, one correction is enough. // At each node, ((X|0)+Y)|0 can be transformed into (X+Y): The inner corrections are not needed @@ -294,7 +296,35 @@ function simplifyExpressionsPre(ast) { } } + // The most common mathop is addition, e.g. in getelementptr done repeatedly. We can join all of those, + // by doing (num+num) ==> newnum, and (name+num)+num = name+newnum + function joinAdditions(ast) { + var rerun = true; + while (rerun) { + rerun = false; + traverseGenerated(ast, function(node, type) { + if (type == 'binary' && node[1] == '+') { + if (node[2][0] == 'num' && node[3][0] == 'num') { + rerun = true; + return ['num', node[2][1] + node[3][1]]; + } + for (var i = 2; i <= 3; i++) { + var ii = 5-i; + for (var j = 2; j <= 3; j++) { + if (node[i][0] == 'num' && node[ii][0] == 'binary' && node[ii][1] == '+' && node[ii][j][0] == 'num') { + rerun = true; + node[ii][j][1] += node[i][1]; + return node[ii]; + } + } + } + } + }); + } + } + simplifyBitops(ast); + joinAdditions(ast); } function simplifyExpressionsPost(ast) { diff --git a/tools/test-js-optimizer-output.js b/tools/test-js-optimizer-output.js index 95426478..d171c5b5 100644 --- a/tools/test-js-optimizer-output.js +++ b/tools/test-js-optimizer-output.js @@ -82,6 +82,8 @@ function bits() { print((($s & 65535) + (($f & 65535) << 16 >> 16) * (($f & 65535) << 16 >> 16) % 256 | 0) & 65535); } function maths() { - __ZN6b2Vec2C1Ev($this1 + 20 + 8 + 8 + 8 + 8 + 8 + 8 + 8 | 0); + check(17); + check(95); + __ZN6b2Vec2C1Ev($this1 + 76 | 0); } // EMSCRIPTEN_GENERATED_FUNCTIONS: ["abc", "xyz", "xyz2", "expr", "loopy", "bits", "maths"] diff --git a/tools/test-js-optimizer.js b/tools/test-js-optimizer.js index c59454e6..0665462b 100644 --- a/tools/test-js-optimizer.js +++ b/tools/test-js-optimizer.js @@ -84,6 +84,8 @@ function bits() { // TODO: optimize this! print((($s & 65535) + ((($f & 65535) << 16 >> 16) * (($f & 65535) << 16 >> 16) | 0 | 0) % 256 | 0) & 65535); } function maths() { + check(5+12); + check(90+3+2); __ZN6b2Vec2C1Ev(((((((($this1 + 20 | 0 | 0) + 8 | 0) + 8 | 0) + 8 | 0) + 8 | 0) + 8 | 0) + 8 | 0) + 8 | 0); } // EMSCRIPTEN_GENERATED_FUNCTIONS: ["abc", "xyz", "xyz2", "expr", "loopy", "bits", "maths"] |