remove unused code from IrLinker
diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/IrLinker.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/IrLinker.kt
index e649281..d9d8784 100644
--- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/IrLinker.kt
+++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/IrLinker.kt
@@ -1,12 +1,8 @@
package org.jetbrains.kotlin.backend.konan
-import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
-import org.jetbrains.kotlin.backend.common.extensions.IrPluginContextImpl
-import org.jetbrains.kotlin.backend.common.linkage.IrDeserializer
import org.jetbrains.kotlin.backend.common.linkage.issues.checkNoUnboundSymbols
import org.jetbrains.kotlin.backend.common.linkage.partial.createPartialLinkageSupportForLinker
import org.jetbrains.kotlin.backend.common.linkage.partial.partialLinkageConfig
-import org.jetbrains.kotlin.backend.common.overrides.FakeOverrideChecker
import org.jetbrains.kotlin.backend.common.serialization.DescriptorByIdSignatureFinderImpl
import org.jetbrains.kotlin.backend.common.serialization.IrModuleDeserializer
import org.jetbrains.kotlin.backend.konan.driver.phases.PsiToIrContext
@@ -21,21 +17,21 @@
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.declarations.DescriptorMetadataSource
+import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
import org.jetbrains.kotlin.ir.objcinterop.IrObjCOverridabilityCondition
-import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
-import org.jetbrains.kotlin.ir.util.IdSignature
+import org.jetbrains.kotlin.ir.util.ExternalDependenciesGenerator
import org.jetbrains.kotlin.library.KotlinLibrary
import org.jetbrains.kotlin.library.isHeader
import org.jetbrains.kotlin.library.metadata.DeserializedKlibModuleOrigin
import org.jetbrains.kotlin.library.metadata.KlibModuleOrigin
import org.jetbrains.kotlin.library.metadata.impl.isForwardDeclarationModule
import org.jetbrains.kotlin.library.uniqueName
-import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
import org.jetbrains.kotlin.psi2ir.descriptors.IrBuiltInsOverDescriptors
import org.jetbrains.kotlin.psi2ir.generators.DeclarationStubGeneratorImpl
+import org.jetbrains.kotlin.psi2ir.generators.ModuleGenerator
import org.jetbrains.kotlin.utils.DFS
@OptIn(ObsoleteDescriptorBasedAPI::class)
@@ -43,7 +39,8 @@
input: PsiToIrInput,
): PsiToIrOutput {
val symbolTable = symbolTable!!
- val (moduleDescriptor, environment, isProducingLibrary) = input
+ val (moduleDescriptor, _, isProducingLibrary) = input
+ require(!isProducingLibrary)
// Translate AST to high level IR.
val messageCollector = config.configuration.messageCollector
@@ -56,8 +53,6 @@
)
val generatorContext = translator.createGeneratorContext(moduleDescriptor, bindingContext, symbolTable)
- val pluginExtensions = IrGenerationExtension.getInstances(config.project)
-
val forwardDeclarationsModuleDescriptor = moduleDescriptor.allDependencyModules.firstOrNull { it.isForwardDeclarationModule }
val libraryToCache = config.libraryToCache
@@ -68,8 +63,6 @@
val stdlibIsCached = stdlibModule.konanLibrary?.let { config.cachedLibraries.isLibraryCached(it) } == true
val stdlibIsBeingCached = libraryToCacheModule == stdlibModule
require(!(stdlibIsCached && stdlibIsBeingCached)) { "The cache for stdlib is already built" }
- val kFunctionImplIsBeingCached = stdlibIsBeingCached && libraryToCache?.strategy.containsKFunctionImpl
- val shouldUseLazyFunctionClasses = (stdlibIsCached || stdlibIsBeingCached) && !kFunctionImplIsBeingCached
val stubGenerator = DeclarationStubGeneratorImpl(
moduleDescriptor, symbolTable,
@@ -79,10 +72,7 @@
)
val irBuiltInsOverDescriptors = generatorContext.irBuiltIns as IrBuiltInsOverDescriptors
val functionIrClassFactory: KonanIrAbstractDescriptorBasedFunctionFactory =
- if (shouldUseLazyFunctionClasses && config.lazyIrForCaches)
- LazyIrFunctionFactory(symbolTable, stubGenerator, irBuiltInsOverDescriptors, reflectionTypes)
- else
- BuiltInFictitiousFunctionIrClassFactory(symbolTable, irBuiltInsOverDescriptors, reflectionTypes)
+ BuiltInFictitiousFunctionIrClassFactory(symbolTable, irBuiltInsOverDescriptors, reflectionTypes)
irBuiltInsOverDescriptors.functionFactory = functionIrClassFactory
val symbols = KonanSymbols(
this,
@@ -90,167 +80,129 @@
this.config.configuration
)
- val irDeserializer = if (isProducingLibrary) {
- // Enable lazy IR generation for newly-created symbols inside BE
- stubGenerator.unboundSymbolGeneration = true
+ val exportedDependencies = (moduleDescriptor.getExportedDependencies(config) + libraryToCacheModule?.let { listOf(it) }.orEmpty()).distinct()
+ val irProviderForCEnumsAndCStructs =
+ IrProviderForCEnumAndCStructStubs(generatorContext, symbols)
+ val cInteropModuleDeserializerFactory = KonanCInteropModuleDeserializerFactory(
+ cachedLibraries = config.cachedLibraries,
+ cenumsProvider = irProviderForCEnumsAndCStructs,
+ stubGenerator = stubGenerator,
+ )
- object : IrDeserializer {
- override fun getDeclaration(symbol: IrSymbol) = functionIrClassFactory.getDeclaration(symbol)
- ?: stubGenerator.getDeclaration(symbol)
+ val friendModules = config.resolvedLibraries.getFullList()
+ .filter { it.libraryFile in config.friendModuleFiles }
+ .map { it.uniqueName }
- override fun resolveBySignatureInModule(signature: IdSignature, kind: IrDeserializer.TopLevelSymbolKind, moduleName: Name): IrSymbol {
- error("Should not be called")
- }
+ val friendModulesMap = (
+ listOf(moduleDescriptor.name.asStringStripSpecialMarkers()) +
+ config.resolve.includedLibraries.map { it.uniqueName }
+ ).associateWith { friendModules }
- override fun postProcess(inOrAfterLinkageStep: Boolean) = Unit
+ val linker = KonanIrLinker(
+ currentModule = moduleDescriptor,
+ messageCollector = messageCollector,
+ builtIns = generatorContext.irBuiltIns,
+ symbolTable = symbolTable,
+ friendModules = friendModulesMap,
+ forwardModuleDescriptor = forwardDeclarationsModuleDescriptor,
+ stubGenerator = stubGenerator,
+ cInteropModuleDeserializerFactory = cInteropModuleDeserializerFactory,
+ exportedDependencies = exportedDependencies,
+ partialLinkageSupport = createPartialLinkageSupportForLinker(
+ partialLinkageConfig = partialLinkageConfig,
+ builtIns = generatorContext.irBuiltIns,
+ messageCollector = messageCollector
+ ),
+ libraryBeingCached = config.libraryToCache,
+ userVisibleIrModulesSupport = config.userVisibleIrModulesSupport,
+ externalOverridabilityConditions = listOf(IrObjCOverridabilityCondition)
+ )
+ // context.config.librariesWithDependencies could change at each iteration.
+ var dependenciesCount = 0
+ while (true) {
+ // context.config.librariesWithDependencies could change at each iteration.
+ val libsWithDeps = config.librariesWithDependencies().toSet()
+ val dependencies = moduleDescriptor.allDependencyModules.filter {
+ libsWithDeps.contains(it.konanLibrary)
}
- } else {
- val exportedDependencies = (moduleDescriptor.getExportedDependencies(config) + libraryToCacheModule?.let { listOf(it) }.orEmpty()).distinct()
- val irProviderForCEnumsAndCStructs =
- IrProviderForCEnumAndCStructStubs(generatorContext, symbols)
- val cInteropModuleDeserializerFactory = KonanCInteropModuleDeserializerFactory(
- cachedLibraries = config.cachedLibraries,
- cenumsProvider = irProviderForCEnumsAndCStructs,
- stubGenerator = stubGenerator,
- )
- val friendModules = config.resolvedLibraries.getFullList()
- .filter { it.libraryFile in config.friendModuleFiles }
- .map { it.uniqueName }
-
- val friendModulesMap = (
- listOf(moduleDescriptor.name.asStringStripSpecialMarkers()) +
- config.resolve.includedLibraries.map { it.uniqueName }
- ).associateWith { friendModules }
-
- KonanIrLinker(
- currentModule = moduleDescriptor,
- messageCollector = messageCollector,
- builtIns = generatorContext.irBuiltIns,
- symbolTable = symbolTable,
- friendModules = friendModulesMap,
- forwardModuleDescriptor = forwardDeclarationsModuleDescriptor,
- stubGenerator = stubGenerator,
- cInteropModuleDeserializerFactory = cInteropModuleDeserializerFactory,
- exportedDependencies = exportedDependencies,
- partialLinkageSupport = createPartialLinkageSupportForLinker(
- partialLinkageConfig = partialLinkageConfig,
- builtIns = generatorContext.irBuiltIns,
- messageCollector = messageCollector
- ),
- libraryBeingCached = config.libraryToCache,
- userVisibleIrModulesSupport = config.userVisibleIrModulesSupport,
- externalOverridabilityConditions = listOf(IrObjCOverridabilityCondition)
- ).also { linker ->
-
- // context.config.librariesWithDependencies could change at each iteration.
- var dependenciesCount = 0
- while (true) {
- // context.config.librariesWithDependencies could change at each iteration.
- val libsWithDeps = config.librariesWithDependencies().toSet()
- val dependencies = moduleDescriptor.allDependencyModules.filter {
- libsWithDeps.contains(it.konanLibrary)
- }
-
- fun sortDependencies(dependencies: List<ModuleDescriptor>): Collection<ModuleDescriptor> {
- return DFS.topologicalOrder(dependencies) {
- it.allDependencyModules
- }.reversed()
- }
-
- for (dependency in sortDependencies(dependencies).filter { it != moduleDescriptor }) {
- val kotlinLibrary = (dependency.getCapability(KlibModuleOrigin.CAPABILITY) as? DeserializedKlibModuleOrigin)?.library
- val isFullyCachedLibrary = kotlinLibrary != null &&
- config.cachedLibraries.isLibraryCached(kotlinLibrary) && kotlinLibrary != config.libraryToCache?.klib
- if (isFullyCachedLibrary && kotlinLibrary?.isHeader == true)
- linker.deserializeHeadersWithInlineBodies(dependency, kotlinLibrary)
- else if (isProducingLibrary || isFullyCachedLibrary)
- linker.deserializeOnlyHeaderModule(dependency, kotlinLibrary)
- else
- linker.deserializeIrModuleHeader(dependency, kotlinLibrary, dependency.name.asString())
- }
- if (dependencies.size == dependenciesCount) break
- dependenciesCount = dependencies.size
- }
-
- // We need to run `buildAllEnumsAndStructsFrom` before `generateModuleFragment` because it adds references to symbolTable
- // that should be bound.
- if (libraryToCacheModule?.isFromCInteropLibrary() == true)
- irProviderForCEnumsAndCStructs.referenceAllEnumsAndStructsFrom(libraryToCacheModule)
-
- translator.addPostprocessingStep {
- irProviderForCEnumsAndCStructs.generateBodies()
- }
+ fun sortDependencies(dependencies: List<ModuleDescriptor>): Collection<ModuleDescriptor> {
+ return DFS.topologicalOrder(dependencies) {
+ it.allDependencyModules
+ }.reversed()
}
+
+ for (dependency in sortDependencies(dependencies).filter { it != moduleDescriptor }) {
+ val kotlinLibrary = (dependency.getCapability(KlibModuleOrigin.CAPABILITY) as? DeserializedKlibModuleOrigin)?.library
+ val isFullyCachedLibrary = kotlinLibrary != null &&
+ config.cachedLibraries.isLibraryCached(kotlinLibrary) && kotlinLibrary != config.libraryToCache?.klib
+ if (isFullyCachedLibrary && kotlinLibrary.isHeader)
+ linker.deserializeHeadersWithInlineBodies(dependency, kotlinLibrary)
+ else if (isFullyCachedLibrary)
+ linker.deserializeOnlyHeaderModule(dependency, kotlinLibrary)
+ else
+ linker.deserializeIrModuleHeader(dependency, kotlinLibrary, dependency.name.asString())
+ }
+ if (dependencies.size == dependenciesCount) break
+ dependenciesCount = dependencies.size
}
- translator.addPostprocessingStep { module ->
- val pluginContext = IrPluginContextImpl(
- generatorContext.moduleDescriptor,
- generatorContext.bindingContext,
- generatorContext.languageVersionSettings,
- generatorContext.symbolTable,
- generatorContext.typeTranslator,
- generatorContext.irBuiltIns,
- linker = irDeserializer,
- messageCollector = messageCollector
- )
- pluginExtensions.forEach { extension ->
- extension.generate(module, pluginContext)
- }
+ // We need to run `buildAllEnumsAndStructsFrom` before `generateModuleFragment` because it adds references to symbolTable
+ // that should be bound.
+ if (libraryToCacheModule?.isFromCInteropLibrary() == true)
+ irProviderForCEnumsAndCStructs.referenceAllEnumsAndStructsFrom(libraryToCacheModule)
+
+ val irProviders = listOf(linker)
+ val moduleGenerator = ModuleGenerator(generatorContext)
+ val irModule = IrModuleFragmentImpl(moduleGenerator.context.moduleDescriptor)
+ linker.init(irModule)
+ ExternalDependenciesGenerator(moduleGenerator.context.symbolTable, irProviders).generateUnboundSymbolsAsDependencies()
+ linker.postProcess(inOrAfterLinkageStep = true)
+ if (!partialLinkageConfig.isEnabled) {
+ messageCollector.checkNoUnboundSymbols(symbolTable, "after generation of IR module ${irModule.name.asString()}")
}
+ irProviderForCEnumsAndCStructs.generateBodies()
+ val mainModule = irModule
- val mainModule = translator.generateModuleFragment(generatorContext, environment.getSourceFiles(), listOf(irDeserializer))
-
- irDeserializer.postProcess(inOrAfterLinkageStep = true)
+ linker.postProcess(inOrAfterLinkageStep = true)
// Enable lazy IR genration for newly-created symbols inside BE
stubGenerator.unboundSymbolGeneration = true
messageCollector.checkNoUnboundSymbols(symbolTable, "at the end of IR linkage process")
- val modules = if (isProducingLibrary) emptyMap() else (irDeserializer as KonanIrLinker).modules
-
- if (config.configuration.getBoolean(KonanConfigKeys.FAKE_OVERRIDE_VALIDATOR)) {
- val fakeOverrideChecker = FakeOverrideChecker(KonanManglerIr, KonanManglerDesc)
- modules.values.forEach { fakeOverrideChecker.check(it) }
- }
+ val modules = linker.modules
// 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.
// 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.
modules.values.forEach { module -> module.files.sortBy { it.fileEntry.name } }
- if (!isProducingLibrary) {
- // TODO: find out what should be done in the new builtins/symbols about it
- if (stdlibIsBeingCached) {
- (functionIrClassFactory as? BuiltInFictitiousFunctionIrClassFactory)?.buildAllClasses()
- }
- (functionIrClassFactory as? BuiltInFictitiousFunctionIrClassFactory)?.module =
- (modules.values + mainModule).single { it.descriptor == this.stdlibModule }
+ // TODO: find out what should be done in the new builtins/symbols about it
+ if (stdlibIsBeingCached) {
+ (functionIrClassFactory as? BuiltInFictitiousFunctionIrClassFactory)?.buildAllClasses()
}
+ (functionIrClassFactory as? BuiltInFictitiousFunctionIrClassFactory)?.module =
+ (modules.values + mainModule).single { it.descriptor == this.stdlibModule }
mainModule.files.forEach { it.metadata = DescriptorMetadataSource.File(listOf(mainModule.descriptor)) }
modules.values.forEach { module ->
module.files.forEach { it.metadata = DescriptorMetadataSource.File(listOf(module.descriptor)) }
}
- return if (isProducingLibrary) {
- PsiToIrOutput.ForKlib(mainModule, generatorContext.irBuiltIns, symbols)
- } else if (libraryToCache == null) {
- PsiToIrOutput.ForBackend(modules, mainModule, generatorContext.irBuiltIns, symbols, symbolTable, irDeserializer as KonanIrLinker)
- } else {
- val libraryName = libraryToCache.klib.libraryName
- val libraryModule = modules[libraryName] ?: error("No module for the library being cached: $libraryName")
- PsiToIrOutput.ForBackend(
- irModules = modules.filterKeys { it != libraryName },
- irModule = libraryModule,
- irBuiltIns = generatorContext.irBuiltIns,
- symbols = symbols,
- symbolTable = symbolTable,
- irLinker = irDeserializer as KonanIrLinker
- )
- }
+ val libraryName = libraryToCache?.klib?.libraryName
+ return PsiToIrOutput.ForBackend(
+ irModules = modules.filterKeys { it != libraryName },
+ irModule = if (libraryName == null) {
+ mainModule
+ } else {
+ modules[libraryName] ?: error("No module for the library being cached: $libraryName")
+ },
+ irBuiltIns = generatorContext.irBuiltIns,
+ symbols = symbols,
+ symbolTable = symbolTable,
+ irLinker = linker
+ )
}
internal class KonanCInteropModuleDeserializerFactory(