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 step: IrExpression?, // null value denotes default step (1)
val increasing: Boolean,
val needLastCalculation: Boolean,
val closed: Boolean
)
@@ -46,9 +45,8 @@ internal class ProgressionHeaderInfo(
upperBound: IrExpression,
step: IrExpression? = null,
increasing: Boolean = true,
needLastCalculation: Boolean = false,
closed: Boolean = true
) : HeaderInfo(progressionType, lowerBound, upperBound, step, increasing, needLastCalculation, closed)
) : HeaderInfo(progressionType, lowerBound, upperBound, step, increasing, closed)
internal class ArrayHeaderInfo(
lowerBound: IrExpression,
@@ -60,7 +58,6 @@ internal class ArrayHeaderInfo(
upperBound,
step = null,
increasing = true,
needLastCalculation = false,
closed = false
)
@@ -89,7 +86,6 @@ private class ProgressionHeaderInfoBuilder(val context: CommonBackendContext) :
IndicesHandler(context),
UntilHandler(progressionElementTypes),
DownToHandler(progressionElementTypes),
StepHandler(context, this),
RangeToHandler(progressionElementTypes)
)
@@ -200,16 +200,8 @@ internal class HeaderProcessor(
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(
lastElement,
lastExpression,
nameHint = "last",
origin = IrDeclarationOrigin.FOR_LOOP_IMPLICIT_VARIABLE
)
@@ -270,21 +262,4 @@ internal class HeaderProcessor(
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
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.matchers.IrCallMatcher
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.singleArgumentExtension
@@ -20,7 +18,6 @@ import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.*
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.Name
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?> {
// 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.lower.*
import org.jetbrains.kotlin.backend.common.lower.loops.forLoopsPhase
import org.jetbrains.kotlin.backend.common.phaser.*
import org.jetbrains.kotlin.backend.jvm.lower.*
import org.jetbrains.kotlin.ir.declarations.IrFile
@@ -86,6 +87,7 @@ val jvmPhases = namedIrFilePhase(
innerClassesPhase then
innerClassConstructorCallsPhase then
forLoopsPhase then
makePatchParentsPhase(2) then
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
const val N = 42L
fun test(): Long {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun Int.digitsUpto(end: Int): Int {
var sum = 0
for (i in rangeTo(end)) {
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun f() {
for (i in 1..2) {
}
@@ -1,4 +1,3 @@
// IGNORE_BACKEND: JVM_IR
fun f(a: Int, b: Int) {
for (i in a..b) {
}