diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt index d76f785f14a..f0ef3f4e642 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt @@ -14,6 +14,7 @@ import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl @@ -45,6 +46,7 @@ private fun KonanSymbols.getTypeConversionImpl( internal val Context.getBoxFunction: (IrClass) -> IrSimpleFunction by Context.lazyMapMember { inlinedClass -> assert(inlinedClass.isUsedAsBoxClass()) + assert(inlinedClass.parent is IrFile) { "Expected top level inline class" } val symbols = ir.symbols @@ -63,7 +65,7 @@ internal val Context.getBoxFunction: (IrClass) -> IrSimpleFunction by Context.la startOffset, endOffset, IrDeclarationOrigin.DEFINED, IrSimpleFunctionSymbolImpl(descriptor), - Name.special(""), + Name.special("<${inlinedClass.name}-box>"), Visibilities.PUBLIC, Modality.FINAL, returnType, @@ -89,12 +91,13 @@ internal val Context.getBoxFunction: (IrClass) -> IrSimpleFunction by Context.la } }) descriptor.bind(function) - function.parent = inlinedClass + function.parent = inlinedClass.getContainingFile()!! } } internal val Context.getUnboxFunction: (IrClass) -> IrSimpleFunction by Context.lazyMapMember { inlinedClass -> assert(inlinedClass.isUsedAsBoxClass()) + assert(inlinedClass.parent is IrFile) { "Expected top level inline class" } val symbols = ir.symbols @@ -113,7 +116,7 @@ internal val Context.getUnboxFunction: (IrClass) -> IrSimpleFunction by Context. startOffset, endOffset, IrDeclarationOrigin.DEFINED, IrSimpleFunctionSymbolImpl(descriptor), - Name.special(""), + Name.special("<${inlinedClass.name}-unbox>"), Visibilities.PUBLIC, Modality.FINAL, returnType, @@ -139,7 +142,7 @@ internal val Context.getUnboxFunction: (IrClass) -> IrSimpleFunction by Context. } }) descriptor.bind(function) - function.parent = inlinedClass + function.parent = inlinedClass.getContainingFile()!! } } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/Autoboxing.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/Autoboxing.kt index e36f3044fd0..cb72d727394 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/Autoboxing.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/Autoboxing.kt @@ -17,7 +17,6 @@ import org.jetbrains.kotlin.backend.konan.descriptors.target import org.jetbrains.kotlin.backend.konan.ir.* import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Visibilities -import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.declarations.* @@ -46,7 +45,7 @@ internal class Autoboxing(val context: Context) : FileLoweringPass { override fun lower(irFile: IrFile) { irFile.transformChildrenVoid(transformer) - irFile.transformChildrenVoid(InlineClassTransformer(context)) + irFile.transform(InlineClassTransformer(context), data = null) } } @@ -213,6 +212,15 @@ private class InlineClassTransformer(private val context: Context) : IrBuildingT private val symbols = context.ir.symbols private val irBuiltIns = context.irBuiltIns + private val builtBoxUnboxFunctions = mutableListOf() + + override fun visitFile(declaration: IrFile): IrFile { + declaration.transformChildrenVoid(this) + declaration.declarations.addAll(builtBoxUnboxFunctions) + builtBoxUnboxFunctions.clear() + return declaration + } + override fun visitClass(declaration: IrClass): IrStatement { super.visitClass(declaration) @@ -341,7 +349,7 @@ private class InlineClassTransformer(private val context: Context) : IrBuildingT +irReturn(irGet(box)) } - irClass.declarations += function + builtBoxUnboxFunctions += function } private fun IrBuilderWithScope.irNullPointerOrReference(type: IrType): IrExpression = @@ -367,7 +375,7 @@ private class InlineClassTransformer(private val context: Context) : IrBuildingT +irReturn(irGetField(irGet(boxParameter), getInlineClassBackingField(irClass))) } - irClass.declarations += function + builtBoxUnboxFunctions += function } private fun buildBoxField(declaration: IrClass) { diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt index 29f42bdb90c..2dafd7e9896 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DataFlowIR.kt @@ -642,7 +642,7 @@ internal object DataFlowIR { } private val IrFunction.isSpecial get() = - name.asString().let { it.startsWith("" || it == "" } + name.asString().let { it.startsWith("") || it.endsWith("-unbox>") } private fun mapPropertyInitializer(irField: IrField): FunctionSymbol { functionMap[irField]?.let { return it } diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/Devirtualization.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/Devirtualization.kt index d9166bdb333..c362808ee3f 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/Devirtualization.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/Devirtualization.kt @@ -1033,10 +1033,10 @@ internal object Devirtualization { } } - private val specialNames = listOf("", "") + private val specialNames = listOf("-box>", "-unbox>") // TODO: do it more reliably. - private fun IrExpression.isBoxOrUnboxCall() = (this is IrCall && symbol.owner.name.asString().let { specialNames.contains(it) }) + private fun IrExpression.isBoxOrUnboxCall() = (this is IrCall && symbol.owner.name.asString().let { name -> specialNames.any { name.endsWith(it) } }) private fun devirtualize(irModule: IrModuleFragment, context: Context, externalModulesDFG: ExternalModulesDFG, devirtualizedCallSites: Map) { @@ -1356,6 +1356,14 @@ internal object Devirtualization { irModule.transformChildrenVoid(object: IrElementTransformerVoid() { + fun IrFunction.getCoercedClass(): IrClassifierSymbol { + if (name.asString().endsWith("-box>")) + return valueParameters[0].type.classifierOrFail + if (name.asString().endsWith("-unbox>")) + return returnType.classifierOrFail + error("Unexpected coercion: ${this.dump()}") + } + fun fold(expression: IrExpression, coercion: IrCall, cast: IrTypeOperatorCall?, transformRecursively: Boolean): PossiblyFoldedExpression { @@ -1367,11 +1375,11 @@ internal object Devirtualization { fun IrElement.transformIfAsked() = if (transformRecursively) this.transform(transformer, data = null) else this - val coercionDeclaringClass = coercion.symbol.owner.parentAsClass + val coercionDeclaringClass = coercion.symbol.owner.getCoercedClass() if (expression.isBoxOrUnboxCall()) { expression as IrCall val result = - if (coercionDeclaringClass == expression.symbol.owner.parentAsClass) + if (coercionDeclaringClass == expression.symbol.owner.getCoercedClass()) expression.getArguments().single().second else expression