JVM_IR generate less bytecode for for-loops if possible(KT-22334).

This commit is contained in:
Xin Wang
2021-12-28 10:54:01 +08:00
committed by Dmitry Petrov
parent 3b928e1780
commit 9ae452e489
27 changed files with 830 additions and 12 deletions
@@ -0,0 +1,227 @@
// TARGET_BACKEND: JVM_IR
// WITH_STDLIB
fun box(): String {
noUnderflow()
testByteArray()
testCharArray()
testShortArray()
testIntArray()
testLongArray()
testFloatArray()
testDoubleArray()
testBooleanArray()
testEmptyList()
testList()
testMutableList()
testCharSequence()
testString()
testEmptySet()
testSet()
testMutableSet()
testEmptyMap()
testMap()
testMutableMap()
return "OK"
}
fun noUnderflow() {
val M1 = Int.MAX_VALUE - 2
val M2 = Int.MIN_VALUE
var t = 0
for (x in M1..M2 - 1) {
++t
assert(t <= 3) { "Failed: too many iterations" }
}
assert(t == 3) { "Failed: t=$t" }
}
fun testByteArray() {
val array = byteArrayOf(1, 2, 3)
val range = array.size - 1
var optimized = 0
var nonOptimized = 0
for (i in 0..array.size - 1) optimized += array[i]
for (i in 0..range) nonOptimized += array[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testCharArray() {
val array = charArrayOf('1', '2', '3')
val range = array.size - 1
var optimized = ""
var nonOptimized = ""
for (i in 0..array.size - 1) optimized += array[i]
for (i in 0..range) nonOptimized += array[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testShortArray() {
val array = shortArrayOf(1, 2, 3)
val range = array.size - 1
var optimized = 0
var nonOptimized = 0
for (i in 0..array.size - 1) optimized += array[i]
for (i in 0..range) nonOptimized += array[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testIntArray() {
val array = intArrayOf(1, 2, 3)
val range = array.size - 1
var optimized = 0
var nonOptimized = 0
for (i in 0..array.size - 1) optimized += array[i]
for (i in 0..range) nonOptimized += array[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testLongArray() {
val array = longArrayOf(1, 2, 3)
val range = array.size - 1
var optimized = 0L
var nonOptimized = 0L
for (i in 0..array.size - 1) optimized += array[i]
for (i in 0..range) nonOptimized += array[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testFloatArray() {
val array = floatArrayOf(1f, 2f, 3f)
val range = array.size - 1
var optimized = 0f
var nonOptimized = 0f
for (i in 0..array.size - 1) optimized += array[i]
for (i in 0..range) nonOptimized += array[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testDoubleArray() {
val array = doubleArrayOf(1.0, 2.0, 3.0)
val range = array.size - 1
var optimized = 0.0
var nonOptimized = 0.0
for (i in 0..array.size - 1) optimized += array[i]
for (i in 0..range) nonOptimized += array[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testBooleanArray() {
val array = booleanArrayOf(true, false, true)
val range = array.size - 1
var optimized = ""
var nonOptimized = ""
for (i in 0..array.size - 1) optimized += array[i]
for (i in 0..range) nonOptimized += array[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testEmptyList() {
val list = emptyList<Int>()
val range = list.size - 1
var optimized = 0
var nonOptimized = 0
for (i in 0..list.size - 1) optimized += list[i]
for (i in 0..range) nonOptimized += list[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testList() {
val list = listOf(1, 2, 3)
val range = list.size - 1
var optimized = 0
var nonOptimized = 0
for (i in 0..list.size - 1) optimized += list[i]
for (i in 0..range) nonOptimized += list[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testMutableList() {
val list = mutableListOf(1, 2, 3)
val range = list.size - 1
var optimized = 0
var nonOptimized = 0
for (i in 0..list.size - 1) optimized += list[i]
for (i in 0..range) nonOptimized += list[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testCharSequence() {
val chars: CharSequence = "123"
val range = chars.length - 1
var optimized = ""
var nonOptimized = ""
for (i in 0..chars.length - 1) optimized += chars[i]
for (i in 0..range) nonOptimized += chars[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testString() {
val str = "123"
val range = str.length - 1
var optimized = ""
var nonOptimized = ""
for (i in 0..str.length - 1) optimized += str[i]
for (i in 0..range) nonOptimized += str[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testEmptySet() {
val set = emptySet<Int>()
val range = set.size - 1
var optimized = ""
var nonOptimized = ""
for (i in 0..set.size - 1) optimized += set.elementAt(i)
for (i in 0..range) nonOptimized += set.elementAt(i)
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testSet() {
val set = setOf(1, 2, 3)
val range = set.size - 1
var optimized = ""
var nonOptimized = ""
for (i in 0..set.size - 1) optimized += set.elementAt(i)
for (i in 0..range) nonOptimized += set.elementAt(i)
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testMutableSet() {
val set = mutableSetOf(1, 2, 3)
val range = set.size - 1
var optimized = ""
var nonOptimized = ""
for (i in 0..set.size - 1) optimized += set.elementAt(i)
for (i in 0..range) nonOptimized += set.elementAt(i)
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testEmptyMap() {
val map = emptyMap<Int, Int>()
val range = map.size - 1
var optimized = ""
var nonOptimized = ""
for (i in 0..map.size - 1) optimized += map[i]
for (i in 0..range) nonOptimized += map[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testMap() {
val map = mapOf(1 to 1, 2 to 2, 3 to 3)
val range = map.size - 1
var optimized = ""
var nonOptimized = ""
for (i in 0..map.size - 1) optimized += map[i]
for (i in 0..range) nonOptimized += map[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
fun testMutableMap() {
val map = mutableMapOf(1 to 1, 2 to 2, 3 to 3)
val range = map.size - 1
var optimized = ""
var nonOptimized = ""
for (i in 0..map.size - 1) optimized += map[i]
for (i in 0..range) nonOptimized += map[i]
assert(optimized == nonOptimized) { "optimized($optimized) and nonOptimized($nonOptimized) should be equal" }
}
@@ -22,11 +22,12 @@ fun test(): Int {
// 1 IF
// JVM_IR_TEMPLATES
// 1 IF_ICMPGT
// 1 IF_ICMPEQ
// 2 IF
// 7 ILOAD
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IF_ICMPEQ
// 1 IF
// 5 ILOAD
// 4 ISTORE
// 1 IINC
// 1 IADD
// 1 ISUB
// 0 ISUB
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val array = booleanArrayOf(true, false, true)
var optimized = ""
for (i in 0..array.size - 1) optimized += array[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IADD
// 0 ISUB
// 3 ILOAD
// 2 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val array = byteArrayOf(1, 2, 3)
var optimized = 0
for (i in 0..array.size - 1) optimized += array[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 1 IADD
// 0 ISUB
// 4 ILOAD
// 4 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val array = charArrayOf('1', '2', '3')
var optimized = ""
for (i in 0..array.size - 1) optimized += array[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IADD
// 0 ISUB
// 3 ILOAD
// 2 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val chars: CharSequence = "123"
var optimized = ""
for (i in 0..chars.length - 1) optimized += chars[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IADD
// 0 ISUB
// 3 ILOAD
// 2 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val array = doubleArrayOf(1.0, 2.0, 3.0)
var optimized = 0.0
for (i in 0..array.size - 1) optimized += array[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IADD
// 0 ISUB
// 3 ILOAD
// 2 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val list = emptyList<Int>()
var optimized = 0
for (i in 0..list.size - 1) optimized += list[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 1 IADD
// 0 ISUB
// 4 ILOAD
// 4 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val map = emptyMap<Int, Int>()
var optimized = ""
for (i in 0..map.size - 1) optimized += map[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IADD
// 0 ISUB
// 3 ILOAD
// 2 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val set = emptySet<Int>()
var optimized = ""
for (i in 0..set.size - 1) optimized += set.elementAt(i)
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IADD
// 0 ISUB
// 3 ILOAD
// 2 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val array = floatArrayOf(1f, 2f, 3f)
var optimized = 0f
for (i in 0..array.size - 1) optimized += array[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IADD
// 0 ISUB
// 3 ILOAD
// 2 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val array = intArrayOf(1, 2, 3)
var optimized = 0
for (i in 0..array.size - 1) optimized += array[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 1 IADD
// 0 ISUB
// 4 ILOAD
// 4 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val list = listOf(1, 2, 3)
var optimized = 0
for (i in 0..list.size - 1) optimized += list[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 1 IADD
// 0 ISUB
// 4 ILOAD
// 4 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val array = longArrayOf(1, 2, 3)
var optimized = 0L
for (i in 0..array.size - 1) optimized += array[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IADD
// 0 ISUB
// 3 ILOAD
// 2 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val map = mapOf(1 to 1, 2 to 2, 3 to 3)
var optimized = ""
for (i in 0..map.size - 1) optimized += map[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IADD
// 0 ISUB
// 3 ILOAD
// 2 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val list = mutableListOf(1, 2, 3)
var optimized = 0
for (i in 0..list.size - 1) optimized += list[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 1 IADD
// 0 ISUB
// 4 ILOAD
// 4 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val map = mutableMapOf(1 to 1, 2 to 2, 3 to 3)
var optimized = ""
for (i in 0..map.size - 1) optimized += map[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IADD
// 0 ISUB
// 3 ILOAD
// 2 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val set = mutableSetOf(1, 2, 3)
var optimized = ""
for (i in 0..set.size - 1) optimized += set.elementAt(i)
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IADD
// 0 ISUB
// 3 ILOAD
// 2 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val set = setOf(1, 2, 3)
var optimized = ""
for (i in 0..set.size - 1) optimized += set.elementAt(i)
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IADD
// 0 ISUB
// 3 ILOAD
// 2 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val array = shortArrayOf(1, 2, 3)
var optimized = 0
for (i in 0..array.size - 1) optimized += array[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 1 IADD
// 0 ISUB
// 4 ILOAD
// 4 ISTORE
// 1 IINC
@@ -0,0 +1,15 @@
// TARGET_BACKEND: JVM_IR
fun test() {
val str = "123"
var optimized = ""
for (i in 0..str.length - 1) optimized += str[i]
}
// 0 IF_ICMPGT
// 1 IF_ICMPGE
// 0 IADD
// 0 ISUB
// 3 ILOAD
// 2 ISTORE
// 1 IINC