diff options
author | Alon Zakai <alonzakai@gmail.com> | 2014-03-17 12:54:55 -0700 |
---|---|---|
committer | Alon Zakai <alonzakai@gmail.com> | 2014-03-17 17:56:17 -0700 |
commit | db3ab955c6167dec0e3d694b13b381f6bf7fb330 (patch) | |
tree | 770462d2525f58dfaad796e485cfa43b6f3782c8 | |
parent | dc797a4570fcb776020c886581f6de7feaf734ea (diff) |
fuse if-elses where the relooper did not emit a label clearing
-rw-r--r-- | tests/test_other.py | 19 | ||||
-rw-r--r-- | tools/js-optimizer.js | 14 | ||||
-rw-r--r-- | tools/test-js-optimizer-si-output.js | 13 | ||||
-rw-r--r-- | tools/test-js-optimizer-si.js | 14 |
4 files changed, 52 insertions, 8 deletions
diff --git a/tests/test_other.py b/tests/test_other.py index 0c597e9f..88a5c9c5 100644 --- a/tests/test_other.py +++ b/tests/test_other.py @@ -2586,7 +2586,8 @@ int main() [['-profiling', '-g2'], nums[2]] ]: print opts, ifs - Popen([PYTHON, EMCC, 'src.c', '-O2'] + opts, stdout=PIPE, stderr=PIPE).communicate() + try_delete('a.out.js') + Popen([PYTHON, EMCC, 'src.c', '-O2'] + opts, stdout=PIPE).communicate() src = open('a.out.js').read() main = src[src.find('function _main'):src.find('\n}', src.find('function _main'))] actual_ifs = main.count('if (') @@ -2620,3 +2621,19 @@ int main() } ''', [8, 5, 5]) + test(r''' + #include <stdio.h> + #include <string.h> + int main(int argc, char **argv) { + while (argc % 17 == 0) argc *= 2; + if (argc > 5 && strlen(argv[0]) > 10 && strlen(argv[1]) > 20) { + printf("halp"); + argc++; + } else { + printf("%d\n", argc--); + } + while (argc % 17 == 0) argc *= 2; + return argc; + } + ''', [6, 3, 3]) + diff --git a/tools/js-optimizer.js b/tools/js-optimizer.js index 1c3bc8c0..d5b30476 100644 --- a/tools/js-optimizer.js +++ b/tools/js-optimizer.js @@ -914,7 +914,9 @@ function simplifyIfs(ast) { }); if (abort) return; + var inLoop = 0; // when in a loop, we do not emit label = 0; in the relooper as there is no need traverse(func, function(node, type) { + if (type === 'while') inLoop++; var stats = getStatements(node); if (stats) { for (var i = 0; i < stats.length-1; i++) { @@ -937,12 +939,14 @@ function simplifyIfs(ast) { // Conditions match, just need to make sure the post clears label if (post[2][0] === 'block' && post[2][1] && post[2][1].length > 0) { var postStat = post[2][1][0]; - if (postStat[0] === 'stat' && postStat[1][0] === 'assign' && - postStat[1][1] === true && postStat[1][2][0] === 'name' && postStat[1][2][1] === 'label' && - postStat[1][3][0] === 'num' && postStat[1][3][1] === 0) { + var haveClear = + postStat[0] === 'stat' && postStat[1][0] === 'assign' && + postStat[1][1] === true && postStat[1][2][0] === 'name' && postStat[1][2][1] === 'label' && + postStat[1][3][0] === 'num' && postStat[1][3][1] === 0; + if (!inLoop || haveClear) { // Everything lines up, do it pre[3] = post[2]; - pre[3][1].splice(0, 1); // remove the label clearing + if (haveClear) pre[3][1].splice(0, 1); // remove the label clearing stats.splice(i+1, 1); // remove the post entirely } } @@ -952,6 +956,8 @@ function simplifyIfs(ast) { } } } + }, function(node, type) { + if (type === 'while') inLoop--; }); } }); diff --git a/tools/test-js-optimizer-si-output.js b/tools/test-js-optimizer-si-output.js index 0a2468b5..9ef5171c 100644 --- a/tools/test-js-optimizer-si-output.js +++ b/tools/test-js-optimizer-si-output.js @@ -121,11 +121,18 @@ function a() { if (x ? y : 0) { f(); } else { - label = 53; - } - if ((label | 0) == 53) { a(); } + while (1) { + if (x ? y : 0) { + f(); + } else { + label = 953; + } + if ((label | 0) == 953) { + a(); + } + } if (x ? y : 0) { label = 54; } else { diff --git a/tools/test-js-optimizer-si.js b/tools/test-js-optimizer-si.js index 9bb82da4..04ceec4a 100644 --- a/tools/test-js-optimizer-si.js +++ b/tools/test-js-optimizer-si.js @@ -164,6 +164,20 @@ function a() { if ((label|0) == 53) { a(); } + while (1) { + if (x) { + if (y) { + f(); + } else { + label = 953; + } + } else { + label = 953; + } + if ((label|0) == 953) { + a(); + } + } if (x) { if (y) { label = 54; // extra label setting, cannot fuse here |