JS: improve switch elimination

This commit is contained in:
Anton Bannykh
2018-02-20 15:03:24 +03:00
parent 92070d132e
commit eabe21726c
4 changed files with 129 additions and 4 deletions
@@ -75,11 +75,13 @@ internal class EmptyStatementElimination(private val root: JsStatement) {
for (case in x.cases) {
processStatements(case.statements)
}
if (x.cases.lastOrNull() is JsDefault &&
x.cases.dropLast(1).all { it.statements.isEmpty() }) {
if (x.cases.lastOrNull() is JsDefault && x.cases.dropLast(1).all { it.statements.isEmpty() }
|| x.cases.all { it.statements.isEmpty() }
) {
hasChanges = true
val conditionStatement = JsAstUtils.asSyntheticStatement(x.expression)
ctx.replaceMe(JsBlock(listOf(conditionStatement) + x.cases.last().statements))
val replacement = mutableListOf(JsAstUtils.asSyntheticStatement(x.expression))
x.cases.lastOrNull()?.apply { replacement.addAll(statements) }
ctx.replaceMe(JsBlock(replacement))
}
}
@@ -24,4 +24,6 @@ class EmptyStatementEliminationTest : BasicOptimizerTest("empty-statement-elimin
@Test fun ifWithEmptyThenAndNoElse() = box()
@Test fun emptyBlockEliminated() = box()
@Test fun switchElimination() = box()
}
@@ -0,0 +1,53 @@
var log = '';
function test1(v) {
switch (v) {
case 1:
case 2:
log += 'A';
break;
}
log += 1;
}
function test2(v) {
loop: while(--v) {
switch (v) {
case 1:
case 2:
log += 'B';
break loop
}
log += 2;
}
}
function test3(v) {
}
function test4(v) {
log += 'D';
log += 4;
}
function test5(v) {
loop: while (--v) {
log += 'E';
break loop;
}
}
function test6(v) {
log += 'F' + v;
}
function box() {
test1(1);
test1(3);
test2(4);
test4(3);
test5(3);
test6(6);
return log === 'A112BD4EF6' ? 'OK' : 'fail: ' + log;
}
@@ -0,0 +1,68 @@
var log = '';
function test1(v) {
switch (v) {
case 1:
case 2:
log += 'A';
break;
}
log += 1;
}
function test2(v) {
loop: while(--v) {
switch (v) {
case 1:
case 2:
log += 'B';
break loop
}
log += 2;
}
}
function test3(v) {
switch (v) {
case 1:
case 2:
}
}
function test4(v) {
switch (v) {
case 1:
case 2:
default:
log += 'D';
}
log += 4;
}
function test5(v) {
loop: while(--v) {
switch (v) {
case 1:
case 2:
default:
log += 'E';
break loop
}
log += 5;
}
}
function test6(v) {
switch (log += 'F' + v) {}
}
function box() {
test1(1);
test1(3);
test2(4);
test4(3);
test5(3);
test6(6);
return log === 'A112BD4EF6' ? 'OK' : 'fail: ' + log;
}