From 1adb130509ab5a3787b1fc1ed66db1b2063840b4 Mon Sep 17 00:00:00 2001 From: Mark Punzalan Date: Wed, 7 Oct 2020 23:25:56 +0000 Subject: [PATCH] ForLoopsLowering: Move `isLastInclusive` to HeaderInfo. --- .../backend/common/lower/loops/HeaderInfo.kt | 36 +++++++++++-------- .../common/lower/loops/HeaderProcessor.kt | 11 +++--- 2 files changed, 26 insertions(+), 21 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 52dfda4b4ad..4e7d00a1bdf 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 @@ -67,6 +67,7 @@ internal sealed class NumericHeaderInfo( val first: IrExpression, val last: IrExpression, val step: IrExpression, + val isLastInclusive: Boolean, val canCacheLast: Boolean, val isReversed: Boolean, val direction: ProgressionDirection, @@ -79,13 +80,14 @@ internal class ProgressionHeaderInfo( first: IrExpression, last: IrExpression, step: IrExpression, + isLastInclusive: Boolean = true, isReversed: Boolean = false, canOverflow: Boolean? = null, direction: ProgressionDirection, additionalNotEmptyCondition: IrExpression? = null, val additionalStatements: List = listOf() ) : NumericHeaderInfo( - progressionType, first, last, step, + progressionType, first, last, step, isLastInclusive, canCacheLast = true, isReversed = isReversed, direction = direction, @@ -152,16 +154,22 @@ internal class ProgressionHeaderInfo( } } - override fun asReversed() = ProgressionHeaderInfo( - progressionType = progressionType, - first = last, - last = first, - step = step.negate(), - isReversed = !isReversed, - direction = direction.asReversed(), - additionalNotEmptyCondition = additionalNotEmptyCondition, - additionalStatements = additionalStatements - ) + override fun asReversed() = if (isLastInclusive) { + ProgressionHeaderInfo( + progressionType = progressionType, + first = last, + last = first, + step = step.negate(), + isReversed = !isReversed, + direction = direction.asReversed(), + additionalNotEmptyCondition = additionalNotEmptyCondition, + additionalStatements = additionalStatements + ) + } else { + // If reversed, we would have a "first-exclusive" loop. We are currently not supporting this since it would add more complexity + // due to possible overflow when pre-incrementing the loop variable (see KT-42533). + null + } } /** @@ -177,10 +185,8 @@ internal class IndexedGetHeaderInfo( val objectVariable: IrVariable, val expressionHandler: IndexedGetIterationHandler ) : NumericHeaderInfo( - IntProgressionType(symbols), - first, - last, - step, + IntProgressionType(symbols), first, last, step, + isLastInclusive = false, canCacheLast = canCacheLast, isReversed = false, direction = ProgressionDirection.INCREASING, 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 a517059b65a..bd0b9c53ddf 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 @@ -59,8 +59,7 @@ internal interface ForLoopHeader { internal abstract class NumericForLoopHeader( protected val headerInfo: T, builder: DeclarationIrBuilder, - context: CommonBackendContext, - protected val isLastInclusive: Boolean + context: CommonBackendContext ) : ForLoopHeader { override val consumesLoopVariableComponents = false @@ -160,7 +159,7 @@ internal abstract class NumericForLoopHeader( // Bounds are signed for unsigned progressions but bound comparisons should be done as unsigned, to ensure that the // correct comparison function is used (`UInt/ULongCompare`). Also, `compareTo` must be used for UInt/ULong; // they don't have intrinsic comparison operators. - val intCompFun = if (isLastInclusive) { + val intCompFun = if (headerInfo.isLastInclusive) { builtIns.lessOrEqualFunByOperandType.getValue(builtIns.intClass) } else { builtIns.lessFunByOperandType.getValue(builtIns.intClass) @@ -174,7 +173,7 @@ internal abstract class NumericForLoopHeader( } else null val elementCompFun = - if (isLastInclusive) { + if (headerInfo.isLastInclusive) { builtIns.lessOrEqualFunByOperandType[elementClass.symbol] } else { builtIns.lessFunByOperandType[elementClass.symbol] @@ -249,7 +248,7 @@ internal class ProgressionLoopHeader( headerInfo: ProgressionHeaderInfo, builder: DeclarationIrBuilder, context: CommonBackendContext -) : NumericForLoopHeader(headerInfo, builder, context, isLastInclusive = true) { +) : NumericForLoopHeader(headerInfo, builder, context) { // For this loop: // @@ -374,7 +373,7 @@ internal class IndexedGetLoopHeader( headerInfo: IndexedGetHeaderInfo, builder: DeclarationIrBuilder, context: CommonBackendContext -) : NumericForLoopHeader(headerInfo, builder, context, isLastInclusive = false) { +) : NumericForLoopHeader(headerInfo, builder, context) { override val loopInitStatements = listOfNotNull(headerInfo.objectVariable, inductionVariable, lastVariableIfCanCacheLast, stepVariable)