Add ForLoopsLowering to JVM phases.

Also deleted StepHandler. Since the HeaderInfo.needLastCalculation is
only set to true for handling step progressions, deleted that property
and all associated logic around it.
This commit is contained in:
Mark Punzalan
2019-03-19 13:34:59 -07:00
committed by max-kammerer
parent 7276b7e66a
commit 409d99a52a
8 changed files with 4 additions and 108 deletions
@@ -36,7 +36,6 @@ internal sealed class HeaderInfo(
val upperBound: IrExpression, val upperBound: IrExpression,
val step: IrExpression?, // null value denotes default step (1) val step: IrExpression?, // null value denotes default step (1)
val increasing: Boolean, val increasing: Boolean,
val needLastCalculation: Boolean,
val closed: Boolean val closed: Boolean
) )
@@ -46,9 +45,8 @@ internal class ProgressionHeaderInfo(
upperBound: IrExpression, upperBound: IrExpression,
step: IrExpression? = null, step: IrExpression? = null,
increasing: Boolean = true, increasing: Boolean = true,
needLastCalculation: Boolean = false,
closed: Boolean = true closed: Boolean = true
) : HeaderInfo(progressionType, lowerBound, upperBound, step, increasing, needLastCalculation, closed) ) : HeaderInfo(progressionType, lowerBound, upperBound, step, increasing, closed)
internal class ArrayHeaderInfo( internal class ArrayHeaderInfo(
lowerBound: IrExpression, lowerBound: IrExpression,
@@ -60,7 +58,6 @@ internal class ArrayHeaderInfo(
upperBound, upperBound,
step = null, step = null,
increasing = true, increasing = true,
needLastCalculation = false,
closed = false closed = false
) )
@@ -89,7 +86,6 @@ private class ProgressionHeaderInfoBuilder(val context: CommonBackendContext) :
IndicesHandler(context), IndicesHandler(context),
UntilHandler(progressionElementTypes), UntilHandler(progressionElementTypes),
DownToHandler(progressionElementTypes), DownToHandler(progressionElementTypes),
StepHandler(context, this),
RangeToHandler(progressionElementTypes) RangeToHandler(progressionElementTypes)
) )
@@ -200,16 +200,8 @@ internal class HeaderProcessor(
dispatchReceiver = irGet(upperBoundTmpVariable) dispatchReceiver = irGet(upperBoundTmpVariable)
} }
} }
// In case of `step` we need to calculate the last element.
val lastElement =
if (needLastCalculation) {
TODO("Implement and use irGetProgressionLast")
// irGetProgressionLast(progressionType, inductionVariable, lastExpression, stepValue)
} else {
lastExpression
}
val lastValue = scope.createTemporaryVariable( val lastValue = scope.createTemporaryVariable(
lastElement, lastExpression,
nameHint = "last", nameHint = "last",
origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE
) )
@@ -270,21 +262,4 @@ internal class HeaderProcessor(
else -> throw IllegalArgumentException() else -> throw IllegalArgumentException()
} }
} }
// private fun irGetProgressionLast(
// progressionType: ProgressionType,
// first: IrVariable,
// lastExpression: IrExpression,
// step: IrVariable
// ): IrExpression {
// val symbol = symbols.getProgressionLast[progressionType.elementType(context).toKotlinType()]
// ?: throw IllegalArgumentException("No `getProgressionLast` for type ${step.type} ${lastExpression.type}")
// val startOffset = lastExpression.startOffset
// val endOffset = lastExpression.endOffset
// return IrCallImpl(startOffset, endOffset, symbol.owner.returnType, symbol).apply {
// putValueArgument(0, IrGetValueImpl(startOffset, endOffset, first.type, first.symbol))
// putValueArgument(1, lastExpression)
// putValueArgument(2, IrGetValueImpl(startOffset, endOffset, step.type, step.symbol))
// }
// }
} }
@@ -6,9 +6,7 @@
package org.jetbrains.kotlin.backend.common.lower.loops package org.jetbrains.kotlin.backend.common.lower.loops
import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.ir.Symbols
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.matchers.IrCallMatcher
import org.jetbrains.kotlin.backend.common.lower.matchers.SimpleCalleeMatcher import org.jetbrains.kotlin.backend.common.lower.matchers.SimpleCalleeMatcher
import org.jetbrains.kotlin.backend.common.lower.matchers.createIrCallMatcher import org.jetbrains.kotlin.backend.common.lower.matchers.createIrCallMatcher
import org.jetbrains.kotlin.backend.common.lower.matchers.singleArgumentExtension import org.jetbrains.kotlin.backend.common.lower.matchers.singleArgumentExtension
@@ -20,7 +18,6 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.* import org.jetbrains.kotlin.ir.types.*
import org.jetbrains.kotlin.ir.util.properties import org.jetbrains.kotlin.ir.util.properties
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.SimpleType import org.jetbrains.kotlin.types.SimpleType
@@ -93,76 +90,6 @@ internal class IndicesHandler(val context: CommonBackendContext) : ProgressionHa
} }
internal class StepHandler(context: CommonBackendContext, val visitor: IrElementVisitor<HeaderInfo?, Nothing?>) : ProgressionHandler {
private val symbols = context.ir.symbols
override val matcher: IrCallMatcher = SimpleCalleeMatcher {
singleArgumentExtension(FqName("kotlin.ranges.step"), symbols.progressionClassesTypes)
parameter(0) { it.type.isInt() || it.type.isLong() }
}
private fun isDefaultStep(step: IrExpression?) =
step == null || (step is IrConst<*> && step.isOne())
override fun build(call: IrCall, data: ProgressionType): HeaderInfo? {
val nestedInfo = call.extensionReceiver!!.accept(visitor, null)
?: return null
// Due to KT-27607 nested non-default steps could lead to incorrect behaviour.
// So disable optimization of such rare cases for now.
if (!isDefaultStep(nestedInfo.step)) {
return null
}
val newStep = call.getValueArgument(0)!!
val (newStepCheck, needBoundCalculation) = irCheckProgressionStep(symbols, data, newStep)
return ProgressionHeaderInfo(
data,
nestedInfo.lowerBound,
nestedInfo.upperBound,
newStepCheck,
nestedInfo.increasing,
needBoundCalculation,
nestedInfo.closed
)
}
private fun IrConst<*>.isOne() = when (kind) {
IrConstKind.Long -> value as Long == 1L
IrConstKind.Int -> value as Int == 1
else -> false
}
private fun IrExpression.isPositiveConst() = this is IrConst<*> &&
((kind == IrConstKind.Long && value as Long > 0) || (kind == IrConstKind.Int && value as Int > 0))
// Used only by the assert.
private fun stepHasRightType(step: IrExpression, progressionType: ProgressionType) = when (progressionType) {
ProgressionType.CHAR_PROGRESSION,
ProgressionType.INT_PROGRESSION -> step.type.makeNotNull().isInt()
ProgressionType.LONG_PROGRESSION -> step.type.makeNotNull().isLong()
}
private fun irCheckProgressionStep(symbols: Symbols<CommonBackendContext>, progressionType: ProgressionType, step: IrExpression) =
if (step.isPositiveConst()) {
step to !(step as IrConst<*>).isOne()
} else
TODO("Implement call to checkProgressionStep")
// {
// // The frontend checks if the step has a right type (Long for LongProgression and Int for {Int/Char}Progression)
// // so there is no need to cast it.
// assert(stepHasRightType(step, progressionType))
//
// val symbol = symbols.checkProgressionStep[step.type.makeNotNull().toKotlinType()]
// ?: throw IllegalArgumentException("No `checkProgressionStep` for type ${step.type}")
// IrCallImpl(step.startOffset, step.endOffset, symbol.owner.returnType, symbol).apply {
// putValueArgument(0, step)
// } to true
// }
}
internal class ArrayIterationHandler(val context: CommonBackendContext) : HeaderInfoHandler<Nothing?> { internal class ArrayIterationHandler(val context: CommonBackendContext) : HeaderInfoHandler<Nothing?> {
// No support for rare cases like `T : IntArray` for now. // No support for rare cases like `T : IntArray` for now.
@@ -18,6 +18,7 @@ package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.common.lower.loops.forLoopsPhase
import org.jetbrains.kotlin.backend.common.phaser.* import org.jetbrains.kotlin.backend.common.phaser.*
import org.jetbrains.kotlin.backend.jvm.lower.* import org.jetbrains.kotlin.backend.jvm.lower.*
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
@@ -86,6 +87,7 @@ val jvmPhases = namedIrFilePhase(
innerClassesPhase then innerClassesPhase then
innerClassConstructorCallsPhase then innerClassConstructorCallsPhase then
forLoopsPhase then
makePatchParentsPhase(2) then makePatchParentsPhase(2) then
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
const val N = 42L const val N = 42L
fun test(): Long { fun test(): Long {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun Int.digitsUpto(end: Int): Int { fun Int.digitsUpto(end: Int): Int {
var sum = 0 var sum = 0
for (i in rangeTo(end)) { for (i in rangeTo(end)) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun f() { fun f() {
for (i in 1..2) { for (i in 1..2) {
} }
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun f(a: Int, b: Int) { fun f(a: Int, b: Int) {
for (i in a..b) { for (i in a..b) {
} }