Merge pull request #3695 from JetBrains/igushkin/descriptor-only-libs

Support compiling a common-Native source set into a descriptor-only library
This commit is contained in:
Sergey Igushkin
2019-12-27 17:53:05 +04:00
committed by GitHub
8 changed files with 58 additions and 20 deletions
@@ -140,6 +140,8 @@ class K2Native : CLICompiler<K2NativeCompilerArguments>() {
val outputKind = CompilerOutputKind.valueOf(
(arguments.produce ?: "program").toUpperCase())
put(PRODUCE, outputKind)
put(METADATA_KLIB, arguments.metadataKlib)
arguments.libraryVersion ?. let { put(LIBRARY_VERSION, it) }
arguments.mainPackage ?.let{ put(ENTRY, it) }
@@ -245,6 +245,9 @@ class K2NativeCompilerArguments : CommonCompilerArguments() {
@Argument(value="-Xallocator", valueDescription = "std | mimalloc", description = "Allocator used in runtime")
var allocator: String = "std"
@Argument(value = "-Xmetadata-klib", description = "Produce a klib that only contains the declarations metadata")
var metadataKlib: Boolean = false
override fun configureAnalysisFlags(collector: MessageCollector): MutableMap<AnalysisFlag<*>, Any> =
super.configureAnalysisFlags(collector).also {
val useExperimental = it[AnalysisFlags.useExperimental] as List<*>
@@ -153,7 +153,7 @@ internal fun produceOutput(context: Context) {
context.config.includeBinaries,
neededLibraries,
context.serializedMetadata!!,
context.serializedIr!!,
context.serializedIr,
versions,
target,
output,
@@ -64,6 +64,8 @@ class KonanConfig(val project: Project, val configuration: CompilerConfiguration
internal val produce get() = configuration.get(KonanConfigKeys.PRODUCE)!!
internal val metadataKlib get() = configuration.get(KonanConfigKeys.METADATA_KLIB)!!
internal val produceStaticFramework get() = configuration.getBoolean(KonanConfigKeys.STATIC_FRAMEWORK)
internal val purgeUserLibs: Boolean
@@ -66,6 +66,8 @@ class KonanConfigKeys {
= CompilerConfigurationKey.create("memory model")
val META_INFO: CompilerConfigurationKey<List<String>>
= CompilerConfigurationKey.create("generate metadata")
val METADATA_KLIB: CompilerConfigurationKey<Boolean>
= CompilerConfigurationKey.create("metadata klib")
val MODULE_KIND: CompilerConfigurationKey<ModuleKind>
= CompilerConfigurationKey.create("module kind")
val MODULE_NAME: CompilerConfigurationKey<String?>
@@ -267,9 +267,11 @@ internal val serializerPhase = konanUnitPhase(
val mppKlibs = config.configuration.get(CommonConfigurationKeys.KLIB_MPP)?:false
val descriptorTable = DescriptorTable.createDefault()
serializedIr = KonanIrModuleSerializer(
this, irModule!!.irBuiltins, descriptorTable, expectDescriptorToSymbol, skipExpects = !mppKlibs
).serializedIrModule(irModule!!)
serializedIr = irModule?.let { ir ->
KonanIrModuleSerializer(
this, ir.irBuiltins, descriptorTable, expectDescriptorToSymbol, skipExpects = !mppKlibs
).serializedIrModule(ir)
}
val serializer = KlibMetadataMonolithicSerializer(
this.config.configuration.languageVersionSettings,
@@ -421,6 +423,22 @@ internal val bitcodePhase = namedIrModulePhase(
cStubsPhase
)
private val backendCodegen = namedUnitPhase(
name = "Backend codegen",
description = "Backend code generation",
lower = takeFromContext<Context, Unit, IrModuleFragment> { it.irModule!! } then
allLoweringsPhase then // Lower current module first.
dependenciesLowerPhase then // Then lower all libraries in topological order.
// With that we guarantee that inline functions are unlowered while being inlined.
entryPointPhase then
bitcodePhase then
verifyBitcodePhase then
printBitcodePhase then
linkBitcodeDependenciesPhase then
bitcodeOptimizationPhase then
unitSink()
)
// Have to hide Context as type parameter in order to expose toplevelPhase outside of this module.
val toplevelPhase: CompilerPhase<*, Unit, Unit> = namedUnitPhase(
name = "Compiler",
@@ -436,16 +454,7 @@ val toplevelPhase: CompilerPhase<*, Unit, Unit> = namedUnitPhase(
namedUnitPhase(
name = "Backend",
description = "All backend",
lower = takeFromContext<Context, Unit, IrModuleFragment> { it.irModule!! } then
allLoweringsPhase then // Lower current module first.
dependenciesLowerPhase then // Then lower all libraries in topological order.
// With that we guarantee that inline functions are unlowered while being inlined.
entryPointPhase then
bitcodePhase then
verifyBitcodePhase then
printBitcodePhase then
linkBitcodeDependenciesPhase then
bitcodeOptimizationPhase then
lower = backendCodegen then
produceOutputPhase then
disposeLLVMPhase then
unitSink()
@@ -485,5 +494,11 @@ internal fun PhaseConfig.konanPhasesConfig(config: KonanConfig) {
disableUnless(dcePhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
disableUnless(ghaPhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
disableUnless(verifyBitcodePhase, config.needCompilerVerification || getBoolean(KonanConfigKeys.VERIFY_BITCODE))
val isDescriptorsOnlyLibrary = config.metadataKlib == true
disableIf(psiToIrPhase, isDescriptorsOnlyLibrary)
disableIf(destroySymbolTablePhase, isDescriptorsOnlyLibrary)
disableIf(copyDefaultValuesToActualPhase, isDescriptorsOnlyLibrary)
disableIf(backendCodegen, isDescriptorsOnlyLibrary)
}
}
@@ -6,6 +6,10 @@
package org.jetbrains.kotlin.backend.konan.llvm
import llvm.*
import org.jetbrains.kotlin.backend.common.phaser.CompilerPhase
import org.jetbrains.kotlin.backend.common.phaser.PhaseConfig
import org.jetbrains.kotlin.backend.common.phaser.PhaserState
import org.jetbrains.kotlin.backend.common.phaser.namedUnitPhase
import org.jetbrains.kotlin.backend.konan.*
import org.jetbrains.kotlin.backend.konan.descriptors.GlobalHierarchyAnalysis
import org.jetbrains.kotlin.backend.konan.optimizations.*
@@ -44,10 +48,14 @@ internal val createLLVMDeclarationsPhase = makeKonanModuleOpPhase(
}
)
internal val disposeLLVMPhase = makeKonanModuleOpPhase(
internal val disposeLLVMPhase = namedUnitPhase(
name = "DisposeLLVM",
description = "Dispose LLVM",
op = { context, _ -> context.disposeLlvm() }
lower = object : CompilerPhase<Context, Unit, Unit> {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<Unit>, context: Context, input: Unit) {
context.disposeLlvm()
}
}
)
internal val RTTIPhase = makeKonanModuleOpPhase(
@@ -265,10 +273,14 @@ internal val bitcodeOptimizationPhase = makeKonanModuleOpPhase(
op = { context, _ -> runLlvmOptimizationPipeline(context) }
)
internal val produceOutputPhase = makeKonanModuleOpPhase(
internal val produceOutputPhase = namedUnitPhase(
name = "ProduceOutput",
description = "Produce output",
op = { context, _ -> produceOutput(context) }
lower = object : CompilerPhase<Context, Unit, Unit> {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<Unit>, context: Context, input: Unit) {
produceOutput(context)
}
}
)
internal val verifyBitcodePhase = makeKonanModuleOpPhase(
@@ -44,7 +44,7 @@ fun buildLibrary(
included: List<String>,
linkDependencies: List<KonanLibrary>,
metadata: SerializedMetadata,
ir: SerializedIrModule,
ir: SerializedIrModule?,
versions: KotlinLibraryVersioning,
target: KonanTarget,
output: String,
@@ -57,7 +57,9 @@ fun buildLibrary(
val library = KonanLibraryWriterImpl(File(output), moduleName, versions, target, nopack)
library.addMetadata(metadata)
library.addIr(ir)
if (ir != null) {
library.addIr(ir)
}
natives.forEach {
library.addNativeBitcode(it)