aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorAlon Zakai <alonzakai@gmail.com>2014-03-17 12:54:55 -0700
committerAlon Zakai <alonzakai@gmail.com>2014-03-17 17:56:17 -0700
commitdb3ab955c6167dec0e3d694b13b381f6bf7fb330 (patch)
tree770462d2525f58dfaad796e485cfa43b6f3782c8
parentdc797a4570fcb776020c886581f6de7feaf734ea (diff)
fuse if-elses where the relooper did not emit a label clearing
-rw-r--r--tests/test_other.py19
-rw-r--r--tools/js-optimizer.js14
-rw-r--r--tools/test-js-optimizer-si-output.js13
-rw-r--r--tools/test-js-optimizer-si.js14
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