KT-12275 Add JS optimization that transforms the following code

```
do {
    X
    if (B) break;
} while (A)
```

to

```
do {
    X
} while (!B && A)
```

Add inversion that takes boolean expression and applies negation to it, simplifying if possible (like !!a => a).
This commit is contained in:
Alexey Andreev
2016-05-16 13:08:44 +03:00
parent b3d29adad9
commit 05dd039151
27 changed files with 812 additions and 1 deletions
@@ -0,0 +1,12 @@
function box() {
var i = 1;
var sum = 0;
while (i < 10 && sum <= 30) {
sum += i;
i++
}
if (sum != 36) return "fail: " + sum;
return "OK"
}
@@ -0,0 +1,18 @@
function box() {
var i = 1;
var sum = 0;
while (true) {
if (i >= 10) {
break;
}
if (sum > 30) {
break;
}
sum += i;
i++
}
if (sum != 36) return "fail: " + sum;
return "OK"
}
@@ -0,0 +1,20 @@
var global = "";
function foo(x) {
global += x + ";";
return x;
}
function box() {
var i = 1;
var sum = 0;
do {
sum += i;
i++;
} while (foo(i) < 10 && foo(sum) <= 30);
if (global != "2;1;3;3;4;6;5;10;6;15;7;21;8;28;9;36;") return "fail1: " + global;
if (sum != 36) return "fail2: " + sum;
return "OK"
}
@@ -0,0 +1,26 @@
var global = "";
function foo(x) {
global += x + ";";
return x;
}
function box() {
var i = 1;
var sum = 0;
do {
sum += i;
i++;
if (foo(i) >= 10) {
break;
}
if (foo(sum) > 30) {
break;
}
} while (true);
if (global != "2;1;3;3;4;6;5;10;6;15;7;21;8;28;9;36;") return "fail1: " + global;
if (sum != 36) return "fail2: " + sum;
return "OK"
}
@@ -0,0 +1,24 @@
var global = "";
function foo(x) {
global += x;
return x;
}
function box() {
var i = 0;
do {
++i;
if (i == 5) {
continue
}
global += ";";
if (foo(i) >= 10) {
break;
}
} while (true);
if (global != ";1;2;3;4;6;7;8;9;10") return "fail: " + global;
return "OK"
}
@@ -0,0 +1,24 @@
var global = "";
function foo(x) {
global += x;
return x;
}
function box() {
var i = 0;
do {
++i;
if (i == 5) {
continue
}
global += ";";
if (foo(i) >= 10) {
break;
}
} while (true);
if (global != ";1;2;3;4;6;7;8;9;10") return "fail: " + global;
return "OK"
}
@@ -0,0 +1,45 @@
var global = "";
function foo(x) {
global += x;
return x;
}
function box() {
var i = 0;
var j;
do {
++i;
global += ";";
for (j = 0; j < 2; ++j) {
if (j == 1) {
continue;
}
global += "-";
}
for (k in { a: 2, b: 3 }) {
if (k != "a") {
continue;
}
global += "@";
}
j = 0;
while (j++ < 2) {
if (j == 1) {
continue;
}
global += "$";
}
j = 0;
do {
if (j == 1) {
continue;
}
global += "#";
} while (j++ < 2);
} while (foo(i) < 3);
if (global != ";-@$##1;-@$##2;-@$##3") return "fail: " + global;
return "OK"
}
@@ -0,0 +1,48 @@
var global = "";
function foo(x) {
global += x;
return x;
}
function box() {
var i = 0;
var j;
do {
++i;
global += ";";
for (j = 0; j < 2; ++j) {
if (j == 1) {
continue;
}
global += "-";
}
for (k in { a: 2, b: 3 }) {
if (k != "a") {
continue;
}
global += "@";
}
j = 0;
while (j++ < 2) {
if (j == 1) {
continue;
}
global += "$";
}
j = 0;
do {
if (j == 1) {
continue;
}
global += "#";
} while (j++ < 2);
if (foo(i) >= 3) {
break;
}
} while (true);
if (global != ";-@$##1;-@$##2;-@$##3") return "fail: " + global;
return "OK"
}
@@ -0,0 +1,15 @@
function box() {
var i = 1;
var sum = 0;
outer: {
while (i < 10) {
sum += i;
i++;
if (sum > 20) break outer;
}
}
if (sum != 21) return "fail: " + sum;
return "OK"
}
@@ -0,0 +1,18 @@
function box() {
var i = 1;
var sum = 0;
outer: {
while (true) {
if (i >= 10) {
break;
}
sum += i;
i++;
if (sum > 20) break outer;
}
}
if (sum != 21) return "fail: " + sum;
return "OK"
}
@@ -0,0 +1,16 @@
function box() {
var i;
var sum = 0;
var count = 2;
while (count-- > 0) {
i = 1;
while (i < 10) {
sum += i;
i++
}
}
if (sum != 90) return "fail: " + sum;
return "OK"
}
@@ -0,0 +1,19 @@
function box() {
var i;
var sum = 0;
var count = 2;
while (count-- > 0) {
i = 1;
while (true) {
if (i >= 10) {
break;
}
sum += i;
i++
}
}
if (sum != 90) return "fail: " + sum;
return "OK"
}
@@ -0,0 +1,28 @@
var global = "";
function foo(x) {
global += x;
return x;
}
function box() {
var i = 0;
var j;
loop: do {
++i;
global += ";";
for (j = 0; j < 2; ++j) {
if (j == 1 && i == 2) {
continue loop;
}
global += "-";
}
if (foo(i) >= 5) {
break;
}
} while (true);
if (global != ";--1;-;--3;--4;--5") return "fail: " + global;
return "OK"
}
@@ -0,0 +1,28 @@
var global = "";
function foo(x) {
global += x;
return x;
}
function box() {
var i = 0;
var j;
loop: do {
++i;
global += ";";
for (j = 0; j < 2; ++j) {
if (j == 1 && i == 2) {
continue loop;
}
global += "-";
}
if (foo(i) >= 5) {
break;
}
} while (true);
if (global != ";--1;-;--3;--4;--5") return "fail: " + global;
return "OK"
}
@@ -0,0 +1,12 @@
function box() {
var i = 1;
var sum = 0;
while (i < 5 || sum <= 40) {
sum += i;
i++
}
if (sum != 45) return "fail: " + sum;
return "OK"
}
@@ -0,0 +1,15 @@
function box() {
var i = 1;
var sum = 0;
while (true) {
if (i >= 5) {
if (sum > 40) break;
}
sum += i;
i++
}
if (sum != 45) return "fail: " + sum;
return "OK"
}
@@ -0,0 +1,18 @@
var global = "";
function foo(x) {
global += x;
return x;
}
function box() {
var i = 0;
do {
++i;
global += ";";
} while (foo(i) < 10);
if (global != ";1;2;3;4;5;6;7;8;9;10") return "fail: " + global;
return "OK"
}
@@ -0,0 +1,21 @@
var global = "";
function foo(x) {
global += x;
return x;
}
function box() {
var i = 0;
do {
++i;
global += ";";
if (foo(i) >= 10) {
break;
}
} while (true);
if (global != ";1;2;3;4;5;6;7;8;9;10") return "fail: " + global;
return "OK"
}
@@ -0,0 +1,12 @@
function box() {
var i = 1;
var sum = 0;
while (i < 10) {
sum += i;
i++
}
if (sum != 45) return "fail: " + sum;
return "OK"
}
@@ -0,0 +1,15 @@
function box() {
var i = 1;
var sum = 0;
while (true) {
if (i >= 10) {
break;
}
sum += i;
i++
}
if (sum != 45) return "fail: " + sum;
return "OK"
}
@@ -0,0 +1,20 @@
var global = "";
function foo(x) {
global += x + ";";
return x;
}
function box() {
var i = 1;
var sum = 0;
while (foo(i) < 10 && foo(sum) <= 30) {
sum += i;
i++;
}
if (global != "1;0;2;1;3;3;4;6;5;10;6;15;7;21;8;28;9;36;") return "fail1: " + global;
if (sum != 36) return "fail2: " + sum;
return "OK"
}
@@ -0,0 +1,26 @@
var global = "";
function foo(x) {
global += x + ";";
return x;
}
function box() {
var i = 1;
var sum = 0;
while (true) {
if (foo(i) >= 10) {
break;
}
if (foo(sum) > 30) {
break;
}
sum += i;
i++;
}
if (global != "1;0;2;1;3;3;4;6;5;10;6;15;7;21;8;28;9;36;") return "fail1: " + global;
if (sum != 36) return "fail2: " + sum;
return "OK"
}