diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLower.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLower.kt index aa47bcd6bdf..79d9d80af94 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLower.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLower.kt @@ -56,10 +56,6 @@ internal class KonanLower(val context: Context) { irModule.files.forEach(PreInlineLowering(context)::lower) } - phaser.phase(KonanPhase.LOWER_INLINE_CONSTRUCTORS) { - InlineConstructorsTransformation(context).lower(irModule) - } - // Inlining must be run before other phases. phaser.phase(KonanPhase.LOWER_INLINE) { FunctionInlining(context).inline(irModule) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPhases.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPhases.kt index 792a492f633..bf2716c3249 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPhases.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanPhases.kt @@ -32,8 +32,7 @@ enum class KonanPhase(val description: String, /* ... ... */ REMOVE_EXPECT_DECLARATIONS("Expect declarations removing"), /* ... ... */ TEST_PROCESSOR("Unit test processor"), /* ... ... */ LOWER_BEFORE_INLINE("Special operations processing before inlining"), - /* ... ... */ LOWER_INLINE_CONSTRUCTORS("Inline constructors transformation", LOWER_BEFORE_INLINE), - /* ... ... */ LOWER_INLINE("Functions inlining", LOWER_INLINE_CONSTRUCTORS, LOWER_BEFORE_INLINE), + /* ... ... */ LOWER_INLINE("Functions inlining", LOWER_BEFORE_INLINE), /* ... ... */ LOWER_AFTER_INLINE("Special operations processing after inlining"), /* ... ... ... */ DESERIALIZER("Deserialize inline bodies"), /* ... ... */ LOWER_INTEROP_PART1("Interop lowering, part 1", LOWER_INLINE), diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt index 15b0779db57..552cc430ddb 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/FunctionInlining.kt @@ -20,6 +20,7 @@ package org.jetbrains.kotlin.backend.konan.lower import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.ScopeWithIr +import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.reportWarning import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.descriptors.isFunctionInvoke @@ -27,23 +28,21 @@ import org.jetbrains.kotlin.backend.konan.descriptors.needsInlining import org.jetbrains.kotlin.backend.konan.descriptors.propertyIfAccessor import org.jetbrains.kotlin.backend.konan.descriptors.resolveFakeOverride import org.jetbrains.kotlin.backend.konan.ir.DeserializerDriver -import org.jetbrains.kotlin.descriptors.DeclarationDescriptor -import org.jetbrains.kotlin.descriptors.ParameterDescriptor -import org.jetbrains.kotlin.descriptors.ValueDescriptor -import org.jetbrains.kotlin.descriptors.ValueParameterDescriptor +import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement +import org.jetbrains.kotlin.ir.builders.irCall +import org.jetbrains.kotlin.ir.builders.irGet +import org.jetbrains.kotlin.ir.builders.irReturn import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.getDefault import org.jetbrains.kotlin.ir.expressions.* -import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrMemberAccessExpressionBase -import org.jetbrains.kotlin.ir.expressions.impl.IrReturnableBlockImpl -import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl +import org.jetbrains.kotlin.ir.expressions.impl.* import org.jetbrains.kotlin.ir.symbols.impl.createValueSymbol import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid +import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe import org.jetbrains.kotlin.resolve.calls.components.hasDefaultValue import org.jetbrains.kotlin.resolve.inline.InlineUtil @@ -103,6 +102,9 @@ internal class FunctionInlining(val context: Context): IrElementTransformerVoidW override fun visitElement(element: IrElement) = element.accept(this, null) } +private val inlineConstructor = FqName("konan.internal.InlineConstructor") +private val FunctionDescriptor.isInlineConstructor get() = annotations.hasAnnotation(inlineConstructor) + //-----------------------------------------------------------------------------// private class Inliner(val globalSubstituteMap: MutableMap, @@ -123,22 +125,46 @@ private class Inliner(val globalSubstituteMap: MutableMap() } - - //-------------------------------------------------------------------------// - - fun lower(irModule: IrModuleFragment) = irModule.accept(this, null) - - //-------------------------------------------------------------------------// - - override fun visitCall(expression: IrCall): IrExpression { - - val irCall = super.visitCall(expression) as IrCall - val functionDescriptor = irCall.descriptor - if (!functionDescriptor.isInlineConstructor) return irCall // This call does not need inlining. - - val functionDeclaration = getFunctionDeclaration(irCall) // Get declaration of the function to be inlined. - if (functionDeclaration == null) { // We failed to get the declaration. - val message = "Inliner failed to obtain function declaration: " + - functionDescriptor.fqNameSafe.toString() - context.reportWarning(message, currentFile, irCall) // Report warning. - return irCall - } - - val statements = (functionDeclaration.body as IrBlockBody).statements - replaceDelegatingConstructorCall(statements, functionDescriptor) - functionDeclaration.transformChildrenVoid(ValueSubstitutor()) - context.ir.originalModuleIndex.functions[functionDescriptor.original] = functionDeclaration - - return irCall - } - - //-------------------------------------------------------------------------// - - private fun getFunctionDeclaration(irCall: IrCall): IrFunction? { - - val functionDescriptor = irCall.descriptor - val originalDescriptor = functionDescriptor.resolveFakeOverride().original - val functionDeclaration = - context.ir.originalModuleIndex.functions[originalDescriptor] ?: // If function is declared in the current module. - deserializer.deserializeInlineBody(originalDescriptor) // Function is declared in another module. - return functionDeclaration as IrFunction? - } - - //-------------------------------------------------------------------------// - - private fun replaceDelegatingConstructorCall(statements: MutableList, functionDescriptor: FunctionDescriptor) { - - val delegatingCall = statements[0] - if (delegatingCall !is IrDelegatingConstructorCallImpl) return - - val thisVariable = generateIrCall(delegatingCall) - - val newThisGetValue = IrGetValueImpl( // Create new expression, representing access the new variable. - startOffset = 0, - endOffset = 0, - symbol = createValueSymbol(thisVariable.descriptor) - ) - - val classDescriptor = delegatingCall.descriptor.constructedClass - val oldThisGetValue = classDescriptor.thisAsReceiverParameter - substituteMap[oldThisGetValue] = newThisGetValue - - val newStatements = statements.toMutableList() - newStatements[0] = thisVariable - newStatements += newThisGetValue - - val block = IrBlockImpl( - startOffset = 0, - endOffset = 0, - type = newThisGetValue.type, - origin = null, - statements = newStatements - ) - - val returnThis = IrReturnImpl(0, 0, createFunctionSymbol(functionDescriptor), block) - - statements.clear() - statements += returnThis - } - - //-------------------------------------------------------------------------// - - private fun generateIrCall(expression: IrDelegatingConstructorCallImpl): IrVariable { - - val newExpression = IrCallImpl( - expression.startOffset, - expression.endOffset, - expression.descriptor.returnType, - expression.symbol, - expression.descriptor, - expression.typeArguments, - expression.origin - ).apply { - expression.descriptor.valueParameters.forEach { - val valueArgument = expression.getValueArgument(it) - putValueArgument(it.index, valueArgument) - } - } - - return currentScope!!.scope.createTemporaryVariable( // Create new variable and init it with constructor call. - irExpression = newExpression, - nameHint = newExpression.descriptor.fqNameSafe.toString() + ".this", - isMutable = false) - } - - //-------------------------------------------------------------------------// - - override fun visitElement(element: IrElement) = element.accept(this, null) - - //-------------------------------------------------------------------------// - - private inner class ValueSubstitutor: IrElementTransformerVoid() { - - override fun visitGetValue(expression: IrGetValue): IrExpression { - val newExpression = super.visitGetValue(expression) as IrGetValue - val descriptor = newExpression.descriptor - val argument = substituteMap[descriptor] // Find expression to replace this parameter. - if (argument == null) return newExpression // If there is no such expression - do nothing. - return argument - } - - //---------------------------------------------------------------------// - - override fun visitElement(element: IrElement) = element.accept(this, null) - } -} \ No newline at end of file diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt index 6101f56a044..97a4bed51bd 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/DFGBuilder.kt @@ -42,7 +42,6 @@ import org.jetbrains.kotlin.ir.util.getArguments import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid -import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.resolve.OverridingUtil import org.jetbrains.kotlin.resolve.scopes.MemberScope @@ -375,18 +374,13 @@ internal class ModuleDFGBuilder(val context: Context, val irModule: IrModuleFrag super.visitSetField(expression) } - // TODO: hack to overcome bad code in InlineConstructorsTransformation. - private val FQ_NAME_INLINE_CONSTRUCTOR = FqName("konan.internal.InlineConstructor") - override fun visitReturn(expression: IrReturn) { val returnableBlock = returnableBlocks[expression.returnTarget] if (returnableBlock != null) { returnableBlockValues[returnableBlock]!!.add(expression.value) } else { // Non-local return. - if (!expression.type.isUnit()) { - if (!expression.returnTarget.annotations.hasAnnotation(FQ_NAME_INLINE_CONSTRUCTOR)) // Not inline constructor. - returnValues += expression.value - } + if (!expression.type.isUnit()) + returnValues += expression.value } super.visitReturn(expression) }