Handle reversed() in ForLoopsLowering.

We get the info for the underlying progression and invert it. For
progressions whose last bound was open (e.g., `until` loop), the
reversed version will have an open first bound and so the induction
variable must be incremented first.

Also unified the way of extracting HeaderInfo out of changed calls
(e.g., `indices.reversed()`), and fixed declaration parents in
ForLoopsLowering.
This commit is contained in:
Mark Punzalan
2019-04-10 14:33:51 -07:00
committed by max-kammerer
parent 3d1b6fb83c
commit 1b703448d3
34 changed files with 953 additions and 201 deletions

View File

@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.test.*
fun intRange() = 1 .. 4
@@ -28,3 +27,8 @@ fun box(): String {
}
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 3 getFirst
// 3 getLast

View File

@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
@@ -13,3 +12,11 @@ fun box(): String {
}
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF(_ICMPG|L)T
// 1 IF

View File

@@ -1,4 +1,5 @@
// IGNORE_BACKEND: JVM_IR
// NOTE: Enable once CharSequence.indices is handled
import kotlin.test.*
fun box(): String {
@@ -13,3 +14,11 @@ fun box(): String {
}
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF(_ICMPG|L)T
// 1 IF

View File

@@ -1,4 +1,5 @@
// IGNORE_BACKEND: JVM_IR
// NOTE: Enable once Collection.indices is handled
import kotlin.test.*
fun box(): String {
@@ -13,3 +14,11 @@ fun box(): String {
}
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 1 IF(_ICMPG|L)T
// 1 IF

View File

@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
@@ -24,3 +23,13 @@ fun box(): String {
}
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 2 IF_ICMP[LG]T
// 1 IF[LG]T
// 3 IF
// 1 LCMP

View File

@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun box(): String {
for (i in (4 .. 1).reversed()) {
throw AssertionError("Loop should not be executed")
@@ -13,6 +12,7 @@ fun box(): String {
}
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst

View File

@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.test.*
fun intRange() = 1 .. 4
@@ -28,3 +27,8 @@ fun box(): String {
}
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 3 getFirst
// 3 getLast

View File

@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
@@ -24,12 +23,13 @@ fun box(): String {
}
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 0 IFEQ
// 0 IF_ICMPEQ
// 2 IF_ICMPLT
// 1 LCMP
// 2 IF_ICMP[LG]T
// 1 IF[LG]T
// 3 IF
// 1 LCMP

View File

@@ -0,0 +1,20 @@
import kotlin.test.*
fun box(): String {
val arr = intArrayOf(1, 1, 1, 1)
var sum = 0
for (i in arr.indices.reversed().reversed()) {
sum = sum * 10 + i + arr[i]
}
assertEquals(4321, sum)
return "OK"
}
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep

View File

@@ -0,0 +1,35 @@
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"
}
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 2 IF_ICMP[LG]T
// 1 IF[LG]T
// 3 IF
// 1 LCMP

View File

@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.test.*
fun intRange() = 1 .. 4
@@ -28,3 +27,8 @@ fun box(): String {
}
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 3 getFirst
// 3 getLast

View File

@@ -0,0 +1,32 @@
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"
}
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 2 IF_ICMP[LG]E
// 1 IF[LG]E
// 3 IF
// 1 LCMP

View File

@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
import kotlin.test.*
fun box(): String {
@@ -21,3 +20,13 @@ fun box(): String {
}
// 0 reversed
// 0 iterator
// 0 getStart
// 0 getEnd
// 0 getFirst
// 0 getLast
// 0 getStep
// 2 IF_ICMP[LG]T
// 1 IF[LG]T
// 3 IF
// 1 LCMP