From 78ec094ce51a17139eb86d94ea25a4e23af7c998 Mon Sep 17 00:00:00 2001 From: Sergey Bogolepov Date: Mon, 2 Dec 2019 17:48:25 +0700 Subject: [PATCH] More precise control over backend phases Refactor backend phases invocation to make it possible to disable LLVM optimization pipeline. Also it makes phases separation a bit more clear. --- .../kotlin/backend/konan/CompilerOutput.kt | 32 +++++++++++-------- .../kotlin/backend/konan/ToplevelPhases.kt | 17 +++++----- .../backend/konan/llvm/BitcodePhases.kt | 12 +++++++ 3 files changed, 39 insertions(+), 22 deletions(-) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt index 777c439100f..7fdba5a1b49 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/CompilerOutput.kt @@ -86,6 +86,25 @@ private fun insertAliasToEntryPoint(context: Context) { LLVMAddAlias(module, LLVMTypeOf(entryPoint)!!, entryPoint, "main") } +internal fun linkBitcodeDependencies(context: Context) { + val config = context.config.configuration + val tempFiles = context.config.tempFiles + val produce = config.get(KonanConfigKeys.PRODUCE) + + val generatedBitcodeFiles = + if (produce == CompilerOutputKind.DYNAMIC || produce == CompilerOutputKind.STATIC) { + produceCAdapterBitcode( + context.config.clang, + tempFiles.cAdapterCppName, + tempFiles.cAdapterBitcodeName) + listOf(tempFiles.cAdapterBitcodeName) + } else emptyList() + if (produce == CompilerOutputKind.FRAMEWORK && context.config.produceStaticFramework) { + embedAppleLinkerOptionsToBitcode(context.llvm, context.config) + } + linkAllDependencies(context, generatedBitcodeFiles) +} + internal fun produceOutput(context: Context) { val config = context.config.configuration @@ -101,19 +120,6 @@ internal fun produceOutput(context: Context) { CompilerOutputKind.PROGRAM -> { val output = tempFiles.nativeBinaryFileName context.bitcodeFileName = output - val generatedBitcodeFiles = - if (produce == CompilerOutputKind.DYNAMIC || produce == CompilerOutputKind.STATIC) { - produceCAdapterBitcode( - context.config.clang, - tempFiles.cAdapterCppName, - tempFiles.cAdapterBitcodeName) - listOf(tempFiles.cAdapterBitcodeName) - } else emptyList() - if (produce == CompilerOutputKind.FRAMEWORK && context.config.produceStaticFramework) { - embedAppleLinkerOptionsToBitcode(context.llvm, context.config) - } - linkAllDependencies(context, generatedBitcodeFiles) - runLlvmOptimizationPipeline(context) // Insert `_main` after pipeline so we won't worry about optimizations // corrupting entry point. insertAliasToEntryPoint(context) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt index fb3c1818ef5..8baa897d45e 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt @@ -271,13 +271,6 @@ internal val linkerPhase = konanUnitPhase( description = "Linker" ) -internal val linkPhase = namedUnitPhase( - name = "Link", - description = "Link stage", - lower = objectFilesPhase then - linkerPhase -) - internal val allLoweringsPhase = namedIrModulePhase( name = "IrLowering", description = "IR Lowering", @@ -428,11 +421,14 @@ val toplevelPhase: CompilerPhase<*, Unit, Unit> = namedUnitPhase( bitcodePhase then verifyBitcodePhase then printBitcodePhase then + linkBitcodeDependenciesPhase then + bitcodeOptimizationPhase then produceOutputPhase then disposeLLVMPhase then unitSink() ) then - linkPhase + objectFilesPhase then + linkerPhase ) internal fun PhaseConfig.disableIf(phase: AnyNamedPhase, condition: Boolean) { @@ -455,7 +451,10 @@ internal fun PhaseConfig.konanPhasesConfig(config: KonanConfig) { disableIf(dependenciesLowerPhase, config.produce == CompilerOutputKind.LIBRARY) disableUnless(entryPointPhase, config.produce == CompilerOutputKind.PROGRAM) disableIf(bitcodePhase, config.produce == CompilerOutputKind.LIBRARY) - disableUnless(linkPhase, config.produce.involvesLinkStage) + disableUnless(bitcodeOptimizationPhase, config.produce.involvesLinkStage) + disableUnless(linkBitcodeDependenciesPhase, config.produce.involvesLinkStage) + disableUnless(objectFilesPhase, config.produce.involvesLinkStage) + disableUnless(linkerPhase, config.produce.involvesLinkStage) disableIf(testProcessorPhase, getNotNull(KonanConfigKeys.GENERATE_TEST_RUNNER) == TestRunnerKind.NONE) disableUnless(buildDFGPhase, getBoolean(KonanConfigKeys.OPTIMIZATION)) disableUnless(devirtualizationPhase, getBoolean(KonanConfigKeys.OPTIMIZATION)) diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt index 35bdf0d1b9e..e2ac06dd199 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/llvm/BitcodePhases.kt @@ -244,6 +244,18 @@ internal val cStubsPhase = makeKonanModuleOpPhase( op = { context, _ -> produceCStubs(context) } ) +internal val linkBitcodeDependenciesPhase = makeKonanModuleOpPhase( + name = "LinkBitcodeDependencies", + description = "Link bitcode dependencies", + op = { context, _ -> linkBitcodeDependencies(context) } +) + +internal val bitcodeOptimizationPhase = makeKonanModuleOpPhase( + name = "BitcodeOptimization", + description = "Optimize bitcode", + op = { context, _ -> runLlvmOptimizationPipeline(context) } +) + internal val produceOutputPhase = makeKonanModuleOpPhase( name = "ProduceOutput", description = "Produce output",