diff options
author | Dan Gohman <sunfish@google.com> | 2013-07-08 11:23:18 -0700 |
---|---|---|
committer | Dan Gohman <sunfish@google.com> | 2013-07-08 11:23:18 -0700 |
commit | b090967580b4b1d03134b4dd11d849fd50f23951 (patch) | |
tree | 041e5826045ab5482ac715b4e391cb30a09affea | |
parent | 3117fa129fe2aef34a7c954bfe02c1eb0e5f8d29 (diff) |
Xor optimizations.
Optimize x^-1 to ~x; this comes up because LLVM does not have a bitwise
negate operator. Optimize x&1^1 to !x; this comes up because of how LLVM
lowers C++ bool variables.
Also, add an optimization to simplifyExpressionsPre to eliminate |0 from
'~' expressions in more cases.
-rw-r--r-- | tools/js-optimizer.js | 8 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-pre-output.js | 3 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-pre.js | 6 |
3 files changed, 17 insertions, 0 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 0d1e8801..f69278b0 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -504,6 +504,8 @@ function simplifyExpressionsPre(ast) { stack.push(1); } else if ((type === 'binary' && node[1] in SAFE_BINARY_OPS) || type === 'num' || type === 'name') { stack.push(0); // This node is safe in that it does not interfere with this optimization + } else if (type === 'unary-prefix' && node[1] === '~') { + stack.push(1); } else { stack.push(-1); // This node is dangerous! Give up if you see this before you see '1' } @@ -554,6 +556,12 @@ function simplifyExpressionsPre(ast) { } } } + } else if (type === 'binary' && node[1] === '^') { + // LLVM represents bitwise not as xor with -1. Translate it back to an actual bitwise not. + if (node[3][0] === 'unary-prefix' && node[3][1] === '-' && node[3][2][0] === 'num' && + node[3][2][1] === 1) { + return ['unary-prefix', '~', node[2]]; + } } else if (type === 'binary' && node[1] === '>>' && node[3][0] === 'num' && node[2][0] === 'binary' && node[2][1] === '<<' && node[2][3][0] === 'num' && node[2][2][0] === 'sub' && node[2][2][1][0] === 'name') { diff --git a/tools/test-js-optimizer-asm-pre-output.js b/tools/test-js-optimizer-asm-pre-output.js index 59a42010..d66c28a4 100644 --- a/tools/test-js-optimizer-asm-pre-output.js +++ b/tools/test-js-optimizer-asm-pre-output.js @@ -63,6 +63,9 @@ function b($this, $__n) { HEAP32[($this + 4 & 16777215) >> 2] = $40; } HEAP8[$38 + $40 & 16777215] = 0; + HEAP32[$4] = ~HEAP32[$5]; + HEAP32[$4] = ~HEAP32[$5]; + HEAP32[$4] = ~HEAP32[$5]; return; } function rett() { diff --git a/tools/test-js-optimizer-asm-pre.js b/tools/test-js-optimizer-asm-pre.js index 7ca941fa..5c09043e 100644 --- a/tools/test-js-optimizer-asm-pre.js +++ b/tools/test-js-optimizer-asm-pre.js @@ -64,6 +64,12 @@ function b($this, $__n) { HEAP32[(($this + 4 | 0) & 16777215) >> 2] = $40; } HEAP8[($38 + $40 | 0) & 16777215] = 0; + // Eliminate the |0. + HEAP32[$4] = ((~(HEAP32[$5]|0))|0); + // Rewrite to ~. + HEAP32[$4] = HEAP32[$5]^-1; + // Rewrite to ~ and eliminate the |0. + HEAP32[$4] = ((HEAP32[$5]|0)^-1)|0; return; } function rett() { |