From 1dd6dcdeef71b53dc101e99ffcf22ecdc707aea1 Mon Sep 17 00:00:00 2001 From: Pavel Kunyavskiy Date: Wed, 19 May 2021 12:14:00 +0300 Subject: [PATCH] [K/N] Store ordinal value in lowered enum --- .../konan/EnumSpecialDescriptorsFactory.kt | 25 +++++++++++-------- .../backend/konan/llvm/CodeGenerator.kt | 4 +-- .../backend/konan/lower/EnumClassLowering.kt | 4 +-- 3 files changed, 19 insertions(+), 14 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EnumSpecialDescriptorsFactory.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EnumSpecialDescriptorsFactory.kt index 8da87831f0e..8e9a43b6fe1 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EnumSpecialDescriptorsFactory.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EnumSpecialDescriptorsFactory.kt @@ -39,6 +39,8 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.module internal object DECLARATION_ORIGIN_ENUM : IrDeclarationOriginImpl("ENUM") +internal data class LoweredEnumEntryDescription(val ordinal: Int, val getterId: Int) + /** * Common interface for both [InternalLoweredEnum] and [ExternalLoweredEnum] * that allows to work with lowered enum regardless of its location. @@ -46,7 +48,7 @@ internal object DECLARATION_ORIGIN_ENUM : IrDeclarationOriginImpl("ENUM") internal interface LoweredEnumAccess { val valuesGetter: IrSimpleFunction val itemGetterSymbol: IrSimpleFunctionSymbol - val entriesMap: Map + val entriesMap: Map fun getValuesField(startOffset: Int, endOffset: Int): IrExpression } @@ -59,7 +61,7 @@ internal data class InternalLoweredEnum( val valuesGetterWrapper: IrSimpleFunction, override val valuesGetter: IrSimpleFunction, override val itemGetterSymbol: IrSimpleFunctionSymbol, - override val entriesMap: Map + override val entriesMap: Map ) : LoweredEnumAccess { private fun internalObjectGetter(startOffset: Int, endOffset: Int) = IrGetObjectValueImpl(startOffset, endOffset, @@ -82,7 +84,7 @@ internal data class InternalLoweredEnum( internal data class ExternalLoweredEnum( override val valuesGetter: IrSimpleFunction, override val itemGetterSymbol: IrSimpleFunctionSymbol, - override val entriesMap: Map + override val entriesMap: Map ) : LoweredEnumAccess { override fun getValuesField(startOffset: Int, endOffset: Int): IrExpression = IrCallImpl(startOffset, endOffset, valuesGetter.returnType, valuesGetter.symbol, valuesGetter.typeParameters.size, valuesGetter.valueParameters.size) @@ -91,13 +93,16 @@ internal data class ExternalLoweredEnum( internal class EnumSpecialDeclarationsFactory(val context: Context) { private val symbols = context.ir.symbols - private fun enumEntriesMap(enumClass: IrClass): Map = - enumClass.declarations - .filterIsInstance() - .sortedBy { it.name } - .withIndex() - .associate { it.value.name to it.index } - .toMap() + private fun enumEntriesMap(enumClass: IrClass): Map { + data class NameWithOrdinal(val name: Name, val ordinal: Int) + return enumClass.declarations.asSequence() + .filterIsInstance() + .mapIndexed { index, it -> NameWithOrdinal(it.name, index) } + .sortedBy { it.name } + .withIndex() + .associate { it.value.name to LoweredEnumEntryDescription(it.value.ordinal, it.index) } + .toMap() + } private fun findItemGetterSymbol(): IrSimpleFunctionSymbol = symbols.array.functions.single { it.descriptor.name == Name.identifier("get") } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt index 611a682fa8f..768aa94ee2e 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/CodeGenerator.kt @@ -1189,7 +1189,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, val enumClass = enumEntry.parentAsClass val loweredEnum = context.specialDeclarationsFactory.getLoweredEnum(enumClass) - val ordinal = loweredEnum.entriesMap[enumEntry.name]!! + val getterId = loweredEnum.entriesMap[enumEntry.name]!!.getterId val values = call( loweredEnum.valuesGetter.llvmFunction, emptyList(), @@ -1199,7 +1199,7 @@ internal class FunctionGenerationContext(val function: LLVMValueRef, return call( loweredEnum.itemGetterSymbol.owner.llvmFunction, - listOf(values, Int32(ordinal).llvm), + listOf(values, Int32(getterId).llvm), Lifetime.GLOBAL, exceptionHandler ) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt index 7d6edbed7c7..de4509da01f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/EnumClassLowering.kt @@ -101,10 +101,10 @@ internal class EnumUsageLowering(val context: Context) private fun IrBuilderWithScope.loadEnumEntry(enumClass: IrClass, name: Name): IrExpression { val loweredEnum = this@EnumUsageLowering.context.specialDeclarationsFactory.getLoweredEnum(enumClass) - val ordinal = loweredEnum.entriesMap.getValue(name) + val getterId = loweredEnum.entriesMap.getValue(name).getterId return irCall(loweredEnum.itemGetterSymbol, enumClass.defaultType).apply { dispatchReceiver = irCall(loweredEnum.valuesGetter) - putValueArgument(0, irInt(ordinal)) + putValueArgument(0, irInt(getterId)) } } }