ForLoopsLowering: Move isLastInclusive to HeaderInfo.

This commit is contained in:
Mark Punzalan
2020-10-07 23:25:56 +00:00
committed by Alexander Udalov
parent a093efde11
commit 1adb130509
2 changed files with 26 additions and 21 deletions
@@ -67,6 +67,7 @@ internal sealed class NumericHeaderInfo(
val first: IrExpression, val first: IrExpression,
val last: IrExpression, val last: IrExpression,
val step: IrExpression, val step: IrExpression,
val isLastInclusive: Boolean,
val canCacheLast: Boolean, val canCacheLast: Boolean,
val isReversed: Boolean, val isReversed: Boolean,
val direction: ProgressionDirection, val direction: ProgressionDirection,
@@ -79,13 +80,14 @@ internal class ProgressionHeaderInfo(
first: IrExpression, first: IrExpression,
last: IrExpression, last: IrExpression,
step: IrExpression, step: IrExpression,
isLastInclusive: Boolean = true,
isReversed: Boolean = false, isReversed: Boolean = false,
canOverflow: Boolean? = null, canOverflow: Boolean? = null,
direction: ProgressionDirection, direction: ProgressionDirection,
additionalNotEmptyCondition: IrExpression? = null, additionalNotEmptyCondition: IrExpression? = null,
val additionalStatements: List<IrStatement> = listOf() val additionalStatements: List<IrStatement> = listOf()
) : NumericHeaderInfo( ) : NumericHeaderInfo(
progressionType, first, last, step, progressionType, first, last, step, isLastInclusive,
canCacheLast = true, canCacheLast = true,
isReversed = isReversed, isReversed = isReversed,
direction = direction, direction = direction,
@@ -152,16 +154,22 @@ internal class ProgressionHeaderInfo(
} }
} }
override fun asReversed() = ProgressionHeaderInfo( override fun asReversed() = if (isLastInclusive) {
progressionType = progressionType, ProgressionHeaderInfo(
first = last, progressionType = progressionType,
last = first, first = last,
step = step.negate(), last = first,
isReversed = !isReversed, step = step.negate(),
direction = direction.asReversed(), isReversed = !isReversed,
additionalNotEmptyCondition = additionalNotEmptyCondition, direction = direction.asReversed(),
additionalStatements = additionalStatements 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 objectVariable: IrVariable,
val expressionHandler: IndexedGetIterationHandler val expressionHandler: IndexedGetIterationHandler
) : NumericHeaderInfo( ) : NumericHeaderInfo(
IntProgressionType(symbols), IntProgressionType(symbols), first, last, step,
first, isLastInclusive = false,
last,
step,
canCacheLast = canCacheLast, canCacheLast = canCacheLast,
isReversed = false, isReversed = false,
direction = ProgressionDirection.INCREASING, direction = ProgressionDirection.INCREASING,
@@ -59,8 +59,7 @@ internal interface ForLoopHeader {
internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>( internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
protected val headerInfo: T, protected val headerInfo: T,
builder: DeclarationIrBuilder, builder: DeclarationIrBuilder,
context: CommonBackendContext, context: CommonBackendContext
protected val isLastInclusive: Boolean
) : ForLoopHeader { ) : ForLoopHeader {
override val consumesLoopVariableComponents = false override val consumesLoopVariableComponents = false
@@ -160,7 +159,7 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
// Bounds are signed for unsigned progressions but bound comparisons should be done as unsigned, to ensure that the // 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; // correct comparison function is used (`UInt/ULongCompare`). Also, `compareTo` must be used for UInt/ULong;
// they don't have intrinsic comparison operators. // they don't have intrinsic comparison operators.
val intCompFun = if (isLastInclusive) { val intCompFun = if (headerInfo.isLastInclusive) {
builtIns.lessOrEqualFunByOperandType.getValue(builtIns.intClass) builtIns.lessOrEqualFunByOperandType.getValue(builtIns.intClass)
} else { } else {
builtIns.lessFunByOperandType.getValue(builtIns.intClass) builtIns.lessFunByOperandType.getValue(builtIns.intClass)
@@ -174,7 +173,7 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
} else null } else null
val elementCompFun = val elementCompFun =
if (isLastInclusive) { if (headerInfo.isLastInclusive) {
builtIns.lessOrEqualFunByOperandType[elementClass.symbol] builtIns.lessOrEqualFunByOperandType[elementClass.symbol]
} else { } else {
builtIns.lessFunByOperandType[elementClass.symbol] builtIns.lessFunByOperandType[elementClass.symbol]
@@ -249,7 +248,7 @@ internal class ProgressionLoopHeader(
headerInfo: ProgressionHeaderInfo, headerInfo: ProgressionHeaderInfo,
builder: DeclarationIrBuilder, builder: DeclarationIrBuilder,
context: CommonBackendContext context: CommonBackendContext
) : NumericForLoopHeader<ProgressionHeaderInfo>(headerInfo, builder, context, isLastInclusive = true) { ) : NumericForLoopHeader<ProgressionHeaderInfo>(headerInfo, builder, context) {
// For this loop: // For this loop:
// //
@@ -374,7 +373,7 @@ internal class IndexedGetLoopHeader(
headerInfo: IndexedGetHeaderInfo, headerInfo: IndexedGetHeaderInfo,
builder: DeclarationIrBuilder, builder: DeclarationIrBuilder,
context: CommonBackendContext context: CommonBackendContext
) : NumericForLoopHeader<IndexedGetHeaderInfo>(headerInfo, builder, context, isLastInclusive = false) { ) : NumericForLoopHeader<IndexedGetHeaderInfo>(headerInfo, builder, context) {
override val loopInitStatements = override val loopInitStatements =
listOfNotNull(headerInfo.objectVariable, inductionVariable, lastVariableIfCanCacheLast, stepVariable) listOfNotNull(headerInfo.objectVariable, inductionVariable, lastVariableIfCanCacheLast, stepVariable)