aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2013-06-07 18:23:34 -0700
committerAlon Zakai <alonzakai@gmail.com>2013-06-07 18:50:56 -0700
commit9e7ce499b5883eeb6cd9deac70d997ff5d0f7eeb (patch)
tree6626a6fd6fc9d8b4978aa05ab99cc233f0a110a0
parentde6512b8598116ad9d7b22b3c38bf47238f6a9da (diff)
optimize some HEAP32 expressions, including some unnecessary bitcasts through tempDoublePtr
-rw-r--r--tools/js-optimizer.js26
-rw-r--r--tools/test-js-optimizer-asm-pre-output.js8
-rw-r--r--tools/test-js-optimizer-asm-pre.js10
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"]