aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorDan Gohman <sunfish@google.com>2013-12-19 15:28:27 -0800
committerDan Gohman <sunfish@google.com>2013-12-19 15:28:27 -0800
commit47e803a62598194891eae3aaef50f551f5fdc4bb (patch)
tree410eddbdd187e299057315d21140be19d3c0c77d
parent970cd15cd79a538b2dc404a16bfa2745915f6b17 (diff)
Optimize away masks on stores to HEAP8 and HEAP16.
Optimize HEAP8[i] = x & 255 to HEAP8[i] = x, and similar for HEAP16.
-rw-r--r--tools/js-optimizer.js24
-rw-r--r--tools/test-js-optimizer-asm-pre-output.js8
-rw-r--r--tools/test-js-optimizer-asm-pre.js4
3 files changed, 27 insertions, 9 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js
index 57ce0071..57585663 100644
--- a/tools/js-optimizer.js
+++ b/tools/js-optimizer.js
@@ -585,12 +585,24 @@ function simplifyExpressions(ast) {
}
} else if (type === 'assign') {
// optimizations for assigning into HEAP32 specifically
- if (node[1] === true && node[2][0] === 'sub' && node[2][1][0] === 'name' && node[2][1][1] === 'HEAP32') {
- // HEAP32[..] = x | 0 does not need the | 0 (unless it is a mandatory |0 of a call)
- if (node[3][0] === 'binary' && node[3][1] === '|') {
- if (node[3][2][0] === 'num' && node[3][2][1] === 0 && node[3][3][0] != 'call') {
- node[3] = node[3][3];
- } else if (node[3][3][0] === 'num' && node[3][3][1] === 0 && node[3][2][0] != 'call') {
+ if (node[1] === true && node[2][0] === 'sub' && node[2][1][0] === 'name') {
+ if (node[2][1][1] === 'HEAP32') {
+ // HEAP32[..] = x | 0 does not need the | 0 (unless it is a mandatory |0 of a call)
+ if (node[3][0] === 'binary' && node[3][1] === '|') {
+ if (node[3][2][0] === 'num' && node[3][2][1] === 0 && node[3][3][0] != 'call') {
+ node[3] = node[3][3];
+ } else if (node[3][3][0] === 'num' && node[3][3][1] === 0 && node[3][2][0] != 'call') {
+ node[3] = node[3][2];
+ }
+ }
+ } else if (node[2][1][1] === 'HEAP8') {
+ // HEAP8[..] = x & 0xff does not need the & 0xff
+ if (node[3][0] === 'binary' && node[3][1] === '&' && node[3][3][0] == 'num' && node[3][3][1] == 0xff) {
+ node[3] = node[3][2];
+ }
+ } else if (node[2][1][1] === 'HEAP16') {
+ // HEAP16[..] = x & 0xffff does not need the & 0xffff
+ if (node[3][0] === 'binary' && node[3][1] === '&' && node[3][3][0] == 'num' && node[3][3][1] == 0xffff) {
node[3] = node[3][2];
}
}
diff --git a/tools/test-js-optimizer-asm-pre-output.js b/tools/test-js-optimizer-asm-pre-output.js
index 2e3db000..0fa81050 100644
--- a/tools/test-js-optimizer-asm-pre-output.js
+++ b/tools/test-js-optimizer-asm-pre-output.js
@@ -58,12 +58,14 @@ function b($this, $__n) {
_memset($38 + $23 | 0, 0, $__n | 0, 1, 1213141516);
$40 = $23 + $__n | 0;
if ((HEAP8[$4 & 16777215] & 1) == 0) {
- HEAP8[$4 & 16777215] = $40 << 1 & 255;
+ HEAP8[$4 & 16777215] = $40 << 1;
} else {
HEAP32[($this + 4 & 16777215) >> 2] = $40;
}
HEAP8[$38 + $40 & 16777215] = 0;
HEAP32[$4] = ~HEAP32[$5];
+ HEAP8[$4] = HEAP32[$5];
+ HEAP16[$4] = HEAP32[$5];
HEAP32[$4] = ~HEAP32[$5];
HEAP32[$4] = ~HEAP32[$5];
h(~~g ^ -1);
@@ -240,10 +242,10 @@ function _main($argc, $argv) {
}
if (($i_09_i_i | 0) > (HEAP32[9600 + ($j_08_i_i << 2) >> 2] | 0)) {
$34 = $j_08_i_i + 1 | 0;
- HEAP8[$i_09_i_i + 8952 | 0] = $34 & 255;
+ HEAP8[$i_09_i_i + 8952 | 0] = $34;
$j_1_i_i = $34;
} else {
- HEAP8[$i_09_i_i + 8952 | 0] = $j_08_i_i & 255;
+ HEAP8[$i_09_i_i + 8952 | 0] = $j_08_i_i;
$j_1_i_i = $j_08_i_i;
}
$38 = $i_09_i_i + 1 | 0;
diff --git a/tools/test-js-optimizer-asm-pre.js b/tools/test-js-optimizer-asm-pre.js
index 9e6edf0f..dadeef53 100644
--- a/tools/test-js-optimizer-asm-pre.js
+++ b/tools/test-js-optimizer-asm-pre.js
@@ -66,6 +66,10 @@ function b($this, $__n) {
HEAP8[($38 + $40 | 0) & 16777215] = 0;
// Eliminate the |0.
HEAP32[$4] = ((~(HEAP32[$5]|0))|0);
+ // Eliminate the &255
+ HEAP8[$4] = HEAP32[$5]&255;
+ // Eliminate the &65535
+ HEAP16[$4] = HEAP32[$5]&65535;
// Rewrite to ~.
HEAP32[$4] = HEAP32[$5]^-1;
// Rewrite to ~ and eliminate the |0.