[K/N][IR] Used liveness analysis in the coroutines lowering
Liveness analysis results are used for spilling variables before suspending a coroutine
This commit is contained in:
+3
-30
@@ -2,6 +2,7 @@ package org.jetbrains.kotlin.backend.konan.lower
|
|||||||
|
|
||||||
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
import org.jetbrains.kotlin.backend.common.descriptors.synthesizedName
|
||||||
import org.jetbrains.kotlin.backend.common.lower.*
|
import org.jetbrains.kotlin.backend.common.lower.*
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.optimizations.LivenessAnalysis
|
||||||
import org.jetbrains.kotlin.backend.konan.Context
|
import org.jetbrains.kotlin.backend.konan.Context
|
||||||
import org.jetbrains.kotlin.backend.konan.NativeGenerationState
|
import org.jetbrains.kotlin.backend.konan.NativeGenerationState
|
||||||
import org.jetbrains.kotlin.descriptors.Modality
|
import org.jetbrains.kotlin.descriptors.Modality
|
||||||
@@ -14,10 +15,7 @@ import org.jetbrains.kotlin.ir.declarations.*
|
|||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSetValueImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSuspendableExpressionImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSuspensionPointImpl
|
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
|
||||||
@@ -85,7 +83,7 @@ internal class NativeSuspendFunctionsLowering(
|
|||||||
// Extract all suspend calls to temporaries in order to make correct jumps to them.
|
// Extract all suspend calls to temporaries in order to make correct jumps to them.
|
||||||
originalBody.transformChildrenVoid(ExpressionSlicer(labelField.type, transformingFunction, saveState, restoreState, suspendResult, resultArgument))
|
originalBody.transformChildrenVoid(ExpressionSlicer(labelField.type, transformingFunction, saveState, restoreState, suspendResult, resultArgument))
|
||||||
|
|
||||||
val liveLocals = computeLivenessAtSuspensionPoints(originalBody)
|
val liveLocals = LivenessAnalysis.run(originalBody) { it is IrSuspensionPoint }
|
||||||
|
|
||||||
val immutableLiveLocals = liveLocals.values.flatten().filterNot { it.isVar }.toSet()
|
val immutableLiveLocals = liveLocals.values.flatten().filterNot { it.isVar }.toSet()
|
||||||
val localsMap = immutableLiveLocals.associate { it to irVar(it.name, it.type, true) }
|
val localsMap = immutableLiveLocals.associate { it to irVar(it.name, it.type, true) }
|
||||||
@@ -238,31 +236,6 @@ internal class NativeSuspendFunctionsLowering(
|
|||||||
})
|
})
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun computeLivenessAtSuspensionPoints(body: IrBody): Map<IrSuspensionPoint, List<IrVariable>> {
|
|
||||||
// TODO: data flow analysis.
|
|
||||||
// Just save all visible for now.
|
|
||||||
val result = mutableMapOf<IrSuspensionPoint, List<IrVariable>>()
|
|
||||||
body.acceptChildrenVoid(object: VariablesScopeTracker() {
|
|
||||||
|
|
||||||
override fun visitExpression(expression: IrExpression) {
|
|
||||||
val suspensionPoint = expression as? IrSuspensionPoint
|
|
||||||
if (suspensionPoint == null) {
|
|
||||||
super.visitExpression(expression)
|
|
||||||
return
|
|
||||||
}
|
|
||||||
|
|
||||||
suspensionPoint.result.acceptChildrenVoid(this)
|
|
||||||
suspensionPoint.resumeResult.acceptChildrenVoid(this)
|
|
||||||
|
|
||||||
val visibleVariables = mutableListOf<IrVariable>()
|
|
||||||
scopeStack.forEach { visibleVariables += it }
|
|
||||||
result[suspensionPoint] = visibleVariables
|
|
||||||
}
|
|
||||||
})
|
|
||||||
|
|
||||||
return result
|
|
||||||
}
|
|
||||||
|
|
||||||
private inner class ExpressionSlicer(val suspensionPointIdType: IrType, val irFunction: IrFunction,
|
private inner class ExpressionSlicer(val suspensionPointIdType: IrType, val irFunction: IrFunction,
|
||||||
val saveState: IrFunction, val restoreState: IrFunction,
|
val saveState: IrFunction, val restoreState: IrFunction,
|
||||||
val suspendResult: IrVariable, val resultArgument: IrValueParameter): IrElementTransformerVoid() {
|
val suspendResult: IrVariable, val resultArgument: IrValueParameter): IrElementTransformerVoid() {
|
||||||
|
|||||||
Reference in New Issue
Block a user