Coroutines lowering: minor refactoring

This commit is contained in:
Igor Chevdar
2017-05-03 13:06:51 +05:00
parent fc4fc438c3
commit a7caf5ba29
2 changed files with 54 additions and 46 deletions
@@ -28,6 +28,8 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrDelegatingConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
import org.jetbrains.kotlin.ir.expressions.IrTypeOperator
import org.jetbrains.kotlin.ir.expressions.impl.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
@@ -72,6 +74,38 @@ inline fun IrGeneratorWithScope.irBlock(expression: IrExpression, origin: IrStat
inline fun IrGeneratorWithScope.irBlockBody(irElement: IrElement, body: IrBlockBodyBuilder.() -> Unit) =
this.irBlockBody(irElement.startOffset, irElement.endOffset, body)
fun IrBuilderWithScope.irUnit() =
IrGetObjectValueImpl(startOffset, endOffset, context.builtIns.unitType, context.builtIns.unit)
fun IrBuilderWithScope.irIfThen(condition: IrExpression, thenPart: IrExpression) =
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, thenPart, null)
fun IrBuilderWithScope.irGet(descriptor: PropertyDescriptor) =
IrGetterCallImpl(startOffset, endOffset, descriptor.getter!!, null)
fun IrBuilderWithScope.irSet(receiver: IrExpression, descriptor: PropertyDescriptor, arg: IrExpression) =
IrSetterCallImpl(startOffset, endOffset, descriptor.setter!!, null, receiver, null, arg)
fun IrBuilderWithScope.irNot(arg: IrExpression) =
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNot, IrStatementOrigin.EXCL, arg)
fun IrBuilderWithScope.irThrow(arg: IrExpression) =
IrThrowImpl(startOffset, endOffset, context.builtIns.nothingType, arg)
fun IrBuilderWithScope.irCast(arg: IrExpression, type: KotlinType, typeOperand: KotlinType) =
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, typeOperand, arg)
fun IrBuilderWithScope.irImplicitCoercionToUnit(arg: IrExpression) =
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.unitType,
IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, context.builtIns.unitType, arg)
fun IrBuilderWithScope.irGetField(receiver: IrExpression, descriptor: PropertyDescriptor) =
IrGetFieldImpl(startOffset, endOffset, descriptor, receiver)
fun IrBuilderWithScope.irSetField(receiver: IrExpression, descriptor: PropertyDescriptor, value: IrExpression) =
IrSetFieldImpl(startOffset, endOffset, descriptor, receiver, value)
open class IrBuildingTransformer(private val context: BackendContext) : IrElementTransformerVoid() {
private var currentBuilder: IrBuilderWithScope? = null
@@ -21,7 +21,10 @@ import org.jetbrains.kotlin.backend.common.descriptors.explicitParameters
import org.jetbrains.kotlin.backend.common.descriptors.isSuspend
import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.descriptors.*
import org.jetbrains.kotlin.backend.konan.descriptors.getKonanInternalClass
import org.jetbrains.kotlin.backend.konan.descriptors.getKonanInternalFunctions
import org.jetbrains.kotlin.backend.konan.descriptors.isSuspendFunctionInvoke
import org.jetbrains.kotlin.backend.konan.descriptors.synthesizedName
import org.jetbrains.kotlin.backend.konan.ir.*
import org.jetbrains.kotlin.backend.konan.util.atMostOne
import org.jetbrains.kotlin.descriptors.*
@@ -1131,7 +1134,9 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
continue
}
first = false
if (!transformedChild.isPure() && hasSuspendCallInTail[index]) {
if (transformedChild.isPure() || !hasSuspendCallInTail[index])
newChildren[index] = transformedChild
else {
// Save to temporary in order to save execution order.
val tmp = IrTemporaryVariableDescriptorImpl(
containingDeclaration = irFunction.descriptor,
@@ -1140,27 +1145,24 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
tempStatements += irVar(tmp, transformedChild)
newChildren[index] = irGet(tmp)
}
else newChildren[index] = transformedChild
}
var calledSaveState = false
if (expression.isSuspendCall) {
val lastChild = newChildren.last()
if (lastChild != null) {
// Save state at late as possible.
// Save state as late as possible.
calledSaveState = true
newChildren[numberOfChildren - 1] =
if (lastChild.isPure())
irBlock(lastChild) {
irBlock(lastChild) {
if (lastChild.isPure()) {
+irCall(saveStateDescriptor)
+lastChild
}
else {
val tmp = IrTemporaryVariableDescriptorImpl(
containingDeclaration = irFunction.descriptor,
name = "tmp${tempIndex++}".synthesizedName,
outType = lastChild.type)
irBlock(lastChild) {
} else {
val tmp = IrTemporaryVariableDescriptorImpl(
containingDeclaration = irFunction.descriptor,
name = "tmp${tempIndex++}".synthesizedName,
outType = lastChild.type)
+irVar(tmp, lastChild)
+irCall(saveStateDescriptor)
+irGet(tmp)
@@ -1233,9 +1235,11 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
private val IrExpression.isSuspendCall: Boolean
get() = this is IrCall && this.descriptor.isSuspend
private object STATEMENT_ORIGIN_COROUTINE_IMPL: IrStatementOriginImpl("COROUTINE_IMPL")
private object STATEMENT_ORIGIN_COROUTINE_IMPL :
IrStatementOriginImpl("COROUTINE_IMPL")
private fun IrElement.isSpecialBlock() = this is IrBlock && this.origin == STATEMENT_ORIGIN_COROUTINE_IMPL
private fun IrElement.isSpecialBlock()
= this is IrBlock && this.origin == STATEMENT_ORIGIN_COROUTINE_IMPL
private fun IrElement.hasSuspendCalls(): Boolean {
var hasSuspendCalls = false
@@ -1257,7 +1261,7 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
return when (this) {
is IrConst<*> -> true
is IrCall -> false // TODO: skip builtin operators.
is IrTypeOperatorCall -> this.argument.isPure()
is IrTypeOperatorCall -> this.argument.isPure() && this.operator != IrTypeOperator.CAST
is IrGetValue -> !this.descriptor.let { it is VariableDescriptor && it.isVar }
else -> false
}
@@ -1315,34 +1319,4 @@ internal class SuspendFunctionsLowering(val context: Context): DeclarationContai
scopeStack.peek()!!.add(declaration.descriptor)
}
}
fun IrBuilderWithScope.irUnit() =
IrGetObjectValueImpl(startOffset, endOffset, context.builtIns.unitType, context.builtIns.unit)
fun IrBuilderWithScope.irIfThen(condition: IrExpression, thenPart: IrExpression) =
IrIfThenElseImpl(startOffset, endOffset, context.builtIns.unitType, condition, thenPart, null)
fun IrBuilderWithScope.irGet(descriptor: PropertyDescriptor) =
IrGetterCallImpl(startOffset, endOffset, descriptor.getter!!, null)
fun IrBuilderWithScope.irSet(receiver: IrExpression, descriptor: PropertyDescriptor, arg: IrExpression) =
IrSetterCallImpl(startOffset, endOffset, descriptor.setter!!, null, receiver, null, arg)
fun IrBuilderWithScope.irNot(arg: IrExpression) =
primitiveOp1(startOffset, endOffset, context.irBuiltIns.booleanNot, IrStatementOrigin.EXCL, arg)
fun IrBuilderWithScope.irThrow(arg: IrExpression) =
IrThrowImpl(startOffset, endOffset, arg.type, arg)
fun IrBuilderWithScope.irCast(arg: IrExpression, type: KotlinType, typeOperand: KotlinType) =
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.CAST, typeOperand, arg)
fun IrBuilderWithScope.irImplicitCoercionToUnit(arg: IrExpression) =
IrTypeOperatorCallImpl(startOffset, endOffset, context.builtIns.unitType, IrTypeOperator.IMPLICIT_COERCION_TO_UNIT, context.builtIns.unitType, arg)
fun IrBuilderWithScope.irGetField(receiver: IrExpression, descriptor: PropertyDescriptor) =
IrGetFieldImpl(startOffset, endOffset, descriptor, receiver)
fun IrBuilderWithScope.irSetField(receiver: IrExpression, descriptor: PropertyDescriptor, value: IrExpression) =
IrSetFieldImpl(startOffset, endOffset, descriptor, receiver, value)
}