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:
Ilya Matveev
2017-07-21 17:35:50 +07:00
committed by ilmat192
parent 295ab0a679
commit 42c4391654
6 changed files with 133 additions and 44 deletions
+5
View File
@@ -357,6 +357,11 @@ task codegen_controlflow_for_loops_coroutines(type: RunKonanTest) {
"Got: 0 2 4 6\n"
}
task codegen_controlflow_for_loops_call_order(type: RunKonanTest) {
source = "codegen/controlflow/for_loops_call_order.kt"
goldValue = "1234\n1234\n2134\n"
}
task local_variable(type: RunKonanTest) {
source = "codegen/basics/local_variable.kt"
}