From 409d99a52acff928ad1fb8c9c002d8475352a5ae Mon Sep 17 00:00:00 2001 From: Mark Punzalan Date: Tue, 19 Mar 2019 13:34:59 -0700 Subject: [PATCH] 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. --- .../backend/common/lower/loops/HeaderInfo.kt | 6 +- .../common/lower/loops/HeaderProcessor.kt | 27 +------ .../common/lower/loops/ProgressionHandlers.kt | 73 ------------------- .../jetbrains/kotlin/backend/jvm/JvmLower.kt | 2 + .../forLoop/forInRangeToLongConst.kt | 1 - .../forLoop/forInRangeWithImplicitReceiver.kt | 1 - .../forLoop/primitiveLiteralRange1.kt | 1 - .../forLoop/primitiveLiteralRange2.kt | 1 - 8 files changed, 4 insertions(+), 108 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt index ad51d9e9ad0..29c913658d8 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderInfo.kt @@ -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) ) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt index e20e8e4f6da..84a8b1a231a 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt @@ -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)) -// } -// } } \ No newline at end of file diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt index cc213851468..22c080e02db 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ProgressionHandlers.kt @@ -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) : 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, 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 { // No support for rare cases like `T : IntArray` for now. diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 81c5b90faa8..6a039e8a8f6 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -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 diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt index d8a392d932b..8cb0c87da52 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR const val N = 42L fun test(): Long { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithImplicitReceiver.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithImplicitReceiver.kt index e5da77a97da..178849e1b5b 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithImplicitReceiver.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithImplicitReceiver.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR fun Int.digitsUpto(end: Int): Int { var sum = 0 for (i in rangeTo(end)) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt b/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt index a0eeeaad577..aad6cac37d4 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR fun f() { for (i in 1..2) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange2.kt b/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange2.kt index 10554e71ac0..112e70eb779 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange2.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange2.kt @@ -1,4 +1,3 @@ -// IGNORE_BACKEND: JVM_IR fun f(a: Int, b: Int) { for (i in a..b) { }