From 48a3c64901f7537117434af79c6d70da0b63ab31 Mon Sep 17 00:00:00 2001 From: Ilya Chernikov Date: Tue, 29 Jun 2021 11:51:27 +0200 Subject: [PATCH] IR: Refactor primitive arrays handling in the new IrBuiltIns for better compatibility e.g. with native --- .../jetbrains/kotlin/backend/common/ir/Ir.kt | 6 ++-- .../common/lower/ArrayConstructorLowering.kt | 2 +- ...AddInternalParametersToConstructorPhase.kt | 4 +-- .../js/lower/ES6ConstructorLowering.kt | 7 +++-- .../backend/jvm/codegen/IrInlineCodegen.kt | 2 +- .../jvm/intrinsics/IrIntrinsicMethods.kt | 2 +- .../generators/OperatorExpressionGenerator.kt | 9 +----- .../src/org/jetbrains/kotlin/ir/IrBuiltIns.kt | 9 ++++-- .../descriptors/IrBuiltInsOverDescriptors.kt | 30 +++++++++++++++---- .../ir/util/DataClassMembersGenerator.kt | 2 +- 10 files changed, 47 insertions(+), 26 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt index a4eee3367a5..ba535faaf0c 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/ir/Ir.kt @@ -150,11 +150,11 @@ abstract class Symbols( val doubleArrayType get() = doubleArray.owner.defaultType val booleanArrayType get() = booleanArray.owner.defaultType - val primitiveArrays get() = irBuiltIns.primitiveArrays + val primitiveArrays get() = irBuiltIns.primitiveTypesToPrimitiveArrays val primitiveArraysToPrimitiveTypes get() = irBuiltIns.primitiveArraysToPrimitiveTypes - val unsignedArrays get() = irBuiltIns.unsignedArrays + val unsignedArrays get() = irBuiltIns.unsignedTypesToUnsignedArrays - val arrays = primitiveArrays + unsignedArrays + array + val arrays = primitiveArrays.values + unsignedArrays.values + array val collection get() = irBuiltIns.collectionClass val set get() = irBuiltIns.setClass diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ArrayConstructorLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ArrayConstructorLowering.kt index bddc4a9859c..0fecc886317 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ArrayConstructorLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ArrayConstructorLowering.kt @@ -50,7 +50,7 @@ private class ArrayConstructorTransformer( return when { irConstructor.valueParameters.size != 2 -> null clazz == context.irBuiltIns.arrayClass -> context.ir.symbols.arrayOfNulls // Array has no unary constructor: it can only exist for Array - context.irBuiltIns.primitiveArrays.contains(clazz) -> clazz.constructors.single { it.owner.valueParameters.size == 1 } + context.irBuiltIns.primitiveArraysToPrimitiveTypes.contains(clazz) -> clazz.constructors.single { it.owner.valueParameters.size == 1 } else -> null } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6AddInternalParametersToConstructorPhase.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6AddInternalParametersToConstructorPhase.kt index d74c4e4c7f4..db16c92ac58 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6AddInternalParametersToConstructorPhase.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6AddInternalParametersToConstructorPhase.kt @@ -6,8 +6,8 @@ package org.jetbrains.kotlin.ir.backend.js.lower import org.jetbrains.kotlin.backend.common.BodyLoweringPass -import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.DescriptorVisibilities +import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.backend.js.JsIrBackendContext @@ -210,7 +210,7 @@ class ES6AddInternalParametersToConstructorPhase(val context: JsIrBackendContext } private fun IrConstructor.hasStrictSignature(): Boolean { - val primitives = with(context.irBuiltIns) { primitiveArrays + stringClass } + val primitives = with(context.irBuiltIns) { primitiveTypesToPrimitiveArrays.values + stringClass } return with(parentAsClass) { isExternal || isInline || symbol in primitives } } } diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6ConstructorLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6ConstructorLowering.kt index 699a22179e0..9bc9a45e483 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6ConstructorLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/ES6ConstructorLowering.kt @@ -23,7 +23,10 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl import org.jetbrains.kotlin.ir.symbols.IrValueSymbol import org.jetbrains.kotlin.ir.symbols.IrVariableSymbol import org.jetbrains.kotlin.ir.types.isAny -import org.jetbrains.kotlin.ir.util.* +import org.jetbrains.kotlin.ir.util.defaultType +import org.jetbrains.kotlin.ir.util.parentAsClass +import org.jetbrains.kotlin.ir.util.statements +import org.jetbrains.kotlin.ir.util.transformInPlace import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.name.Name @@ -376,7 +379,7 @@ class ES6ConstructorLowering(val context: JsIrBackendContext) : BodyLoweringPass //util private fun IrConstructor.hasStrictSignature(): Boolean { - val primitives = with(context.irBuiltIns) { primitiveArrays + stringClass } + val primitives = with(context.irBuiltIns) { primitiveTypesToPrimitiveArrays.values + stringClass } return with(parentAsClass) { isExternal || isInline || symbol in primitives } } } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt index f06b87e6b2f..883ef53f631 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/IrInlineCodegen.kt @@ -183,5 +183,5 @@ fun IrFunction.isInlineFunctionCall(context: JvmBackendContext) = // Constructors can't be marked as inline in metadata, hence this hack. private fun IrFunction.isInlineArrayConstructor(context: JvmBackendContext): Boolean = this is IrConstructor && valueParameters.size == 2 && constructedClass.symbol.let { - it == context.irBuiltIns.arrayClass || it in context.irBuiltIns.primitiveArrays + it == context.irBuiltIns.arrayClass || it in context.irBuiltIns.primitiveArraysToPrimitiveTypes } diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt index 5cb06fa71a1..bdbf20a64cd 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/intrinsics/IrIntrinsicMethods.kt @@ -128,7 +128,7 @@ class IrIntrinsicMethods(val irBuiltIns: IrBuiltIns, val symbols: JvmSymbols) { ).toMap() private fun intrinsicsThatShouldHaveBeenLowered() = - (symbols.primitiveArrays.map { primitiveClassSymbol -> + (symbols.primitiveArrays.map { (_, primitiveClassSymbol) -> val name = primitiveClassSymbol.owner.name.asString() // IntArray -> intArrayOf val arrayOfFunName = name.decapitalizeAsciiOnly() + "Of" diff --git a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt index e30b545c8e1..940f5fecf5c 100644 --- a/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt +++ b/compiler/ir/ir.psi2ir/src/org/jetbrains/kotlin/psi2ir/generators/OperatorExpressionGenerator.kt @@ -48,15 +48,8 @@ import org.jetbrains.kotlin.types.checker.intersectTypes import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberType import org.jetbrains.kotlin.types.typeUtil.makeNotNullable import org.jetbrains.kotlin.types.typeUtil.makeNullable -import kotlin.collections.Map import kotlin.collections.contains -import kotlin.collections.get -import kotlin.collections.listOf -import kotlin.collections.mapOf -import kotlin.collections.mapTo import kotlin.collections.set -import kotlin.collections.toMap -import kotlin.collections.zip class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : StatementGeneratorExtension(statementGenerator) { @@ -443,7 +436,7 @@ class OperatorExpressionGenerator(statementGenerator: StatementGenerator) : Stat return memberScope.findSingleFunction(Name.identifier("to$targetTypeName")) } - private val primitiveTypeMapping = context.irBuiltInsOverDescriptors.run { primitiveTypes.zip(primitiveIrTypes).toMap() } + private val primitiveTypeMapping: Map = context.irBuiltInsOverDescriptors.run { primitiveTypes.zip(primitiveIrTypes).toMap() } private fun kotlinTypeToIrType(kotlinType: KotlinType?) = kotlinType?.let { primitiveTypeMapping[it] } private fun generateComparisonOperator(ktExpression: KtBinaryExpression, origin: IrStatementOrigin): IrExpression { diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt index 6995a7f8f8a..76772f72c74 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/IrBuiltIns.kt @@ -6,6 +6,7 @@ package org.jetbrains.kotlin.ir import org.jetbrains.kotlin.builtins.PrimitiveType +import org.jetbrains.kotlin.builtins.UnsignedType import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl @@ -109,11 +110,11 @@ abstract class IrBuiltIns { abstract val booleanArray: IrClassSymbol abstract val primitiveArraysToPrimitiveTypes: Map - abstract val primitiveArrays: Set + abstract val primitiveTypesToPrimitiveArrays: Map abstract val primitiveArrayElementTypes: Map abstract val primitiveArrayForType: Map - abstract val unsignedArrays: Set + abstract val unsignedTypesToUnsignedArrays: Map abstract val lessFunByOperandType: Map abstract val lessOrEqualFunByOperandType: Map @@ -157,8 +158,12 @@ abstract class IrBuiltIns { abstract fun suspendFunctionN(arity: Int): IrClass abstract fun kSuspendFunctionN(arity: Int): IrClass + // TODO: drop variants from segments, add helper from whole fqn abstract fun findFunctions(name: Name, vararg packageNameSegments: String = arrayOf("kotlin")): Iterable + abstract fun findFunctions(name: Name, packageFqName: FqName): Iterable abstract fun findClass(name: Name, vararg packageNameSegments: String = arrayOf("kotlin")): IrClassSymbol? + abstract fun findClass(name: Name, packageFqName: FqName): IrClassSymbol? + abstract fun findBuiltInClassMemberFunctions(builtInClass: IrClassSymbol, name: Name): Iterable abstract fun getBinaryOperator(name: Name, lhsType: IrType, rhsType: IrType): IrSimpleFunctionSymbol abstract fun getUnaryOperator(name: Name, receiverType: IrType): IrSimpleFunctionSymbol diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltInsOverDescriptors.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltInsOverDescriptors.kt index 3ca7b8d793a..1eae007dd31 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltInsOverDescriptors.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/descriptors/IrBuiltInsOverDescriptors.kt @@ -325,7 +325,7 @@ class IrBuiltInsOverDescriptors( ) // TODO switch to IrType - val primitiveTypes = listOf(bool, char, byte, short, int, float, long, double) + val primitiveTypes = listOf(bool, builtIns.charType, builtIns.byteType, short, int, float, long, double) override val primitiveIrTypes = listOf(booleanType, charType, byteType, shortType, intType, floatType, longType, doubleType) override val primitiveIrTypesWithComparisons = listOf(charType, byteType, shortType, intType, floatType, longType, doubleType) override val primitiveFloatingPointIrTypes = listOf(floatType, doubleType) @@ -340,12 +340,15 @@ class IrBuiltInsOverDescriptors( override val booleanArray = builtIns.getPrimitiveArrayClassDescriptor(PrimitiveType.BOOLEAN).toIrSymbol() override val primitiveArraysToPrimitiveTypes = PrimitiveType.values().associate { builtIns.getPrimitiveArrayClassDescriptor(it).toIrSymbol() to it } - override val primitiveArrays = primitiveArraysToPrimitiveTypes.keys + override val primitiveTypesToPrimitiveArrays = primitiveArraysToPrimitiveTypes.map { (k, v) -> v to k }.toMap() override val primitiveArrayElementTypes = primitiveArraysToPrimitiveTypes.mapValues { primitiveTypeToIrType[it.value] } override val primitiveArrayForType = primitiveArrayElementTypes.asSequence().associate { it.value to it.key } - override val unsignedArrays: Set = UnsignedType.values().mapNotNullTo(mutableSetOf()) { unsignedType -> - builtIns.builtInsModule.findClassAcrossModuleDependencies(unsignedType.arrayClassId)?.toIrSymbol() + override val unsignedTypesToUnsignedArrays: Map by lazy { + UnsignedType.values().mapNotNull { unsignedType -> + val array = builtIns.builtInsModule.findClassAcrossModuleDependencies(unsignedType.arrayClassId)?.toIrSymbol() + if (array == null) null else unsignedType to array + }.toMap() } override val lessFunByOperandType = primitiveIrTypesWithComparisons.defineComparisonOperatorForEachIrType(BuiltInOperatorNames.LESS) @@ -409,12 +412,28 @@ class IrBuiltInsOverDescriptors( symbolTable.referenceSimpleFunction(it) } + override fun findFunctions(name: Name, packageFqName: FqName): Iterable = + builtIns.builtInsModule.getPackage(packageFqName).memberScope.getContributedFunctions(name, NoLookupLocation.FROM_BACKEND).map { + symbolTable.referenceSimpleFunction(it) + } + override fun findClass(name: Name, vararg packageNameSegments: String): IrClassSymbol? = (builtInsPackage(*packageNameSegments).getContributedClassifier( name, NoLookupLocation.FROM_BACKEND ) as? ClassDescriptor)?.let { symbolTable.referenceClass(it) } + override fun findClass(name: Name, packageFqName: FqName): IrClassSymbol? = + (builtIns.builtInsModule.getPackage(packageFqName).memberScope.getContributedClassifier( + name, + NoLookupLocation.FROM_BACKEND + ) as? ClassDescriptor)?.let { symbolTable.referenceClass(it) } + + override fun findBuiltInClassMemberFunctions(builtInClass: IrClassSymbol, name: Name): Iterable = + builtInClass.descriptor.unsubstitutedMemberScope + .getContributedFunctions(name, NoLookupLocation.FROM_BACKEND) + .map { symbolTable.referenceSimpleFunction(it) } + private val binaryOperatorCache = mutableMapOf, IrSimpleFunctionSymbol>() override fun getBinaryOperator(name: Name, lhsType: IrType, rhsType: IrType): IrSimpleFunctionSymbol { @@ -504,7 +523,7 @@ class IrBuiltInsOverDescriptors( override fun suspendFunctionN(arity: Int): IrClass = functionFactory.suspendFunctionN(arity) override fun kSuspendFunctionN(arity: Int): IrClass = functionFactory.kSuspendFunctionN(arity) - override val getProgressionLastElementByReturnType: Map = + override val getProgressionLastElementByReturnType: Map by lazy { builtInsPackage("kotlin", "internal") .getContributedFunctions(Name.identifier("getProgressionLastElement"), NoLookupLocation.FROM_BACKEND) .filter { it.containingDeclaration !is BuiltInsPackageFragment } @@ -514,6 +533,7 @@ class IrBuiltInsOverDescriptors( klass to function } .toMap() + } } private inline fun MemberScope.findFirstFunction(name: String, predicate: (CallableMemberDescriptor) -> Boolean) = diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt index 6c03fb9f75a..98bddaae0ed 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/util/DataClassMembersGenerator.kt @@ -240,7 +240,7 @@ abstract class DataClassMembersGenerator( getIrProperty(property).backingField!! val IrClassifierSymbol?.isArrayOrPrimitiveArray: Boolean - get() = this == context.irBuiltIns.arrayClass || this in context.irBuiltIns.primitiveArrays + get() = this == context.irBuiltIns.arrayClass || this in context.irBuiltIns.primitiveArraysToPrimitiveTypes abstract fun declareSimpleFunction(startOffset: Int, endOffset: Int, functionDescriptor: FunctionDescriptor): IrFunction