Use clang instead if llvm-lto for darwin-based targets (#2974)

* Use LLVM C API for optimizations
* Use Clang for bitcode compilation
* Test bitcode embedding
This commit is contained in:
Sergey Bogolepov
2019-05-15 13:00:43 +07:00
committed by GitHub
parent 89c2fb21c4
commit 5306d7b427
23 changed files with 620 additions and 367 deletions
@@ -171,7 +171,6 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
put(VERBOSE_PHASES, put(VERBOSE_PHASES,
arguments.verbosePhases.toNonNullList()) arguments.verbosePhases.toNonNullList())
put(LIST_PHASES, arguments.listPhases) put(LIST_PHASES, arguments.listPhases)
put(TIME_PHASES, arguments.timePhases)
put(COMPATIBLE_COMPILER_VERSIONS, put(COMPATIBLE_COMPILER_VERSIONS,
arguments.compatibleCompilerVersions.toNonNullList()) arguments.compatibleCompilerVersions.toNonNullList())
@@ -153,9 +153,6 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
@Argument(value = "-Xtemporary-files-dir", deprecatedName = "--temporary_files_dir", valueDescription = "<path>", description = "Save temporary files to the given directory") @Argument(value = "-Xtemporary-files-dir", deprecatedName = "--temporary_files_dir", valueDescription = "<path>", description = "Save temporary files to the given directory")
var temporaryFilesDir: String? = null var temporaryFilesDir: String? = null
@Argument(value = "-Xtime", deprecatedName = "--time", description = "Report execution time for compiler phases")
var timePhases: Boolean = false
@Argument(value = "-Xverify-bitcode", deprecatedName = "--verify_bitcode", description = "Verify llvm bitcode after each method") @Argument(value = "-Xverify-bitcode", deprecatedName = "--verify_bitcode", description = "Verify llvm bitcode after each method")
var verifyBitCode: Boolean = false var verifyBitCode: Boolean = false
@@ -0,0 +1,179 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
package org.jetbrains.kotlin.backend.konan
import llvm.*
import org.jetbrains.kotlin.backend.konan.llvm.parseBitcodeFile
import org.jetbrains.kotlin.konan.exec.Command
import org.jetbrains.kotlin.konan.target.*
typealias BitcodeFile = String
typealias ObjectFile = String
typealias ExecutableFile = String
private fun mangleSymbol(target: KonanTarget,symbol: String) =
if (target.family == Family.IOS || target.family == Family.OSX) {
"_$symbol"
} else {
symbol
}
internal class BitcodeCompiler(val context: Context) {
private val target = context.config.target
private val platform = context.config.platform
private val optimize = context.shouldOptimize()
private val debug = context.config.debug
private fun MutableList<String>.addNonEmpty(elements: List<String>) {
addAll(elements.filter { !it.isEmpty() })
}
private val exportedSymbols = context.coverage.addExportedSymbols()
private fun runTool(vararg command: String) =
Command(*command)
.logWith(context::log)
.execute()
private fun temporary(name: String, suffix: String): String =
context.config.tempFiles.create(name, suffix).absolutePath
private fun targetTool(tool: String, vararg arg: String) {
val absoluteToolName = if (platform.configurables is AppleConfigurables) {
"${platform.absoluteTargetToolchain}/usr/bin/$tool"
} else {
"${platform.absoluteTargetToolchain}/bin/$tool"
}
runTool(absoluteToolName, *arg)
}
private fun hostLlvmTool(tool: String, vararg arg: String) {
val absoluteToolName = "${platform.absoluteLlvmHome}/bin/$tool"
runTool(absoluteToolName, *arg)
}
private fun llvmLto(configurables: LlvmLtoFlags, file: BitcodeFile): ObjectFile {
val combined = temporary("combined", ".o")
val arguments = mutableListOf<String>().apply {
addNonEmpty(configurables.llvmLtoFlags)
addNonEmpty(llvmProfilingFlags())
when {
optimize -> addNonEmpty(configurables.llvmLtoOptFlags)
debug -> addNonEmpty(platform.llvmDebugOptFlags)
else -> addNonEmpty(configurables.llvmLtoNooptFlags)
}
addNonEmpty(configurables.llvmLtoDynamicFlags)
add(file)
// Prevent symbols from being deleted by DCE.
addNonEmpty(exportedSymbols.map { "-exported-symbol=${mangleSymbol(target, it)}"} )
}
hostLlvmTool("llvm-lto", "-o", combined, *arguments.toTypedArray())
return combined
}
private fun opt(optFlags: OptFlags, bitcodeFile: BitcodeFile): BitcodeFile {
val flags = (optFlags.optFlags + when {
optimize -> optFlags.optOptFlags
debug -> optFlags.optDebugFlags
else -> optFlags.optNooptFlags
} + llvmProfilingFlags()).toTypedArray()
val optimizedBc = temporary("opt_output", ".bc")
hostLlvmTool("opt", bitcodeFile, "-o", optimizedBc, *flags)
if (shouldRunLateBitcodePasses(context)) {
val module = parseBitcodeFile(optimizedBc)
runLateBitcodePasses(context, module)
LLVMWriteBitcodeToFile(module, optimizedBc)
}
return optimizedBc
}
private fun llc(llcFlags: LlcFlags, bitcodeFile: BitcodeFile): ObjectFile {
val flags = (llcFlags.llcFlags + when {
optimize -> llcFlags.llcOptFlags
debug -> llcFlags.llcDebugFlags
else -> llcFlags.llcNooptFlags
} + llvmProfilingFlags()).toTypedArray()
val combinedO = temporary("llc_output", ".o")
hostLlvmTool("llc", bitcodeFile, "-o", combinedO, *flags, "-filetype=obj")
return combinedO
}
private fun bitcodeToWasm(configurables: WasmConfigurables, file: BitcodeFile): String {
val optimizedBc = opt(configurables, file)
val compiled = llc(configurables, optimizedBc)
// TODO: should be moved to linker.
val linkedWasm = temporary("linked", ".wasm")
hostLlvmTool("wasm-ld", compiled, "-o", linkedWasm, *configurables.lldFlags.toTypedArray())
return linkedWasm
}
private fun optAndLlc(configurables: ZephyrConfigurables, file: BitcodeFile): String {
val optimizedBc = temporary("optimized", ".bc")
val optFlags = llvmProfilingFlags() + listOf("-O3", "-internalize", "-globaldce")
hostLlvmTool("opt", file, "-o=$optimizedBc", *optFlags.toTypedArray())
val combinedO = temporary("combined", ".o")
val llcFlags = llvmProfilingFlags() + listOf("-function-sections", "-data-sections")
hostLlvmTool("llc", optimizedBc, "-filetype=obj", "-o", combinedO, *llcFlags.toTypedArray())
return combinedO
}
private fun clang(configurables: AppleConfigurables, file: BitcodeFile): ObjectFile {
val objectFile = temporary("result", ".o")
val profilingFlags = llvmProfilingFlags().map { listOf("-mllvm", it) }.flatten()
val flags = mutableListOf<String>().apply {
addNonEmpty(configurables.clangFlags)
addNonEmpty(listOf("-triple", context.llvm.targetTriple))
addNonEmpty(when {
optimize -> configurables.clangOptFlags
debug -> configurables.clangDebugFlags
else -> configurables.clangNooptFlags
})
addNonEmpty(BitcodeEmbedding.getClangOptions(context.config))
if (determineLinkerOutput(context) == LinkerOutputKind.DYNAMIC_LIBRARY) {
addNonEmpty(configurables.clangDynamicFlags)
}
addNonEmpty(profilingFlags)
}
targetTool("clang++", *flags.toTypedArray(), file, "-o", objectFile)
return objectFile
}
// llvm-lto, opt and llc share same profiling flags, so we can
// reuse this function.
private fun llvmProfilingFlags(): List<String> {
val flags = mutableListOf<String>()
if (context.shouldProfilePhases()) {
flags += "-time-passes"
}
if (context.inVerbosePhase) {
flags += "-debug-pass=Structure"
}
return flags
}
fun makeObjectFiles(bitcodeFile: BitcodeFile): List<ObjectFile> =
listOf(when (val configurables = platform.configurables) {
is AppleConfigurables ->
clang(configurables, bitcodeFile)
is WasmConfigurables ->
bitcodeToWasm(configurables, bitcodeFile)
is ZephyrConfigurables ->
optAndLlc(configurables, bitcodeFile)
is LlvmLtoFlags ->
llvmLto(configurables, bitcodeFile)
else ->
error("Unsupported configurables kind: ${configurables::class.simpleName}!")
})
}
@@ -16,6 +16,12 @@ object BitcodeEmbedding {
Mode.FULL -> listOf("-bitcode_bundle") Mode.FULL -> listOf("-bitcode_bundle")
} }
internal fun getClangOptions(config: KonanConfig): List<String> = when (config.bitcodeEmbeddingMode) {
BitcodeEmbedding.Mode.NONE -> listOf("-fembed-bitcode=off")
BitcodeEmbedding.Mode.MARKER -> listOf("-fembed-bitcode=marker")
BitcodeEmbedding.Mode.FULL -> listOf("-fembed-bitcode=all")
}
private val KonanConfig.bitcodeEmbeddingMode get() = configuration.get(KonanConfigKeys.BITCODE_EMBEDDING_MODE)!!.also { private val KonanConfig.bitcodeEmbeddingMode get() = configuration.get(KonanConfigKeys.BITCODE_EMBEDDING_MODE)!!.also {
require(it == Mode.NONE || this.produce == CompilerOutputKind.FRAMEWORK) { require(it == Mode.NONE || this.produce == CompilerOutputKind.FRAMEWORK) {
"${it.name.toLowerCase()} bitcode embedding mode is not supported when producing ${this.produce.name.toLowerCase()}" "${it.name.toLowerCase()} bitcode embedding mode is not supported when producing ${this.produce.name.toLowerCase()}"
@@ -4,16 +4,19 @@
*/ */
package org.jetbrains.kotlin.backend.konan package org.jetbrains.kotlin.backend.konan
import llvm.* import llvm.LLVMLinkModules2
import llvm.LLVMModuleRef
import llvm.LLVMWriteBitcodeToFile
import org.jetbrains.kotlin.backend.konan.library.impl.buildLibrary import org.jetbrains.kotlin.backend.konan.library.impl.buildLibrary
import org.jetbrains.kotlin.backend.konan.llvm.*
import org.jetbrains.kotlin.backend.konan.llvm.Llvm import org.jetbrains.kotlin.backend.konan.llvm.Llvm
import org.jetbrains.kotlin.backend.konan.llvm.embedLlvmLinkOptions
import org.jetbrains.kotlin.backend.konan.llvm.parseBitcodeFile
import org.jetbrains.kotlin.konan.CURRENT import org.jetbrains.kotlin.konan.CURRENT
import org.jetbrains.kotlin.konan.KonanAbiVersion import org.jetbrains.kotlin.konan.KonanAbiVersion
import org.jetbrains.kotlin.konan.KonanVersion import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.file.isBitcode
import org.jetbrains.kotlin.konan.library.KonanLibraryVersioning import org.jetbrains.kotlin.konan.library.KonanLibraryVersioning
import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.Family
val CompilerOutputKind.isNativeBinary: Boolean get() = when (this) { val CompilerOutputKind.isNativeBinary: Boolean get() = when (this) {
CompilerOutputKind.PROGRAM, CompilerOutputKind.DYNAMIC, CompilerOutputKind.PROGRAM, CompilerOutputKind.DYNAMIC,
@@ -28,20 +31,30 @@ internal fun produceCStubs(context: Context) {
} }
} }
private fun shouldRunBitcodePasses(context: Context): Boolean = private fun linkAllDependecies(context: Context, generatedBitcodeFiles: List<String>) {
context.coverage.enabled
val nativeLibraries = context.config.nativeLibraries + context.config.defaultNativeLibraries
val bitcodeLibraries = context.llvm.bitcodeToLink.map { it.bitcodePaths }.flatten().filter { it.isBitcode }
val additionalBitcodeFilesToLink = context.llvm.additionalProducedBitcodeFiles
val bitcodeFiles = (nativeLibraries + generatedBitcodeFiles + additionalBitcodeFilesToLink + bitcodeLibraries).toSet()
internal fun runBitcodePasses(context: Context) {
if (!shouldRunBitcodePasses(context)) {
return
}
val llvmModule = context.llvmModule!! val llvmModule = context.llvmModule!!
val passManager = LLVMCreatePassManager()!! bitcodeFiles.forEach {
val targetLibraryInfo = LLVMGetTargetLibraryInfo(llvmModule) parseAndLinkBitcodeFile(llvmModule, it)
LLVMAddTargetLibraryInfo(targetLibraryInfo, passManager) }
context.coverage.addLlvmPasses(passManager) }
LLVMRunPassManager(passManager, llvmModule)
LLVMDisposePassManager(passManager) private fun shouldOptimizeWithLlvmApi(context: Context) =
(context.config.target.family == Family.IOS || context.config.target.family == Family.OSX)
private fun shoudRunClosedWorldCleanUp(context: Context) =
// GlobalDCE will kill coverage-related globals.
!context.coverage.enabled
private fun runLlvmPipeline(context: Context) = when {
shouldOptimizeWithLlvmApi(context) -> runLlvmOptimizationPipeline(context)
shoudRunClosedWorldCleanUp(context) -> runClosedWorldCleanup(context)
else -> {}
} }
internal fun produceOutput(context: Context) { internal fun produceOutput(context: Context) {
@@ -57,7 +70,6 @@ internal fun produceOutput(context: Context) {
CompilerOutputKind.PROGRAM -> { CompilerOutputKind.PROGRAM -> {
val output = tempFiles.nativeBinaryFileName val output = tempFiles.nativeBinaryFileName
context.bitcodeFileName = output context.bitcodeFileName = output
val generatedBitcodeFiles = val generatedBitcodeFiles =
if (produce == CompilerOutputKind.DYNAMIC || produce == CompilerOutputKind.STATIC) { if (produce == CompilerOutputKind.DYNAMIC || produce == CompilerOutputKind.STATIC) {
produceCAdapterBitcode( produceCAdapterBitcode(
@@ -66,20 +78,11 @@ internal fun produceOutput(context: Context) {
tempFiles.cAdapterBitcodeName) tempFiles.cAdapterBitcodeName)
listOf(tempFiles.cAdapterBitcodeName) listOf(tempFiles.cAdapterBitcodeName)
} else emptyList() } else emptyList()
val nativeLibraries =
context.config.nativeLibraries +
context.config.defaultNativeLibraries +
generatedBitcodeFiles
for (library in nativeLibraries) {
parseAndLinkBitcodeFile(context.llvmModule!!, library)
}
if (produce == CompilerOutputKind.FRAMEWORK && context.config.produceStaticFramework) { if (produce == CompilerOutputKind.FRAMEWORK && context.config.produceStaticFramework) {
embedAppleLinkerOptionsToBitcode(context.llvm, context.config) embedAppleLinkerOptionsToBitcode(context.llvm, context.config)
} }
linkAllDependecies(context, generatedBitcodeFiles)
runLlvmPipeline(context)
LLVMWriteBitcodeToFile(context.llvmModule!!, output) LLVMWriteBitcodeToFile(context.llvmModule!!, output)
} }
CompilerOutputKind.LIBRARY -> { CompilerOutputKind.LIBRARY -> {
@@ -94,7 +97,6 @@ internal fun produceOutput(context: Context) {
val nopack = config.getBoolean(KonanConfigKeys.NOPACK) val nopack = config.getBoolean(KonanConfigKeys.NOPACK)
val manifestProperties = context.config.manifestProperties val manifestProperties = context.config.manifestProperties
val library = buildLibrary( val library = buildLibrary(
context.config.nativeLibraries, context.config.nativeLibraries,
context.config.includeBinaries, context.config.includeBinaries,
@@ -109,7 +111,6 @@ internal fun produceOutput(context: Context) {
manifestProperties, manifestProperties,
context.dataFlowGraph) context.dataFlowGraph)
context.library = library
context.bitcodeFileName = library.mainBitcodeFileName context.bitcodeFileName = library.mainBitcodeFileName
} }
CompilerOutputKind.BITCODE -> { CompilerOutputKind.BITCODE -> {
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.backend.common.descriptors.WrappedTypeParameterDescr
import org.jetbrains.kotlin.backend.common.validateIrModule import org.jetbrains.kotlin.backend.common.validateIrModule
import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.descriptors.*
import org.jetbrains.kotlin.backend.konan.ir.KonanIr import org.jetbrains.kotlin.backend.konan.ir.KonanIr
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryWriter
import org.jetbrains.kotlin.backend.konan.library.LinkData import org.jetbrains.kotlin.backend.konan.library.LinkData
import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.llvm.*
import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_BRIDGE_METHOD import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_BRIDGE_METHOD
@@ -40,7 +39,6 @@ import org.jetbrains.kotlin.builtins.konan.KonanBuiltIns
import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment import org.jetbrains.kotlin.cli.jvm.compiler.KotlinCoreEnvironment
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
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.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.resolve.BindingContext import org.jetbrains.kotlin.resolve.BindingContext
import org.jetbrains.kotlin.resolve.descriptorUtil.module import org.jetbrains.kotlin.resolve.descriptorUtil.module
@@ -54,6 +52,7 @@ import org.jetbrains.kotlin.backend.common.serialization.KotlinMangler
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
import org.jetbrains.kotlin.name.FqName
/** /**
* Offset for synthetic elements created by lowerings and not attributable to other places in the source code. * Offset for synthetic elements created by lowerings and not attributable to other places in the source code.
@@ -322,7 +321,6 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
val llvmImports: LlvmImports = Llvm.ImportsImpl(this) val llvmImports: LlvmImports = Llvm.ImportsImpl(this)
lateinit var llvmDeclarations: LlvmDeclarations lateinit var llvmDeclarations: LlvmDeclarations
lateinit var bitcodeFileName: String lateinit var bitcodeFileName: String
lateinit var library: KonanLibraryWriter
val cStubsManager = CStubsManager(config.target) val cStubsManager = CStubsManager(config.target)
@@ -441,7 +439,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
fun shouldPrintLocations() = config.configuration.getBoolean(KonanConfigKeys.PRINT_LOCATIONS) fun shouldPrintLocations() = config.configuration.getBoolean(KonanConfigKeys.PRINT_LOCATIONS)
fun shouldProfilePhases() = config.configuration.getBoolean(KonanConfigKeys.TIME_PHASES) fun shouldProfilePhases() = config.phaseConfig.needProfiling
fun shouldContainDebugInfo() = config.debug fun shouldContainDebugInfo() = config.debug
@@ -469,7 +467,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
internal val stdlibModule internal val stdlibModule
get() = this.builtIns.any.module get() = this.builtIns.any.module
lateinit var linkStage: LinkStage lateinit var compilerOutput: List<ObjectFile>
} }
private fun MemberScope.getContributedClassifier(name: String) = private fun MemberScope.getContributedClassifier(name: String) =
@@ -96,8 +96,6 @@ class KonanConfigKeys {
= CompilerConfigurationKey.create("target we compile for") = CompilerConfigurationKey.create("target we compile for")
val TEMPORARY_FILES_DIR: CompilerConfigurationKey<String?> val TEMPORARY_FILES_DIR: CompilerConfigurationKey<String?>
= CompilerConfigurationKey.create("directory for temporary files") = CompilerConfigurationKey.create("directory for temporary files")
val TIME_PHASES: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("time backend phases")
val VERIFY_BITCODE: CompilerConfigurationKey<Boolean> val VERIFY_BITCODE: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("verify bitcode") = CompilerConfigurationKey.create("verify bitcode")
val VERIFY_DESCRIPTORS: CompilerConfigurationKey<Boolean> val VERIFY_DESCRIPTORS: CompilerConfigurationKey<Boolean>
@@ -1,250 +0,0 @@
/*
* Copyright 2010-2018 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license
* that can be found in the LICENSE file.
*/
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.konan.KonanExternalToolFailure
import org.jetbrains.kotlin.konan.exec.Command
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.file.isBitcode
import org.jetbrains.kotlin.konan.target.*
typealias BitcodeFile = String
typealias ObjectFile = String
typealias ExecutableFile = String
private fun determineLinkerOutput(context: Context): LinkerOutputKind =
when (context.config.produce) {
CompilerOutputKind.FRAMEWORK -> {
val staticFramework = context.config.produceStaticFramework
if (staticFramework) LinkerOutputKind.STATIC_LIBRARY else LinkerOutputKind.DYNAMIC_LIBRARY
}
CompilerOutputKind.DYNAMIC -> LinkerOutputKind.DYNAMIC_LIBRARY
CompilerOutputKind.STATIC -> LinkerOutputKind.STATIC_LIBRARY
CompilerOutputKind.PROGRAM -> LinkerOutputKind.EXECUTABLE
else -> TODO("${context.config.produce} should not reach native linker stage")
}
internal class LinkStage(val context: Context) {
private val config = context.config.configuration
private val target = context.config.target
private val platform = context.config.platform
private val linker = platform.linker
private val optimize = context.shouldOptimize()
private val debug = context.config.debug
private val linkerOutput = determineLinkerOutput(context)
private val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false
private val emitted = context.bitcodeFileName
private val bitcodeLibraries = context.llvm.bitcodeToLink
private val nativeDependencies = context.llvm.nativeDependenciesToLink
private val additionalBitcodeFilesToLink = context.llvm.additionalProducedBitcodeFiles
private fun MutableList<String>.addNonEmpty(elements: List<String>) {
addAll(elements.filter { !it.isEmpty() })
}
private val exportedSymbols = context.coverage.addExportedSymbols()
private fun mangleSymbol(symbol: String) =
if (target.family == Family.IOS || target.family == Family.OSX) {
"_$symbol"
} else {
symbol
}
private fun runTool(command: List<String>) = runTool(*command.toTypedArray())
private fun runTool(vararg command: String) =
Command(*command)
.logWith(context::log)
.execute()
private fun llvmLto(files: List<BitcodeFile>): ObjectFile {
val combined = temporary("combined", ".o")
val tool = "${platform.absoluteLlvmHome}/bin/llvm-lto"
val command = mutableListOf(tool, "-o", combined)
command.addNonEmpty(platform.llvmLtoFlags)
command.addNonEmpty(llvmProfilingFlags())
when {
optimize -> command.addNonEmpty(platform.llvmLtoOptFlags)
debug -> command.addNonEmpty(platform.llvmDebugOptFlags)
else -> command.addNonEmpty(platform.llvmLtoNooptFlags)
}
command.addNonEmpty(platform.llvmLtoDynamicFlags)
command.addNonEmpty(files)
// Prevent symbols from being deleted by DCE.
command.addNonEmpty(exportedSymbols.map { "-exported-symbol=${mangleSymbol(it)}"} )
runTool(command)
return combined
}
private fun temporary(name: String, suffix: String): String =
context.config.tempFiles.create(name, suffix).absolutePath
private fun targetTool(tool: String, vararg arg: String) {
val absoluteToolName = "${platform.absoluteTargetToolchain}/bin/$tool"
runTool(absoluteToolName, *arg)
}
private fun hostLlvmTool(tool: String, vararg arg: String) {
val absoluteToolName = "${platform.absoluteLlvmHome}/bin/$tool"
runTool(absoluteToolName, *arg)
}
private fun bitcodeToWasm(bitcodeFiles: List<BitcodeFile>): String {
val configurables = platform.configurables as WasmConfigurables
val combinedBc = temporary("combined", ".bc")
// TODO: use -only-needed for the stdlib
hostLlvmTool("llvm-link", *bitcodeFiles.toTypedArray(), "-o", combinedBc)
val optFlags = (configurables.optFlags + when {
optimize -> configurables.optOptFlags
debug -> configurables.optDebugFlags
else -> configurables.optNooptFlags
} + llvmProfilingFlags()).toTypedArray()
val optimizedBc = temporary("optimized", ".bc")
hostLlvmTool("opt", combinedBc, "-o", optimizedBc, *optFlags)
val llcFlags = (configurables.llcFlags + when {
optimize -> configurables.llcOptFlags
debug -> configurables.llcDebugFlags
else -> configurables.llcNooptFlags
} + llvmProfilingFlags()).toTypedArray()
val combinedO = temporary("combined", ".o")
hostLlvmTool("llc", optimizedBc, "-o", combinedO, *llcFlags, "-filetype=obj")
val linkedWasm = temporary("linked", ".wasm")
hostLlvmTool("wasm-ld", combinedO, "-o", linkedWasm, *configurables.lldFlags.toTypedArray())
return linkedWasm
}
private fun llvmLinkAndLlc(bitcodeFiles: List<BitcodeFile>): String {
val combinedBc = temporary("combined", ".bc")
hostLlvmTool("llvm-link", "-o", combinedBc, *bitcodeFiles.toTypedArray())
val optimizedBc = temporary("optimized", ".bc")
val optFlags = llvmProfilingFlags() + listOf("-O3", "-internalize", "-globaldce")
hostLlvmTool("opt", combinedBc, "-o=$optimizedBc", *optFlags.toTypedArray())
val combinedO = temporary("combined", ".o")
val llcFlags = llvmProfilingFlags() + listOf("-function-sections", "-data-sections")
hostLlvmTool("llc", optimizedBc, "-filetype=obj", "-o", combinedO, *llcFlags.toTypedArray())
return combinedO
}
// llvm-lto, opt and llc share same profiling flags, so we can
// reuse this function.
private fun llvmProfilingFlags(): List<String> {
val flags = mutableListOf<String>()
if (context.shouldProfilePhases()) {
flags += "-time-passes"
}
if (context.inVerbosePhase) {
flags += "-debug-pass=Structure"
}
return flags
}
private fun asLinkerArgs(args: List<String>): List<String> {
if (linker.useCompilerDriverAsLinker) {
return args
}
val result = mutableListOf<String>()
for (arg in args) {
// If user passes compiler arguments to us - transform them to linker ones.
if (arg.startsWith("-Wl,")) {
result.addAll(arg.substring(4).split(','))
} else {
result.add(arg)
}
}
return result
}
// Ideally we'd want to have
// #pragma weak main = Konan_main
// in the launcher.cpp.
// Unfortunately, anything related to weak linking on MacOS
// only seems to be working with dynamic libraries.
// So we stick to "-alias _main _konan_main" on Mac.
// And just do the same on Linux.
private val entryPointSelector: List<String>
get() = if (nomain || linkerOutput != LinkerOutputKind.EXECUTABLE) emptyList() else platform.entrySelector
private fun link(objectFiles: List<ObjectFile>,
includedBinaries: List<String>,
libraryProvidedLinkerFlags: List<String>): ExecutableFile? {
val frameworkLinkerArgs: List<String>
val executable: String
if (context.config.produce != CompilerOutputKind.FRAMEWORK) {
frameworkLinkerArgs = emptyList()
executable = context.config.outputFile
} else {
val framework = File(context.config.outputFile)
val dylibName = framework.name.removeSuffix(".framework")
val dylibRelativePath = when (target.family) {
Family.IOS -> dylibName
Family.OSX -> "Versions/A/$dylibName"
else -> error(target)
}
frameworkLinkerArgs = listOf("-install_name", "@rpath/${framework.name}/$dylibRelativePath")
val dylibPath = framework.child(dylibRelativePath)
dylibPath.parentFile.mkdirs()
executable = dylibPath.absolutePath
}
try {
File(executable).delete()
linker.linkCommands(objectFiles = objectFiles, executable = executable,
libraries = linker.linkStaticLibraries(includedBinaries) + context.config.defaultSystemLibraries,
linkerArgs = entryPointSelector +
asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) +
BitcodeEmbedding.getLinkerOptions(context.config) +
libraryProvidedLinkerFlags + frameworkLinkerArgs,
optimize = optimize, debug = debug, kind = linkerOutput,
outputDsymBundle = context.config.outputFile + ".dSYM").forEach {
it.logWith(context::log)
it.execute()
}
} catch (e: KonanExternalToolFailure) {
context.reportCompilationError("${e.toolName} invocation reported errors")
}
return executable
}
val objectFiles = mutableListOf<String>()
fun makeObjectFiles() {
val bitcodeFiles = listOf(emitted) + additionalBitcodeFilesToLink +
bitcodeLibraries.map { it.bitcodePaths }.flatten().filter { it.isBitcode }
objectFiles.add(when (platform.configurables) {
is WasmConfigurables
-> bitcodeToWasm(bitcodeFiles)
is ZephyrConfigurables
-> llvmLinkAndLlc(bitcodeFiles)
else
-> llvmLto(bitcodeFiles)
})
}
fun linkStage() {
val includedBinaries =
nativeDependencies.map { it.includedPaths }.flatten()
val libraryProvidedLinkerFlags =
nativeDependencies.map { it.linkerOpts }.flatten()
link(objectFiles, includedBinaries, libraryProvidedLinkerFlags)
}
}
@@ -0,0 +1,109 @@
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.konan.KonanExternalToolFailure
import org.jetbrains.kotlin.konan.file.File
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.konan.target.Family
import org.jetbrains.kotlin.konan.target.LinkerOutputKind
internal fun determineLinkerOutput(context: Context): LinkerOutputKind =
when (context.config.produce) {
CompilerOutputKind.FRAMEWORK -> {
val staticFramework = context.config.produceStaticFramework
if (staticFramework) LinkerOutputKind.STATIC_LIBRARY else LinkerOutputKind.DYNAMIC_LIBRARY
}
CompilerOutputKind.DYNAMIC -> LinkerOutputKind.DYNAMIC_LIBRARY
CompilerOutputKind.STATIC -> LinkerOutputKind.STATIC_LIBRARY
CompilerOutputKind.PROGRAM -> LinkerOutputKind.EXECUTABLE
else -> TODO("${context.config.produce} should not reach native linker stage")
}
// TODO: We have a Linker.kt file in the shared module.
internal class Linker(val context: Context) {
private val platform = context.config.platform
private val config = context.config.configuration
private val linkerOutput = determineLinkerOutput(context)
private val nomain = config.get(KonanConfigKeys.NOMAIN) ?: false
private val linker = platform.linker
private val target = context.config.target
private val optimize = context.shouldOptimize()
private val debug = context.config.debug
// Ideally we'd want to have
// #pragma weak main = Konan_main
// in the launcher.cpp.
// Unfortunately, anything related to weak linking on MacOS
// only seems to be working with dynamic libraries.
// So we stick to "-alias _main _konan_main" on Mac.
// And just do the same on Linux.
private val entryPointSelector: List<String>
get() = if (nomain || linkerOutput != LinkerOutputKind.EXECUTABLE) emptyList() else platform.entrySelector
fun link(objectFiles: List<ObjectFile>) {
val nativeDependencies = context.llvm.nativeDependenciesToLink
val includedBinaries = nativeDependencies.map { it.includedPaths }.flatten()
val libraryProvidedLinkerFlags = nativeDependencies.map { it.linkerOpts }.flatten()
runLinker(objectFiles, includedBinaries, libraryProvidedLinkerFlags)
}
private fun asLinkerArgs(args: List<String>): List<String> {
if (linker.useCompilerDriverAsLinker) {
return args
}
val result = mutableListOf<String>()
for (arg in args) {
// If user passes compiler arguments to us - transform them to linker ones.
if (arg.startsWith("-Wl,")) {
result.addAll(arg.substring(4).split(','))
} else {
result.add(arg)
}
}
return result
}
private fun runLinker(objectFiles: List<ObjectFile>,
includedBinaries: List<String>,
libraryProvidedLinkerFlags: List<String>): ExecutableFile? {
val frameworkLinkerArgs: List<String>
val executable: String
if (context.config.produce != CompilerOutputKind.FRAMEWORK) {
frameworkLinkerArgs = emptyList()
executable = context.config.outputFile
} else {
val framework = File(context.config.outputFile)
val dylibName = framework.name.removeSuffix(".framework")
val dylibRelativePath = when (target.family) {
Family.IOS -> dylibName
Family.OSX -> "Versions/A/$dylibName"
else -> error(target)
}
frameworkLinkerArgs = listOf("-install_name", "@rpath/${framework.name}/$dylibRelativePath")
val dylibPath = framework.child(dylibRelativePath)
dylibPath.parentFile.mkdirs()
executable = dylibPath.absolutePath
}
try {
File(executable).delete()
linker.linkCommands(objectFiles = objectFiles, executable = executable,
libraries = linker.linkStaticLibraries(includedBinaries) + context.config.defaultSystemLibraries,
linkerArgs = entryPointSelector +
asLinkerArgs(config.getNotNull(KonanConfigKeys.LINKER_ARGS)) +
BitcodeEmbedding.getLinkerOptions(context.config) +
libraryProvidedLinkerFlags + frameworkLinkerArgs,
optimize = optimize, debug = debug, kind = linkerOutput,
outputDsymBundle = context.config.outputFile + ".dSYM").forEach {
it.logWith(context::log)
it.execute()
}
} catch (e: KonanExternalToolFailure) {
context.reportCompilationError("${e.toolName} invocation reported errors")
}
return executable
}
}
@@ -0,0 +1,146 @@
package org.jetbrains.kotlin.backend.konan
import kotlinx.cinterop.alloc
import kotlinx.cinterop.memScoped
import kotlinx.cinterop.ptr
import kotlinx.cinterop.value
import llvm.*
import org.jetbrains.kotlin.konan.target.KonanTarget
private fun initializeLlvmGlobalPassRegistry() {
val passRegistry = LLVMGetGlobalPassRegistry()
LLVMInitializeCore(passRegistry)
LLVMInitializeTransformUtils(passRegistry)
LLVMInitializeScalarOpts(passRegistry)
LLVMInitializeVectorization(passRegistry)
LLVMInitializeInstCombine(passRegistry)
LLVMInitializeIPO(passRegistry)
LLVMInitializeInstrumentation(passRegistry)
LLVMInitializeAnalysis(passRegistry)
LLVMInitializeIPA(passRegistry)
LLVMInitializeCodeGen(passRegistry)
LLVMInitializeTarget(passRegistry)
}
internal fun shouldRunLateBitcodePasses(context: Context): Boolean {
return context.coverage.enabled
}
internal fun runLateBitcodePasses(context: Context, llvmModule: LLVMModuleRef) {
val passManager = LLVMCreatePassManager()!!
val targetLibraryInfo = LLVMGetTargetLibraryInfo(llvmModule)
LLVMAddTargetLibraryInfo(targetLibraryInfo, passManager)
context.coverage.addLateLlvmPasses(passManager)
LLVMRunPassManager(passManager, llvmModule)
LLVMDisposePassManager(passManager)
}
private class LlvmPipelineConfiguration(context: Context) {
private val target = context.config.target
val targetTriple: String = context.llvm.targetTriple
val cpuArchitecture: String = when (target) {
KonanTarget.IOS_ARM32 -> "armv7"
KonanTarget.IOS_ARM64 -> "arm64"
KonanTarget.MACOS_X64 -> "core2"
else -> error("There is no support for ${target.name} target yet.")
}
val cpuFeatures: String = ""
val customInlineThreshold: Int? = when {
context.shouldOptimize() -> 100
context.shouldContainDebugInfo() -> null
else -> null
}
val optimizationLevel: Int = when {
context.shouldOptimize() -> 3
context.shouldContainDebugInfo() -> 0
else -> 1
}
val sizeLevel: Int = when {
context.shouldOptimize() -> 0
context.shouldContainDebugInfo() -> 0
else -> 0
}
val codegenOptimizationLevel: LLVMCodeGenOptLevel = when {
context.shouldOptimize() -> LLVMCodeGenOptLevel.LLVMCodeGenLevelAggressive
context.shouldContainDebugInfo() -> LLVMCodeGenOptLevel.LLVMCodeGenLevelNone
else -> LLVMCodeGenOptLevel.LLVMCodeGenLevelDefault
}
val relocMode: LLVMRelocMode = LLVMRelocMode.LLVMRelocDefault
val codeModel: LLVMCodeModel = LLVMCodeModel.LLVMCodeModelDefault
}
// Since we are in a "closed world" internalization and global dce
// can be safely used to reduce size of a bitcode.
internal fun runClosedWorldCleanup(context: Context) {
initializeLlvmGlobalPassRegistry()
val llvmModule = context.llvmModule!!
val modulePasses = LLVMCreatePassManager()
LLVMAddInternalizePass(modulePasses, 0)
LLVMAddGlobalDCEPass(modulePasses)
LLVMRunPassManager(modulePasses, llvmModule)
LLVMDisposePassManager(modulePasses)
}
internal fun runLlvmOptimizationPipeline(context: Context) {
val llvmModule = context.llvmModule!!
val config = LlvmPipelineConfiguration(context)
memScoped {
LLVMKotlinInitializeTargets()
initializeLlvmGlobalPassRegistry()
val passBuilder = LLVMPassManagerBuilderCreate()
val modulePasses = LLVMCreatePassManager()
LLVMPassManagerBuilderSetOptLevel(passBuilder, config.optimizationLevel)
LLVMPassManagerBuilderSetSizeLevel(passBuilder, config.sizeLevel)
// TODO: use LLVMGetTargetFromName instead.
val target = alloc<LLVMTargetRefVar>()
val foundLlvmTarget = LLVMGetTargetFromTriple(config.targetTriple, target.ptr, null) == 0
check(foundLlvmTarget) { "Cannot get target from triple ${config.targetTriple}." }
val targetMachine = LLVMCreateTargetMachine(
target.value,
config.targetTriple,
config.cpuArchitecture,
config.cpuFeatures,
config.codegenOptimizationLevel,
config.relocMode,
config.codeModel)
val targetLibraryInfo = LLVMGetTargetLibraryInfo(llvmModule)
LLVMAddTargetLibraryInfo(targetLibraryInfo, modulePasses)
// TargetTransformInfo pass.
LLVMAddAnalysisPasses(targetMachine, modulePasses)
// Since we are in a "closed world" internalization and global dce
// can be safely used to reduce size of a bitcode.
LLVMAddInternalizePass(modulePasses, 0)
LLVMAddGlobalDCEPass(modulePasses)
config.customInlineThreshold?.let { threshold ->
LLVMPassManagerBuilderUseInlinerWithThreshold(passBuilder, threshold)
}
// Pipeline that is similar to `llvm-lto`.
// TODO: Add ObjC optimization passes.
LLVMPassManagerBuilderPopulateLTOPassManager(passBuilder, modulePasses, Internalize = 0, RunInliner = 1)
LLVMPassManagerBuilderDispose(passBuilder)
LLVMRunPassManager(modulePasses, llvmModule)
LLVMDisposeTargetMachine(targetMachine)
LLVMDisposePassManager(modulePasses)
}
if (shouldRunLateBitcodePasses(context)) {
runLateBitcodePasses(context, llvmModule)
}
}
@@ -1,9 +1,9 @@
package org.jetbrains.kotlin.backend.konan package org.jetbrains.kotlin.backend.konan
import llvm.LLVMWriteBitcodeToFile
import org.jetbrains.kotlin.backend.common.LoggingContext import org.jetbrains.kotlin.backend.common.LoggingContext
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
import org.jetbrains.kotlin.backend.common.phaser.* import org.jetbrains.kotlin.backend.common.phaser.*
import org.jetbrains.kotlin.backend.common.serialization.DeserializationStrategy
import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule import org.jetbrains.kotlin.backend.konan.descriptors.isForwardDeclarationModule
import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary import org.jetbrains.kotlin.backend.konan.descriptors.konanLibrary
import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols import org.jetbrains.kotlin.backend.konan.ir.KonanSymbols
@@ -15,10 +15,15 @@ import org.jetbrains.kotlin.cli.common.messages.AnalyzerWithCompilerReport
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.backend.common.serialization.DescriptorTable import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
import org.jetbrains.kotlin.backend.konan.library.impl.buildLibrary
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.SymbolTable import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.patchDeclarationParents import org.jetbrains.kotlin.ir.util.patchDeclarationParents
import org.jetbrains.kotlin.konan.CURRENT
import org.jetbrains.kotlin.konan.KonanAbiVersion
import org.jetbrains.kotlin.konan.KonanVersion
import org.jetbrains.kotlin.konan.library.KonanLibraryVersioning
import org.jetbrains.kotlin.konan.target.CompilerOutputKind import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
@@ -185,20 +190,14 @@ internal val serializerPhase = konanUnitPhase(
description = "Serialize descriptor tree and inline IR bodies" description = "Serialize descriptor tree and inline IR bodies"
) )
internal val setUpLinkStagePhase = konanUnitPhase(
op = { linkStage = LinkStage(this) },
name = "SetUpLinkStage",
description = "Set up link stage"
)
internal val objectFilesPhase = konanUnitPhase( internal val objectFilesPhase = konanUnitPhase(
op = { linkStage.makeObjectFiles() }, op = { compilerOutput = BitcodeCompiler(this).makeObjectFiles(bitcodeFileName) },
name = "ObjectFiles", name = "ObjectFiles",
description = "Bitcode to object file" description = "Bitcode to object file"
) )
internal val linkerPhase = konanUnitPhase( internal val linkerPhase = konanUnitPhase(
op = { linkStage.linkStage() }, op = { Linker(this).link(compilerOutput) },
name = "Linker", name = "Linker",
description = "Linker" description = "Linker"
) )
@@ -206,8 +205,7 @@ internal val linkerPhase = konanUnitPhase(
internal val linkPhase = namedUnitPhase( internal val linkPhase = namedUnitPhase(
name = "Link", name = "Link",
description = "Link stage", description = "Link stage",
lower = setUpLinkStagePhase then lower = objectFilesPhase then
objectFilesPhase then
linkerPhase linkerPhase
) )
@@ -304,7 +302,6 @@ internal val bitcodePhase = namedIrModulePhase(
escapeAnalysisPhase then escapeAnalysisPhase then
codegenPhase then codegenPhase then
finalizeDebugInfoPhase then finalizeDebugInfoPhase then
bitcodePassesPhase then
cStubsPhase cStubsPhase
) )
@@ -330,9 +327,9 @@ val toplevelPhase: CompilerPhase<*, Unit, Unit> = namedUnitPhase(
dependenciesLowerPhase then // Then lower all libraries in topological order. dependenciesLowerPhase then // Then lower all libraries in topological order.
// With that we guarantee that inline functions are unlowered while being inlined. // With that we guarantee that inline functions are unlowered while being inlined.
bitcodePhase then bitcodePhase then
produceOutputPhase then
verifyBitcodePhase then verifyBitcodePhase then
printBitcodePhase then printBitcodePhase then
produceOutputPhase then
unitSink() unitSink()
) then ) then
linkPhase linkPhase
@@ -124,16 +124,6 @@ internal val cStubsPhase = makeKonanModuleOpPhase(
op = { context, _ -> produceCStubs(context) } op = { context, _ -> produceCStubs(context) }
) )
/**
* Runs specific passes over context.llvmModule. The main compilation pipeline
* is performed by [linkPhase].
*/
internal val bitcodePassesPhase = makeKonanModuleOpPhase(
name = "BitcodePasses",
description = "Run custom LLVM passes over bitcode",
op = { context, _ -> runBitcodePasses(context) }
)
internal val produceOutputPhase = makeKonanModuleOpPhase( internal val produceOutputPhase = makeKonanModuleOpPhase(
name = "ProduceOutput", name = "ProduceOutput",
description = "Produce output", description = "Produce output",
@@ -409,9 +409,11 @@ internal class Llvm(val context: Context, val llvmModule: LLVMModuleRef) {
val runtimeFile = context.config.distribution.runtime(target) val runtimeFile = context.config.distribution.runtime(target)
val runtime = Runtime(runtimeFile) // TODO: dispose val runtime = Runtime(runtimeFile) // TODO: dispose
val targetTriple = runtime.target
init { init {
LLVMSetDataLayout(llvmModule, runtime.dataLayout) LLVMSetDataLayout(llvmModule, runtime.dataLayout)
LLVMSetTarget(llvmModule, runtime.target) LLVMSetTarget(llvmModule, targetTriple)
} }
private fun importRtFunction(name: String) = importFunction(name, runtime.llvmModule) private fun importRtFunction(name: String) = importFunction(name, runtime.llvmModule)
@@ -318,7 +318,6 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
codegen.objCDataGenerator?.finishModule() codegen.objCDataGenerator?.finishModule()
BitcodeEmbedding.processModule(context.llvm)
context.coverage.writeRegionInfo() context.coverage.writeRegionInfo()
appendDebugSelector() appendDebugSelector()
appendLlvmUsed("llvm.used", context.llvm.usedFunctions + context.llvm.usedGlobals) appendLlvmUsed("llvm.used", context.llvm.usedFunctions + context.llvm.usedGlobals)
@@ -4,12 +4,9 @@
*/ */
package org.jetbrains.kotlin.backend.konan.llvm.coverage package org.jetbrains.kotlin.backend.konan.llvm.coverage
import llvm.LLVMAddInstrProfPass import llvm.*
import llvm.LLVMPassManagerRef import org.jetbrains.kotlin.backend.konan.*
import llvm.LLVMValueRef
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.KonanConfigKeys
import org.jetbrains.kotlin.backend.konan.isNativeBinary
import org.jetbrains.kotlin.backend.konan.reportCompilationError import org.jetbrains.kotlin.backend.konan.reportCompilationError
import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.descriptors.ModuleDescriptor
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
@@ -106,10 +103,11 @@ internal class CoverageManager(val context: Context) {
} }
/** /**
* Add InstrProfilingLegacyPass to the list of llvm passes * Add passes that should be executed after main LLVM optimization pipeline.
*/ */
fun addLlvmPasses(passManager: LLVMPassManagerRef) { fun addLateLlvmPasses(passManager: LLVMPassManagerRef) {
if (enabled) { if (enabled) {
// It's a late pass since DCE can kill __llvm_profile_filename global.
LLVMAddInstrProfPass(passManager, outputFileName) LLVMAddInstrProfPass(passManager, outputFileName)
} }
} }
+15 -13
View File
@@ -1,7 +1,9 @@
headers = llvm-c/Core.h llvm-c/Target.h llvm-c/Analysis.h llvm-c/BitWriter.h \ headers = llvm-c/Core.h llvm-c/Target.h llvm-c/Analysis.h llvm-c/BitWriter.h \
llvm-c/BitReader.h llvm-c/Linker.h DebugInfoC.h CoverageMappingC.h llvm-c/BitReader.h llvm-c/Transforms/PassManagerBuilder.h llvm-c/Transforms/IPO.h \
llvm-c/TargetMachine.h llvm-c/Target.h llvm-c/Linker.h llvm-c/Initialization.h \
DebugInfoC.h CoverageMappingC.h
headerFilter = llvm-c/* DebugInfoC.h CoverageMappingC.h headerFilter = llvm-c/* llvm-c/**/* DebugInfoC.h CoverageMappingC.h
compilerOpts = -std=c99 \ compilerOpts = -std=c99 \
-Wall -W -Wno-unused-parameter -Wwrite-strings -Wmissing-field-initializers \ -Wall -W -Wno-unused-parameter -Wwrite-strings -Wmissing-field-initializers \
@@ -16,25 +18,25 @@ linkerOpts = -fvisibility-inlines-hidden \
-pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor \ -pedantic -Wno-long-long -Wcovered-switch-default -Wnon-virtual-dtor -Wdelete-non-virtual-dtor \
-std=c++11 \ -std=c++11 \
-DNDEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS \ -DNDEBUG -D__STDC_CONSTANT_MACROS -D__STDC_FORMAT_MACROS -D__STDC_LIMIT_MACROS \
-ldebugInfo -lcoverageMapping -lLLVMCoverage -lLLVMTarget -lLLVMInstrumentation \ -ldebugInfo -lcoverageMapping
-lLLVMMC -lLLVMLinker -lLLVMTransformUtils -lLLVMBitWriter \
-lLLVMBitReader -lLLVMAnalysis -lLLVMProfileData -lLLVMObject -lLLVMMCParser -lLLVMMC \
-lLLVMCore -lLLVMBinaryFormat -lLLVMSupport -lLLVMDemangle
# ./llvm-config --libs analysis bitreader bitwriter core linker target coverage
# ./llvm-config --libs analysis bitreader bitwriter core linker target coverage analysis ipo instrumentation lto objcarcopts arm aarch64 webassembly x86 mips
linkerOpts.osx = -fPIC \ linkerOpts.osx = -fPIC \
-Wl,-search_paths_first -Wl,-headerpad_max_install_names \ -Wl,-search_paths_first -Wl,-headerpad_max_install_names \
-lpthread -lz -lm -lcurses -Wl,-U,_futimens -Wl,-U,_LLVMDumpType -lpthread -lz -lm -lcurses -Wl,-U,_futimens -Wl,-U,_LLVMDumpType \
-lLLVMLTO -lLLVMPasses -lLLVMObjCARCOpts -lLLVMipo -lLLVMInstrumentation -lLLVMVectorize -lLLVMIRReader -lLLVMAsmParser -lLLVMMipsDisassembler -lLLVMMipsCodeGen -lLLVMMipsAsmParser -lLLVMMipsDesc -lLLVMMipsInfo -lLLVMMipsAsmPrinter -lLLVMX86Disassembler -lLLVMX86AsmParser -lLLVMX86CodeGen -lLLVMX86Desc -lLLVMX86Info -lLLVMX86AsmPrinter -lLLVMX86Utils -lLLVMWebAssemblyDisassembler -lLLVMWebAssemblyCodeGen -lLLVMWebAssemblyDesc -lLLVMWebAssemblyInfo -lLLVMWebAssemblyAsmPrinter -lLLVMAArch64Disassembler -lLLVMAArch64CodeGen -lLLVMAArch64AsmParser -lLLVMAArch64Desc -lLLVMAArch64Info -lLLVMAArch64AsmPrinter -lLLVMAArch64Utils -lLLVMARMDisassembler -lLLVMARMCodeGen -lLLVMGlobalISel -lLLVMSelectionDAG -lLLVMAsmPrinter -lLLVMDebugInfoCodeView -lLLVMDebugInfoMSF -lLLVMCodeGen -lLLVMScalarOpts -lLLVMInstCombine -lLLVMARMAsmParser -lLLVMARMDesc -lLLVMMCDisassembler -lLLVMARMInfo -lLLVMARMAsmPrinter -lLLVMARMUtils -lLLVMCoverage -lLLVMTarget -lLLVMLinker -lLLVMTransformUtils -lLLVMBitWriter -lLLVMAnalysis -lLLVMProfileData -lLLVMObject -lLLVMMCParser -lLLVMMC -lLLVMBitReader -lLLVMCore -lLLVMBinaryFormat -lLLVMSupport -lLLVMDemangle
linkerOpts.linux= -fPIC \ # ./llvm-config --libs analysis bitreader bitwriter core linker target coverage analysis ipo instrumentation lto
linkerOpts.linux= -lLLVMLTO -lLLVMPasses -lLLVMObjCARCOpts -lLLVMCodeGen -lLLVMipo -lLLVMInstrumentation -lLLVMVectorize -lLLVMScalarOpts -lLLVMIRReader -lLLVMAsmParser -lLLVMInstCombine -lLLVMCoverage -lLLVMTarget -lLLVMLinker -lLLVMTransformUtils -lLLVMBitWriter -lLLVMAnalysis -lLLVMProfileData -lLLVMObject -lLLVMMCParser -lLLVMMC -lLLVMBitReader -lLLVMCore -lLLVMBinaryFormat -lLLVMSupport -lLLVMDemangle \
-fPIC \
-Wl,-z,noexecstack \ -Wl,-z,noexecstack \
-lrt -ldl -lpthread -lz -lm -lrt -ldl -lpthread -lz -lm
linkerOpts.mingw = -lole32 -luuid -static-libgcc -static-libstdc++ \ # ./llvm-config --libs analysis bitreader bitwriter core linker target coverage analysis ipo instrumentation lto
linkerOpts.mingw = -lLLVMLTO -lLLVMPasses -lLLVMObjCARCOpts -lLLVMCodeGen -lLLVMipo -lLLVMInstrumentation -lLLVMVectorize -lLLVMScalarOpts -lLLVMIRReader -lLLVMAsmParser -lLLVMInstCombine -lLLVMCoverage -lLLVMTarget -lLLVMLinker -lLLVMTransformUtils -lLLVMBitWriter -lLLVMAnalysis -lLLVMProfileData -lLLVMObject -lLLVMMCParser -lLLVMMC -lLLVMBitReader -lLLVMCore -lLLVMBinaryFormat -lLLVMSupport -lLLVMDemangle \
-lole32 -luuid -static-libgcc -static-libstdc++ \
-Wl,-Bstatic -lz \ -Wl,-Bstatic -lz \
-Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic -Wl,-Bstatic,--whole-archive -lwinpthread -Wl,--no-whole-archive,-Bdynamic \
# It looks like mingw port compiled without LLVM_ENABLE_DUMP # It looks like mingw port compiled without LLVM_ENABLE_DUMP
#Note: ld on mingw process -Wl,-U,_LLVMDumpType use different from other platform #Note: ld on mingw process -Wl,-U,_LLVMDumpType use different from other platform
@@ -3,11 +3,8 @@ package org.jetbrains.kotlin
import groovy.lang.Closure import groovy.lang.Closure
import org.gradle.api.Action import org.gradle.api.Action
import org.gradle.api.DefaultTask import org.gradle.api.DefaultTask
import org.gradle.api.Project
import org.gradle.api.Task import org.gradle.api.Task
import org.gradle.api.tasks.Input import org.gradle.api.tasks.Input
import org.gradle.api.tasks.SourceSet
import org.gradle.api.tasks.SourceSetContainer
import org.gradle.api.tasks.TaskAction import org.gradle.api.tasks.TaskAction
import org.jetbrains.kotlin.konan.target.* import org.jetbrains.kotlin.konan.target.*
@@ -55,9 +52,11 @@ open class FrameworkTest : DefaultTask() {
@TaskAction @TaskAction
fun run() { fun run() {
val frameworkPath = "$testOutput/$frameworkName/${project.testTarget().name}" val frameworkParentDirPath = "$testOutput/$frameworkName/${project.testTarget().name}"
val frameworkPath = "$frameworkParentDirPath/$frameworkName.framework"
codesign(project, Paths.get(frameworkPath, "$frameworkName.framework").toString()) val frameworkBinaryPath = "$frameworkPath/$frameworkName"
validateBitcodeEmbedding(frameworkBinaryPath)
codesign(project, frameworkPath)
// create a test provider and get main entry point // create a test provider and get main entry point
val provider = Paths.get(testOutput, frameworkName, "provider.swift") val provider = Paths.get(testOutput, frameworkName, "provider.swift")
@@ -77,7 +76,7 @@ open class FrameworkTest : DefaultTask() {
// Compile swift sources // Compile swift sources
val sources = swiftSources.map { Paths.get(it).toString() } + val sources = swiftSources.map { Paths.get(it).toString() } +
listOf(provider.toString(), swiftMain) listOf(provider.toString(), swiftMain)
val options = listOf("-g", "-Xlinker", "-rpath", "-Xlinker", frameworkPath, "-F", frameworkPath) val options = listOf("-g", "-Xlinker", "-rpath", "-Xlinker", frameworkParentDirPath, "-F", frameworkParentDirPath)
val testExecutable = Paths.get(testOutput, frameworkName, "swiftTestExecutable") val testExecutable = Paths.get(testOutput, frameworkName, "swiftTestExecutable")
swiftc(sources, options, testExecutable) swiftc(sources, options, testExecutable)
@@ -139,4 +138,32 @@ open class FrameworkTest : DefaultTask() {
check(exitCode == 0, { "Compilation failed" }) check(exitCode == 0, { "Compilation failed" })
check(output.toFile().exists(), { "Compiler swiftc hasn't produced an output file: $output" }) check(output.toFile().exists(), { "Compiler swiftc hasn't produced an output file: $output" })
} }
private fun validateBitcodeEmbedding(frameworkBinary: String) {
// Check only the full bitcode embedding for now.
if (!fullBitcode) {
return
}
val testTarget = project.testTarget()
val configurables = project.platformManager().platform(testTarget).configurables as AppleConfigurables
val bitcodeBuildTool = "${configurables.absoluteAdditionalToolsDir}/bin/bitcode-build-tool"
val ldPath = "${configurables.absoluteTargetToolchain}/usr/bin/ld"
val sdk = when (testTarget) {
KonanTarget.IOS_X64 -> Xcode.current.iphonesimulatorSdk
KonanTarget.IOS_ARM64, KonanTarget.IOS_ARM32 -> Xcode.current.iphoneosSdk
KonanTarget.MACOS_X64 -> Xcode.current.macosxSdk
else -> error("Cannot validate bitcode for test target $testTarget")
}
val args = listOf("--sdk", sdk, "-v", "-t", ldPath, frameworkBinary)
val (stdOut, stdErr, exitCode) = runProcess(executor = localExecutor(project), executable = bitcodeBuildTool, args = args)
check(exitCode == 0) {
"""
|bitcode-build-tool failed:
|stdout: $stdOut
|stderr: $stdErr
""".trimMargin()
}
}
} }
+3 -2
View File
@@ -23,8 +23,9 @@ kotlinVersion=1.3.40-dev-2423
testKotlinVersion=1.3.40-dev-2423 testKotlinVersion=1.3.40-dev-2423
# See https://teamcity.jetbrains.com/project.html?projectId=Kotlin_KotlinNativeShared&tab=projectOverview # See https://teamcity.jetbrains.com/project.html?projectId=Kotlin_KotlinNativeShared&tab=projectOverview
sharedRepo=https://dl.bintray.com/jetbrains/kotlin-native-dependencies sharedRepo=https://dl.bintray.com/jetbrains/kotlin-native-dependencies
sharedVersion=1.0-dev-50 sharedVersion=1.0-dev-57
konanVersion=1.3.0 konanVersion=1.3.0
org.gradle.jvmargs='-Dfile.encoding=UTF-8' org.gradle.jvmargs='-Dfile.encoding=UTF-8'
org.gradle.workers.max=4 org.gradle.workers.max=4
#kotlinProjectPath=/Users/jetbrains/kotlin-native/kotlin #kotlinProjectPath=/Users/jetbrains/IdeaProjects/kotlin
#sharedProjectPath=/Users/jetbrains/IdeaProjects/kotlin-native-shared
+38 -20
View File
@@ -39,24 +39,30 @@ llvmVersion = 6.0.1
llvmHome.macos_x64 = clang-llvm-6.0.1-darwin-macos llvmHome.macos_x64 = clang-llvm-6.0.1-darwin-macos
targetToolchain.macos_x64 = target-toolchain-9-macos_x64 targetToolchain.macos_x64 = target-toolchain-9-macos_x64
libffiDir.macos_x64 = libffi-3.2.1-3-darwin-macos libffiDir.macos_x64 = libffi-3.2.1-3-darwin-macos
additionalToolsDir.macos_x64 = xcode-addon-9-macos_x64
arch.macos_x64 = x86_64 arch.macos_x64 = x86_64
targetSysRoot.macos_x64 = target-sysroot-9-macos_x64 targetSysRoot.macos_x64 = target-sysroot-9-macos_x64
llvmLtoFlags.macos_x64 =
llvmLtoOptFlags.macos_x64 = -O3 -function-sections clangFlags.macos_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir
llvmLtoNooptFlags.macos_x64 = -O1 clangNooptFlags.macos_x64 = -O1
llvmLtoDynamicFlags.macos_x64 = -relocation-model=pic clangOptFlags.macos_x64 = -O3
clangDebugFlags.macos_x64 = -O0
clangDynamicFlags.macos_x64 =
linkerKonanFlags.macos_x64 = -lSystem -lc++ -lobjc -framework Foundation linkerKonanFlags.macos_x64 = -lSystem -lc++ -lobjc -framework Foundation
linkerOptimizationFlags.macos_x64 = -dead_strip linkerOptimizationFlags.macos_x64 = -dead_strip
linkerNoDebugFlags.macos_x64 = -S linkerNoDebugFlags.macos_x64 = -S
linkerDynamicFlags.macos_x64 = -dylib linkerDynamicFlags.macos_x64 = -dylib
osVersionMinFlagLd.macos_x64 = -macosx_version_min osVersionMinFlagLd.macos_x64 = -macosx_version_min
osVersionMinFlagClang.macos_x64 = -mmacosx-version-min osVersionMinFlagClang.macos_x64 = -mmacosx-version-min
osVersionMin.macos_x64 = 10.11 osVersionMin.macos_x64 = 10.11
entrySelector.macos_x64 = -alias _Konan_main _main entrySelector.macos_x64 = -alias _Konan_main _main
dependencies.macos_x64 = \ dependencies.macos_x64 = \
libffi-3.2.1-3-darwin-macos \ libffi-3.2.1-3-darwin-macos \
clang-llvm-6.0.1-darwin-macos clang-llvm-6.0.1-darwin-macos \
xcode-addon-9-macos_x64
target-sysroot-9-macos_x64.default = \ target-sysroot-9-macos_x64.default = \
remote:internal remote:internal
@@ -64,6 +70,10 @@ target-sysroot-9-macos_x64.default = \
target-toolchain-9-macos_x64.default = \ target-toolchain-9-macos_x64.default = \
remote:internal remote:internal
xcode-addon-9-macos_x64.default = \
remote:internal
# Apple's 32-bit iOS. # Apple's 32-bit iOS.
targetToolchain.macos_x64-ios_arm32 = target-toolchain-9-macos_x64 targetToolchain.macos_x64-ios_arm32 = target-toolchain-9-macos_x64
dependencies.macos_x64-ios_arm32 = \ dependencies.macos_x64-ios_arm32 = \
@@ -77,13 +87,15 @@ arch.ios_arm32 = armv7
entrySelector.ios_arm32 = -alias _Konan_main _main entrySelector.ios_arm32 = -alias _Konan_main _main
# Shared with 64-bit version. # Shared with 64-bit version.
targetSysRoot.ios_arm32 = target-sysroot-9-ios_arm64 targetSysRoot.ios_arm32 = target-sysroot-9-ios_arm64
llvmLtoFlags.ios_arm32 =
llvmLtoOptFlags.ios_arm32 = -O3 -function-sections clangFlags.ios_arm32 = -cc1 -emit-obj -disable-llvm-optzns -x ir
clangNooptFlags.ios_arm32 = -O1
clangOptFlags.ios_arm32 = -O3
clangDebugFlags.ios_arm32 = -O0
clangDynamicFlags.ios_arm32 =
linkerNoDebugFlags.ios_arm32 = -S linkerNoDebugFlags.ios_arm32 = -S
linkerDynamicFlags.ios_arm32 = -dylib linkerDynamicFlags.ios_arm32 = -dylib
llvmLtoNooptFlags.ios_arm32 = -O1 linkerKonanFlags.ios_arm32 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 11.2
llvmLtoDynamicFlags.ios_arm32 = -relocation-model=pic
linkerKonanFlags.ios_arm32 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 12.2
linkerOptimizationFlags.ios_arm32 = -dead_strip linkerOptimizationFlags.ios_arm32 = -dead_strip
osVersionMinFlagLd.ios_arm32 = -iphoneos_version_min osVersionMinFlagLd.ios_arm32 = -iphoneos_version_min
osVersionMinFlagClang.ios_arm32 = -miphoneos-version-min osVersionMinFlagClang.ios_arm32 = -miphoneos-version-min
@@ -101,13 +113,16 @@ target-sysroot-9-ios_arm64.default = \
arch.ios_arm64 = arm64 arch.ios_arm64 = arm64
entrySelector.ios_arm64 = -alias _Konan_main _main entrySelector.ios_arm64 = -alias _Konan_main _main
targetSysRoot.ios_arm64 = target-sysroot-9-ios_arm64 targetSysRoot.ios_arm64 = target-sysroot-9-ios_arm64
llvmLtoFlags.ios_arm64 =
llvmLtoOptFlags.ios_arm64 = -O3 -function-sections clangFlags.ios_arm64 = -cc1 -emit-obj -disable-llvm-passes -x ir
clangNooptFlags.ios_arm64 = -O1
clangOptFlags.ios_arm64 = -O3
clangDebugFlags.ios_arm64 = -O0
clangDynamicFlags.ios_arm64 =
linkerNoDebugFlags.ios_arm64 = -S linkerNoDebugFlags.ios_arm64 = -S
linkerDynamicFlags.ios_arm64 = -dylib linkerDynamicFlags.ios_arm64 = -dylib
llvmLtoNooptFlags.ios_arm64 = -O1 linkerKonanFlags.ios_arm64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 11.2
llvmLtoDynamicFlags.ios_arm64 = -relocation-model=pic
linkerKonanFlags.ios_arm64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 12.2
linkerOptimizationFlags.ios_arm64 = -dead_strip linkerOptimizationFlags.ios_arm64 = -dead_strip
osVersionMinFlagLd.ios_arm64 = -iphoneos_version_min osVersionMinFlagLd.ios_arm64 = -iphoneos_version_min
osVersionMinFlagClang.ios_arm64 = -miphoneos-version-min osVersionMinFlagClang.ios_arm64 = -miphoneos-version-min
@@ -125,11 +140,14 @@ target-sysroot-9-ios_x64.default = \
arch.ios_x64 = x86_64 arch.ios_x64 = x86_64
entrySelector.ios_x64 = -alias _Konan_main _main entrySelector.ios_x64 = -alias _Konan_main _main
targetSysRoot.ios_x64 = target-sysroot-9-ios_x64 targetSysRoot.ios_x64 = target-sysroot-9-ios_x64
llvmLtoFlags.ios_x64 =
llvmLtoOptFlags.ios_x64 = -O3 -function-sections clangFlags.ios_x64 = -cc1 -emit-obj -disable-llvm-passes -x ir
llvmLtoNooptFlags.ios_x64 = -O1 clangNooptFlags.ios_x64 = -O1
llvmLtoDynamicFlags.ios_x64 = -relocation-model=pic clangOptFlags.ios_x64 = -O3
linkerKonanFlags.ios_x64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 12.2 clangDebugFlags.ios_x64 = -O0
clangDynamicFlags.ios_x64 =
linkerKonanFlags.ios_x64 = -lSystem -lc++ -lobjc -framework Foundation -sdk_version 11.2
linkerOptimizationFlags.ios_x64 = -dead_strip linkerOptimizationFlags.ios_x64 = -dead_strip
linkerNoDebugFlags.ios_x64 = -S linkerNoDebugFlags.ios_x64 = -S
linkerDynamicFlags.ios_x64 = -dylib linkerDynamicFlags.ios_x64 = -dylib
+9
View File
@@ -30,6 +30,15 @@ model {
if (!project.parent.convention.plugins.platformInfo.isWindows()) if (!project.parent.convention.plugins.platformInfo.isWindows())
cppCompiler.args "-fPIC" cppCompiler.args "-fPIC"
cppCompiler.args "--std=c++11", "-I${llvmDir}/include", "-I${projectDir}/src/main/include" cppCompiler.args "--std=c++11", "-I${llvmDir}/include", "-I${projectDir}/src/main/include"
if (isMac()) {
cppCompiler.args "-DKONAN_MACOS=1"
} else if (isWindows()) {
cppCompiler.args "-DKONAN_WINDOWS=1"
} else if (isLinux()) {
cppCompiler.args "-DKONAN_LINUX=1"
} else {
throw new Error("Unsupported host OS.")
}
linker.args "-L${llvmDir}/lib", "-lLLVMCore", "-lLLVMSupport" linker.args "-L${llvmDir}/lib", "-lLLVMCore", "-lLLVMSupport"
} }
binaries.withType(SharedLibraryBinarySpec) { binary -> binaries.withType(SharedLibraryBinarySpec) { binary ->
@@ -228,3 +228,21 @@ LLVMTargetLibraryInfoRef LLVMGetTargetLibraryInfo(LLVMModuleRef moduleRef) {
auto* libraryInfo = new TargetLibraryInfoImpl(Triple(unwrap(moduleRef)->getTargetTriple())); auto* libraryInfo = new TargetLibraryInfoImpl(Triple(unwrap(moduleRef)->getTargetTriple()));
return llvm::wrap(libraryInfo); return llvm::wrap(libraryInfo);
} }
void LLVMKotlinInitializeTargets() {
#define INIT_LLVM_TARGET(TargetName) \
LLVMInitialize##TargetName##TargetInfo();\
LLVMInitialize##TargetName##Target();\
LLVMInitialize##TargetName##TargetMC();
#if KONAN_MACOS
INIT_LLVM_TARGET(AArch64)
INIT_LLVM_TARGET(ARM)
INIT_LLVM_TARGET(Mips)
INIT_LLVM_TARGET(X86)
INIT_LLVM_TARGET(WebAssembly)
#elif KONAN_LINUX
#elif KONAN_WINDOWS
#endif
#undef INIT_LLVM_TARGET
}
@@ -74,8 +74,9 @@ void LLVMAddInstrProfPass(LLVMPassManagerRef passManagerRef, const char* outputF
LLVMTargetLibraryInfoRef LLVMGetTargetLibraryInfo(LLVMModuleRef moduleRef); LLVMTargetLibraryInfoRef LLVMGetTargetLibraryInfo(LLVMModuleRef moduleRef);
void LLVMKotlinInitializeTargets();
# ifdef __cplusplus # ifdef __cplusplus
} }
# endif # endif
#endif #endif
+8
View File
@@ -9,6 +9,7 @@ TARBALL_iphonesimulator=target-sysroot-$KONAN_TOOLCHAIN_VERSION-ios_x64
TARBALL_watchos=target-sysroot-$KONAN_TOOLCHAIN_VERSION-watchos_arm32 TARBALL_watchos=target-sysroot-$KONAN_TOOLCHAIN_VERSION-watchos_arm32
TARBALL_watchsimulator=target-sysroot-$KONAN_TOOLCHAIN_VERSION-watchos_x64 TARBALL_watchsimulator=target-sysroot-$KONAN_TOOLCHAIN_VERSION-watchos_x64
TARBALL_xcode=target-toolchain-$KONAN_TOOLCHAIN_VERSION-macos_x64 TARBALL_xcode=target-toolchain-$KONAN_TOOLCHAIN_VERSION-macos_x64
TARBALL_xcode_addon=xcode-addon-$KONAN_TOOLCHAIN_VERSION-macos_x64
OUT=`pwd` OUT=`pwd`
for s in $SDKS; do for s in $SDKS; do
@@ -26,3 +27,10 @@ t=`grealpath $t/../..`
tarball=$TARBALL_xcode tarball=$TARBALL_xcode
echo "Packing toolchain $OUT/$tarball.tar.gz..." echo "Packing toolchain $OUT/$tarball.tar.gz..."
$SHELL -c "tar czf $OUT/$tarball.tar.gz -C $t -s '/^\./$tarball/' ." $SHELL -c "tar czf $OUT/$tarball.tar.gz -C $t -s '/^\./$tarball/' ."
t=`xcrun -f bitcode-build-tool`
t=`dirname $t`
t=`grealpath $t/..`
tarball=$TARBALL_xcode_addon
echo "Packing additional tools $OUT/$tarball.tar.gz..."
$SHELL -c "tar czf $OUT/$tarball.tar.gz -C $t -s '/^\./$tarball/' ."