[K/N] Untie PsiToIr phase from Context

This commit is contained in:
Sergey Bogolepov
2022-11-29 16:08:39 +02:00
committed by Space Team
parent 182662f7ed
commit b828672a2e
11 changed files with 181 additions and 51 deletions
@@ -5,10 +5,14 @@
package org.jetbrains.kotlin.backend.konan package org.jetbrains.kotlin.backend.konan
import llvm.* import llvm.LLVMArrayType
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import llvm.LLVMConstInt
import org.jetbrains.kotlin.backend.konan.llvm.* import llvm.LLVMTypeRef
import org.jetbrains.kotlin.backend.common.getOrPut import org.jetbrains.kotlin.backend.common.getOrPut
import org.jetbrains.kotlin.backend.konan.llvm.ConstValue
import org.jetbrains.kotlin.backend.konan.llvm.StaticData
import org.jetbrains.kotlin.backend.konan.llvm.constValue
import org.jetbrains.kotlin.backend.konan.llvm.toLLVMType
import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter import org.jetbrains.kotlin.ir.builders.declarations.addValueParameter
import org.jetbrains.kotlin.ir.builders.declarations.buildFun import org.jetbrains.kotlin.ir.builders.declarations.buildFun
@@ -23,10 +27,11 @@ import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
import org.jetbrains.kotlin.konan.target.KonanTarget import org.jetbrains.kotlin.konan.target.KonanTarget
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
internal fun KonanSymbols.getTypeConversion(actualType: IrType, expectedType: IrType): IrSimpleFunctionSymbol? = // TODO: Find a better home for this function than Context.
internal fun Context.getTypeConversion(actualType: IrType, expectedType: IrType): IrSimpleFunctionSymbol? =
getTypeConversionImpl(actualType.getInlinedClassNative(), expectedType.getInlinedClassNative()) getTypeConversionImpl(actualType.getInlinedClassNative(), expectedType.getInlinedClassNative())
private fun KonanSymbols.getTypeConversionImpl( private fun Context.getTypeConversionImpl(
actualInlinedClass: IrClass?, actualInlinedClass: IrClass?,
expectedInlinedClass: IrClass? expectedInlinedClass: IrClass?
): IrSimpleFunctionSymbol? { ): IrSimpleFunctionSymbol? {
@@ -34,8 +39,8 @@ private fun KonanSymbols.getTypeConversionImpl(
return when { return when {
actualInlinedClass == null && expectedInlinedClass == null -> null actualInlinedClass == null && expectedInlinedClass == null -> null
actualInlinedClass != null && expectedInlinedClass == null -> context.getBoxFunction(actualInlinedClass) actualInlinedClass != null && expectedInlinedClass == null -> getBoxFunction(actualInlinedClass)
actualInlinedClass == null && expectedInlinedClass != null -> context.getUnboxFunction(expectedInlinedClass) actualInlinedClass == null && expectedInlinedClass != null -> getUnboxFunction(expectedInlinedClass)
else -> error("actual type is ${actualInlinedClass?.fqNameForIrSerialization}, expected ${expectedInlinedClass?.fqNameForIrSerialization}") else -> error("actual type is ${actualInlinedClass?.fqNameForIrSerialization}, expected ${expectedInlinedClass?.fqNameForIrSerialization}")
}?.symbol }?.symbol
} }
@@ -12,11 +12,12 @@ import org.jetbrains.kotlin.backend.common.LoggingContext
import org.jetbrains.kotlin.backend.konan.descriptors.BridgeDirections import org.jetbrains.kotlin.backend.konan.descriptors.BridgeDirections
import org.jetbrains.kotlin.backend.konan.descriptors.ClassLayoutBuilder import org.jetbrains.kotlin.backend.konan.descriptors.ClassLayoutBuilder
import org.jetbrains.kotlin.backend.konan.descriptors.GlobalHierarchyAnalysisResult import org.jetbrains.kotlin.backend.konan.descriptors.GlobalHierarchyAnalysisResult
import org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrContext
import org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrOutput
import org.jetbrains.kotlin.backend.konan.ir.KonanIr import org.jetbrains.kotlin.backend.konan.ir.KonanIr
import org.jetbrains.kotlin.backend.konan.llvm.CodegenClassMetadata import org.jetbrains.kotlin.backend.konan.llvm.CodegenClassMetadata
import org.jetbrains.kotlin.backend.konan.llvm.Lifetime import org.jetbrains.kotlin.backend.konan.llvm.Lifetime
import org.jetbrains.kotlin.backend.konan.lower.* import org.jetbrains.kotlin.backend.konan.lower.*
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportCodeSpec import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportCodeSpec
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportedInterface import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExportedInterface
import org.jetbrains.kotlin.backend.konan.optimizations.DevirtualizationAnalysis import org.jetbrains.kotlin.backend.konan.optimizations.DevirtualizationAnalysis
@@ -66,13 +67,27 @@ internal class Context(
config: KonanConfig, config: KonanConfig,
val environment: KotlinCoreEnvironment, val environment: KotlinCoreEnvironment,
val frontendServices: FrontendServices, val frontendServices: FrontendServices,
var bindingContext: BindingContext, override var bindingContext: BindingContext,
val moduleDescriptor: ModuleDescriptor, val moduleDescriptor: ModuleDescriptor,
) : KonanBackendContext(config), ConfigChecks { ) : KonanBackendContext(config), PsiToIrContext {
fun populateAfterPsiToIr(
psiToIrOutput: PsiToIrOutput
) {
irModules = psiToIrOutput.irModules
irModule = psiToIrOutput.irModule
expectDescriptorToSymbol = psiToIrOutput.expectDescriptorToSymbol
ir = KonanIr(this, psiToIrOutput.irModule)
ir.symbols = psiToIrOutput.symbols
if (psiToIrOutput.irLinker is KonanIrLinker) {
irLinker = psiToIrOutput.irLinker
}
}
/** /**
* Valid from [createSymbolTablePhase] until [destroySymbolTablePhase]. * Valid from [createSymbolTablePhase] until [destroySymbolTablePhase].
*/ */
var symbolTable: SymbolTable? = null override var symbolTable: SymbolTable? = null
lateinit var cAdapterGenerator: CAdapterGenerator lateinit var cAdapterGenerator: CAdapterGenerator
@@ -102,7 +117,7 @@ internal class Context(
val enumsSupport by lazy { EnumsSupport(mapping, irBuiltIns, irFactory) } val enumsSupport by lazy { EnumsSupport(mapping, irBuiltIns, irFactory) }
val cachesAbiSupport by lazy { CachesAbiSupport(mapping, irFactory) } val cachesAbiSupport by lazy { CachesAbiSupport(mapping, irFactory) }
val reflectionTypes: KonanReflectionTypes by lazy(PUBLICATION) { override val reflectionTypes: KonanReflectionTypes by lazy(PUBLICATION) {
KonanReflectionTypes(moduleDescriptor) KonanReflectionTypes(moduleDescriptor)
} }
@@ -162,7 +177,7 @@ internal class Context(
override val typeSystem: IrTypeSystemContext override val typeSystem: IrTypeSystemContext
get() = IrTypeSystemContextImpl(irBuiltIns) get() = IrTypeSystemContextImpl(irBuiltIns)
val interopBuiltIns by lazy { override val interopBuiltIns by lazy {
InteropBuiltIns(this.builtIns) InteropBuiltIns(this.builtIns)
} }
@@ -202,7 +217,7 @@ internal class Context(
var referencedFunctions: Set<IrFunction>? = null var referencedFunctions: Set<IrFunction>? = null
internal val stdlibModule override val stdlibModule
get() = this.builtIns.any.module get() = this.builtIns.any.module
val declaredLocalArrays: MutableMap<String, LLVMTypeRef> = HashMap() val declaredLocalArrays: MutableMap<String, LLVMTypeRef> = HashMap()
@@ -222,6 +237,8 @@ internal class Context(
} }
} }
} }
override fun dispose() {}
} }
internal class ContextLogger(val context: LoggingContext) { internal class ContextLogger(val context: LoggingContext) {
@@ -9,12 +9,16 @@ import org.jetbrains.kotlin.backend.common.serialization.mangle.ManglerChecker
import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter import org.jetbrains.kotlin.backend.common.serialization.mangle.descriptor.Ir2DescriptorManglerAdapter
import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule
import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
import org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrContext
import org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrInput
import org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrOutput
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs import org.jetbrains.kotlin.backend.konan.ir.interop.IrProviderForCEnumAndCStructStubs
import org.jetbrains.kotlin.backend.konan.ir.konanLibrary import org.jetbrains.kotlin.backend.konan.ir.konanLibrary
import org.jetbrains.kotlin.backend.konan.serialization.* import org.jetbrains.kotlin.backend.konan.serialization.*
import org.jetbrains.kotlin.config.CommonConfigurationKeys import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor
import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin
@@ -31,8 +35,6 @@ import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.CleanableBindingContext
import org.jetbrains.kotlin.utils.DFS import org.jetbrains.kotlin.utils.DFS
object KonanStubGeneratorExtensions : StubGeneratorExtensions() { object KonanStubGeneratorExtensions : StubGeneratorExtensions() {
@@ -41,11 +43,12 @@ object KonanStubGeneratorExtensions : StubGeneratorExtensions() {
} }
} }
internal fun Context.psiToIr( internal fun PsiToIrContext.psiToIr(
symbolTable: SymbolTable, input: PsiToIrInput,
isProducingLibrary: Boolean,
useLinkerWhenProducingLibrary: Boolean useLinkerWhenProducingLibrary: Boolean
) { ): PsiToIrOutput {
val symbolTable = symbolTable!!
val (moduleDescriptor, environment, isProducingLibrary) = input
// Translate AST to high level IR. // Translate AST to high level IR.
val expectActualLinker = config.configuration[CommonConfigurationKeys.EXPECT_ACTUAL_LINKER] ?: false val expectActualLinker = config.configuration[CommonConfigurationKeys.EXPECT_ACTUAL_LINKER] ?: false
val messageLogger = config.configuration[IrMessageLogger.IR_MESSAGE_LOGGER] ?: IrMessageLogger.None val messageLogger = config.configuration[IrMessageLogger.IR_MESSAGE_LOGGER] ?: IrMessageLogger.None
@@ -102,7 +105,7 @@ internal fun Context.psiToIr(
} }
} }
} else { } else {
val exportedDependencies = (getExportedDependencies() + libraryToCacheModule?.let { listOf(it) }.orEmpty()).distinct() val exportedDependencies = (moduleDescriptor.getExportedDependencies(config) + libraryToCacheModule?.let { listOf(it) }.orEmpty()).distinct()
val irProviderForCEnumsAndCStructs = val irProviderForCEnumsAndCStructs =
IrProviderForCEnumAndCStructStubs(generatorContext, interopBuiltIns, symbols) IrProviderForCEnumAndCStructStubs(generatorContext, interopBuiltIns, symbols)
@@ -200,7 +203,7 @@ internal fun Context.psiToIr(
} }
} }
expectDescriptorToSymbol = mutableMapOf() val expectDescriptorToSymbol = mutableMapOf<DeclarationDescriptor, IrSymbol>()
val mainModule = translator.generateModuleFragment( val mainModule = translator.generateModuleFragment(
generatorContext, generatorContext,
environment.getSourceFiles(), environment.getSourceFiles(),
@@ -228,20 +231,11 @@ internal fun Context.psiToIr(
val fakeOverrideChecker = FakeOverrideChecker(KonanManglerIr, KonanManglerDesc) val fakeOverrideChecker = FakeOverrideChecker(KonanManglerIr, KonanManglerDesc)
modules.values.forEach { fakeOverrideChecker.check(it) } modules.values.forEach { fakeOverrideChecker.check(it) }
} }
irModule = mainModule
irModules = modules
// IR linker deserializes files in the order they lie on the disk, which might be inconvenient, // IR linker deserializes files in the order they lie on the disk, which might be inconvenient,
// so to make the pipeline more deterministic, the files are to be sorted. // so to make the pipeline more deterministic, the files are to be sorted.
// This concerns in the first place global initializers order for the eager initialization strategy, // This concerns in the first place global initializers order for the eager initialization strategy,
// where the files are being initialized in order one by one. // where the files are being initialized in order one by one.
irModules.values.forEach { module -> module.files.sortBy { it.fileEntry.name } } modules.values.forEach { module -> module.files.sortBy { it.fileEntry.name } }
if (!isProducingLibrary)
irLinker = irDeserializer as KonanIrLinker
ir.symbols = symbols
if (!isProducingLibrary) { if (!isProducingLibrary) {
// TODO: find out what should be done in the new builtins/symbols about it // TODO: find out what should be done in the new builtins/symbols about it
@@ -249,7 +243,7 @@ internal fun Context.psiToIr(
(functionIrClassFactory as? BuiltInFictitiousFunctionIrClassFactory)?.buildAllClasses() (functionIrClassFactory as? BuiltInFictitiousFunctionIrClassFactory)?.buildAllClasses()
} }
(functionIrClassFactory as? BuiltInFictitiousFunctionIrClassFactory)?.module = (functionIrClassFactory as? BuiltInFictitiousFunctionIrClassFactory)?.module =
(modules.values + irModule!!).single { it.descriptor == this.stdlibModule } (modules.values + mainModule).single { it.descriptor == this.stdlibModule }
} }
mainModule.files.forEach { it.metadata = KonanFileMetadataSource(mainModule) } mainModule.files.forEach { it.metadata = KonanFileMetadataSource(mainModule) }
@@ -257,9 +251,11 @@ internal fun Context.psiToIr(
module.files.forEach { it.metadata = KonanFileMetadataSource(module as KonanIrModuleFragmentImpl) } module.files.forEach { it.metadata = KonanFileMetadataSource(module as KonanIrModuleFragmentImpl) }
} }
val originalBindingContext = bindingContext as? CleanableBindingContext return PsiToIrOutput(
?: error("BindingContext should be cleanable in K/N IR to avoid leaking memory: $bindingContext") modules,
originalBindingContext.clear() mainModule,
expectDescriptorToSymbol,
this.bindingContext = BindingContext.EMPTY symbols,
if (isProducingLibrary) null else irDeserializer as KonanIrLinker
)
} }
@@ -12,6 +12,7 @@ import org.jetbrains.kotlin.backend.common.phaser.*
import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMonolithicSerializer import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMonolithicSerializer
import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary
import org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrInput
import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.llvm.*
import org.jetbrains.kotlin.backend.konan.lower.CacheInfoBuilder import org.jetbrains.kotlin.backend.konan.lower.CacheInfoBuilder
import org.jetbrains.kotlin.backend.konan.lower.ExpectToActualDefaultValueCopier import org.jetbrains.kotlin.backend.konan.lower.ExpectToActualDefaultValueCopier
@@ -30,6 +31,8 @@ import org.jetbrains.kotlin.ir.declarations.path
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.name.FqName import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.CleanableBindingContext
internal fun moduleValidationCallback(state: ActionState, module: IrModuleFragment, context: Context) { internal fun moduleValidationCallback(state: ActionState, module: IrModuleFragment, context: Context) {
if (!context.config.needVerifyIr) return if (!context.config.needVerifyIr) return
@@ -111,9 +114,13 @@ internal val buildCExportsPhase = konanUnitPhase(
internal val psiToIrPhase = konanUnitPhase( internal val psiToIrPhase = konanUnitPhase(
op = { op = {
this.psiToIr(symbolTable!!, val input = PsiToIrInput(moduleDescriptor, environment, isProducingLibrary = config.produce == CompilerOutputKind.LIBRARY)
isProducingLibrary = config.produce == CompilerOutputKind.LIBRARY, val psiToIrOutput = this.psiToIr(input, useLinkerWhenProducingLibrary = false)
useLinkerWhenProducingLibrary = false) this.populateAfterPsiToIr(psiToIrOutput)
val originalBindingContext = bindingContext as? CleanableBindingContext
?: error("BindingContext should be cleanable in K/N IR to avoid leaking memory: $bindingContext")
originalBindingContext.clear()
this.bindingContext = BindingContext.EMPTY
}, },
name = "Psi2Ir", name = "Psi2Ir",
description = "Psi to IR conversion and klib linkage", description = "Psi to IR conversion and klib linkage",
@@ -0,0 +1,102 @@
/*
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.konan.driver.phases
import org.jetbrains.kotlin.backend.konan.InteropBuiltIns
import org.jetbrains.kotlin.backend.konan.KonanConfig
import org.jetbrains.kotlin.backend.konan.KonanReflectionTypes
import org.jetbrains.kotlin.backend.konan.driver.BasicPhaseContext
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.backend.konan.driver.PhaseEngine
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
import org.jetbrains.kotlin.backend.konan.psiToIr
import org.jetbrains.kotlin.backend.konan.serialization.KonanIdSignaturer
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrLinker
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc
import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.CleanableBindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.module
data class PsiToIrInput(
val moduleDescriptor: ModuleDescriptor,
val environment: KotlinCoreEnvironment,
val isProducingLibrary: Boolean,
)
// TODO: Possible improvement: a separate class for klib output (without irModules and irLinker).
internal class PsiToIrOutput(
val irModules: Map<String, IrModuleFragment>,
val irModule: IrModuleFragment,
val expectDescriptorToSymbol: MutableMap<DeclarationDescriptor, IrSymbol>,
val symbols: KonanSymbols,
val irLinker: KonanIrLinker?,
)
// TODO: Consider component-based approach
internal interface PsiToIrContext : PhaseContext {
val symbolTable: SymbolTable?
val reflectionTypes: KonanReflectionTypes
val builtIns: KonanBuiltIns
val interopBuiltIns: InteropBuiltIns
val bindingContext: BindingContext
val stdlibModule: ModuleDescriptor
get() = this.builtIns.any.module
}
internal class PsiToIrContextImpl(
config: KonanConfig,
private val moduleDescriptor: ModuleDescriptor,
override val bindingContext: BindingContext,
) : BasicPhaseContext(config), PsiToIrContext {
// TODO: Invalidate properly in dispose method.
override val symbolTable = SymbolTable(KonanIdSignaturer(KonanManglerDesc), IrFactoryImpl)
override val reflectionTypes: KonanReflectionTypes by lazy(LazyThreadSafetyMode.PUBLICATION) {
KonanReflectionTypes(moduleDescriptor)
}
override val builtIns: KonanBuiltIns by lazy(LazyThreadSafetyMode.PUBLICATION) {
moduleDescriptor.builtIns as KonanBuiltIns
}
override val interopBuiltIns by lazy {
InteropBuiltIns(this.builtIns)
}
override fun dispose() {
val originalBindingContext = bindingContext as? CleanableBindingContext
?: error("BindingContext should be cleanable in K/N IR to avoid leaking memory: $bindingContext")
originalBindingContext.clear()
}
}
internal val PsiToIrPhase = createSimpleNamedCompilerPhase<PsiToIrContext, PsiToIrInput, PsiToIrOutput>(
"PsiToIr", "Translate PSI to IR",
outputIfNotEnabled = { _, _, _, _ -> error("PsiToIr phase cannot be disabled") }
) { context, input ->
context.psiToIr(input, useLinkerWhenProducingLibrary = false)
}
internal fun <T : PsiToIrContext> PhaseEngine<T>.runPsiToIr(
frontendResult: FrontendPhaseOutput.Full,
isProducingLibrary: Boolean
): PsiToIrOutput {
val psiToIrInput = PsiToIrInput(frontendResult.moduleDescriptor, frontendResult.environment, isProducingLibrary)
return this.runPhase(PsiToIrPhase, psiToIrInput)
}
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.COROUTINE_SUSPENDED_NAME
import org.jetbrains.kotlin.backend.common.ir.Ir import org.jetbrains.kotlin.backend.common.ir.Ir
import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.common.ir.Symbols
import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.backend.konan.llvm.findMainEntryPoint import org.jetbrains.kotlin.backend.konan.llvm.findMainEntryPoint
import org.jetbrains.kotlin.backend.konan.lower.TestProcessor import org.jetbrains.kotlin.backend.konan.lower.TestProcessor
import org.jetbrains.kotlin.builtins.StandardNames import org.jetbrains.kotlin.builtins.StandardNames
@@ -40,14 +41,14 @@ internal class KonanIr(context: Context, irModule: IrModuleFragment): Ir<Context
} }
internal class KonanSymbols( internal class KonanSymbols(
val context: Context, context: PhaseContext,
private val descriptorsLookup: DescriptorsLookup, descriptorsLookup: DescriptorsLookup,
irBuiltIns: IrBuiltIns, irBuiltIns: IrBuiltIns,
private val symbolTable: SymbolTable, private val symbolTable: SymbolTable,
lazySymbolTable: ReferenceSymbolTable lazySymbolTable: ReferenceSymbolTable
): Symbols(irBuiltIns, symbolTable) { ): Symbols(irBuiltIns, symbolTable) {
val entryPoint = findMainEntryPoint(context)?.let { symbolTable.referenceSimpleFunction(it) } val entryPoint = findMainEntryPoint(context, descriptorsLookup.builtIns)?.let { symbolTable.referenceSimpleFunction(it) }
override val externalSymbolTable = lazySymbolTable override val externalSymbolTable = lazySymbolTable
@@ -7,6 +7,8 @@ package org.jetbrains.kotlin.backend.konan.llvm
import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.descriptors.isArray import org.jetbrains.kotlin.backend.konan.descriptors.isArray
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
import org.jetbrains.kotlin.config.CompilerConfiguration import org.jetbrains.kotlin.config.CompilerConfiguration
import org.jetbrains.kotlin.descriptors.ClassDescriptor import org.jetbrains.kotlin.descriptors.ClassDescriptor
import org.jetbrains.kotlin.descriptors.FunctionDescriptor import org.jetbrains.kotlin.descriptors.FunctionDescriptor
@@ -17,7 +19,7 @@ import org.jetbrains.kotlin.resolve.descriptorUtil.fqNameSafe
import org.jetbrains.kotlin.types.KotlinType import org.jetbrains.kotlin.types.KotlinType
import org.jetbrains.kotlin.types.typeUtil.isUnit import org.jetbrains.kotlin.types.typeUtil.isUnit
internal fun findMainEntryPoint(context: Context): FunctionDescriptor? { internal fun findMainEntryPoint(context: PhaseContext, builtIns: KotlinBuiltIns): FunctionDescriptor? {
val config = context.config.configuration val config = context.config.configuration
if (config.get(KonanConfigKeys.PRODUCE) != PROGRAM) return null if (config.get(KonanConfigKeys.PRODUCE) != PROGRAM) return null
@@ -27,7 +29,7 @@ internal fun findMainEntryPoint(context: Context): FunctionDescriptor? {
val entryName = entryPoint.shortName() val entryName = entryPoint.shortName()
val packageName = entryPoint.parent() val packageName = entryPoint.parent()
val packageScope = context.builtIns.builtInsModule.getPackage(packageName).memberScope val packageScope = builtIns.builtInsModule.getPackage(packageName).memberScope
val candidates = packageScope.getContributedFunctions(entryName, val candidates = packageScope.getContributedFunctions(entryName,
NoLookupLocation.FROM_BACKEND).filter { NoLookupLocation.FROM_BACKEND).filter {
@@ -1816,7 +1816,7 @@ internal class CodeGeneratorVisitor(val generationState: NativeGenerationState,
return when (value) { return when (value) {
is IrConstantPrimitive -> { is IrConstantPrimitive -> {
val constructedType = value.value.type val constructedType = value.value.type
if (context.ir.symbols.getTypeConversion(constructedType, value.type) != null) { if (context.getTypeConversion(constructedType, value.type) != null) {
if (value.value.kind == IrConstKind.Null) { if (value.value.kind == IrConstKind.Null) {
Zero(value.type.toLLVMType(llvm)) Zero(value.type.toLLVMType(llvm))
} else { } else {
@@ -1846,7 +1846,7 @@ internal class CodeGeneratorVisitor(val generationState: NativeGenerationState,
val constructedType = value.constructor.owner.constructedClassType val constructedType = value.constructor.owner.constructedClassType
val constructedClass = constructedType.getClass()!! val constructedClass = constructedType.getClass()!!
val needUnBoxing = constructedType.getInlinedClassNative() != null && val needUnBoxing = constructedType.getInlinedClassNative() != null &&
context.ir.symbols.getTypeConversion(constructedType, value.type) == null context.getTypeConversion(constructedType, value.type) == null
if (needUnBoxing) { if (needUnBoxing) {
val unboxed = value.valueArguments.singleOrNull() val unboxed = value.valueArguments.singleOrNull()
?: error("Inlined class should have exactly one constructor argument") ?: error("Inlined class should have exactly one constructor argument")
@@ -408,7 +408,7 @@ internal class ObjCExportCodeGenerator(
resultLifetime: Lifetime resultLifetime: Lifetime
): LLVMValueRef { ): LLVMValueRef {
val conversion = symbols.getTypeConversion(actualType, expectedType) val conversion = context.getTypeConversion(actualType, expectedType)
?: return genValue(resultLifetime) ?: return genValue(resultLifetime)
val value = genValue(Lifetime.ARGUMENT) val value = genValue(Lifetime.ARGUMENT)
@@ -134,7 +134,7 @@ private class AutoboxingTransformer(val context: Context) : AbstractValueUsageTr
} }
private fun IrExpression.adaptIfNecessary(actualType: IrType, expectedType: IrType): IrExpression { private fun IrExpression.adaptIfNecessary(actualType: IrType, expectedType: IrType): IrExpression {
val conversion = symbols.getTypeConversion(actualType, expectedType) val conversion = context.getTypeConversion(actualType, expectedType)
return if (conversion == null) { return if (conversion == null) {
this this
} else { } else {
@@ -1472,7 +1472,7 @@ internal object DevirtualizationAnalysis {
}) })
} }
// Insert proper unboxing (unreachable code): // Insert proper unboxing (unreachable code):
+irCoerce(throwExpr, symbols.getTypeConversion(throwExpr.type, type)) +irCoerce(throwExpr, context.getTypeConversion(throwExpr.type, type))
} }
optimize && possibleCallees.size == 1 -> { // Monomorphic callsite. optimize && possibleCallees.size == 1 -> { // Monomorphic callsite.