[K/N] Move temp file from BitcodeCompiler to the driver

Continue extracting all temporary files to the driver, so we have
a better control over them. For example, this allows creating of a new
driver where pipeline split between multiple compiler invocations.
This commit is contained in:
Sergey Bogolepov
2023-01-25 12:46:25 +02:00
committed by Space Team
parent a11be433e2
commit 2f1e9844df
3 changed files with 24 additions and 27 deletions
@@ -6,17 +6,15 @@
package org.jetbrains.kotlin.backend.konan package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.konan.TempFiles
import org.jetbrains.kotlin.konan.exec.Command import org.jetbrains.kotlin.konan.exec.Command
import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.target.*
import java.io.File
typealias BitcodeFile = String
typealias ObjectFile = String typealias ObjectFile = String
typealias ExecutableFile = String typealias ExecutableFile = String
internal class BitcodeCompiler( internal class BitcodeCompiler(
private val context: PhaseContext, private val context: PhaseContext,
private val temporaryFiles: TempFiles,
) { ) {
private val config = context.config private val config = context.config
@@ -36,9 +34,6 @@ internal class BitcodeCompiler(
.logWith(context::log) .logWith(context::log)
.execute() .execute()
private fun temporary(name: String, suffix: String): String =
temporaryFiles.create(name, suffix).absolutePath
private fun targetTool(tool: String, vararg arg: String) { private fun targetTool(tool: String, vararg arg: String) {
val absoluteToolName = if (platform.configurables is AppleConfigurables) { val absoluteToolName = if (platform.configurables is AppleConfigurables) {
"${platform.absoluteTargetToolchain}/usr/bin/$tool" "${platform.absoluteTargetToolchain}/usr/bin/$tool"
@@ -53,9 +48,7 @@ internal class BitcodeCompiler(
runTool(absoluteToolName, *arg) runTool(absoluteToolName, *arg)
} }
private fun clang(configurables: ClangFlags, file: BitcodeFile): ObjectFile { private fun clang(configurables: ClangFlags, bitcodeFile: File, objectFile: File) {
val objectFile = temporary("result", ".o")
val targetTriple = if (configurables is AppleConfigurables) { val targetTriple = if (configurables is AppleConfigurables) {
platform.targetTriple.withOSVersion(configurables.osVersionMin) platform.targetTriple.withOSVersion(configurables.osVersionMin)
} else { } else {
@@ -76,12 +69,13 @@ internal class BitcodeCompiler(
addNonEmpty(BitcodeEmbedding.getClangOptions(config)) addNonEmpty(BitcodeEmbedding.getClangOptions(config))
addNonEmpty(configurables.currentRelocationMode(context).translateToClangCc1Flag()) addNonEmpty(configurables.currentRelocationMode(context).translateToClangCc1Flag())
} }
val bitcodePath = bitcodeFile.absoluteFile.normalize().path
val objectPath = objectFile.absoluteFile.normalize().path
if (configurables is AppleConfigurables) { if (configurables is AppleConfigurables) {
targetTool("clang++", *flags.toTypedArray(), file, "-o", objectFile) targetTool("clang++", *flags.toTypedArray(), bitcodePath, "-o", objectPath)
} else { } else {
hostLlvmTool("clang++", *flags.toTypedArray(), file, "-o", objectFile) hostLlvmTool("clang++", *flags.toTypedArray(), bitcodePath, "-o", objectPath)
} }
return objectFile
} }
private fun RelocationModeFlags.Mode.translateToClangCc1Flag() = when (this) { private fun RelocationModeFlags.Mode.translateToClangCc1Flag() = when (this) {
@@ -90,9 +84,12 @@ internal class BitcodeCompiler(
RelocationModeFlags.Mode.DEFAULT -> emptyList() RelocationModeFlags.Mode.DEFAULT -> emptyList()
} }
fun makeObjectFiles(bitcodeFile: BitcodeFile): List<ObjectFile> = /**
listOf(when (val configurables = platform.configurables) { * Compile [bitcodeFile] to [objectFile].
is ClangFlags -> clang(configurables, bitcodeFile) */
fun makeObjectFile(bitcodeFile: File, objectFile: File) =
when (val configurables = platform.configurables) {
is ClangFlags -> clang(configurables, bitcodeFile, objectFile)
else -> error("Unsupported configurables kind: ${configurables::class.simpleName}!") else -> error("Unsupported configurables kind: ${configurables::class.simpleName}!")
}) }
} }
@@ -6,19 +6,17 @@
package org.jetbrains.kotlin.backend.konan.driver.phases package org.jetbrains.kotlin.backend.konan.driver.phases
import org.jetbrains.kotlin.backend.konan.BitcodeCompiler import org.jetbrains.kotlin.backend.konan.BitcodeCompiler
import org.jetbrains.kotlin.backend.konan.ObjectFile
import org.jetbrains.kotlin.backend.konan.driver.PhaseContext import org.jetbrains.kotlin.backend.konan.driver.PhaseContext
import org.jetbrains.kotlin.konan.TempFiles import java.io.File
internal data class ObjectFilesPhaseInput( internal data class ObjectFilesPhaseInput(
val bitcodeFileName: String, val bitcodeFile: File,
val temporaryFiles: TempFiles val objectFile: File,
) )
internal val ObjectFilesPhase = createSimpleNamedCompilerPhase<PhaseContext, ObjectFilesPhaseInput, List<ObjectFile>>( internal val ObjectFilesPhase = createSimpleNamedCompilerPhase<PhaseContext, ObjectFilesPhaseInput>(
name = "ObjectFiles", name = "ObjectFiles",
description = "Bitcode to object file", description = "Bitcode to object file",
outputIfNotEnabled = { _, _, _, _ -> emptyList() }
) { context, input -> ) { context, input ->
BitcodeCompiler(context, input.temporaryFiles).makeObjectFiles(input.bitcodeFileName) BitcodeCompiler(context).makeObjectFile(input.bitcodeFile, input.objectFile)
} }
@@ -21,6 +21,7 @@ import org.jetbrains.kotlin.konan.TempFiles
import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.Family import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.library.impl.javaFile import org.jetbrains.kotlin.library.impl.javaFile
import java.io.File
internal fun PhaseEngine<PhaseContext>.runFrontend(config: KonanConfig, environment: KotlinCoreEnvironment): FrontendPhaseOutput.Full? { internal fun PhaseEngine<PhaseContext>.runFrontend(config: KonanConfig, environment: KotlinCoreEnvironment): FrontendPhaseOutput.Full? {
val frontendOutput = useContext(FrontendContextImpl(config)) { it.runPhase(FrontendPhase, environment) } val frontendOutput = useContext(FrontendContextImpl(config)) { it.runPhase(FrontendPhase, environment) }
@@ -111,7 +112,7 @@ private fun PhaseEngine<out Context>.splitIntoFragments(
} }
internal data class ModuleCompilationOutput( internal data class ModuleCompilationOutput(
val bitcodeFile: String, val bitcodeFile: File,
val dependenciesTrackingResult: DependenciesTrackingResult, val dependenciesTrackingResult: DependenciesTrackingResult,
// Passing tempFiles and output files through this file looks silly and incorrect. // Passing tempFiles and output files through this file looks silly and incorrect.
// TODO: Refactor these classes and remove them from here. // TODO: Refactor these classes and remove them from here.
@@ -146,7 +147,7 @@ internal fun PhaseEngine<NativeGenerationState>.compileModule(module: IrModuleFr
context.dependenciesTracker.allNativeDependencies, context.dependenciesTracker.allNativeDependencies,
context.dependenciesTracker.allCachedBitcodeDependencies, context.dependenciesTracker.allCachedBitcodeDependencies,
) )
return ModuleCompilationOutput(bitcodeFile.canonicalPath, dependenciesTrackingResult, context.tempFiles, context.outputFiles) return ModuleCompilationOutput(bitcodeFile, dependenciesTrackingResult, context.tempFiles, context.outputFiles)
} }
internal fun <C : PhaseContext> PhaseEngine<C>.compileAndLink( internal fun <C : PhaseContext> PhaseEngine<C>.compileAndLink(
@@ -156,8 +157,9 @@ internal fun <C : PhaseContext> PhaseEngine<C>.compileAndLink(
temporaryFiles: TempFiles, temporaryFiles: TempFiles,
isCoverageEnabled: Boolean, isCoverageEnabled: Boolean,
) { ) {
val objectFiles = runPhase(ObjectFilesPhase, ObjectFilesPhaseInput(moduleCompilationOutput.bitcodeFile, temporaryFiles)) val objectFile = temporaryFiles.create("result", ".o").javaFile()
val linkerPhaseInput = LinkerPhaseInput(linkerOutputFile, objectFiles, moduleCompilationOutput.dependenciesTrackingResult, runPhase(ObjectFilesPhase, ObjectFilesPhaseInput(moduleCompilationOutput.bitcodeFile, objectFile))
val linkerPhaseInput = LinkerPhaseInput(linkerOutputFile, listOf(objectFile.canonicalPath), moduleCompilationOutput.dependenciesTrackingResult,
outputFiles, temporaryFiles, isCoverageEnabled = isCoverageEnabled) outputFiles, temporaryFiles, isCoverageEnabled = isCoverageEnabled)
runPhase(LinkerPhase, linkerPhaseInput) runPhase(LinkerPhase, linkerPhaseInput)
if (context.config.produce.isCache) { if (context.config.produce.isCache) {