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:
Mark Punzalan
2019-06-14 00:59:47 -07:00
committed by Mikhael Bogdanov
parent 39f6416757
commit de1e27c584
75 changed files with 1873 additions and 377 deletions
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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
@@ -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