Extract SameTypeNamedCompilerPhase from NamedCompilerPhase

Currently, compiler pipelines are heavily couples with
NamedCompilerPhase. Unfortunately, NamedCompilerPhase uses the same
type for Input and Output, thus it is not applicable to phases that
try to transform some data purely.
Thus, we separate this class into two, allowing to have a new
inheritor of NamedCompilerPhase with different Input and Output types.
This commit is contained in:
Sergey Bogolepov
2022-10-03 14:07:50 +03:00
committed by Space Team
parent 3a500e536a
commit 6a4722188f
9 changed files with 142 additions and 101 deletions
@@ -18,7 +18,7 @@ class PhaserState<Data>(
}
// Copy state, forgetting the sticky postconditions (which will not be applicable to the new type)
fun <Input, Output> PhaserState<Input>.changeType() = PhaserState<Output>(alreadyDone, depth, phaseCount, mutableSetOf())
fun <Input, Output> PhaserState<Input>.changePhaserStateType() = PhaserState<Output>(alreadyDone, depth, phaseCount, mutableSetOf())
inline fun <R, D> PhaserState<D>.downlevel(nlevels: Int, block: () -> R): R {
depth += nlevels
@@ -30,7 +30,7 @@ inline fun <R, D> PhaserState<D>.downlevel(nlevels: Int, block: () -> R): R {
interface CompilerPhase<in Context : LoggingContext, Input, Output> {
fun invoke(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Input>, context: Context, input: Input): Output
fun getNamedSubphases(startDepth: Int = 0): List<Pair<Int, NamedCompilerPhase<Context, *>>> = emptyList()
fun getNamedSubphases(startDepth: Int = 0): List<Pair<Int, AbstractNamedCompilerPhase<Context, *, *>>> = emptyList()
// In phase trees, `stickyPostconditions` is inherited along the right edge to be used in `then`.
val stickyPostconditions: Set<Checker<Output>> get() = emptySet()
@@ -47,7 +47,7 @@ interface SameTypeCompilerPhase<in Context : LoggingContext, Data> : CompilerPha
// A failing checker should just throw an exception.
typealias Checker<Data> = (Data) -> Unit
typealias AnyNamedPhase = NamedCompilerPhase<*, *>
typealias AnyNamedPhase = AbstractNamedCompilerPhase<*, *, *>
enum class BeforeOrAfter { BEFORE, AFTER }
@@ -66,20 +66,18 @@ infix operator fun <Data, Context> Action<Data, Context>.plus(other: Action<Data
other(phaseState, data, context)
}
class NamedCompilerPhase<in Context : LoggingContext, Data>(
// TODO: A better name would be just `NamedCompilerPhase`, but it is already used (see below).
abstract class AbstractNamedCompilerPhase<in Context : LoggingContext, Input, Output>(
val name: String,
val description: String,
val prerequisite: Set<NamedCompilerPhase<Context, *>> = emptySet(),
private val lower: CompilerPhase<Context, Data, Data>,
val preconditions: Set<Checker<Data>> = emptySet(),
val postconditions: Set<Checker<Data>> = emptySet(),
override val stickyPostconditions: Set<Checker<Data>> = emptySet(),
private val actions: Set<Action<Data, Context>> = emptySet(),
private val nlevels: Int = 0
) : SameTypeCompilerPhase<Context, Data> {
override fun invoke(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Data>, context: Context, input: Data): Data {
val prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>> = emptySet(),
val preconditions: Set<Checker<Input>> = emptySet(),
val postconditions: Set<Checker<Output>> = emptySet(),
protected val nlevels: Int = 0
) : CompilerPhase<Context, Input, Output> {
override fun invoke(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Input>, context: Context, input: Input): Output {
if (!phaseConfig.isEnabled(this)) {
return input
return outputIfNotEnabled(phaseConfig, phaserState, context, input)
}
assert(phaserState.alreadyDone.containsAll(prerequisite)) {
@@ -93,10 +91,10 @@ class NamedCompilerPhase<in Context : LoggingContext, Data>(
runAndProfile(phaseConfig, phaserState, context, input)
} else {
phaserState.downlevel(nlevels) {
lower.invoke(phaseConfig, phaserState, context, input)
phaseBody(phaseConfig, phaserState, context, input)
}
}
runAfter(phaseConfig, phaserState, context, output)
runAfter(phaseConfig, changePhaserStateType(phaserState), context, output)
phaserState.alreadyDone.add(this)
phaserState.phaseCount++
@@ -104,7 +102,57 @@ class NamedCompilerPhase<in Context : LoggingContext, Data>(
return output
}
private fun runBefore(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Data>, context: Context, input: Data) {
abstract fun phaseBody(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Input>, context: Context, input: Input): Output
abstract fun outputIfNotEnabled(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Input>, context: Context, input: Input): Output
abstract fun changePhaserStateType(phaserState: PhaserState<Input>): PhaserState<Output>
abstract fun runBefore(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Input>, context: Context, input: Input)
abstract fun runAfter(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Output>, context: Context, output: Output)
private fun runAndProfile(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Input>, context: Context, source: Input): Output {
var result: Output? = null
val msec = measureTimeMillis {
result = phaserState.downlevel(nlevels) {
phaseBody(phaseConfig, phaserState, context, source)
}
}
// TODO: use a proper logger
println("${"\t".repeat(phaserState.depth)}$description: $msec msec")
return result!!
}
override fun toString() = "Compiler Phase @$name"
}
// TODO: This class should be named `SameTypeNamedCompilerPhase`,
// but it would be a breaking change (e.g. there are usages in IntelliJ repo),
// so we introduce a typealias instead as a temporary solution.
class NamedCompilerPhase<in Context : LoggingContext, Data>(
name: String,
description: String,
prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>> = emptySet(),
private val lower: CompilerPhase<Context, Data, Data>,
preconditions: Set<Checker<Data>> = emptySet(),
postconditions: Set<Checker<Data>> = emptySet(),
override val stickyPostconditions: Set<Checker<Data>> = emptySet(),
private val actions: Set<Action<Data, Context>> = emptySet(),
nlevels: Int = 0
) : AbstractNamedCompilerPhase<Context, Data, Data>(
name, description, prerequisite, preconditions, postconditions, nlevels
) {
override fun phaseBody(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Data>, context: Context, input: Data): Data =
lower.invoke(phaseConfig, phaserState, context, input)
override fun outputIfNotEnabled(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Data>, context: Context, input: Data): Data =
input
override fun changePhaserStateType(phaserState: PhaserState<Data>): PhaserState<Data> =
phaserState
override fun runBefore(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Data>, context: Context, input: Data) {
val state = ActionState(phaseConfig, this, phaserState.phaseCount, BeforeOrAfter.BEFORE)
for (action in actions) action(state, input, context)
@@ -113,7 +161,7 @@ class NamedCompilerPhase<in Context : LoggingContext, Data>(
}
}
private fun runAfter(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Data>, context: Context, output: Data) {
override fun runAfter(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Data>, context: Context, output: Data) {
val state = ActionState(phaseConfig, this, phaserState.phaseCount, BeforeOrAfter.AFTER)
for (action in actions) action(state, output, context)
@@ -126,20 +174,9 @@ class NamedCompilerPhase<in Context : LoggingContext, Data>(
}
}
private fun runAndProfile(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<Data>, context: Context, source: Data): Data {
var result: Data? = null
val msec = measureTimeMillis {
result = phaserState.downlevel(nlevels) {
lower.invoke(phaseConfig, phaserState, context, source)
}
}
// TODO: use a proper logger
println("${"\t".repeat(phaserState.depth)}$description: $msec msec")
return result!!
}
override fun getNamedSubphases(startDepth: Int): List<Pair<Int, NamedCompilerPhase<Context, *>>> =
override fun getNamedSubphases(startDepth: Int): List<Pair<Int, AbstractNamedCompilerPhase<Context, *, *>>> =
listOf(startDepth to this) + lower.getNamedSubphases(startDepth + nlevels)
override fun toString() = "Compiler Phase @$name"
}
typealias SameTypeNamedCompilerPhase<Context, Data> = NamedCompilerPhase<Context, Data>
@@ -23,7 +23,7 @@ private class CompositePhase<Context : CommonBackendContext, Input, Output>(
for ((previous, next) in phases.zip(phases.drop(1))) {
if (next !is SameTypeCompilerPhase<*, *>) {
// Discard `stickyPostconditions`, they are useless since data type is changing.
currentState = currentState.changeType()
currentState = currentState.changePhaserStateType()
}
currentState.stickyPostconditions.addAll(previous.stickyPostconditions)
result = next.invoke(phaseConfig, currentState, context, result)
@@ -32,7 +32,7 @@ private class CompositePhase<Context : CommonBackendContext, Input, Output>(
return result as Output
}
override fun getNamedSubphases(startDepth: Int): List<Pair<Int, NamedCompilerPhase<Context, *>>> =
override fun getNamedSubphases(startDepth: Int): List<Pair<Int, AbstractNamedCompilerPhase<Context, *, *>>> =
phases.flatMap { it.getNamedSubphases(startDepth) }
override val stickyPostconditions get() = phases.last().stickyPostconditions
@@ -51,14 +51,14 @@ fun <Context : CommonBackendContext, Element : IrElement> makeCustomPhase(
op: (Context, Element) -> Unit,
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<Context, *>> = emptySet(),
prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>> = emptySet(),
preconditions: Set<Checker<Element>> = emptySet(),
postconditions: Set<Checker<Element>> = emptySet(),
stickyPostconditions: Set<Checker<Element>> = emptySet(),
actions: Set<Action<Element, Context>> = setOf(defaultDumper, validationAction),
nlevels: Int = 1
): NamedCompilerPhase<Context, Element> =
NamedCompilerPhase(
): SameTypeNamedCompilerPhase<Context, Element> =
SameTypeNamedCompilerPhase(
name, description, prerequisite, CustomPhaseAdapter(op), preconditions, postconditions, stickyPostconditions, actions, nlevels,
)
@@ -74,11 +74,11 @@ private class CustomPhaseAdapter<Context : CommonBackendContext, Element>(
fun <Context : CommonBackendContext> namedUnitPhase(
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<Context, *>> = emptySet(),
prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>> = emptySet(),
nlevels: Int = 1,
lower: CompilerPhase<Context, Unit, Unit>
): NamedCompilerPhase<Context, Unit> =
NamedCompilerPhase(
): SameTypeNamedCompilerPhase<Context, Unit> =
SameTypeNamedCompilerPhase(
name, description, prerequisite, lower, nlevels = nlevels
)
@@ -86,9 +86,9 @@ fun <Context : CommonBackendContext> namedUnitPhase(
fun <Context : CommonBackendContext> namedOpUnitPhase(
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<Context, *>>,
prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>>,
op: Context.() -> Unit
): NamedCompilerPhase<Context, Unit> = namedUnitPhase(
): SameTypeNamedCompilerPhase<Context, Unit> = namedUnitPhase(
name, description, prerequisite,
nlevels = 0,
lower = object : SameTypeCompilerPhase<Context, Unit> {
@@ -102,13 +102,13 @@ fun <Context : CommonBackendContext> makeIrFilePhase(
lowering: (Context) -> FileLoweringPass,
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<Context, *>> = emptySet(),
prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>> = emptySet(),
preconditions: Set<Checker<IrFile>> = emptySet(),
postconditions: Set<Checker<IrFile>> = emptySet(),
stickyPostconditions: Set<Checker<IrFile>> = emptySet(),
actions: Set<Action<IrFile, Context>> = setOf(defaultDumper, validationAction)
): NamedCompilerPhase<Context, IrFile> =
NamedCompilerPhase(
): SameTypeNamedCompilerPhase<Context, IrFile> =
SameTypeNamedCompilerPhase(
name, description, prerequisite, FileLoweringPhaseAdapter(lowering), preconditions, postconditions, stickyPostconditions, actions,
nlevels = 0,
)
@@ -126,13 +126,13 @@ fun <Context : CommonBackendContext> makeIrModulePhase(
lowering: (Context) -> FileLoweringPass,
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<Context, *>> = emptySet(),
prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>> = emptySet(),
preconditions: Set<Checker<IrModuleFragment>> = emptySet(),
postconditions: Set<Checker<IrModuleFragment>> = emptySet(),
stickyPostconditions: Set<Checker<IrModuleFragment>> = emptySet(),
actions: Set<Action<IrModuleFragment, Context>> = setOf(defaultDumper, validationAction)
): NamedCompilerPhase<Context, IrModuleFragment> =
NamedCompilerPhase(
): SameTypeNamedCompilerPhase<Context, IrModuleFragment> =
SameTypeNamedCompilerPhase(
name, description, prerequisite, ModuleLoweringPhaseAdapter(lowering), preconditions, postconditions, stickyPostconditions, actions,
nlevels = 0,
)
@@ -32,8 +32,8 @@ fun <Context : CommonBackendContext> performByIrFile(
description: String = "Perform phases by IrFile",
copyBeforeLowering: Boolean = true,
lower: List<CompilerPhase<Context, IrFile, IrFile>>,
): NamedCompilerPhase<Context, IrModuleFragment> =
NamedCompilerPhase(
): SameTypeNamedCompilerPhase<Context, IrModuleFragment> =
SameTypeNamedCompilerPhase(
name, description, emptySet(), PerformByIrFilePhase(lower, copyBeforeLowering), emptySet(), emptySet(), emptySet(),
setOf(defaultDumper), nlevels = 1,
)
@@ -60,7 +60,7 @@ private class PerformByIrFilePhase<Context : CommonBackendContext>(
): IrModuleFragment {
for (irFile in input.files) {
try {
val filePhaserState = phaserState.changeType<IrModuleFragment, IrFile>()
val filePhaserState = phaserState.changePhaserStateType<IrModuleFragment, IrFile>()
for (phase in lower) {
phase.invoke(phaseConfig, filePhaserState, context, irFile)
}
@@ -97,7 +97,7 @@ private class PerformByIrFilePhase<Context : CommonBackendContext>(
for ((irFile, state) in filesAndStates) {
executor.execute {
try {
val filePhaserState = state.changeType<IrModuleFragment, IrFile>()
val filePhaserState = state.changePhaserStateType<IrModuleFragment, IrFile>()
for (phase in lower) {
phase.invoke(phaseConfig, filePhaserState, context, irFile)
}
@@ -134,7 +134,7 @@ private class PerformByIrFilePhase<Context : CommonBackendContext>(
return input
}
override fun getNamedSubphases(startDepth: Int): List<Pair<Int, NamedCompilerPhase<Context, *>>> =
override fun getNamedSubphases(startDepth: Int): List<Pair<Int, AbstractNamedCompilerPhase<Context, *, *>>> =
lower.flatMap { it.getNamedSubphases(startDepth) }
}
@@ -33,8 +33,8 @@ private fun makeJsModulePhase(
lowering: (JsIrBackendContext) -> FileLoweringPass,
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<JsIrBackendContext, *>> = emptySet()
): NamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>> = makeCustomJsModulePhase(
prerequisite: Set<AbstractNamedCompilerPhase<JsIrBackendContext, *, *>> = emptySet()
): SameTypeNamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>> = makeCustomJsModulePhase(
op = { context, modules -> lowering(context).lower(modules) },
name = name,
description = description,
@@ -45,8 +45,8 @@ private fun makeCustomJsModulePhase(
op: (JsIrBackendContext, IrModuleFragment) -> Unit,
description: String,
name: String,
prerequisite: Set<NamedCompilerPhase<JsIrBackendContext, *>> = emptySet()
): NamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>> = NamedCompilerPhase(
prerequisite: Set<AbstractNamedCompilerPhase<JsIrBackendContext, *, *>> = emptySet()
): SameTypeNamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>> = SameTypeNamedCompilerPhase(
name = name,
description = description,
prerequisite = prerequisite,
@@ -67,13 +67,13 @@ private fun makeCustomJsModulePhase(
)
sealed class Lowering(val name: String) {
abstract val modulePhase: NamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>>
abstract val modulePhase: SameTypeNamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>>
}
class DeclarationLowering(
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<JsIrBackendContext, *>> = emptySet(),
prerequisite: Set<AbstractNamedCompilerPhase<JsIrBackendContext, *, *>> = emptySet(),
private val factory: (JsIrBackendContext) -> DeclarationTransformer
) : Lowering(name) {
fun declarationTransformer(context: JsIrBackendContext): DeclarationTransformer {
@@ -86,7 +86,7 @@ class DeclarationLowering(
class BodyLowering(
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<JsIrBackendContext, *>> = emptySet(),
prerequisite: Set<AbstractNamedCompilerPhase<JsIrBackendContext, *, *>> = emptySet(),
private val factory: (JsIrBackendContext) -> BodyLoweringPass
) : Lowering(name) {
fun bodyLowering(context: JsIrBackendContext): BodyLoweringPass {
@@ -98,7 +98,7 @@ class BodyLowering(
class ModuleLowering(
name: String,
override val modulePhase: NamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>>
override val modulePhase: SameTypeNamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>>
) : Lowering(name)
private fun makeDeclarationTransformerPhase(
@@ -115,7 +115,7 @@ private fun makeBodyLoweringPhase(
prerequisite: Set<Lowering> = emptySet()
) = BodyLowering(name, description, prerequisite.map { it.modulePhase }.toSet(), lowering)
fun NamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>>.toModuleLowering() = ModuleLowering(this.name, this)
fun SameTypeNamedCompilerPhase<JsIrBackendContext, Iterable<IrModuleFragment>>.toModuleLowering() = ModuleLowering(this.name, this)
private val validateIrBeforeLowering = makeCustomJsModulePhase(
{ context, module -> validationCallback(context, module) },
@@ -927,7 +927,7 @@ val loweringList = listOf<Lowering>(
// TODO comment? Eliminate ModuleLowering's? Don't filter them here?
val pirLowerings = loweringList.filter { it is DeclarationLowering || it is BodyLowering } + staticMembersLoweringPhase
val jsPhases = NamedCompilerPhase(
val jsPhases = SameTypeNamedCompilerPhase(
name = "IrModuleLowering",
description = "IR module lowering",
lower = loweringList.map {
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.backend.jvm
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase
import org.jetbrains.kotlin.backend.common.phaser.SameTypeNamedCompilerPhase
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.common.phaser.performByIrFile
import org.jetbrains.kotlin.backend.common.phaser.then
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.util.render
private fun codegenPhase(generateMultifileFacade: Boolean): NamedCompilerPhase<JvmBackendContext, IrModuleFragment> {
private fun codegenPhase(generateMultifileFacade: Boolean): SameTypeNamedCompilerPhase<JvmBackendContext, IrModuleFragment> {
val suffix = if (generateMultifileFacade) "MultifileFacades" else "Regular"
val descriptionSuffix = if (generateMultifileFacade) ", multifile facades" else ", regular files"
return performByIrFile(
@@ -50,7 +50,7 @@ private class FileCodegen(private val context: JvmBackendContext, private val ge
// Generate multifile facades first, to compute and store JVM signatures of const properties which are later used
// when serializing metadata in the multifile parts.
// TODO: consider dividing codegen itself into separate phases (bytecode generation, metadata serialization) to avoid this
internal val jvmCodegenPhases = NamedCompilerPhase(
internal val jvmCodegenPhases = SameTypeNamedCompilerPhase(
name = "Codegen",
description = "Code generation",
nlevels = 1,
@@ -60,5 +60,5 @@ internal val jvmCodegenPhases = NamedCompilerPhase(
// This property is needed to avoid dependencies from "leaf" modules (cli, tests-common-new) on backend.jvm:lower.
// It's used to create PhaseConfig and is the only thing needed from lowerings in the leaf modules.
val jvmPhases: NamedCompilerPhase<JvmBackendContext, IrModuleFragment>
val jvmPhases: SameTypeNamedCompilerPhase<JvmBackendContext, IrModuleFragment>
get() = jvmLoweringPhases
@@ -31,7 +31,7 @@ import org.jetbrains.kotlin.name.NameUtils
private var patchParentPhases = 0
@Suppress("unused")
private fun makePatchParentsPhase(): NamedCompilerPhase<CommonBackendContext, IrFile> {
private fun makePatchParentsPhase(): SameTypeNamedCompilerPhase<CommonBackendContext, IrFile> {
val number = patchParentPhases++
return makeIrFilePhase(
{ PatchDeclarationParents() },
@@ -43,7 +43,7 @@ private fun makePatchParentsPhase(): NamedCompilerPhase<CommonBackendContext, Ir
private var checkParentPhases = 0
@Suppress("unused")
private fun makeCheckParentsPhase(): NamedCompilerPhase<CommonBackendContext, IrFile> {
private fun makeCheckParentsPhase(): SameTypeNamedCompilerPhase<CommonBackendContext, IrFile> {
val number = checkParentPhases++
return makeIrFilePhase(
{ CheckDeclarationParents() },
@@ -387,9 +387,9 @@ val jvmLoweringPhases = buildJvmLoweringPhases("IrLowering", listOf("PerformByIr
private fun buildJvmLoweringPhases(
name: String,
phases: List<Pair<String, List<NamedCompilerPhase<JvmBackendContext, IrFile>>>>
): NamedCompilerPhase<JvmBackendContext, IrModuleFragment> {
return NamedCompilerPhase(
phases: List<Pair<String, List<SameTypeNamedCompilerPhase<JvmBackendContext, IrFile>>>>
): SameTypeNamedCompilerPhase<JvmBackendContext, IrModuleFragment> {
return SameTypeNamedCompilerPhase(
name = name,
description = "IR lowering",
nlevels = 1,
@@ -417,7 +417,7 @@ private fun buildJvmLoweringPhases(
// Build a compiler phase from a list of lowering sequences: each subsequence is run
// in parallel per file, and each parallel composition is run in sequence.
private fun buildLoweringsPhase(
perModuleLowerings: List<Pair<String, List<NamedCompilerPhase<JvmBackendContext, IrFile>>>>,
perModuleLowerings: List<Pair<String, List<SameTypeNamedCompilerPhase<JvmBackendContext, IrFile>>>>,
): CompilerPhase<JvmBackendContext, IrModuleFragment, IrModuleFragment> =
perModuleLowerings.map { (name, lowerings) -> performByIrFile(name, lower = lowerings) }
.reduce<
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.wasm
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.common.lower.coroutines.AddContinuationToNonLocalSuspendFunctionsLowering
import org.jetbrains.kotlin.backend.common.lower.inline.FunctionInlining
import org.jetbrains.kotlin.backend.common.lower.loops.ForLoopsLowering
import org.jetbrains.kotlin.backend.common.lower.optimizations.PropertyAccessorInlineLowering
@@ -16,7 +17,6 @@ import org.jetbrains.kotlin.backend.common.toMultiModuleAction
import org.jetbrains.kotlin.backend.wasm.lower.*
import org.jetbrains.kotlin.ir.backend.js.lower.*
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.AddContinuationToFunctionCallsLowering
import org.jetbrains.kotlin.backend.common.lower.coroutines.AddContinuationToNonLocalSuspendFunctionsLowering
import org.jetbrains.kotlin.ir.backend.js.lower.coroutines.JsSuspendFunctionsLowering
import org.jetbrains.kotlin.ir.backend.js.lower.inline.RemoveInlineDeclarationsWithReifiedTypeParametersLowering
import org.jetbrains.kotlin.ir.backend.wasm.lower.generateMainFunctionCalls
@@ -27,8 +27,8 @@ private fun makeWasmModulePhase(
lowering: (WasmBackendContext) -> FileLoweringPass,
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<WasmBackendContext, *>> = emptySet()
): NamedCompilerPhase<WasmBackendContext, Iterable<IrModuleFragment>> =
prerequisite: Set<AbstractNamedCompilerPhase<WasmBackendContext, *, *>> = emptySet()
): SameTypeNamedCompilerPhase<WasmBackendContext, Iterable<IrModuleFragment>> =
makeCustomWasmModulePhase(
op = { context, modules -> lowering(context).lower(modules) },
name = name,
@@ -40,9 +40,9 @@ private fun makeCustomWasmModulePhase(
op: (WasmBackendContext, IrModuleFragment) -> Unit,
description: String,
name: String,
prerequisite: Set<NamedCompilerPhase<WasmBackendContext, *>> = emptySet()
): NamedCompilerPhase<WasmBackendContext, Iterable<IrModuleFragment>> =
NamedCompilerPhase(
prerequisite: Set<AbstractNamedCompilerPhase<WasmBackendContext, *, *>> = emptySet()
): SameTypeNamedCompilerPhase<WasmBackendContext, Iterable<IrModuleFragment>> =
SameTypeNamedCompilerPhase(
name = name,
description = description,
prerequisite = prerequisite,
@@ -549,7 +549,7 @@ private val unitToVoidLowering = makeWasmModulePhase(
description = "Replace some Unit's with Void's"
)
val wasmPhases = NamedCompilerPhase(
val wasmPhases = SameTypeNamedCompilerPhase(
name = "IrModuleLowering",
description = "IR module lowering",
lower = validateIrBeforeLowering then
@@ -40,22 +40,22 @@ private fun makeKonanFileLoweringPhase(
lowering: (Context) -> FileLoweringPass,
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<Context, *>> = emptySet()
prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>> = emptySet()
) = makeIrFilePhase(lowering, name, description, prerequisite, actions = filePhaseActions)
private fun makeKonanModuleLoweringPhase(
lowering: (Context) -> FileLoweringPass,
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<Context, *>> = emptySet()
prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>> = emptySet()
) = makeIrModulePhase(lowering, name, description, prerequisite, actions = modulePhaseActions)
internal fun makeKonanFileOpPhase(
op: (Context, IrFile) -> Unit,
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<Context, *>> = emptySet()
) = NamedCompilerPhase(
prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>> = emptySet()
) = SameTypeNamedCompilerPhase(
name, description, prerequisite, nlevels = 0,
lower = object : SameTypeCompilerPhase<Context, IrFile> {
override fun invoke(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<IrFile>, context: Context, input: IrFile): IrFile {
@@ -70,8 +70,8 @@ internal fun makeKonanModuleOpPhase(
op: (Context, IrModuleFragment) -> Unit,
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<Context, *>> = emptySet()
) = NamedCompilerPhase(
prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>> = emptySet()
) = SameTypeNamedCompilerPhase(
name, description, prerequisite, nlevels = 0,
lower = object : SameTypeCompilerPhase<Context, IrModuleFragment> {
override fun invoke(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<IrModuleFragment>, context: Context, input: IrModuleFragment): IrModuleFragment {
@@ -5,9 +5,9 @@
package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.common.checkDeclarationParents
import org.jetbrains.kotlin.backend.common.IrValidator
import org.jetbrains.kotlin.backend.common.IrValidatorConfig
import org.jetbrains.kotlin.backend.common.checkDeclarationParents
import org.jetbrains.kotlin.backend.common.phaser.*
import org.jetbrains.kotlin.backend.common.serialization.CompatibilityMode
import org.jetbrains.kotlin.backend.common.serialization.metadata.KlibMetadataMonolithicSerializer
@@ -19,11 +19,15 @@ import org.jetbrains.kotlin.backend.konan.lower.SamSuperTypesChecker
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
import org.jetbrains.kotlin.backend.konan.objcexport.createCodeSpec
import org.jetbrains.kotlin.backend.konan.objcexport.produceObjCExportInterface
import org.jetbrains.kotlin.backend.konan.serialization.*
import org.jetbrains.kotlin.backend.konan.serialization.KonanIdSignaturer
import org.jetbrains.kotlin.backend.konan.serialization.KonanIrModuleSerializer
import org.jetbrains.kotlin.backend.konan.serialization.KonanManglerDesc
import org.jetbrains.kotlin.config.CommonConfigurationKeys
import org.jetbrains.kotlin.config.languageVersionSettings
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl
import org.jetbrains.kotlin.ir.declarations.path
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
import org.jetbrains.kotlin.name.FqName
@@ -69,7 +73,7 @@ internal fun fileValidationCallback(state: ActionState, irFile: IrFile, context:
internal fun konanUnitPhase(
name: String,
description: String,
prerequisite: Set<NamedCompilerPhase<Context, *>> = emptySet(),
prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>> = emptySet(),
op: Context.() -> Unit
) = namedOpUnitPhase(name, description, prerequisite, op)
@@ -235,7 +239,7 @@ internal val finalizeCachePhase = konanUnitPhase(
description = "Finalize cache (rename temp to the final dist)"
)
internal val allLoweringsPhase = NamedCompilerPhase(
internal val allLoweringsPhase = SameTypeNamedCompilerPhase(
name = "IrLowering",
description = "IR Lowering",
// TODO: The lowerings before inlinePhase should be aligned with [NativeInlineFunctionResolver.kt]
@@ -298,7 +302,7 @@ internal val allLoweringsPhase = NamedCompilerPhase(
actions = setOf(defaultDumper, ::moduleValidationCallback)
)
internal val dependenciesLowerPhase = NamedCompilerPhase(
internal val dependenciesLowerPhase = SameTypeNamedCompilerPhase(
name = "LowerLibIR",
description = "Lower library's IR",
prerequisite = emptySet(),
@@ -336,7 +340,7 @@ internal val dependenciesLowerPhase = NamedCompilerPhase(
}
})
internal val umbrellaCompilation = NamedCompilerPhase(
internal val umbrellaCompilation = SameTypeNamedCompilerPhase(
name = "UmbrellaCompilation",
description = "A batched compilation with shared FE and ME phases",
prerequisite = emptySet(),
@@ -389,7 +393,7 @@ internal val entryPointPhase = makeCustomPhase<Context, IrModuleFragment>(
}
)
internal val bitcodePhase = NamedCompilerPhase(
internal val bitcodePhase = SameTypeNamedCompilerPhase(
name = "Bitcode",
description = "LLVM Bitcode generation",
lower = returnsInsertionPhase then
@@ -411,7 +415,7 @@ internal val bitcodePhase = NamedCompilerPhase(
cStubsPhase
)
private val bitcodePostprocessingPhase = NamedCompilerPhase(
private val bitcodePostprocessingPhase = SameTypeNamedCompilerPhase(
name = "BitcodePostprocessing",
description = "Optimize and rewrite bitcode",
lower = checkExternalCallsPhase then
@@ -422,7 +426,7 @@ private val bitcodePostprocessingPhase = NamedCompilerPhase(
rewriteExternalCallsCheckerGlobals
)
private val backendCodegen = NamedCompilerPhase(
private val backendCodegen = SameTypeNamedCompilerPhase(
name = "Backend codegen",
description = "Backend code generation",
lower = entryPointPhase then
@@ -456,7 +460,7 @@ internal val disposeGenerationStatePhase = namedUnitPhase(
}
)
private val phasesOverMainModule = NamedCompilerPhase(
private val phasesOverMainModule = SameTypeNamedCompilerPhase(
name = "PhasesOverMainModule",
description = "Phases over main module",
lower = takeFromContext<Context, Unit, IrModuleFragment> { it.irModule!! } then
@@ -466,7 +470,7 @@ private val phasesOverMainModule = NamedCompilerPhase(
prerequisite = setOf(psiToIrPhase)
)
private val entireBackend = NamedCompilerPhase(
private val entireBackend = SameTypeNamedCompilerPhase(
name = "EntireBackend",
description = "Entire backend",
lower = createGenerationStatePhase then
@@ -480,7 +484,7 @@ private val entireBackend = NamedCompilerPhase(
disposeGenerationStatePhase
)
private val middleEnd = NamedCompilerPhase(
private val middleEnd = SameTypeNamedCompilerPhase(
name = "MiddleEnd",
description = "Build and prepare IR for back end",
lower = createSymbolTablePhase then
@@ -494,7 +498,7 @@ private val middleEnd = NamedCompilerPhase(
functionsWithoutBoundCheck
)
private val singleCompilation = NamedCompilerPhase(
private val singleCompilation = SameTypeNamedCompilerPhase(
name = "SingleCompilation",
description = "Single compilation",
lower = entireBackend