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.
This commit is contained in:
Sergey Bogolepov
2019-12-02 17:48:25 +07:00
committed by Sergey Bogolepov
parent 625f14d9d1
commit 78ec094ce5
3 changed files with 39 additions and 22 deletions
@@ -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)
@@ -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))
@@ -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",