Refactor ForLoopHeader to clarify the purpose of its functions.
This commit is contained in:
committed by
max-kammerer
parent
7f803e60b6
commit
60c05362d2
+5
-10
@@ -150,14 +150,13 @@ private class RangeLoopTransformer(
|
|||||||
?: return null // If the for-loop cannot be lowered.
|
?: return null // If the for-loop cannot be lowered.
|
||||||
iteratorToLoopHeader[variable.symbol] = forLoopInfo
|
iteratorToLoopHeader[variable.symbol] = forLoopInfo
|
||||||
|
|
||||||
// Lower into a composite with additional declarations (e.g., induction variable)
|
// Lower into a composite with additional statements (e.g., induction variable) used in the loop condition and body.
|
||||||
// used in the loop condition and body.
|
|
||||||
return IrCompositeImpl(
|
return IrCompositeImpl(
|
||||||
variable.startOffset,
|
variable.startOffset,
|
||||||
variable.endOffset,
|
variable.endOffset,
|
||||||
context.irBuiltIns.unitType,
|
context.irBuiltIns.unitType,
|
||||||
null,
|
null,
|
||||||
forLoopInfo.declarations
|
forLoopInfo.loopInitStatements
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -213,26 +212,22 @@ private class RangeLoopTransformer(
|
|||||||
val initializer = variable.initializer as IrCall
|
val initializer = variable.initializer as IrCall
|
||||||
val forLoopInfo = getLoopHeader(initializer)
|
val forLoopInfo = getLoopHeader(initializer)
|
||||||
?: return null // If the for-loop cannot be lowered.
|
?: return null // If the for-loop cannot be lowered.
|
||||||
forLoopInfo.loopVariable = variable
|
|
||||||
|
|
||||||
// The "next" statement (at the top of the loop):
|
// The "next" statement (at the top of the loop):
|
||||||
//
|
//
|
||||||
// val i = it.next()
|
// val i = it.next()
|
||||||
//
|
//
|
||||||
// ...is lowered into:
|
// ...is lowered into something like:
|
||||||
//
|
//
|
||||||
// val i = initializeLoopVariable() // `inductionVariable` for progressions
|
// val i = inductionVariable // For progressions, or `array[inductionVariable]` for arrays
|
||||||
// // `array[inductionVariable]` for arrays
|
|
||||||
// inductionVariable = inductionVariable + step
|
// inductionVariable = inductionVariable + step
|
||||||
return with(context.createIrBuilder(getScopeOwnerSymbol(), initializer.startOffset, initializer.endOffset)) {
|
return with(context.createIrBuilder(getScopeOwnerSymbol(), initializer.startOffset, initializer.endOffset)) {
|
||||||
variable.initializer = forLoopInfo.initializeLoopVariable(symbols, this)
|
|
||||||
val increment = forLoopInfo.incrementInductionVariable(this)
|
|
||||||
IrCompositeImpl(
|
IrCompositeImpl(
|
||||||
variable.startOffset,
|
variable.startOffset,
|
||||||
variable.endOffset,
|
variable.endOffset,
|
||||||
context.irBuiltIns.unitType,
|
context.irBuiltIns.unitType,
|
||||||
IrStatementOrigin.FOR_LOOP_NEXT,
|
IrStatementOrigin.FOR_LOOP_NEXT,
|
||||||
listOf(variable, increment)
|
forLoopInfo.initializeIteration(variable, symbols, this)
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
+45
-29
@@ -37,28 +37,36 @@ internal data class LoopReplacement(
|
|||||||
val replacementExpression: IrExpression
|
val replacementExpression: IrExpression
|
||||||
)
|
)
|
||||||
|
|
||||||
/** Contains information about variables used in the loop. */
|
internal interface ForLoopHeader {
|
||||||
internal sealed class ForLoopHeader(
|
/** Statements used to initialize the entire loop (e.g., declare induction variable). */
|
||||||
|
val loopInitStatements: List<IrStatement>
|
||||||
|
|
||||||
|
/** Statements used to initialize an iteration of the loop (e.g., assign loop variable). */
|
||||||
|
fun initializeIteration(
|
||||||
|
loopVariable: IrVariable,
|
||||||
|
symbols: Symbols<CommonBackendContext>,
|
||||||
|
builder: DeclarationIrBuilder
|
||||||
|
): List<IrStatement>
|
||||||
|
|
||||||
|
/** Builds a new loop from the old loop. */
|
||||||
|
fun buildLoop(builder: DeclarationIrBuilder, oldLoop: IrLoop, newBody: IrExpression?): LoopReplacement
|
||||||
|
}
|
||||||
|
|
||||||
|
internal abstract class NumericForLoopHeader(
|
||||||
protected open val headerInfo: HeaderInfo,
|
protected open val headerInfo: HeaderInfo,
|
||||||
val inductionVariable: IrVariable,
|
val inductionVariable: IrVariable,
|
||||||
lastExpression: IrExpression,
|
lastExpression: IrExpression,
|
||||||
val step: IrVariable,
|
val step: IrVariable,
|
||||||
var loopVariable: IrVariable? = null,
|
|
||||||
val isLastInclusive: Boolean,
|
val isLastInclusive: Boolean,
|
||||||
val declarations: List<IrVariable>
|
override val loopInitStatements: List<IrStatement>
|
||||||
) {
|
) : ForLoopHeader {
|
||||||
|
|
||||||
val lastExpression: IrExpression = lastExpression
|
val lastExpression: IrExpression = lastExpression
|
||||||
// Always copy `lastExpression` is it may be used in multiple conditions.
|
// Always copy `lastExpression` is it may be used in multiple conditions.
|
||||||
get() = field.deepCopyWithSymbols()
|
get() = field.deepCopyWithSymbols()
|
||||||
|
|
||||||
/** Expression used to initialize the loop variable at the beginning of the loop. */
|
|
||||||
abstract fun initializeLoopVariable(symbols: Symbols<CommonBackendContext>, builder: DeclarationIrBuilder): IrExpression
|
|
||||||
|
|
||||||
/** Builds a new loop from the old loop. */
|
|
||||||
abstract fun buildLoop(builder: DeclarationIrBuilder, oldLoop: IrLoop, newBody: IrExpression?): LoopReplacement
|
|
||||||
|
|
||||||
/** Statement used to increment the induction variable. */
|
/** Statement used to increment the induction variable. */
|
||||||
fun incrementInductionVariable(builder: DeclarationIrBuilder): IrStatement = with(builder) {
|
protected fun incrementInductionVariable(builder: DeclarationIrBuilder): IrStatement = with(builder) {
|
||||||
// inductionVariable = inductionVariable + step
|
// inductionVariable = inductionVariable + step
|
||||||
val plusFun = inductionVariable.type.getClass()!!.functions.single {
|
val plusFun = inductionVariable.type.getClass()!!.functions.single {
|
||||||
it.name == OperatorNameConventions.PLUS &&
|
it.name == OperatorNameConventions.PLUS &&
|
||||||
@@ -133,19 +141,25 @@ internal class ProgressionLoopHeader(
|
|||||||
inductionVariable: IrVariable,
|
inductionVariable: IrVariable,
|
||||||
lastExpression: IrExpression,
|
lastExpression: IrExpression,
|
||||||
step: IrVariable,
|
step: IrVariable,
|
||||||
declarations: List<IrVariable>
|
loopInitStatements: List<IrStatement>
|
||||||
) : ForLoopHeader(
|
) : NumericForLoopHeader(
|
||||||
headerInfo, inductionVariable,
|
headerInfo, inductionVariable,
|
||||||
lastExpression = lastExpression,
|
lastExpression = lastExpression,
|
||||||
step = step,
|
step = step,
|
||||||
isLastInclusive = true,
|
isLastInclusive = true,
|
||||||
declarations = declarations
|
loopInitStatements = loopInitStatements
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun initializeLoopVariable(symbols: Symbols<CommonBackendContext>, builder: DeclarationIrBuilder) = with(builder) {
|
private var loopVariable: IrVariable? = null
|
||||||
// loopVariable = inductionVariable
|
|
||||||
irGet(inductionVariable)
|
override fun initializeIteration(loopVariable: IrVariable, symbols: Symbols<CommonBackendContext>, builder: DeclarationIrBuilder) =
|
||||||
}
|
with(builder) {
|
||||||
|
this@ProgressionLoopHeader.loopVariable = loopVariable
|
||||||
|
// loopVariable = inductionVariable
|
||||||
|
// inductionVariable = inductionVariable + step
|
||||||
|
loopVariable.initializer = irGet(inductionVariable)
|
||||||
|
listOf(loopVariable, incrementInductionVariable(this))
|
||||||
|
}
|
||||||
|
|
||||||
override fun buildLoop(builder: DeclarationIrBuilder, oldLoop: IrLoop, newBody: IrExpression?) =
|
override fun buildLoop(builder: DeclarationIrBuilder, oldLoop: IrLoop, newBody: IrExpression?) =
|
||||||
with(builder) {
|
with(builder) {
|
||||||
@@ -198,21 +212,23 @@ internal class IndexedGetLoopHeader(
|
|||||||
inductionVariable: IrVariable,
|
inductionVariable: IrVariable,
|
||||||
lastExpression: IrExpression,
|
lastExpression: IrExpression,
|
||||||
step: IrVariable,
|
step: IrVariable,
|
||||||
declarations: List<IrVariable>
|
loopInitStatements: List<IrStatement>
|
||||||
) : ForLoopHeader(
|
) : NumericForLoopHeader(
|
||||||
headerInfo, inductionVariable, lastExpression, step,
|
headerInfo, inductionVariable, lastExpression, step,
|
||||||
isLastInclusive = false,
|
isLastInclusive = false,
|
||||||
declarations = declarations
|
loopInitStatements = loopInitStatements
|
||||||
) {
|
) {
|
||||||
|
|
||||||
override fun initializeLoopVariable(symbols: Symbols<CommonBackendContext>, builder: DeclarationIrBuilder) = with(builder) {
|
override fun initializeIteration(loopVariable: IrVariable, symbols: Symbols<CommonBackendContext>, builder: DeclarationIrBuilder) =
|
||||||
// inductionVar = loopVar[inductionVariable]
|
with(builder) {
|
||||||
val indexedGetFun = with(headerInfo.expressionHandler) { headerInfo.objectVariable.type.getFunction }
|
// loopVariable = objectVariable[inductionVariable]
|
||||||
irCall(indexedGetFun).apply {
|
val indexedGetFun = with(headerInfo.expressionHandler) { headerInfo.objectVariable.type.getFunction }
|
||||||
dispatchReceiver = irGet(headerInfo.objectVariable)
|
loopVariable.initializer = irCall(indexedGetFun).apply {
|
||||||
putValueArgument(0, irGet(inductionVariable))
|
dispatchReceiver = irGet(headerInfo.objectVariable)
|
||||||
|
putValueArgument(0, irGet(inductionVariable))
|
||||||
|
}
|
||||||
|
listOf(loopVariable, incrementInductionVariable(this))
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
override fun buildLoop(builder: DeclarationIrBuilder, oldLoop: IrLoop, newBody: IrExpression?): LoopReplacement = with(builder) {
|
override fun buildLoop(builder: DeclarationIrBuilder, oldLoop: IrLoop, newBody: IrExpression?): LoopReplacement = with(builder) {
|
||||||
// Loop is lowered into something like:
|
// Loop is lowered into something like:
|
||||||
|
|||||||
Reference in New Issue
Block a user