Optimize constant conditions
Using basic constant propagation (only integer constants, no arithmetic calculations), rewrite conditional jump instructions with constant arguments. This covers problem description in KT-17007. Note that it also works transparently with inline functions. Partial evaluation is required to cover more "advanced" cases. As a side effect, this also covers KT-3098: rewrite IF_ICMP<cmp_op>(x, 0) to IF<cmp0_op>(x).
This commit is contained in:
@@ -0,0 +1,25 @@
|
||||
// FILE: util.kt
|
||||
|
||||
inline fun ieq(x: Int, y: Int) = x == y
|
||||
inline fun ine(x: Int, y: Int) = x != y
|
||||
inline fun ilt(x: Int, y: Int) = x < y
|
||||
inline fun ile(x: Int, y: Int) = x <= y
|
||||
inline fun igt(x: Int, y: Int) = x > y
|
||||
inline fun ige(x: Int, y: Int) = x >= y
|
||||
|
||||
// FILE: test.kt
|
||||
|
||||
fun testeq(x: Int) = ieq(x, 0)
|
||||
fun testne(x: Int) = ine(x, 0)
|
||||
fun testlt(x: Int) = ilt(x, 0)
|
||||
fun testle(x: Int) = ile(x, 0)
|
||||
fun testgt(x: Int) = igt(x, 0)
|
||||
fun testge(x: Int) = ige(x, 0)
|
||||
|
||||
// @TestKt.class:
|
||||
// 0 IF_ICMPEQ
|
||||
// 0 IF_ICMPNE
|
||||
// 0 IF_ICMPGE
|
||||
// 0 IF_ICMPGT
|
||||
// 0 IF_ICMPLE
|
||||
// 0 IF_ICMPLT
|
||||
@@ -0,0 +1,35 @@
|
||||
// FILE: util.kt
|
||||
const val FLAG = true
|
||||
const val OTHER_FLAG = false
|
||||
|
||||
fun doStuff1() {}
|
||||
fun doStuff2() {}
|
||||
fun doStuff3() {}
|
||||
|
||||
inline fun doStuff1IfTrue(flag: Boolean) {
|
||||
if (flag) doStuff1()
|
||||
}
|
||||
|
||||
inline fun doStuff2IfFalse(flag: Boolean) {
|
||||
if (!flag) doStuff2()
|
||||
}
|
||||
|
||||
inline fun doStuff3IfComplex(flag: Boolean) {
|
||||
if (flag && !OTHER_FLAG) doStuff3()
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
fun test() {
|
||||
doStuff1IfTrue(FLAG)
|
||||
doStuff2IfFalse(FLAG)
|
||||
doStuff3IfComplex(FLAG)
|
||||
}
|
||||
|
||||
// @TestKt.class:
|
||||
// 0 FLAG
|
||||
// 1 INVOKESTATIC UtilKt.doStuff1
|
||||
// 0 INVOKESTATIC UtilKt.doStuff2
|
||||
// 1 INVOKESTATIC UtilKt.doStuff3
|
||||
// 0 ILOAD 0
|
||||
// 0 IFEQ
|
||||
// 0 IFNE
|
||||
@@ -0,0 +1,58 @@
|
||||
// FILE: util.kt
|
||||
const val MAGIC = 42
|
||||
|
||||
fun doStuffEq() {}
|
||||
fun doStuffNotEq() {}
|
||||
fun doStuffLt() {}
|
||||
fun doStuffLe() {}
|
||||
fun doStuffGt() {}
|
||||
fun doStuffGe() {}
|
||||
|
||||
inline fun doStuffIfEq(i: Int) {
|
||||
if (i == MAGIC) doStuffEq()
|
||||
}
|
||||
|
||||
inline fun doStuffIfNotEq(i: Int) {
|
||||
if (i != MAGIC) doStuffNotEq()
|
||||
}
|
||||
|
||||
inline fun doStuffIfLt(i: Int) {
|
||||
if (i < MAGIC) doStuffLt()
|
||||
}
|
||||
|
||||
inline fun doStuffIfLe(i: Int) {
|
||||
if (i <= MAGIC) doStuffLe()
|
||||
}
|
||||
|
||||
inline fun doStuffIfGt(i: Int) {
|
||||
if (i > MAGIC) doStuffGt()
|
||||
}
|
||||
|
||||
inline fun doStuffIfGe(i: Int) {
|
||||
if (i >= MAGIC) doStuffGe()
|
||||
}
|
||||
|
||||
// FILE: test.kt
|
||||
fun test() {
|
||||
doStuffIfEq(100)
|
||||
doStuffIfNotEq(100)
|
||||
doStuffIfLt(100)
|
||||
doStuffIfLe(100)
|
||||
doStuffIfGt(100)
|
||||
doStuffIfGe(100)
|
||||
}
|
||||
|
||||
// @TestKt.class:
|
||||
// 0 INVOKESTATIC UtilKt.doStuffEq
|
||||
// 1 INVOKESTATIC UtilKt.doStuffNotEq
|
||||
// 0 INVOKESTATIC UtilKt.doStuffLt
|
||||
// 0 INVOKESTATIC UtilKt.doStuffLe
|
||||
// 1 INVOKESTATIC UtilKt.doStuffGt
|
||||
// 1 INVOKESTATIC UtilKt.doStuffGe
|
||||
// 0 ILOAD 0
|
||||
// 0 IFEQ
|
||||
// 0 IFNE
|
||||
// 0 IFLT
|
||||
// 0 IFLE
|
||||
// 0 IFGE
|
||||
// 0 IFGT
|
||||
@@ -0,0 +1,9 @@
|
||||
fun testLt(x: String, y: String) = x < y
|
||||
fun testLe(x: String, y: String) = x <= y
|
||||
fun testGt(x: String, y: String) = x > y
|
||||
fun testGe(x: String, y: String) = x >= y
|
||||
|
||||
// 0 IF_ICMPGE
|
||||
// 0 IF_ICMPGT
|
||||
// 0 IF_ICMPLE
|
||||
// 0 IF_ICMPLT
|
||||
Reference in New Issue
Block a user