backend: Process 'until MIN_VALUE' in for loops
This patch takes into account a corner case available for loops
over a progression (see backend.native/tests/external/codegen/box/
ranges/forInUntil/forInUntilMinint.kt test):
for (i in 0 until Int.MIN_VALUE) { ... }
Here we cannot use subtraction to obtain a right bound of the loop
due to an overflow. Instead we consider any loop with MIN_VALUE in
it's right bound as empty loop. Such behaviour is similar to the one
of 'until' method.
So now the empty check for a loops with 'until' call:
for (i in first until bound) { ... }
is as follows:
val last = getProgressionLast(first, bound, step) // Only if step==1
if (first <= last && bound > <Int|Long|Char>.MIN_VALUE) {
do { ... } while(i != last)
}
Further improvements: We can generate a simpler IR for some simple
frequent cases (e.g. for until calls without steps) and eliminate
loops if we can prove that they are empty.
This commit is contained in:
@@ -91,8 +91,8 @@ fun <T: Enum<T>> valuesForEnum(values: Array<T>): Array<T>
|
||||
fun checkProgressionStep(step: Int) = if (step > 0) step else throw IllegalArgumentException("Step must be positive, was: $step.")
|
||||
fun checkProgressionStep(step: Long) = if (step > 0) step else throw IllegalArgumentException("Step must be positive, was: $step.")
|
||||
|
||||
fun getProgressionBound(start: Char, end: Char, step: Int): Char =
|
||||
getProgressionBound(start.toInt(), end.toInt(), step).toChar()
|
||||
fun getProgressionLast(start: Char, end: Char, step: Int): Char =
|
||||
getProgressionLast(start.toInt(), end.toInt(), step).toChar()
|
||||
|
||||
fun getProgressionBound(start: Int, end: Int, step: Int): Int = getProgressionLastElement(start, end, step)
|
||||
fun getProgressionBound(start: Long, end: Long, step: Long): Long = getProgressionLastElement(start, end, step)
|
||||
fun getProgressionLast(start: Int, end: Int, step: Int): Int = getProgressionLastElement(start, end, step)
|
||||
fun getProgressionLast(start: Long, end: Long, step: Long): Long = getProgressionLastElement(start, end, step)
|
||||
Reference in New Issue
Block a user