diff options
author | Alon Zakai <alonzakai@gmail.com> | 2013-06-07 18:23:34 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2013-06-07 18:50:56 -0700 |
commit | 9e7ce499b5883eeb6cd9deac70d997ff5d0f7eeb (patch) | |
tree | 6626a6fd6fc9d8b4978aa05ab99cc233f0a110a0 | |
parent | de6512b8598116ad9d7b22b3c38bf47238f6a9da (diff) |
optimize some HEAP32 expressions, including some unnecessary bitcasts through tempDoublePtr
-rw-r--r-- | tools/js-optimizer.js | 26 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-pre-output.js | 8 | ||||
-rw-r--r-- | tools/test-js-optimizer-asm-pre.js | 10 |
3 files changed, 41 insertions, 3 deletions
diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 5a202de9..9b559ee2 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -522,6 +522,27 @@ function simplifyExpressionsPre(ast) { return node; } } + } 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') { + node[3] = node[3][2]; + } + } + // remove bitcasts that are now obviously pointless, e.g. + // HEAP32[$45 >> 2] = HEAPF32[tempDoublePtr >> 2] = ($14 < $28 ? $14 : $28) - $42, HEAP32[tempDoublePtr >> 2] | 0; + var value = node[3]; + if (value[0] == 'seq' && value[1][0] == 'assign' && value[1][2][0] == 'sub' && value[1][2][1][0] == 'name' && value[1][2][1][1] == 'HEAPF32' && + value[1][2][2][0] == 'binary' && value[1][2][2][2][0] == 'name' && value[1][2][2][2][1] == 'tempDoublePtr') { + // transform to HEAPF32[$45 >> 2] = ($14 < $28 ? $14 : $28) - $42; + node[2][1][1] = 'HEAPF32'; + node[3] = value[1][3]; + } + } } }); @@ -2349,9 +2370,9 @@ function eliminate(ast, memSafe) { var seenUses = {}, helperReplacements = {}; // for looper-helper optimization - // clean up vars - //printErr('cleaning up ' + JSON.stringify(varsToRemove)); + // clean up vars, and loop variable elimination traverse(func, function(node, type) { + // pre if (type === 'var') { node[1] = node[1].filter(function(pair) { return !varsToRemove[pair[0]] }); if (node[1].length == 0) { @@ -2361,6 +2382,7 @@ function eliminate(ast, memSafe) { } } }, function(node, type) { + // post if (type == 'name') { var name = node[1]; if (name in helperReplacements) { diff --git a/tools/test-js-optimizer-asm-pre-output.js b/tools/test-js-optimizer-asm-pre-output.js index ab953e5d..57a7a4f8 100644 --- a/tools/test-js-optimizer-asm-pre-output.js +++ b/tools/test-js-optimizer-asm-pre-output.js @@ -107,4 +107,12 @@ function sign_extension_simplification() { print(5); } } +function tempDoublePtr($45, $14, $28, $42) { + $45 = $45 | 0; + $14 = $14 | 0; + $28 = $28 | 0; + $42 = $42 | 0; + HEAPF32[$45 >> 2] = ($14 < $28 ? $14 : $28) - $42; + HEAP32[$world + 102916 >> 2] = _malloc(192) | 0; +} diff --git a/tools/test-js-optimizer-asm-pre.js b/tools/test-js-optimizer-asm-pre.js index 264587d2..27eff714 100644 --- a/tools/test-js-optimizer-asm-pre.js +++ b/tools/test-js-optimizer-asm-pre.js @@ -109,4 +109,12 @@ function sign_extension_simplification() { print(5); } } -// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "rett", "ret2t", "retf", "i32_8"] +function tempDoublePtr($45, $14, $28, $42) { + $45 = $45 | 0; + $14 = $14 | 0; + $28 = $28 | 0; + $42 = $42 | 0; + HEAP32[$45 >> 2] = 0 | (HEAPF32[tempDoublePtr >> 2] = ($14 < $28 ? $14 : $28) - $42, HEAP32[tempDoublePtr >> 2] | 0); + HEAP32[$world + 102916 >> 2] = _malloc(192) | 0; +} +// EMSCRIPTEN_GENERATED_FUNCTIONS: ["a", "b", "rett", "ret2t", "retf", "i32_8", "tempDoublePtr"] |