From eabe21726c34d2b458a826caa89e6d72e86a2e17 Mon Sep 17 00:00:00 2001 From: Anton Bannykh Date: Tue, 20 Feb 2018 15:03:24 +0300 Subject: [PATCH] JS: improve switch elimination --- .../inline/clean/EmptyStatementElimination.kt | 10 +-- .../EmptyStatementEliminationTest.kt | 2 + .../switchElimination.optimized.js | 53 +++++++++++++++ .../switchElimination.original.js | 68 +++++++++++++++++++ 4 files changed, 129 insertions(+), 4 deletions(-) create mode 100644 js/js.translator/testData/js-optimizer/empty-statement-elimination/switchElimination.optimized.js create mode 100644 js/js.translator/testData/js-optimizer/empty-statement-elimination/switchElimination.original.js diff --git a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/EmptyStatementElimination.kt b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/EmptyStatementElimination.kt index 0718844ab76..77412f8cf1f 100644 --- a/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/EmptyStatementElimination.kt +++ b/js/js.inliner/src/org/jetbrains/kotlin/js/inline/clean/EmptyStatementElimination.kt @@ -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)) } } diff --git a/js/js.tests/test/org/jetbrains/kotlin/js/test/optimizer/EmptyStatementEliminationTest.kt b/js/js.tests/test/org/jetbrains/kotlin/js/test/optimizer/EmptyStatementEliminationTest.kt index b912e93296d..d1305305143 100644 --- a/js/js.tests/test/org/jetbrains/kotlin/js/test/optimizer/EmptyStatementEliminationTest.kt +++ b/js/js.tests/test/org/jetbrains/kotlin/js/test/optimizer/EmptyStatementEliminationTest.kt @@ -24,4 +24,6 @@ class EmptyStatementEliminationTest : BasicOptimizerTest("empty-statement-elimin @Test fun ifWithEmptyThenAndNoElse() = box() @Test fun emptyBlockEliminated() = box() + + @Test fun switchElimination() = box() } diff --git a/js/js.translator/testData/js-optimizer/empty-statement-elimination/switchElimination.optimized.js b/js/js.translator/testData/js-optimizer/empty-statement-elimination/switchElimination.optimized.js new file mode 100644 index 00000000000..941d9c483ea --- /dev/null +++ b/js/js.translator/testData/js-optimizer/empty-statement-elimination/switchElimination.optimized.js @@ -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; +} \ No newline at end of file diff --git a/js/js.translator/testData/js-optimizer/empty-statement-elimination/switchElimination.original.js b/js/js.translator/testData/js-optimizer/empty-statement-elimination/switchElimination.original.js new file mode 100644 index 00000000000..552a380138a --- /dev/null +++ b/js/js.translator/testData/js-optimizer/empty-statement-elimination/switchElimination.original.js @@ -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; +} \ No newline at end of file