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 6e5ff4fed6f..a4275325f9b 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 @@ -9,7 +9,6 @@ import llvm.* import org.jetbrains.kotlin.backend.konan.driver.BasicPhaseContext import org.jetbrains.kotlin.backend.konan.driver.utilities.BackendContextHolder import org.jetbrains.kotlin.backend.konan.driver.utilities.LlvmIrHolder -import org.jetbrains.kotlin.backend.konan.ir.konanLibrary import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport @@ -18,7 +17,6 @@ import org.jetbrains.kotlin.backend.konan.serialization.SerializedEagerInitializ import org.jetbrains.kotlin.backend.konan.serialization.SerializedInlineFunctionReference import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.konan.TempFiles -import org.jetbrains.kotlin.konan.file.File internal class InlineFunctionOriginInfo(val irFunction: IrFunction, val irFile: IrFile, val startOffset: Int, val endOffset: Int) @@ -45,19 +43,13 @@ internal class NativeGenerationState( // TODO: Get rid of this property completely once transition to the dynamic driver is complete. // It will reduce code coupling and make it easier to create NativeGenerationState instances. val context: Context, - val cacheDeserializationStrategy: CacheDeserializationStrategy? + val cacheDeserializationStrategy: CacheDeserializationStrategy?, + val dependenciesTracker: DependenciesTracker, + val llvmModuleSpecification: LlvmModuleSpecification, + val outputFiles: OutputFiles, + val tempFiles: TempFiles, + val llvmModuleName: String, ) : BasicPhaseContext(config), BackendContextHolder, LlvmIrHolder { - 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 = cacheDeserializationStrategy as? CacheDeserializationStrategy.SingleFile - if (singleFileStrategy == null) - it - else File(it, CacheSupport.cacheFileId(singleFileStrategy.fqName, singleFileStrategy.filePath)).path - } - TempFiles(pathToTempDir) - } val outputFile = outputFiles.mainFileName val inlineFunctionBodies = mutableListOf() @@ -78,22 +70,10 @@ internal class NativeGenerationState( lateinit var fileLowerState: FileLowerState - val llvmModuleSpecification by lazy { - if (config.produce.isCache) - CacheLlvmModuleSpecification( - config.cachedLibraries, - PartialCacheInfo(config.libraryToCache!!.klib, cacheDeserializationStrategy!!), - containsStdlib = config.libraryToCache!!.klib == context.stdlibModule.konanLibrary - ) - else DefaultLlvmModuleSpecification(config.cachedLibraries) - } - val producedLlvmModuleContainsStdlib get() = llvmModuleSpecification.containsModule(context.stdlibModule) - val dependenciesTracker: DependenciesTracker = DependenciesTrackerImpl(llvmModuleSpecification, config, context) - private val runtimeDelegate = lazy { Runtime(llvmContext, config.distribution.compilerInterface(config.target)) } - private val llvmDelegate = lazy { Llvm(this, LLVMModuleCreateWithNameInContext("out", llvmContext)!!) } + private val llvmDelegate = lazy { Llvm(this, LLVMModuleCreateWithNameInContext(llvmModuleName, llvmContext)!!) } private val debugInfoDelegate = lazy { DebugInfo(this) } val llvmContext = LLVMContextCreate()!! @@ -137,7 +117,6 @@ internal class NativeGenerationState( LLVMDisposeModule(runtime.llvmModule) } LLVMContextDispose(llvmContext) - tempFiles.dispose() isDisposed = true } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/TopLevelPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/TopLevelPhases.kt index 4d84f0a6432..6ef07dca2af 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/TopLevelPhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/TopLevelPhases.kt @@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.konan.driver.phases import org.jetbrains.kotlin.backend.konan.* import org.jetbrains.kotlin.backend.konan.driver.PhaseContext import org.jetbrains.kotlin.backend.konan.driver.PhaseEngine +import org.jetbrains.kotlin.backend.konan.driver.utilities.createTempFiles import org.jetbrains.kotlin.backend.konan.ir.konanLibrary import org.jetbrains.kotlin.backend.konan.llvm.getName import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment @@ -53,18 +54,28 @@ internal fun PhaseEngine.runPsiToIr( } internal fun PhaseEngine.runBackend(backendContext: Context, irModule: IrModuleFragment) { + val config = context.config useContext(backendContext) { backendEngine -> backendEngine.runPhase(functionsWithoutBoundCheck) val fragments = backendEngine.splitIntoFragments(irModule) fragments.forEach { fragment -> - val generationState = NativeGenerationState(context.config, backendContext, - fragment.cacheDeserializationStrategy - ) - backendEngine.useContext(generationState) { generationStateEngine -> - // TODO: Make this work if we first compile all the fragments and only after that run the link phases. - val it = generationStateEngine.compileModule(fragment.irModule) - // Split here - compileAndLink(it, it.outputFiles.mainFileName, it.outputFiles, it.temporaryFiles, isCoverageEnabled = false) + val tempFiles = createTempFiles(config, fragment.cacheDeserializationStrategy) + try { + val outputPath = config.cacheSupport.tryGetImplicitOutput(fragment.cacheDeserializationStrategy) ?: config.outputPath + val outputFiles = OutputFiles(outputPath, config.target, config.produce) + val generationState = NativeGenerationState(context.config, backendContext, + fragment.cacheDeserializationStrategy, fragment.dependenciesTracker, fragment.llvmModuleSpecification, outputFiles, + tempFiles, + llvmModuleName = "out" // TODO: Currently, all llvm modules are named as "out" which might lead to collisions. + ) + backendEngine.useContext(generationState) { generationStateEngine -> + // TODO: Make this work if we first compile all the fragments and only after that run the link phases. + val it = generationStateEngine.compileModule(fragment.irModule) + // Split here + compileAndLink(it, it.outputFiles.mainFileName, it.outputFiles, it.temporaryFiles, isCoverageEnabled = false) + } + } finally { + tempFiles.dispose() } } } diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/utilities/FileManagement.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/utilities/FileManagement.kt new file mode 100644 index 00000000000..793442cea3a --- /dev/null +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/utilities/FileManagement.kt @@ -0,0 +1,22 @@ +/* + * Copyright 2010-2023 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.utilities + +import org.jetbrains.kotlin.backend.konan.CacheDeserializationStrategy +import org.jetbrains.kotlin.backend.konan.CacheSupport +import org.jetbrains.kotlin.backend.konan.KonanConfig +import org.jetbrains.kotlin.backend.konan.KonanConfigKeys +import org.jetbrains.kotlin.konan.TempFiles + +internal fun createTempFiles(config: KonanConfig, cacheDeserializationStrategy: CacheDeserializationStrategy?): TempFiles { + val pathToTempDir = config.configuration.get(KonanConfigKeys.TEMPORARY_FILES_DIR)?.let { + val singleFileStrategy = cacheDeserializationStrategy as? CacheDeserializationStrategy.SingleFile + if (singleFileStrategy == null) + it + else org.jetbrains.kotlin.konan.file.File(it, CacheSupport.cacheFileId(singleFileStrategy.fqName, singleFileStrategy.filePath)).path + } + return TempFiles(pathToTempDir) +} \ No newline at end of file