From 4f1d181c885bf5d44f00b2d8832345b67a83468d Mon Sep 17 00:00:00 2001 From: "vladislav.grechko" Date: Mon, 22 May 2023 18:50:47 +0200 Subject: [PATCH] [JVM_IR] Set correct origin for new variables on MFVC flattening. Preserve information that variable is temporary while flattening. Otherwise, unnecessary bytecode for them might be generated. --- .../lower/JvmMultiFieldValueClassLowering.kt | 19 ++++++++++++++----- .../jetbrains/kotlin/backend/jvm/MfvcNode.kt | 19 +++++++++++++++---- .../box/valueClasses/inlineFunctions.kt | 1 - 3 files changed, 29 insertions(+), 10 deletions(-) diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmMultiFieldValueClassLowering.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmMultiFieldValueClassLowering.kt index a18c720dd5d..3b1da6a1fad 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmMultiFieldValueClassLowering.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/lower/JvmMultiFieldValueClassLowering.kt @@ -30,10 +30,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrDelegatingConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrEnumConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrFunctionReferenceImpl -import org.jetbrains.kotlin.ir.symbols.IrConstructorSymbol -import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol -import org.jetbrains.kotlin.ir.symbols.IrSymbol -import org.jetbrains.kotlin.ir.symbols.IrValueSymbol +import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.symbols.impl.IrAnonymousInitializerSymbolImpl import org.jetbrains.kotlin.ir.transformStatement import org.jetbrains.kotlin.ir.types.* @@ -877,6 +874,7 @@ internal class JvmMultiFieldValueClassLowering( name = Name.identifier("constructor_tmp"), saveVariable = ::variablesSaver, isVar = false, + origin = JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_REPRESENTATION_VARIABLE ) for (valueDeclaration in instance.valueDeclarations) { valueDeclaration.origin = JvmLoweredDeclarationOrigin.TEMPORARY_MULTI_FIELD_VALUE_CLASS_VARIABLE @@ -1173,14 +1171,25 @@ internal class JvmMultiFieldValueClassLowering( } }.unwrapBlock() + private val IrDeclarationOrigin.isTemporary + get() = + this == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE + || this == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE_FOR_INLINED_EXTENSION_RECEIVER + || this == IrDeclarationOrigin.IR_TEMPORARY_VARIABLE_FOR_INLINED_PARAMETER + override fun visitVariable(declaration: IrVariable): IrStatement { val initializer = declaration.initializer if (declaration.type.needsMfvcFlattening()) { val irClass = declaration.type.erasedUpperBound val rootNode = replacements.getRootMfvcNode(irClass) return context.createJvmIrBuilder(getCurrentScopeSymbol(), declaration).irBlock { + val origin = if (declaration.origin.isTemporary) { + JvmLoweredDeclarationOrigin.TEMPORARY_MULTI_FIELD_VALUE_CLASS_VARIABLE + } else { + JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_REPRESENTATION_VARIABLE + } val instance = rootNode.createInstanceFromValueDeclarationsAndBoxType( - this, declaration.type as IrSimpleType, declaration.name, ::variablesSaver, declaration.isVar + this, declaration.type as IrSimpleType, declaration.name, ::variablesSaver, declaration.isVar, origin ) valueDeclarationsRemapper.registerReplacement(declaration, instance) initializer?.let { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNode.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNode.kt index 4617ab7108c..0da50fd4d8d 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNode.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/MfvcNode.kt @@ -61,20 +61,31 @@ fun MfvcNode.createInstanceFromBox( * Create instance-specific [ValueDeclarationMfvcNodeInstance] from instance-agnostic [MfvcNode] using new flattened variables as data source. */ fun MfvcNode.createInstanceFromValueDeclarationsAndBoxType( - scope: IrBuilderWithScope, type: IrSimpleType, name: Name, saveVariable: (IrVariable) -> Unit, isVar: Boolean -): ValueDeclarationMfvcNodeInstance = createInstanceFromValueDeclarations(scope, makeTypeArgumentsFromType(type), name, saveVariable, isVar) + scope: IrBuilderWithScope, + type: IrSimpleType, + name: Name, + saveVariable: (IrVariable) -> Unit, + isVar: Boolean, + origin: IrDeclarationOrigin, +): ValueDeclarationMfvcNodeInstance = + createInstanceFromValueDeclarations(scope, makeTypeArgumentsFromType(type), name, saveVariable, isVar, origin) /** * Create instance-specific [ValueDeclarationMfvcNodeInstance] from instance-agnostic [MfvcNode] using new flattened variables as data source. */ fun MfvcNode.createInstanceFromValueDeclarations( - scope: IrBuilderWithScope, typeArguments: TypeArguments, name: Name, saveVariable: (IrVariable) -> Unit, isVar: Boolean + scope: IrBuilderWithScope, + typeArguments: TypeArguments, + name: Name, + saveVariable: (IrVariable) -> Unit, + isVar: Boolean, + origin: IrDeclarationOrigin, ): ValueDeclarationMfvcNodeInstance { val valueDeclarations = mapLeaves { scope.savableStandaloneVariable( type = it.type, name = listOf(name, it.fullFieldName).joinToString("-"), - origin = JvmLoweredDeclarationOrigin.MULTI_FIELD_VALUE_CLASS_REPRESENTATION_VARIABLE, + origin = origin, saveVariable = saveVariable, isVar = isVar, ) diff --git a/compiler/testData/codegen/box/valueClasses/inlineFunctions.kt b/compiler/testData/codegen/box/valueClasses/inlineFunctions.kt index 3233cdc68fd..fe143e661f3 100644 --- a/compiler/testData/codegen/box/valueClasses/inlineFunctions.kt +++ b/compiler/testData/codegen/box/valueClasses/inlineFunctions.kt @@ -1,6 +1,5 @@ // LANGUAGE: +ValueClasses // TARGET_BACKEND: JVM_IR -// IGNORE_INLINER: IR // CHECK_BYTECODE_LISTING // WITH_STDLIB // CHECK_BYTECODE_TEXT