diff options
| author | Alon Zakai <alonzakai@gmail.com> | 2011-12-29 18:55:41 -0800 | 
|---|---|---|
| committer | Alon Zakai <alonzakai@gmail.com> | 2011-12-29 18:55:41 -0800 | 
| commit | 3d9832b7518bfd7b0585269fcb0ec605fff5f8e3 (patch) | |
| tree | dfcf93ddbd92f83575141009fc810cc2cb35196e | |
| parent | e53ee130a3fd19746f312ee30bd26a549ca09223 (diff) | |
make shift optimizer output more similar to normal output
| -rw-r--r-- | tools/js-optimizer.js | 38 | ||||
| -rw-r--r-- | tools/test-js-optimizer-t2-output.js | 35 | ||||
| -rw-r--r-- | tools/test-js-optimizer-t2.js | 8 | 
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"]  | 
