From f8b8cbb9f23189b9a38fec6f8d4b0b46b618dea3 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Fri, 14 Oct 2022 22:14:31 +0300 Subject: [PATCH] [K/N] Moved llvmModuleSpecification from context to generation state --- .../jetbrains/kotlin/backend/konan/Boxing.kt | 2 +- .../kotlin/backend/konan/CacheSupport.kt | 6 +-- .../kotlin/backend/konan/CompilerOutput.kt | 21 +++++----- .../jetbrains/kotlin/backend/konan/Context.kt | 8 ---- .../kotlin/backend/konan/EntryPoint.kt | 4 +- .../jetbrains/kotlin/backend/konan/Linker.kt | 2 +- .../konan/LlvmModuleSpecificationImpl.kt | 4 +- .../backend/konan/NativeGenerationState.kt | 15 +++++-- .../backend/konan/OptimizationPipeline.kt | 2 +- .../jetbrains/kotlin/backend/konan/PsiToIr.kt | 32 ++++++++------- .../kotlin/backend/konan/ToplevelPhases.kt | 40 ++++++++++--------- .../kotlin/backend/konan/llvm/ContextUtils.kt | 6 +-- .../kotlin/backend/konan/llvm/IrToBitcode.kt | 6 +-- .../backend/konan/llvm/LlvmDeclarations.kt | 4 +- .../objcexport/ObjCExportCodeGenerator.kt | 16 ++++---- .../backend/konan/lower/CachesAbiLowering.kt | 2 +- .../lower/NativeInlineFunctionResolver.kt | 2 +- .../backend/konan/objcexport/ObjCExport.kt | 2 +- 18 files changed, 89 insertions(+), 85 deletions(-) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt index 9f4080de247..4d152599cb3 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Boxing.kt @@ -173,7 +173,7 @@ internal fun initializeCachedBoxes(context: Context) { val rangeStart = "${cache.name}_RANGE_FROM" val rangeEnd = "${cache.name}_RANGE_TO" initCache(cache, context, cacheName, rangeStart, rangeEnd, - declareOnly = !context.shouldDefineCachedBoxes + declareOnly = !context.generationState.shouldDefineCachedBoxes ).also { context.generationState.llvm.boxCacheGlobals[cache] = it } } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CacheSupport.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CacheSupport.kt index e93004bc1a4..47ac4e24192 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CacheSupport.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CacheSupport.kt @@ -52,7 +52,7 @@ sealed class CacheDeserializationStrategy { } } -class PartialCacheInfo(val klib: KotlinLibrary, var strategy: CacheDeserializationStrategy) +class PartialCacheInfo(val klib: KotlinLibrary, val strategy: CacheDeserializationStrategy) class CacheSupport( private val configuration: CompilerConfiguration, @@ -72,11 +72,11 @@ class CacheSupport( ?: configuration.reportCompilationError("cache directory $it is not found or not a directory") } - internal fun tryGetImplicitOutput(): String? { + internal fun tryGetImplicitOutput(cacheDeserializationStrategy: CacheDeserializationStrategy?): String? { val libraryToCache = libraryToCache ?: return null // Put the resulting library in the first cache directory. val cacheDirectory = implicitCacheDirectories.firstOrNull() ?: return null - val singleFileStrategy = libraryToCache.strategy as? CacheDeserializationStrategy.SingleFile + val singleFileStrategy = cacheDeserializationStrategy as? CacheDeserializationStrategy.SingleFile val baseLibraryCacheDirectory = cacheDirectory.child( if (singleFileStrategy == null) CachedLibraries.getCachedLibraryName(libraryToCache.klib) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt index 267e08907cd..4815eda6181 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt @@ -43,20 +43,19 @@ val CompilerOutputKind.isNativeLibrary: Boolean val CompilerOutputKind.involvesBitcodeGeneration: Boolean get() = this != CompilerOutputKind.LIBRARY -internal val Context.producedLlvmModuleContainsStdlib: Boolean - get() = this.llvmModuleSpecification.containsModule(this.stdlibModule) +internal val CacheDeserializationStrategy?.containsKFunctionImpl: Boolean + get() = this?.contains(KonanFqNames.internalPackageName, "KFunctionImpl.kt") != false -internal val Context.shouldDefineFunctionClasses: Boolean - get() = producedLlvmModuleContainsStdlib && - config.libraryToCache?.strategy?.contains(KonanFqNames.internalPackageName, "KFunctionImpl.kt") != false +internal val NativeGenerationState.shouldDefineFunctionClasses: Boolean + get() = producedLlvmModuleContainsStdlib && cacheDeserializationStrategy.containsKFunctionImpl -internal val Context.shouldDefineCachedBoxes: Boolean +internal val NativeGenerationState.shouldDefineCachedBoxes: Boolean get() = producedLlvmModuleContainsStdlib && - config.libraryToCache?.strategy?.contains(KonanFqNames.internalPackageName, "Boxing.kt") != false + cacheDeserializationStrategy?.contains(KonanFqNames.internalPackageName, "Boxing.kt") != false -internal val Context.shouldLinkRuntimeNativeLibraries: Boolean +internal val NativeGenerationState.shouldLinkRuntimeNativeLibraries: Boolean get() = producedLlvmModuleContainsStdlib && - config.libraryToCache?.strategy?.contains(KonanFqNames.packageName, "Runtime.kt") != false + cacheDeserializationStrategy?.contains(KonanFqNames.packageName, "Runtime.kt") != false val KonanConfig.involvesLinkStage: Boolean get() = when (this.produce) { @@ -116,7 +115,7 @@ private fun collectLlvmModules(context: Context, generatedBitcodeFiles: List libraries.flatMap { it.bitcodePaths }.filter { it.isBitcode } @@ -146,7 +145,7 @@ private fun collectLlvmModules(context: Context, generatedBitcodeFiles: List - val llvmModuleSpecification: LlvmModuleSpecification by lazy { - when { - config.produce.isCache -> - CacheLlvmModuleSpecification(this, config.cachedLibraries, config.libraryToCache!!) - else -> DefaultLlvmModuleSpecification(config.cachedLibraries) - } - } - val declaredLocalArrays: MutableMap = HashMap() lateinit var irLinker: KonanIrLinker diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EntryPoint.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EntryPoint.kt index bfb5ae28945..b60ed35d862 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EntryPoint.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/EntryPoint.kt @@ -25,11 +25,11 @@ internal object DECLARATION_ORIGIN_ENTRY_POINT : IrDeclarationOriginImpl("ENTRY_ internal fun makeEntryPoint(context: Context): IrFunction { val actualMain = context.ir.symbols.entryPoint!!.owner // TODO: Do we need to do something with the offsets if
is in a cached library? - val startOffset = if (context.llvmModuleSpecification.containsDeclaration(actualMain)) + val startOffset = if (context.generationState.llvmModuleSpecification.containsDeclaration(actualMain)) actualMain.startOffset else SYNTHETIC_OFFSET - val endOffset = if (context.llvmModuleSpecification.containsDeclaration(actualMain)) + val endOffset = if (context.generationState.llvmModuleSpecification.containsDeclaration(actualMain)) actualMain.endOffset else SYNTHETIC_OFFSET diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Linker.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Linker.kt index 1b38b9a43ee..fa110f7de84 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Linker.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/Linker.kt @@ -236,7 +236,7 @@ private fun determineCachesToLink(context: Context): CachesToLink { val dynamicCaches = mutableListOf() context.generationState.llvm.allCachedBitcodeDependencies.forEach { library -> - val currentBinaryContainsLibrary = context.llvmModuleSpecification.containsLibrary(library) + val currentBinaryContainsLibrary = context.generationState.llvmModuleSpecification.containsLibrary(library) val cache = context.config.cachedLibraries.getLibraryCache(library) ?: error("Library $library is expected to be cached") diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LlvmModuleSpecificationImpl.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LlvmModuleSpecificationImpl.kt index 06b9549b4cd..bf4292b16d2 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LlvmModuleSpecificationImpl.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/LlvmModuleSpecificationImpl.kt @@ -52,10 +52,10 @@ internal class CacheLlvmModuleSpecification( override fun containsLibrary(library: KotlinLibrary): Boolean = library == libraryToCache.klib override fun containsDeclaration(declaration: IrDeclaration): Boolean { - if (context.shouldDefineFunctionClasses && declaration.getPackageFragment().isFunctionInterfaceFile) + if (context.generationState.shouldDefineFunctionClasses && declaration.getPackageFragment().isFunctionInterfaceFile) return true if (!super.containsDeclaration(declaration)) return false - return (libraryToCache.strategy as? CacheDeserializationStrategy.SingleFile) + return (context.generationState.cacheDeserializationStrategy as? CacheDeserializationStrategy.SingleFile) ?.filePath.let { it == null || it == declaration.fileOrNull?.path } } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/NativeGenerationState.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/NativeGenerationState.kt index fb1c0983e3d..41a267df362 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/NativeGenerationState.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/NativeGenerationState.kt @@ -40,14 +40,14 @@ internal class FileLowerState { "$prefix${cStubCount++}" } -internal class NativeGenerationState(private val context: Context) { +internal class NativeGenerationState(private val context: Context, val cacheDeserializationStrategy: CacheDeserializationStrategy?) { private val config = context.config - private val outputPath = config.cacheSupport.tryGetImplicitOutput() ?: config.outputPath + private val outputPath = config.cacheSupport.tryGetImplicitOutput(cacheDeserializationStrategy) ?: config.outputPath val outputFiles = OutputFiles(outputPath, config.target, config.produce) val tempFiles = run { val pathToTempDir = config.configuration.get(KonanConfigKeys.TEMPORARY_FILES_DIR)?.let { - val singleFileStrategy = config.cacheSupport.libraryToCache?.strategy as? CacheDeserializationStrategy.SingleFile + val singleFileStrategy = cacheDeserializationStrategy as? CacheDeserializationStrategy.SingleFile if (singleFileStrategy == null) it else File(it, CacheSupport.cacheFileId(singleFileStrategy.fqName, singleFileStrategy.filePath)).path @@ -73,6 +73,15 @@ internal class NativeGenerationState(private val context: Context) { lateinit var fileLowerState: FileLowerState + val llvmModuleSpecification by lazy { + if (config.produce.isCache) + CacheLlvmModuleSpecification(context, config.cachedLibraries, + PartialCacheInfo(config.libraryToCache!!.klib, cacheDeserializationStrategy!!)) + else DefaultLlvmModuleSpecification(config.cachedLibraries) + } + + val producedLlvmModuleContainsStdlib get() = llvmModuleSpecification.containsModule(context.stdlibModule) + private val runtimeDelegate = lazy { Runtime(llvmContext, config.distribution.compilerInterface(config.target)) } private val llvmDelegate = lazy { Llvm(context, LLVMModuleCreateWithNameInContext("out", llvmContext)!!) } private val debugInfoDelegate = lazy { DebugInfo(context) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt index 50ea8b0a606..aa0bae65792 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/OptimizationPipeline.kt @@ -142,7 +142,7 @@ internal fun createLTOFinalPipelineConfig(context: Context): LlvmPipelineConfig val globalDce = true // Since we are in a "closed world" internalization can be safely used // to reduce size of a bitcode with global dce. - val internalize = context.llvmModuleSpecification.isFinal + val internalize = context.generationState.llvmModuleSpecification.isFinal // Hidden visibility makes symbols internal when linking the binary. // When producing dynamic library, this enables stripping unused symbols from binary with -dead_strip flag, // similar to DCE enabled by internalize but later: diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt index 274c78a77c2..e6c60a181f3 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/PsiToIr.kt @@ -19,7 +19,6 @@ import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.PropertyDescriptor import org.jetbrains.kotlin.descriptors.konan.DeserializedKlibModuleOrigin import org.jetbrains.kotlin.descriptors.konan.KlibModuleOrigin -import org.jetbrains.kotlin.descriptors.konan.isNativeStdlib import org.jetbrains.kotlin.ir.IrBuiltIns import org.jetbrains.kotlin.ir.builders.TranslationPluginContext import org.jetbrains.kotlin.ir.linkage.IrDeserializer @@ -64,10 +63,15 @@ internal fun Context.psiToIr( val forwardDeclarationsModuleDescriptor = moduleDescriptor.allDependencyModules.firstOrNull { it.isForwardDeclarationModule } - val modulesWithoutDCE = moduleDescriptor.allDependencyModules - .filter { !llvmModuleSpecification.isFinal && llvmModuleSpecification.containsModule(it) } + val libraryToCacheModule = config.libraryToCache?.klib?.let { + moduleDescriptor.allDependencyModules.single { module -> module.konanLibrary == it } + } - // Note: using [llvmModuleSpecification] since this phase produces IR for generating single LLVM module. + 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 && config.libraryToCache?.strategy.containsKFunctionImpl + val shouldUseLazyFunctionClasses = (stdlibIsCached || stdlibIsBeingCached) && !kFunctionImplIsBeingCached val stubGenerator = DeclarationStubGeneratorImpl( moduleDescriptor, symbolTable, @@ -77,10 +81,10 @@ internal fun Context.psiToIr( ) val irBuiltInsOverDescriptors = generatorContext.irBuiltIns as IrBuiltInsOverDescriptors val functionIrClassFactory: KonanIrAbstractDescriptorBasedFunctionFactory = - if (shouldDefineFunctionClasses || !config.lazyIrForCaches) - BuiltInFictitiousFunctionIrClassFactory(symbolTable, irBuiltInsOverDescriptors, reflectionTypes) - else + if (shouldUseLazyFunctionClasses && config.lazyIrForCaches) LazyIrFunctionFactory(symbolTable, stubGenerator, irBuiltInsOverDescriptors, reflectionTypes) + else + BuiltInFictitiousFunctionIrClassFactory(symbolTable, irBuiltInsOverDescriptors, reflectionTypes) irBuiltInsOverDescriptors.functionFactory = functionIrClassFactory val descriptorsLookup = DescriptorsLookup(this.builtIns) val symbols = KonanSymbols(this, descriptorsLookup, generatorContext.irBuiltIns, symbolTable, symbolTable.lazyWrapper) @@ -98,7 +102,7 @@ internal fun Context.psiToIr( } } } else { - val exportedDependencies = (getExportedDependencies() + modulesWithoutDCE).distinct() + val exportedDependencies = (getExportedDependencies() + libraryToCacheModule?.let { listOf(it) }.orEmpty()).distinct() val irProviderForCEnumsAndCStructs = IrProviderForCEnumAndCStructStubs(generatorContext, interopBuiltIns, symbols) @@ -171,9 +175,8 @@ internal fun Context.psiToIr( // We need to run `buildAllEnumsAndStructsFrom` before `generateModuleFragment` because it adds references to symbolTable // that should be bound. - modulesWithoutDCE - .filter(ModuleDescriptor::isFromInteropLibrary) - .forEach(irProviderForCEnumsAndCStructs::referenceAllEnumsAndStructsFrom) + if (libraryToCacheModule?.isFromInteropLibrary() == true) + irProviderForCEnumsAndCStructs.referenceAllEnumsAndStructsFrom(libraryToCacheModule) translator.addPostprocessingStep { irProviderForCEnumsAndCStructs.generateBodies() @@ -228,8 +231,7 @@ internal fun Context.psiToIr( irModule = mainModule - // Note: coupled with [shouldLower] below. - irModules = modules.filterValues { llvmModuleSpecification.containsModule(it) } + irModules = 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, @@ -243,11 +245,11 @@ internal fun Context.psiToIr( if (!isProducingLibrary) { // TODO: find out what should be done in the new builtins/symbols about it - if (this.stdlibModule in modulesWithoutDCE) { + if (stdlibIsBeingCached) { (functionIrClassFactory as? BuiltInFictitiousFunctionIrClassFactory)?.buildAllClasses() } (functionIrClassFactory as? BuiltInFictitiousFunctionIrClassFactory)?.module = - (modules.values + irModule!!).single { it.descriptor.isNativeStdlib() } + (modules.values + irModule!!).single { it.descriptor == this.stdlibModule } } mainModule.files.forEach { it.metadata = KonanFileMetadataSource(mainModule) } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt index 154826cf18f..4d08bcfe03a 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt @@ -129,13 +129,13 @@ internal val psiToIrPhase = konanUnitPhase( internal val buildAdditionalCacheInfoPhase = konanUnitPhase( op = { - irModules.values.single().let { module -> - val moduleDeserializer = irLinker.moduleDeserializers[module.descriptor] - if (moduleDeserializer == null) { - require(module.descriptor.isFromInteropLibrary()) { "No module deserializer for ${module.descriptor}" } - } else { - CacheInfoBuilder(this, moduleDeserializer).build() - } + val module = irModules[config.libraryToCache!!.klib.libraryName] + ?: error("No module for the library being cached: ${config.libraryToCache!!.klib.libraryName}") + val moduleDeserializer = irLinker.moduleDeserializers[module.descriptor] + if (moduleDeserializer == null) { + require(module.descriptor.isFromInteropLibrary()) { "No module deserializer for ${module.descriptor}" } + } else { + CacheInfoBuilder(this, moduleDeserializer).build() } }, name = "BuildAdditionalCacheInfo", @@ -319,7 +319,8 @@ internal val dependenciesLowerPhase = SameTypeNamedCompilerPhase( .reversed() .forEach { val libModule = context.irModules[it.libraryName] - ?: return@forEach + if (libModule == null || !context.generationState.llvmModuleSpecification.containsModule(libModule)) + return@forEach input.files += libModule.files allLoweringsPhase.invoke(phaseConfig, phaserState, context, input) @@ -332,7 +333,9 @@ internal val dependenciesLowerPhase = SameTypeNamedCompilerPhase( context.librariesWithDependencies .forEach { val libModule = context.irModules[it.libraryName] - ?: return@forEach + if (libModule == null || !context.generationState.llvmModuleSpecification.containsModule(libModule)) + return@forEach + input.files += libModule.files } @@ -348,7 +351,8 @@ internal val umbrellaCompilation = SameTypeNamedCompilerPhase( prerequisite = emptySet(), lower = object : CompilerPhase { override fun invoke(phaseConfig: PhaseConfigurationService, phaserState: PhaserState, context: Context, input: Unit) { - val module = context.irModules.values.single() + val module = context.irModules[context.config.libraryToCache!!.klib.libraryName] + ?: error("No module for the library being cached: ${context.config.libraryToCache!!.klib.libraryName}") val files = module.files.toList() module.files.clear() @@ -357,12 +361,10 @@ internal val umbrellaCompilation = SameTypeNamedCompilerPhase( for (file in files) { if (file.isFunctionInterfaceFile) continue - // Pretend we're about to create a single file cache. - context.config.cacheSupport.libraryToCache!!.strategy = - CacheDeserializationStrategy.SingleFile(file.path, file.fqName.asString()) + context.generationState = NativeGenerationState(context, CacheDeserializationStrategy.SingleFile(file.path, file.fqName.asString())) module.files += file - if (context.shouldDefineFunctionClasses) + if (context.generationState.shouldDefineFunctionClasses) module.files += functionInterfaceFiles entireBackend.invoke(phaseConfig, phaserState, context, Unit) @@ -383,7 +385,7 @@ internal val entryPointPhase = makeCustomPhase( require(context.config.produce == CompilerOutputKind.PROGRAM) val entryPoint = context.ir.symbols.entryPoint!!.owner - val file = if (context.llvmModuleSpecification.containsDeclaration(entryPoint)) { + val file = if (context.generationState.llvmModuleSpecification.containsDeclaration(entryPoint)) { entryPoint.file } else { // `main` function is compiled to other LLVM module. @@ -447,7 +449,7 @@ internal val createGenerationStatePhase = namedUnitPhase( description = "Create generation state", lower = object : CompilerPhase { override fun invoke(phaseConfig: PhaseConfigurationService, phaserState: PhaserState, context: Context, input: Unit) { - context.generationState = NativeGenerationState(context) + context.generationState = NativeGenerationState(context, context.config.libraryToCache?.strategy) } } ) @@ -475,8 +477,7 @@ private val phasesOverMainModule = SameTypeNamedCompilerPhase( private val entireBackend = SameTypeNamedCompilerPhase( name = "EntireBackend", description = "Entire backend", - lower = createGenerationStatePhase then - buildAdditionalCacheInfoPhase then + lower = buildAdditionalCacheInfoPhase then phasesOverMainModule then saveAdditionalCacheInfoPhase then produceOutputPhase then @@ -503,7 +504,8 @@ private val middleEnd = SameTypeNamedCompilerPhase( private val singleCompilation = SameTypeNamedCompilerPhase( name = "SingleCompilation", description = "Single compilation", - lower = entireBackend + lower = createGenerationStatePhase then + entireBackend ) internal val toplevelPhase: CompilerPhase = namedUnitPhase( diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt index 9b6a4b0983e..b5ff583179a 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/ContextUtils.kt @@ -163,7 +163,7 @@ internal interface ContextUtils : RuntimeAware { * or just drop all [else] branches of corresponding conditionals. */ fun isExternal(declaration: IrDeclaration): Boolean { - return !context.llvmModuleSpecification.containsDeclaration(declaration) + return !context.generationState.llvmModuleSpecification.containsDeclaration(declaration) } /** @@ -450,11 +450,11 @@ internal class Llvm(private val context: Context, val module: LLVMModuleRef) : R } private fun shouldContainBitcode(library: KonanLibrary): Boolean { - if (!context.llvmModuleSpecification.containsLibrary(library)) { + if (!context.generationState.llvmModuleSpecification.containsLibrary(library)) { return false } - if (!context.llvmModuleSpecification.isFinal) { + if (!context.generationState.llvmModuleSpecification.isFinal) { return true } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt index 182d3359b06..6cbbc2e0690 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/IrToBitcode.kt @@ -2670,7 +2670,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map library.moduleConstructorName } - if (library == null || context.llvmModuleSpecification.containsLibrary(library)) { + if (library == null || context.generationState.llvmModuleSpecification.containsLibrary(library)) { val otherInitializers = llvm.otherStaticInitializers.takeIf { library == null }.orEmpty() val ctorFunction = addCtorFunction(ctorName) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt index 2a2a240b6f9..eeeb262aafd 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/LlvmDeclarations.kt @@ -168,7 +168,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : if (!context.config.producePerFileCache) "${MangleConstant.CLASS_PREFIX}:$internalName" else { - val containerName = (context.config.libraryToCache!!.strategy as CacheDeserializationStrategy.SingleFile).filePath + val containerName = (context.generationState.cacheDeserializationStrategy as CacheDeserializationStrategy.SingleFile).filePath declaration.computePrivateTypeInfoSymbolName(containerName) } } @@ -341,7 +341,7 @@ private class DeclarationsGeneratorVisitor(override val context: Context) : "${MangleConstant.FUN_PREFIX}:${qualifyInternalName(declaration)}" else { val containerName = declaration.parentClassOrNull?.fqNameForIrSerialization?.asString() - ?: (context.config.libraryToCache!!.strategy as CacheDeserializationStrategy.SingleFile).filePath + ?: (context.generationState.cacheDeserializationStrategy as CacheDeserializationStrategy.SingleFile).filePath declaration.computePrivateSymbolName(containerName) } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt index 09defe0413b..72eb496652c 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/objcexport/ObjCExportCodeGenerator.kt @@ -287,7 +287,7 @@ internal class ObjCExportBlockCodeGenerator(codegen: CodeGenerator) : ObjCExport // 1. Enumerates [BuiltInFictitiousFunctionIrClassFactory] built classes, which may be incomplete otherwise. // 2. Modifies stdlib global initializers. // 3. Defines runtime-declared globals. - require(context.shouldDefineFunctionClasses) + require(context.generationState.shouldDefineFunctionClasses) } fun generate() { @@ -499,7 +499,7 @@ internal class ObjCExportCodeGenerator( descriptorToAdapter[adapter.objCName] = typeAdapter if (irClass != null) { - if (!context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { + if (!context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { setObjCExportTypeInfo(irClass, typeAdapter = typeAdapter) } else { // Optimization: avoid generating huge initializers; @@ -527,7 +527,7 @@ internal class ObjCExportCodeGenerator( emitSortedAdapters(placedClassAdapters, "Kotlin_ObjCExport_sortedClassAdapters") emitSortedAdapters(placedInterfaceAdapters, "Kotlin_ObjCExport_sortedProtocolAdapters") - if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { + if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { replaceExternalWeakOrCommonGlobal( "Kotlin_ObjCExport_initTypeAdapters", llvm.constInt1(true), @@ -555,7 +555,7 @@ internal class ObjCExportCodeGenerator( if (determineLinkerOutput(context) == LinkerOutputKind.STATIC_LIBRARY) { // Might be affected by https://youtrack.jetbrains.com/issue/KT-42254. // The code below generally follows [replaceExternalWeakOrCommonGlobal] implementation. - if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) { + if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) { // So the compiler uses caches. If a user is linking two such static frameworks into a single binary, // the linker might fail with a lot of "duplicate symbol" errors due to KT-42254. // Adding a similar symbol that would explicitly hint to take a look at the YouTrack issue if reported. @@ -701,14 +701,14 @@ private fun ObjCExportCodeGenerator.replaceExternalWeakOrCommonGlobal( origin: CompiledKlibModuleOrigin ) { // TODO: A similar mechanism is used in `IrToBitcode.overrideRuntimeGlobal`. Consider merging them. - if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { + if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherSharedLibraries()) { val global = codegen.importGlobal(name, value.llvmType, origin) externalGlobalInitializers[global] = value } else { context.generationState.llvmImports.add(origin) val global = staticData.placeGlobal(name, value, isExported = true) - if (context.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) { + if (context.generationState.llvmModuleSpecification.importsKotlinDeclarationsFromOtherObjectFiles()) { // Note: actually this is required only if global's weak/common definition is in another object file, // but it is simpler to do this for all globals, considering that all usages can't be removed by DCE anyway. llvm.usedGlobals += global.llvmGlobal @@ -872,7 +872,7 @@ private val ObjCExportBlockCodeGenerator.mappedFunctionNClasses get() = .filter { it.descriptor.isMappedFunctionClass() } private fun ObjCExportBlockCodeGenerator.emitFunctionConverters() { - require(context.shouldDefineFunctionClasses) + require(context.generationState.shouldDefineFunctionClasses) mappedFunctionNClasses.forEach { functionClass -> val convertToRetained = kotlinFunctionToRetainedBlockConverter(BlockPointerBridge(functionClass.arity, returnsVoid = false)) @@ -882,7 +882,7 @@ private fun ObjCExportBlockCodeGenerator.emitFunctionConverters() { } private fun ObjCExportBlockCodeGenerator.emitBlockToKotlinFunctionConverters() { - require(context.shouldDefineFunctionClasses) + require(context.generationState.shouldDefineFunctionClasses) val functionClassesByArity = mappedFunctionNClasses.associateBy { it.arity } val arityLimit = (functionClassesByArity.keys.maxOrNull() ?: -1) + 1 diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/CachesAbiLowering.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/CachesAbiLowering.kt index a09e55d87fc..60258749ff0 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/CachesAbiLowering.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/CachesAbiLowering.kt @@ -162,7 +162,7 @@ internal class ImportCachesAbiTransformer(val context: Context) : FileLoweringPa val property = field.correspondingPropertySymbol?.owner return when { - context.llvmModuleSpecification.containsDeclaration(field) -> expression + context.generationState.llvmModuleSpecification.containsDeclaration(field) -> expression irClass?.isInner == true && context.innerClassesSupport.getOuterThisField(irClass) == field -> { val accessor = cachesAbiSupport.getOuterThisAccessor(irClass) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeInlineFunctionResolver.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeInlineFunctionResolver.kt index 14202057abc..0c0b3c1e7e5 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeInlineFunctionResolver.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/lower/NativeInlineFunctionResolver.kt @@ -80,7 +80,7 @@ internal class NativeInlineFunctionResolver(override val context: Context) : Def LocalClassesInInlineLambdasLowering(context).lower(body, possiblyLoweredFunction) - if (context.llvmModuleSpecification.containsDeclaration(function)) { + if (context.generationState.llvmModuleSpecification.containsDeclaration(function)) { // Do not extract local classes off of inline functions from cached libraries. LocalClassesInInlineFunctionsLowering(context).lower(body, possiblyLoweredFunction) LocalClassesExtractionFromInlineFunctionsLowering(context).lower(body, possiblyLoweredFunction) diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExport.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExport.kt index c89d1273e64..d643f730d6e 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExport.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/objcexport/ObjCExport.kt @@ -68,7 +68,7 @@ internal class ObjCExport( internal fun generate(codegen: CodeGenerator) { if (!target.family.isAppleFamily) return - if (context.shouldDefineFunctionClasses) { + if (context.generationState.shouldDefineFunctionClasses) { ObjCExportBlockCodeGenerator(codegen).generate() }