mirror of
https://github.com/jlengrand/kotlin.git
synced 2026-05-08 15:53:19 +00:00
Make all progression headers inclusive, and decrement last for
last-exclusive progressions (i.e., "until" progressions and loop over array indices). This change makes it possible to correctly implement the handling of "step" progressions. Computing the last element of a stepped progression requires that the last is inclusive. Also invert the while loop (into if + do-while) that is used when lowering for-loops over progressions that cannot overflow. This keeps the performance characteristics closer to the ForLoopsLowering in kotlin-native, since the goal is to converge to this shared version. Also used IrType instead of KotlinType, where possible. https://github.com/JetBrains/kotlin/pull/2390 https://github.com/JetBrains/kotlin/pull/2305
This commit is contained in:
committed by
Mikhael Bogdanov
parent
39f6416757
commit
de1e27c584
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
fun test() {
|
||||
var sum = 0
|
||||
for (i in arrayOf("", "", "", "").indices) {
|
||||
@@ -5,10 +6,20 @@ fun test() {
|
||||
}
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
|
||||
// JVM_TEMPLATES
|
||||
// 1 IF_ICMPGE
|
||||
// 1 IF
|
||||
// 1 IF
|
||||
|
||||
// JVM_IR_TEMPLATES
|
||||
// 1 IF_ICMPGT
|
||||
// 1 IF_ICMPLE
|
||||
// 2 IF
|
||||
19
compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndicesIR.kt
vendored
Normal file
19
compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndicesIR.kt
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
fun test() {
|
||||
var sum = 0
|
||||
for (i in arrayOf("", "", "", "").indices) {
|
||||
sum += i
|
||||
}
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 1 IF_ICMPGT
|
||||
// 1 IF_ICMPLE
|
||||
// 2 IF
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
fun test() {
|
||||
var sum = 0
|
||||
for (i in intArrayOf(0, 0, 0, 0).indices) {
|
||||
@@ -5,6 +6,9 @@ fun test() {
|
||||
}
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
|
||||
19
compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndicesIR.kt
vendored
Normal file
19
compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndicesIR.kt
vendored
Normal file
@@ -0,0 +1,19 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
fun test() {
|
||||
var sum = 0
|
||||
for (i in intArrayOf(0, 0, 0, 0).indices) {
|
||||
sum += i
|
||||
}
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 1 IF_ICMPGT
|
||||
// 1 IF_ICMPLE
|
||||
// 2 IF
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
const val N = 'Z'
|
||||
|
||||
fun test(): Int {
|
||||
@@ -8,6 +9,9 @@ fun test(): Int {
|
||||
return sum
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition).
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
|
||||
22
compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConstIR.kt
vendored
Normal file
22
compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConstIR.kt
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
const val N = 'Z'
|
||||
|
||||
fun test(): Int {
|
||||
var sum = 0
|
||||
for (i in 'A' .. N) {
|
||||
sum += i.toInt()
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition).
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 IF_ICMPLE
|
||||
// 1 IF
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
const val N = 42
|
||||
|
||||
fun test(): Int {
|
||||
@@ -8,6 +9,9 @@ fun test(): Int {
|
||||
return sum
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition).
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
|
||||
22
compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConstIR.kt
vendored
Normal file
22
compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConstIR.kt
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
const val N = 42
|
||||
|
||||
fun test(): Int {
|
||||
var sum = 0
|
||||
for (i in 1 .. N) {
|
||||
sum += i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition).
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 IF_ICMPLE
|
||||
// 1 IF
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
const val N = 42L
|
||||
|
||||
fun test(): Long {
|
||||
@@ -8,6 +9,9 @@ fun test(): Long {
|
||||
return sum
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
|
||||
26
compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConstIR.kt
vendored
Normal file
26
compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConstIR.kt
vendored
Normal file
@@ -0,0 +1,26 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
const val N = 42L
|
||||
|
||||
fun test(): Long {
|
||||
var sum = 0L
|
||||
for (i in 1L .. N) {
|
||||
sum += i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 LCMP
|
||||
// 1 IFGT
|
||||
// 1 IFLE
|
||||
// 2 IF
|
||||
// 0 L2I
|
||||
// 0 I2L
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
object Host {
|
||||
const val M = 1
|
||||
const val N = 4
|
||||
@@ -11,6 +12,9 @@ fun test(): Int {
|
||||
return s
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition).
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
|
||||
25
compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConstIR.kt
vendored
Normal file
25
compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConstIR.kt
vendored
Normal file
@@ -0,0 +1,25 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
object Host {
|
||||
const val M = 1
|
||||
const val N = 4
|
||||
}
|
||||
|
||||
fun test(): Int {
|
||||
var s = 0
|
||||
for (i in Host.M .. Host.N) {
|
||||
s += i
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition).
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 IF_ICMPLE
|
||||
// 1 IF
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
@@ -11,6 +12,9 @@ fun box(): String {
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 reversed
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
@@ -18,5 +22,5 @@ fun box(): String {
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 IF(_ICMPG|L)T
|
||||
// 1 IFLT
|
||||
// 1 IF
|
||||
27
compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndicesIR.kt
vendored
Normal file
27
compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndicesIR.kt
vendored
Normal file
@@ -0,0 +1,27 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
val arr = intArrayOf(1, 1, 1, 1)
|
||||
var sum = 0
|
||||
for (i in arr.indices.reversed()) {
|
||||
sum = sum * 10 + i + arr[i]
|
||||
}
|
||||
assertEquals(4321, sum)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 reversed
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 IF_ICMPGT
|
||||
// 1 IF_ICMPLE
|
||||
// 2 IF
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
@@ -22,6 +23,9 @@ fun box(): String {
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
|
||||
|
||||
// 0 reversed
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
@@ -29,7 +33,7 @@ fun box(): String {
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 IF_ICMP[LG]T
|
||||
// 1 IF[LG]T
|
||||
// 2 IF_ICMPGT
|
||||
// 1 IFGT
|
||||
// 3 IF
|
||||
// 1 LCMP
|
||||
40
compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownToIR.kt
vendored
Normal file
40
compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownToIR.kt
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
var sum = 0
|
||||
for (i in (4 downTo 1).reversed()) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
assertEquals(1234, sum)
|
||||
|
||||
var sumL = 0L
|
||||
for (i in (4L downTo 1L).reversed()) {
|
||||
sumL = sumL * 10 + i
|
||||
}
|
||||
assertEquals(1234L, sumL)
|
||||
|
||||
var sumC = 0
|
||||
for (i in ('4' downTo '1').reversed()) {
|
||||
sumC = sumC * 10 + i.toInt() - '0'.toInt()
|
||||
}
|
||||
assertEquals(1234, sumC)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
|
||||
|
||||
// 0 reversed
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 IF_ICMPLE
|
||||
// 1 IFGT
|
||||
// 1 IFLE
|
||||
// 4 IF
|
||||
// 2 LCMP
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
@@ -22,6 +23,9 @@ fun box(): String {
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
|
||||
|
||||
// 0 reversed
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
@@ -29,7 +33,7 @@ fun box(): String {
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 IF_ICMP[LG]T
|
||||
// 1 IF[LG]T
|
||||
// 2 IF_ICMPLT
|
||||
// 1 IFLT
|
||||
// 3 IF
|
||||
// 1 LCMP
|
||||
40
compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteralIR.kt
vendored
Normal file
40
compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteralIR.kt
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
var sum = 0
|
||||
for (i in (1 .. 4).reversed()) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
assertEquals(4321, sum)
|
||||
|
||||
var sumL = 0L
|
||||
for (i in (1L .. 4L).reversed()) {
|
||||
sumL = sumL * 10 + i
|
||||
}
|
||||
assertEquals(4321L, sumL)
|
||||
|
||||
var sumC = 0
|
||||
for (i in ('1' .. '4').reversed()) {
|
||||
sumC = sumC * 10 + i.toInt() - '0'.toInt()
|
||||
}
|
||||
assertEquals(4321, sumC)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
|
||||
|
||||
// 0 reversed
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 IF_ICMPLE
|
||||
// 1 IFGT
|
||||
// 1 IFLE
|
||||
// 4 IF
|
||||
// 2 LCMP
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
@@ -22,6 +23,9 @@ fun box(): String {
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
|
||||
|
||||
// 0 reversed
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
@@ -29,7 +33,7 @@ fun box(): String {
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 IF_ICMP[LG]T
|
||||
// 1 IF[LG]T
|
||||
// 2 IF_ICMPLT
|
||||
// 1 IFLT
|
||||
// 3 IF
|
||||
// 1 LCMP
|
||||
40
compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownToIR.kt
vendored
Normal file
40
compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownToIR.kt
vendored
Normal file
@@ -0,0 +1,40 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
var sum = 0
|
||||
for (i in (4 downTo 1).reversed().reversed()) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
assertEquals(1234, sum)
|
||||
|
||||
var sumL = 0L
|
||||
for (i in (4L downTo 1L).reversed().reversed()) {
|
||||
sumL = sumL * 10 + i
|
||||
}
|
||||
assertEquals(1234L, sumL)
|
||||
|
||||
var sumC = 0
|
||||
for (i in ('4' downTo '1').reversed().reversed()) {
|
||||
sumC = sumC * 10 + i.toInt() - '0'.toInt()
|
||||
}
|
||||
assertEquals(1234, sumC)
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
|
||||
|
||||
// 0 reversed
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 IF_ICMPLE
|
||||
// 1 IFGT
|
||||
// 1 IFLE
|
||||
// 4 IF
|
||||
// 2 LCMP
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
@@ -19,6 +20,9 @@ fun box(): String {
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
|
||||
|
||||
// 0 reversed
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
@@ -26,7 +30,7 @@ fun box(): String {
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 IF_ICMP[LG]E
|
||||
// 1 IF[LG]E
|
||||
// 2 IF_ICMPGE
|
||||
// 1 IFGE
|
||||
// 3 IF
|
||||
// 1 LCMP
|
||||
37
compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntilIR.kt
vendored
Normal file
37
compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntilIR.kt
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
var sum = 0
|
||||
for (i in (1 until 5).reversed().reversed()) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
|
||||
var sumL = 0L
|
||||
for (i in (1L until 5L).reversed().reversed()) {
|
||||
sumL = sumL * 10 + i
|
||||
}
|
||||
|
||||
var sumC = 0
|
||||
for (i in ('1' until '5').reversed().reversed()) {
|
||||
sumC = sumC * 10 + i.toInt() - '0'.toInt()
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
|
||||
|
||||
// 0 reversed
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 IF_ICMPLE
|
||||
// 1 IFGT
|
||||
// 1 IFLE
|
||||
// 4 IF
|
||||
// 2 LCMP
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
@@ -19,6 +20,9 @@ fun box(): String {
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
|
||||
|
||||
// 0 reversed
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
@@ -26,7 +30,7 @@ fun box(): String {
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 IF_ICMP[LG]T
|
||||
// 1 IF[LG]T
|
||||
// 2 IF_ICMPLT
|
||||
// 1 IFLT
|
||||
// 3 IF
|
||||
// 1 LCMP
|
||||
37
compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntilIR.kt
vendored
Normal file
37
compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntilIR.kt
vendored
Normal file
@@ -0,0 +1,37 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
import kotlin.test.*
|
||||
|
||||
fun box(): String {
|
||||
var sum = 0
|
||||
for (i in (1 until 5).reversed()) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
|
||||
var sumL = 0L
|
||||
for (i in (1L until 5L).reversed()) {
|
||||
sumL = sumL * 10 + i
|
||||
}
|
||||
|
||||
var sumC = 0
|
||||
for (i in ('1' until '5').reversed()) {
|
||||
sumC = sumC * 10 + i.toInt() - '0'.toInt()
|
||||
}
|
||||
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition), except for Long.
|
||||
|
||||
// 0 reversed
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 IF_ICMPLE
|
||||
// 1 IFGT
|
||||
// 1 IFLE
|
||||
// 4 IF
|
||||
// 2 LCMP
|
||||
20
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilChar.kt
vendored
Normal file
20
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilChar.kt
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
fun test(a: Char, b: Char): String {
|
||||
var s = ""
|
||||
for (i in a until b) {
|
||||
s += i
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 IF_ICMPGE
|
||||
// 1 IF
|
||||
22
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharIR.kt
vendored
Normal file
22
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharIR.kt
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
fun test(a: Char, b: Char): String {
|
||||
var s = ""
|
||||
for (i in a until b) {
|
||||
s += i
|
||||
}
|
||||
return s
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 IFEQ
|
||||
// 1 IF_ICMPGT
|
||||
// 1 IF_ICMPLE
|
||||
// 3 IF
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
const val M = Char.MAX_VALUE
|
||||
|
||||
fun f(a: Char): Int {
|
||||
@@ -8,6 +9,9 @@ fun f(a: Char): Int {
|
||||
return n
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
23
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValueIR.kt
vendored
Normal file
23
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValueIR.kt
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
const val M = Char.MAX_VALUE
|
||||
|
||||
fun f(a: Char): Int {
|
||||
var n = 0
|
||||
for (i in a until M) {
|
||||
n++
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 IF_ICMPGT
|
||||
// 1 IF_ICMPLE
|
||||
// 2 IF
|
||||
22
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMinValueIR.kt
vendored
Normal file
22
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMinValueIR.kt
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
const val M = Char.MIN_VALUE
|
||||
|
||||
fun f(a: Char): Int {
|
||||
var n = 0
|
||||
for (i in a until M) {
|
||||
n++
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// For "until" progressions in JVM IR, there is a check that the range is not empty: upper bound != MIN_VALUE.
|
||||
// When the upper bound == const MIN_VALUE, the backend can eliminate the entire loop as dead code.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 0 IF
|
||||
// 0 LINENUMBER 7
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
fun test(a: Int, b: Int): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
@@ -6,6 +7,9 @@ fun test(a: Int, b: Int): Int {
|
||||
return sum
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
23
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntIR.kt
vendored
Normal file
23
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntIR.kt
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
fun test(a: Int, b: Int): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 LDC -2147483648
|
||||
// 1 IF_ICMPEQ
|
||||
// 1 IF_ICMPGT
|
||||
// 1 IF_ICMPLE
|
||||
// 3 IF
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
const val M = Int.MAX_VALUE
|
||||
|
||||
fun f(a: Int): Int {
|
||||
@@ -8,6 +9,9 @@ fun f(a: Int): Int {
|
||||
return n
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
23
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValueIR.kt
vendored
Normal file
23
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValueIR.kt
vendored
Normal file
@@ -0,0 +1,23 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
const val M = Int.MAX_VALUE
|
||||
|
||||
fun f(a: Int): Int {
|
||||
var n = 0
|
||||
for (i in a until M) {
|
||||
n++
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 IF_ICMPGT
|
||||
// 1 IF_ICMPLE
|
||||
// 2 IF
|
||||
22
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMinValueIR.kt
vendored
Normal file
22
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMinValueIR.kt
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
const val M = Int.MIN_VALUE
|
||||
|
||||
fun f(a: Int): Int {
|
||||
var n = 0
|
||||
for (i in a until M) {
|
||||
n++
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// For "until" progressions in JVM IR, there is a check that the range is not empty: upper bound != MIN_VALUE.
|
||||
// When the upper bound == const MIN_VALUE, the backend can eliminate the entire loop as dead code.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 0 IF
|
||||
// 0 LINENUMBER 7
|
||||
21
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLong.kt
vendored
Normal file
21
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLong.kt
vendored
Normal file
@@ -0,0 +1,21 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
fun test(a: Long, b: Long): Long {
|
||||
var sum = 0L
|
||||
for (i in a until b) {
|
||||
sum = sum * 10L + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 LCMP
|
||||
// 1 IFGE
|
||||
// 1 IF
|
||||
24
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongIR.kt
vendored
Normal file
24
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongIR.kt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
fun test(a: Long, b: Long): Long {
|
||||
var sum = 0L
|
||||
for (i in a until b) {
|
||||
sum = sum * 10L + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. In addition, for "until" progressions, there is a check that the range is not empty: upper bound != MIN_VALUE.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 LDC -9223372036854775808
|
||||
// 3 LCMP
|
||||
// 1 IFEQ
|
||||
// 1 IFGT
|
||||
// 1 IFLE
|
||||
// 3 IF
|
||||
@@ -1,3 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
const val M = Long.MAX_VALUE
|
||||
|
||||
fun f(a: Long): Int {
|
||||
@@ -8,6 +9,9 @@ fun f(a: Long): Int {
|
||||
return n
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
24
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValueIR.kt
vendored
Normal file
24
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValueIR.kt
vendored
Normal file
@@ -0,0 +1,24 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
const val M = Long.MAX_VALUE
|
||||
|
||||
fun f(a: Long): Int {
|
||||
var n = 0
|
||||
for (i in a until M) {
|
||||
n++
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 LCMP
|
||||
// 1 IFGT
|
||||
// 1 IFLE
|
||||
// 2 IF
|
||||
22
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMinValueIR.kt
vendored
Normal file
22
compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMinValueIR.kt
vendored
Normal file
@@ -0,0 +1,22 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
const val M = Long.MIN_VALUE
|
||||
|
||||
fun f(a: Long): Int {
|
||||
var n = 0
|
||||
for (i in a until M) {
|
||||
n++
|
||||
}
|
||||
return n
|
||||
}
|
||||
|
||||
// For "until" progressions in JVM IR, there is a check that the range is not empty: upper bound != MIN_VALUE.
|
||||
// When the upper bound == const MIN_VALUE, the backend can eliminate the entire loop as dead code.
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 0 IF
|
||||
// 0 LINENUMBER 7
|
||||
@@ -0,0 +1,41 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
fun testByteUntilInt(a: Byte, b: Int): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fun testShortUntilInt(a: Short, b: Int): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// For "until" progressions in JVM IR, there is typically a check that the range is not empty: upper bound != MIN_VALUE.
|
||||
// However, this check is not needed when the upper bound is smaller than the range element type.
|
||||
// Here are the available `until` extension functions with mixed bounds that return IntRange:
|
||||
//
|
||||
// infix fun Byte.until(to: Byte): IntRange
|
||||
// infix fun Byte.until(to: Short): IntRange
|
||||
// infix fun Byte.until(to: Int): IntRange // Bound check needed
|
||||
// infix fun Short.until(to: Byte): IntRange
|
||||
// infix fun Short.until(to: Short): IntRange
|
||||
// infix fun Short.until(to: Int): IntRange // Bound check needed
|
||||
// infix fun Int.until(to: Byte): IntRange
|
||||
// infix fun Int.until(to: Short): IntRange
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 2 LDC -2147483648
|
||||
// 2 IF_ICMPEQ
|
||||
// 2 IF_ICMPGT
|
||||
// 2 IF_ICMPLE
|
||||
// 6 IF
|
||||
@@ -0,0 +1,72 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
fun testByteUntilByte(a: Byte, b: Byte): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fun testByteUntilShort(a: Byte, b: Short): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fun testShortUntilByte(a: Short, b: Byte): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fun testShortUntilShort(a: Short, b: Short): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fun testIntUntilByte(a: Int, b: Byte): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fun testIntUntilShort(a: Int, b: Short): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
sum = sum * 10 + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// For "until" progressions in JVM IR, there is typically a check that the range is not empty: upper bound != MIN_VALUE.
|
||||
// However, this check is not needed when the upper bound is smaller than the range element type.
|
||||
// Here are the available `until` extension functions with mixed bounds that return IntRange:
|
||||
//
|
||||
// infix fun Byte.until(to: Byte): IntRange // NO bound check needed
|
||||
// infix fun Byte.until(to: Short): IntRange // NO bound check needed
|
||||
// infix fun Byte.until(to: Int): IntRange
|
||||
// infix fun Short.until(to: Byte): IntRange // NO bound check needed
|
||||
// infix fun Short.until(to: Short): IntRange // NO bound check needed
|
||||
// infix fun Short.until(to: Int): IntRange
|
||||
// infix fun Int.until(to: Byte): IntRange // NO bound check needed
|
||||
// infix fun Int.until(to: Short): IntRange // NO bound check needed
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 0 LDC -2147483648
|
||||
// 6 IF_ICMPGT
|
||||
// 6 IF_ICMPLE
|
||||
// 12 IF
|
||||
@@ -0,0 +1,44 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
fun testLongUntilByte(a: Long, b: Byte): Long {
|
||||
var sum = 0L
|
||||
for (i in a until b) {
|
||||
sum = sum * 10L + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fun testLongUntilShort(a: Long, b: Short): Long {
|
||||
var sum = 0L
|
||||
for (i in a until b) {
|
||||
sum = sum * 10L + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fun testLongUntilInt(a: Long, b: Int): Long {
|
||||
var sum = 0L
|
||||
for (i in a until b) {
|
||||
sum = sum * 10L + i
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
// For "until" progressions in JVM IR, there is typically a check that the range is not empty: upper bound != MIN_VALUE.
|
||||
// However, this check is not needed when the upper bound is smaller than the range element type.
|
||||
// Here are the available `until` extension functions with mixed bounds that return LongRange:
|
||||
//
|
||||
// infix fun Long.until(to: Byte): LongRange // NO bound check needed
|
||||
// infix fun Long.until(to: Short): LongRange // NO bound check needed
|
||||
// infix fun Long.until(to: Int): LongRange // NO bound check needed
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 0 LDC -9223372036854775808
|
||||
// 6 LCMP
|
||||
// 3 IFGT
|
||||
// 3 IFLE
|
||||
// 6 IF
|
||||
@@ -1,8 +1,12 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
fun f() {
|
||||
for (i in 1..2) {
|
||||
}
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition).
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
|
||||
17
compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1IR.kt
vendored
Normal file
17
compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1IR.kt
vendored
Normal file
@@ -0,0 +1,17 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
fun f() {
|
||||
for (i in 1..2) {
|
||||
}
|
||||
}
|
||||
|
||||
// JVM non-IR uses while.
|
||||
// JVM IR uses if + do-while. The surrounding "if" gets optimized in this test (constant condition).
|
||||
|
||||
// 0 iterator
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 IF_ICMPLE
|
||||
// 1 IF
|
||||
Reference in New Issue
Block a user