JVM_IR generate less bytecode for for-loops if possible(KT-22334).
This commit is contained in:
+6
@@ -34261,6 +34261,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/ranges/forInRangeWithImplicitReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forInRangeWithUpperBoundMinus1.kt")
|
||||
public void testForInRangeWithUpperBoundMinus1() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/forInRangeWithUpperBoundMinus1.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forInStringVarUpdatedInLoopBody.kt")
|
||||
public void testForInStringVarUpdatedInLoopBody() throws Exception {
|
||||
|
||||
+124
@@ -2794,6 +2794,130 @@ public class FirBytecodeTextTestGenerated extends AbstractFirBytecodeTextTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class ForInRangeWithUpperBoundMinus1 {
|
||||
@Test
|
||||
public void testAllFilesPresentInForInRangeWithUpperBoundMinus1() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("booleanArray.kt")
|
||||
public void testBooleanArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/booleanArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("byteArray.kt")
|
||||
public void testByteArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/byteArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("charArray.kt")
|
||||
public void testCharArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/charArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("charSequence.kt")
|
||||
public void testCharSequence() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/charSequence.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("doubleArray.kt")
|
||||
public void testDoubleArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/doubleArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("emptyList.kt")
|
||||
public void testEmptyList() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/emptyList.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("emptyMap.kt")
|
||||
public void testEmptyMap() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/emptyMap.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("emptySet.kt")
|
||||
public void testEmptySet() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/emptySet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("floatArray.kt")
|
||||
public void testFloatArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/floatArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("intArray.kt")
|
||||
public void testIntArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/intArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("list.kt")
|
||||
public void testList() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/list.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("longArray.kt")
|
||||
public void testLongArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/longArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("map.kt")
|
||||
public void testMap() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/map.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mutableList.kt")
|
||||
public void testMutableList() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/mutableList.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mutableMap.kt")
|
||||
public void testMutableMap() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/mutableMap.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mutableSet.kt")
|
||||
public void testMutableSet() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/mutableSet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("set.kt")
|
||||
public void testSet() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/set.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("shortArray.kt")
|
||||
public void testShortArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/shortArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("string.kt")
|
||||
public void testString() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/string.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInReversed")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+42
-7
@@ -10,12 +10,10 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.loops.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.matchers.SimpleCalleeMatcher
|
||||
import org.jetbrains.kotlin.ir.builders.irInt
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
/** Builds a [HeaderInfo] for progressions built using the `rangeTo` function. */
|
||||
@@ -67,7 +65,46 @@ internal class RangeToHandler(private val context: CommonBackendContext) :
|
||||
if (preferJavaLikeCounterLoop || this.constLongValue == -1L) return null
|
||||
}
|
||||
|
||||
val irConst = this as? IrConst<*> ?: return null
|
||||
return when (this) {
|
||||
is IrConst<*> -> convertIrConst(this)
|
||||
is IrCall -> convertIrCall(this)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private val allowedMethods = listOf(
|
||||
"kotlin.ByteArray.<get-size>",
|
||||
"kotlin.CharArray.<get-size>",
|
||||
"kotlin.String.<get-length>",
|
||||
"kotlin.ShortArray.<get-size>",
|
||||
"kotlin.IntArray.<get-size>",
|
||||
"kotlin.LongArray.<get-size>",
|
||||
"kotlin.FloatArray.<get-size>",
|
||||
"kotlin.DoubleArray.<get-size>",
|
||||
"kotlin.BooleanArray.<get-size>",
|
||||
"kotlin.collections.List.<get-size>",
|
||||
"kotlin.collections.MutableList.<get-size>",
|
||||
"kotlin.CharSequence.<get-length>",
|
||||
"kotlin.collections.Set.<get-size>",
|
||||
"kotlin.collections.MutableSet.<get-size>",
|
||||
"kotlin.collections.Map.<get-size>",
|
||||
"kotlin.collections.MutableMap.<get-size>",
|
||||
)
|
||||
|
||||
private fun convertIrCall(irCall: IrCall): IrExpression? {
|
||||
fun IrCall.dispatchReceiverName() = (dispatchReceiver as? IrCall)?.symbol?.owner?.fqNameWhenAvailable.toString()
|
||||
|
||||
return if (irCall.origin == IrStatementOrigin.MINUS
|
||||
&& (irCall.getValueArgument(0) as? IrConst<*>)?.value == 1
|
||||
&& irCall.dispatchReceiverName() in allowedMethods // to avoid possible underflow
|
||||
) irCall.dispatchReceiver
|
||||
else null
|
||||
}
|
||||
|
||||
private fun convertIrConst(irConst: IrConst<*>): IrExpression? {
|
||||
val startOffset = irConst.startOffset
|
||||
val endOffset = irConst.endOffset
|
||||
val type = irConst.type
|
||||
return when (irConst.kind) {
|
||||
IrConstKind.Char -> {
|
||||
val charValue = IrConstKind.Char.valueOf(irConst)
|
||||
@@ -108,6 +145,4 @@ internal class RangeToHandler(private val context: CommonBackendContext) :
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
@@ -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" }
|
||||
}
|
||||
+6
-5
@@ -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
|
||||
|
||||
Vendored
+15
@@ -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
|
||||
+15
@@ -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
|
||||
+15
@@ -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
|
||||
Vendored
+15
@@ -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
|
||||
Vendored
+15
@@ -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
|
||||
+15
@@ -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
|
||||
+15
@@ -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
|
||||
+15
@@ -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
|
||||
Vendored
+15
@@ -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
|
||||
+15
@@ -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
|
||||
+15
@@ -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
|
||||
+15
@@ -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
|
||||
+15
@@ -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
|
||||
Vendored
+15
@@ -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
|
||||
Vendored
+15
@@ -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
|
||||
Vendored
+15
@@ -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
|
||||
+15
@@ -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
|
||||
Vendored
+15
@@ -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
|
||||
+15
@@ -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
|
||||
+10
@@ -2764,6 +2764,16 @@ public class BytecodeTextTestGenerated extends AbstractBytecodeTextTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class ForInRangeWithUpperBoundMinus1 {
|
||||
@Test
|
||||
public void testAllFilesPresentInForInRangeWithUpperBoundMinus1() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM, true);
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInReversed")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
+6
@@ -34261,6 +34261,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/ranges/forInRangeWithImplicitReceiver.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forInRangeWithUpperBoundMinus1.kt")
|
||||
public void testForInRangeWithUpperBoundMinus1() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/ranges/forInRangeWithUpperBoundMinus1.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("forInStringVarUpdatedInLoopBody.kt")
|
||||
public void testForInStringVarUpdatedInLoopBody() throws Exception {
|
||||
|
||||
+124
@@ -2794,6 +2794,130 @@ public class IrBytecodeTextTestGenerated extends AbstractIrBytecodeTextTest {
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
public class ForInRangeWithUpperBoundMinus1 {
|
||||
@Test
|
||||
public void testAllFilesPresentInForInRangeWithUpperBoundMinus1() throws Exception {
|
||||
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("booleanArray.kt")
|
||||
public void testBooleanArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/booleanArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("byteArray.kt")
|
||||
public void testByteArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/byteArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("charArray.kt")
|
||||
public void testCharArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/charArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("charSequence.kt")
|
||||
public void testCharSequence() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/charSequence.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("doubleArray.kt")
|
||||
public void testDoubleArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/doubleArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("emptyList.kt")
|
||||
public void testEmptyList() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/emptyList.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("emptyMap.kt")
|
||||
public void testEmptyMap() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/emptyMap.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("emptySet.kt")
|
||||
public void testEmptySet() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/emptySet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("floatArray.kt")
|
||||
public void testFloatArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/floatArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("intArray.kt")
|
||||
public void testIntArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/intArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("list.kt")
|
||||
public void testList() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/list.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("longArray.kt")
|
||||
public void testLongArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/longArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("map.kt")
|
||||
public void testMap() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/map.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mutableList.kt")
|
||||
public void testMutableList() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/mutableList.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mutableMap.kt")
|
||||
public void testMutableMap() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/mutableMap.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("mutableSet.kt")
|
||||
public void testMutableSet() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/mutableSet.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("set.kt")
|
||||
public void testSet() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/set.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("shortArray.kt")
|
||||
public void testShortArray() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/shortArray.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("string.kt")
|
||||
public void testString() throws Exception {
|
||||
runTest("compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithUpperBoundMinus1/string.kt");
|
||||
}
|
||||
}
|
||||
|
||||
@Nested
|
||||
@TestMetadata("compiler/testData/codegen/bytecodeText/forLoop/forInReversed")
|
||||
@TestDataPath("$PROJECT_ROOT")
|
||||
|
||||
Reference in New Issue
Block a user