aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2011-12-29 18:55:41 -0800
committerAlon Zakai <alonzakai@gmail.com>2011-12-29 18:55:41 -0800
commit3d9832b7518bfd7b0585269fcb0ec605fff5f8e3 (patch)
treedfcf93ddbd92f83575141009fc810cc2cb35196e
parente53ee130a3fd19746f312ee30bd26a549ca09223 (diff)
make shift optimizer output more similar to normal output
-rw-r--r--tools/js-optimizer.js38
-rw-r--r--tools/test-js-optimizer-t2-output.js35
-rw-r--r--tools/test-js-optimizer-t2.js8
3 files changed, 62 insertions, 19 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 1764f4b7..3bfa3c8b 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -543,8 +543,8 @@ function optimizeShifts(ast) {
}
}, null, []);
cleanNotes();
- var more = true;
var SIMPLE_SHIFTS = set('<<', '>>');
+ var more = true;
while (more) { // collapse shifts and unshifts, completing the optimization
more = false;
traverse(fun, function(node, type) {
@@ -590,7 +590,7 @@ function optimizeShifts(ast) {
return subNode;
}
}
- // Optimize the case of ($a*80)>>2
+ // Optimize the case of ($a*80)>>2 into ($a*20)|0
if (type == 'binary' && node[1] in SIMPLE_SHIFTS &&
node[2][0] == 'binary' && node[2][1] == '*') {
var mulNode = node[2];
@@ -602,11 +602,15 @@ function optimizeShifts(ast) {
if (mulNode[3][0] == 'num') {
if (node[1] == '<<') {
mulNode[3][1] *= Math.pow(2, node[3][1]);
- return mulNode;
+ node[1] = '|';
+ node[3][1] = 0;
+ return node;
} else {
if (mulNode[3][1] % Math.pow(2, node[3][1]) == 0) {
mulNode[3][1] /= Math.pow(2, node[3][1]);
- return mulNode;
+ node[1] = '|';
+ node[3][1] = 0;
+ return node;
}
}
}
@@ -615,7 +619,7 @@ function optimizeShifts(ast) {
// Re-combine remaining shifts, to undo the breaking up we did before. may require reordering inside +'s
traverse(fun, function(node, type, stack) {
stack.push(node);
- if (type == 'binary' && node[1] == '+') {
+ if (type == 'binary' && node[1] == '+' && (stack[stack.length-2][0] != 'binary' || stack[stack.length-2][1] != '+')) {
// 'Flatten' added items
var addedItems = [];
function flatten(node) {
@@ -636,6 +640,7 @@ function optimizeShifts(ast) {
if (node[3][0] == 'num' && node[3][1] >= 0 && node[3][1] <= 3) return 2*node[3][1] + (node[1] == '>>' ? 100 : 0); // 0-106
return (node[1] == '>>' ? 20000 : 10000) + originalOrderKey(node);
}
+ if (node[0] == 'num') return -20000 + node[1];
return -10000 + originalOrderKey(node); // Don't modify the original order if we don't modify anything
}
for (var i = 0; i < addedItems.length; i++) {
@@ -655,6 +660,29 @@ function optimizeShifts(ast) {
i++;
}
}
+ var num = 0;
+ for (i = 0; i < addedItems.length; i++) { // combine all numbers into one
+ if (addedItems[i][0] == 'num') {
+ num += addedItems[i][1];
+ addedItems.splice(i, 1);
+ i--;
+ }
+ }
+ if (num != 0) { // add the numbers into an existing shift, we
+ // prefer (x+5)>>7 over (x>>7)+5 , since >>'s result is known to be 32-bit and is more easily optimized.
+ // Also, in the former we can avoid the parentheses, which saves a little space (the number will be bigger,
+ // so it might take more space, but normally at most one more digit).
+ var added = false;
+ for (i = 0; i < addedItems.length; i++) {
+ if (addedItems[i][0] == 'binary' && addedItems[i][1] == '>>' && addedItems[i][3][0] == 'num') {
+ addedItems[i] = ['binary', '>>', ['binary', '+', addedItems[i][2], ['num', num << addedItems[i][3][1]]], addedItems[i][3]];
+ added = true;
+ }
+ }
+ if (!added) {
+ addedItems.unshift(['num', num]);
+ }
+ }
var ret = addedItems.pop();
while (addedItems.length > 0) { // re-create AST from addedItems
ret = ['binary', '+', ret, addedItems.pop()];
diff --git a/tools/test-js-optimizer-t2-output.js b/tools/test-js-optimizer-t2-output.js
index ea384e07..7a676fbe 100644
--- a/tools/test-js-optimizer-t2-output.js
+++ b/tools/test-js-optimizer-t2-output.js
@@ -24,9 +24,9 @@ function shifty($id) {
q($id3);
pause(0);
var _idents = get("abc") >> 2;
- q(HEAP32[(HEAP32[_idents] >> 2) + 2]);
- q(HEAP32[(HEAP32[_idents] >> 2) + 2]);
- q(HEAP32[(HEAP32[_idents] >> 2) + 2]);
+ q(HEAP32[HEAP32[_idents] + 8 >> 2]);
+ q(HEAP32[HEAP32[_idents] + 8 >> 2]);
+ q(HEAP32[HEAP32[_idents] + 8 >> 2]);
pause(1);
var $sn_addr = get(12), $a_addr = get(999), $a_addr$s2 = $a_addr >> 2;
var $i = get(112233);
@@ -40,24 +40,24 @@ function shifty($id) {
pause(2);
var $level = HEAP[get(322) >> 2];
var _dwt_norms_real = get("a") >> 2, $orient = get("cheez");
- q(HEAP32[($level << 1) + _dwt_norms_real + $orient * 20]);
- q(HEAP32[($level << 1) + _dwt_norms_real + $orient * 20 + 1]);
- q(HEAP32[($level << 1) + _dwt_norms_real + $orient * 20 + 2]);
+ q(HEAP32[($level << 1) + _dwt_norms_real + ($orient * 20 | 0)]);
+ q(HEAP32[($level << 1) + _dwt_norms_real + ($orient * 20 | 0) + 1]);
+ q(HEAP32[($level << 1) + _dwt_norms_real + ($orient * 20 | 0) + 2]);
pause(3);
var $wavelet38 = get(38) >> 2;
$k = $a_addr;
- q(HEAPF32[(HEAP32[$wavelet38] >> 2) + ($k << 2) + 2]);
- q(HEAPF32[(HEAP32[$wavelet38] >> 2) + ($k << 2) + 3]);
- q(HEAPF32[(HEAP32[$wavelet38] >> 2) + ($k << 2) + 100]);
+ q(HEAPF32[(HEAP32[$wavelet38] + 8 >> 2) + ($k << 2)]);
+ q(HEAPF32[(HEAP32[$wavelet38] + 12 >> 2) + ($k << 2)]);
+ q(HEAPF32[(HEAP32[$wavelet38] + 400 >> 2) + ($k << 2)]);
pause(4);
var $p = $k, $parameters_addr = get("burger") >> 2;
- q(HEAP32[$parameters_addr + 1406 + $p]);
- q(HEAP32[$parameters_addr + 1411 + $p]);
- q(HEAP32[$parameters_addr + 1416 + $p]);
+ q(HEAP32[$parameters_addr + $p + 1406]);
+ q(HEAP32[$parameters_addr + $p + 1411]);
+ q(HEAP32[$parameters_addr + $p + 1416]);
pause(5);
var $res_spec242 = get($real), $cp = get("b"), $tileno = arguments[2];
- q(HEAP32[$parameters_addr + 1406 + ($res_spec242 - 1)]);
- q(HEAP32[(HEAP32[($cp >> 2) + 27] >> 2) + $tileno * 1397 + 105]);
+ q(HEAP32[$parameters_addr + ($res_spec242 - 1) + 1406]);
+ q(HEAP32[(HEAP32[$cp + 108 >> 2] + 420 >> 2) + ($tileno * 1397 | 0)]);
pause(6);
q($idx << 3);
q(1 << $idx << 1);
@@ -76,5 +76,12 @@ function shifty($id) {
q(go());
q(go() >> 8 << 8);
q(go() + 2 >> 2);
+ pause(7.5);
+ q($13 + 8 >> 2);
+ q($13 + 28 >> 2);
+ q($13 + 60 >> 2);
+ q($13 + $15 + 12 >> 2);
+ q(HEAPF32[($output + 4 >> 2) + ($j37 << 2)]);
+ q($13 + 13 << 2);
}
// EMSCRIPTEN_GENERATED_FUNCTIONS: ["shifty"]
diff --git a/tools/test-js-optimizer-t2.js b/tools/test-js-optimizer-t2.js
index f7bda9ea..167c1f47 100644
--- a/tools/test-js-optimizer-t2.js
+++ b/tools/test-js-optimizer-t2.js
@@ -82,5 +82,13 @@ function shifty($id) {
q(go() >> 1 << 1);
q(go() >> 8 << 8);
q((go() + 2) >> 2); // the 2 >> 2 can't be simplified
+ pause(7.5);
+ // We prefer to do additions then shifts, so the shift happens last, because the shift output is known to be 32-bit. So these should not change
+ q($13 + 8 >> 2);
+ q(28 + $13 >> 2);
+ q(48 + $13 + 12 >> 2);
+ q($13 + $15 + 12 >> 2);
+ q(HEAPF32[$output + ($j37 << 4) + 4 >> 2]);
+ q(5 + $13 + 8 << 2);
}
// EMSCRIPTEN_GENERATED_FUNCTIONS: ["shifty"]