Optimize coercion to Unit.

POP operations are backward-propagated.

Operation can't be transformed if its result is moved within stack
(by DUP, DUP_X1, DUP_X2, DUP2, DUP2_X1, DUP2_X2, or SWAP).

Unnecessary operations are replaced with NOPs (for debugger).
Unnecessary NOPs are removed.

KT-9922 Suboptimal generation for simple safe call with unused return value
KT-11116 Optimize methods returning Unit
This commit is contained in:
Dmitry Petrov
2016-04-05 17:27:01 +03:00
parent c4a568efff
commit f1b061d662
12 changed files with 433 additions and 84 deletions
@@ -0,0 +1,26 @@
fun test() {
val a = inlineFunInt { 1 }
val b = simpleFunInt { 1 }
val c = inlineFunVoid { val aa = 1 }
val d = simpleFunVoid { val aa = 1 }
}
inline fun inlineFunInt(f: () -> Int): Int {
val a = 1
return f()
}
inline fun inlineFunVoid(f: () -> Unit): Unit {
val a = 1
return f()
}
fun simpleFunInt(f: () -> Int): Int {
return f()
}
fun simpleFunVoid(f: () -> Unit): Unit {
return f()
}
// 3 NOP
@@ -0,0 +1,4 @@
fun test() = Unit
// 0 GETSTATIC
// 0 POP
@@ -0,0 +1,10 @@
interface A {
fun foo()
}
fun test(x: A?) {
x?.foo()
}
// 1 POP
// 0 ACONST_NULL
@@ -0,0 +1,10 @@
interface A {
fun foo(): Any
}
fun test(x: A?) {
x?.foo()
}
// 2 POP
// 0 ACONST_NULL
@@ -0,0 +1,19 @@
fun test(ss: List<String?>) {
val shortStrings = hashSetOf<String>()
val longStrings = hashSetOf<String>()
for (s in ss) {
s?.let {
if (s.length < 4) {
shortStrings.add(s)
}
else {
longStrings.add(s)
}
}
}
}
// 2 POP
// 0 INVOKESTATIC java/lang/Boolean\.valueOf
// 0 CHECKCAST java/lang/Boolean
// 0 ACONST_NULL
@@ -0,0 +1,10 @@
// WITH_RUNTIME
import java.io.*
fun test(r: Reader) {
val ss = hashSetOf<String>()
r.useLines { it.forEach { ss.add(it) } }
}
// 2 POP