[IR][K/N] Refactored a bit SuspendFunctionLowering
This commit is contained in:
-28
@@ -256,34 +256,6 @@ abstract class AbstractSuspendFunctionsLowering<C : CommonBackendContext>(val co
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
protected open class VariablesScopeTracker : IrElementVisitorVoid {
|
|
||||||
|
|
||||||
protected val scopeStack = mutableListOf<MutableSet<IrVariable>>(mutableSetOf())
|
|
||||||
|
|
||||||
override fun visitElement(element: IrElement) {
|
|
||||||
element.acceptChildrenVoid(this)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitContainerExpression(expression: IrContainerExpression) {
|
|
||||||
if (!expression.isTransparentScope)
|
|
||||||
scopeStack.push(mutableSetOf())
|
|
||||||
super.visitContainerExpression(expression)
|
|
||||||
if (!expression.isTransparentScope)
|
|
||||||
scopeStack.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitCatch(aCatch: IrCatch) {
|
|
||||||
scopeStack.push(mutableSetOf())
|
|
||||||
super.visitCatch(aCatch)
|
|
||||||
scopeStack.pop()
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitVariable(declaration: IrVariable) {
|
|
||||||
super.visitVariable(declaration)
|
|
||||||
scopeStack.peek()!!.add(declaration)
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
fun IrClass.addField(name: Name, type: IrType, isMutable: Boolean): IrField {
|
fun IrClass.addField(name: Name, type: IrType, isMutable: Boolean): IrField {
|
||||||
val klass = this
|
val klass = this
|
||||||
return factory.buildField {
|
return factory.buildField {
|
||||||
|
|||||||
+5
-61
@@ -14,8 +14,6 @@ import org.jetbrains.kotlin.ir.builders.*
|
|||||||
import org.jetbrains.kotlin.ir.declarations.*
|
import org.jetbrains.kotlin.ir.declarations.*
|
||||||
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.IrSetValueImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSuspendableExpressionImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrSuspendableExpressionImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrSuspensionPointImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrSuspensionPointImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
|
||||||
@@ -89,16 +87,11 @@ internal class NativeSuspendFunctionsLowering(
|
|||||||
|
|
||||||
val liveLocals = LivenessAnalysis.run(originalBody) { it is IrSuspensionPoint }
|
val liveLocals = LivenessAnalysis.run(originalBody) { it is IrSuspensionPoint }
|
||||||
|
|
||||||
val immutableLiveLocals = liveLocals.values.flatten().filterNot { it.isVar }.toSet()
|
|
||||||
val localsMap = immutableLiveLocals.associate { it to irVar(it.name, it.type, true) }
|
|
||||||
|
|
||||||
if (localsMap.isNotEmpty())
|
|
||||||
transformVariables(originalBody, localsMap) // Make variables mutable in order to save/restore them.
|
|
||||||
|
|
||||||
val localToPropertyMap = mutableMapOf<IrVariableSymbol, IrField>()
|
val localToPropertyMap = mutableMapOf<IrVariableSymbol, IrField>()
|
||||||
// TODO: optimize by using the same property for different locals.
|
// TODO: optimize by using the same property for different locals.
|
||||||
liveLocals.values.forEach { scope ->
|
liveLocals.values.forEach { scope ->
|
||||||
scope.forEach {
|
scope.forEach {
|
||||||
|
it.isVar = true // Make variables mutable in order to save/restore them.
|
||||||
localToPropertyMap.getOrPut(it.symbol) {
|
localToPropertyMap.getOrPut(it.symbol) {
|
||||||
coroutineClass.addField(it.name, it.type, true)
|
coroutineClass.addField(it.name, it.type, true)
|
||||||
}
|
}
|
||||||
@@ -148,10 +141,8 @@ internal class NativeSuspendFunctionsLowering(
|
|||||||
saveState.symbol -> {
|
saveState.symbol -> {
|
||||||
val scope = liveLocals[suspensionPoint]!!
|
val scope = liveLocals[suspensionPoint]!!
|
||||||
return irBlock(expression) {
|
return irBlock(expression) {
|
||||||
scope.forEach {
|
for (variable in scope)
|
||||||
val variable = localsMap[it] ?: it
|
+irSetField(irGet(thisReceiver), localToPropertyMap[variable.symbol]!!, irGet(variable))
|
||||||
+irSetField(irGet(thisReceiver), localToPropertyMap[it.symbol]!!, irGet(variable))
|
|
||||||
}
|
|
||||||
+irSetField(
|
+irSetField(
|
||||||
irGet(thisReceiver),
|
irGet(thisReceiver),
|
||||||
labelField,
|
labelField,
|
||||||
@@ -162,10 +153,8 @@ internal class NativeSuspendFunctionsLowering(
|
|||||||
restoreState.symbol -> {
|
restoreState.symbol -> {
|
||||||
val scope = liveLocals[suspensionPoint]!!
|
val scope = liveLocals[suspensionPoint]!!
|
||||||
return irBlock(expression) {
|
return irBlock(expression) {
|
||||||
scope.forEach {
|
for (variable in scope)
|
||||||
+irSet(localsMap[it]
|
+irSet(variable, irGetField(irGet(thisReceiver), localToPropertyMap[variable.symbol]!!))
|
||||||
?: it, irGetField(irGet(thisReceiver), localToPropertyMap[it.symbol]!!))
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -195,51 +184,6 @@ internal class NativeSuspendFunctionsLowering(
|
|||||||
private var tempIndex = 0
|
private var tempIndex = 0
|
||||||
private var suspensionPointIdIndex = 0
|
private var suspensionPointIdIndex = 0
|
||||||
|
|
||||||
private fun transformVariables(element: IrElement, variablesMap: Map<IrVariable, IrVariable>) {
|
|
||||||
element.transformChildrenVoid(object: IrElementTransformerVoid() {
|
|
||||||
|
|
||||||
override fun visitGetValue(expression: IrGetValue): IrExpression {
|
|
||||||
expression.transformChildrenVoid(this)
|
|
||||||
|
|
||||||
val newVariable = variablesMap[expression.symbol.owner]
|
|
||||||
?: return expression
|
|
||||||
|
|
||||||
return IrGetValueImpl(
|
|
||||||
startOffset = expression.startOffset,
|
|
||||||
endOffset = expression.endOffset,
|
|
||||||
type = newVariable.type,
|
|
||||||
symbol = newVariable.symbol,
|
|
||||||
origin = expression.origin)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitSetValue(expression: IrSetValue): IrExpression {
|
|
||||||
expression.transformChildrenVoid(this)
|
|
||||||
|
|
||||||
val newVariable = variablesMap[expression.symbol.owner]
|
|
||||||
?: return expression
|
|
||||||
|
|
||||||
return IrSetValueImpl(
|
|
||||||
startOffset = expression.startOffset,
|
|
||||||
endOffset = expression.endOffset,
|
|
||||||
type = context.irBuiltIns.unitType,
|
|
||||||
symbol = newVariable.symbol,
|
|
||||||
value = expression.value,
|
|
||||||
origin = expression.origin)
|
|
||||||
}
|
|
||||||
|
|
||||||
override fun visitVariable(declaration: IrVariable): IrStatement {
|
|
||||||
declaration.transformChildrenVoid(this)
|
|
||||||
|
|
||||||
val newVariable = variablesMap[declaration]
|
|
||||||
?: return declaration
|
|
||||||
|
|
||||||
newVariable.initializer = declaration.initializer
|
|
||||||
|
|
||||||
return newVariable
|
|
||||||
}
|
|
||||||
})
|
|
||||||
}
|
|
||||||
|
|
||||||
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