
org.jetbrains.kotlin.backend.common.phaser.PhaseBuilders.kt Maven / Gradle / Ivy
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.backend.common.phaser
import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
// Phase composition.
private class CompositePhase(
val phases: List>
) : CompilerPhase {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input): Output {
@Suppress("UNCHECKED_CAST") var currentState = phaserState as PhaserState
var result = phases.first().invoke(phaseConfig, currentState, context, input)
for ((previous, next) in phases.zip(phases.drop(1))) {
if (next !is SameTypeCompilerPhase<*, *>) {
// Discard `stickyPostcoditions`, they are useless since data type is changing.
currentState = currentState.changeType()
}
currentState.stickyPostconditions.addAll(previous.stickyPostconditions)
result = next.invoke(phaseConfig, currentState, context, result)
}
@Suppress("UNCHECKED_CAST")
return result as Output
}
override fun getNamedSubphases(startDepth: Int): List> =
phases.flatMap { it.getNamedSubphases(startDepth) }
override val stickyPostconditions get() = phases.last().stickyPostconditions
}
@Suppress("UNCHECKED_CAST")
infix fun CompilerPhase.then(
other: CompilerPhase
): CompilerPhase {
val unsafeThis = this as CompilerPhase
val unsafeOther = other as CompilerPhase
return CompositePhase(if (this is CompositePhase) phases + unsafeOther else listOf(unsafeThis, unsafeOther))
}
fun namedIrModulePhase(
name: String,
description: String,
prerequisite: Set = emptySet(),
lower: CompilerPhase,
preconditions: Set> = emptySet(),
postconditions: Set> = emptySet(),
stickyPostconditions: Set> = lower.stickyPostconditions,
actions: Set> = setOf(defaultDumper),
nlevels: Int = 1
) = SameTypeNamedPhaseWrapper(
name,
description,
prerequisite,
lower,
preconditions,
postconditions,
stickyPostconditions,
actions,
nlevels
)
fun namedIrFilePhase(
name: String,
description: String,
prerequisite: Set = emptySet(),
lower: CompilerPhase,
preconditions: Set> = emptySet(),
postconditions: Set> = emptySet(),
stickyPostconditions: Set> = lower.stickyPostconditions,
actions: Set> = setOf(defaultDumper),
nlevels: Int = 1
) = SameTypeNamedPhaseWrapper(
name,
description,
prerequisite,
lower,
preconditions,
postconditions,
stickyPostconditions,
actions,
nlevels
)
fun namedUnitPhase(
name: String,
description: String,
prerequisite: Set = emptySet(),
nlevels: Int = 1,
lower: CompilerPhase
) = SameTypeNamedPhaseWrapper(
name, description, prerequisite,
lower = lower,
nlevels = nlevels
)
fun namedOpUnitPhase(
name: String,
description: String,
prerequisite: Set,
op: Context.() -> Unit
) = namedUnitPhase(
name, description, prerequisite,
nlevels = 0,
lower = object : SameTypeCompilerPhase {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Unit) {
context.op()
}
}
)
fun performByIrFile(
name: String = "PerformByIrFile",
description: String = "Perform phases by IrFile",
prerequisite: Set = emptySet(),
preconditions: Set> = emptySet(),
postconditions: Set> = emptySet(),
stickyPostconditions: Set> = emptySet(),
actions: Set> = setOf(defaultDumper),
lower: CompilerPhase
) = namedIrModulePhase(
name, description, prerequisite,
preconditions = preconditions,
postconditions = postconditions,
stickyPostconditions = stickyPostconditions,
actions = actions,
nlevels = 1,
lower = object : SameTypeCompilerPhase {
override fun invoke(
phaseConfig: PhaseConfig,
phaserState: PhaserState,
context: Context,
input: IrModuleFragment
): IrModuleFragment {
for (irFile in input.files) {
lower.invoke(phaseConfig, phaserState.changeType(), context, irFile)
}
// TODO: no guarantee that module identity is preserved by `lower`
return input
}
override fun getNamedSubphases(startDepth: Int) = lower.getNamedSubphases(startDepth)
}
)
fun makeIrFilePhase(
lowering: (Context) -> FileLoweringPass,
name: String,
description: String,
prerequisite: Set = emptySet(),
preconditions: Set> = emptySet(),
postconditions: Set> = emptySet(),
stickyPostconditions: Set> = emptySet(),
actions: Set> = setOf(defaultDumper)
) = namedIrFilePhase(
name, description, prerequisite,
preconditions = preconditions,
postconditions = postconditions,
stickyPostconditions = stickyPostconditions,
actions = actions,
nlevels = 0,
lower = object : SameTypeCompilerPhase {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: IrFile): IrFile {
lowering(context).lower(input)
return input
}
}
)
fun makeIrModulePhase(
lowering: (Context) -> FileLoweringPass,
name: String,
description: String,
prerequisite: Set = emptySet(),
preconditions: Set> = emptySet(),
postconditions: Set> = emptySet(),
stickyPostconditions: Set> = emptySet(),
actions: Set> = setOf(defaultDumper)
) = namedIrModulePhase(
name, description, prerequisite,
preconditions=preconditions,
postconditions = postconditions,
stickyPostconditions = stickyPostconditions,
actions = actions,
nlevels = 0,
lower = object : SameTypeCompilerPhase {
override fun invoke(
phaseConfig: PhaseConfig,
phaserState: PhaserState,
context: Context,
input: IrModuleFragment
): IrModuleFragment {
lowering(context).lower(input)
return input
}
}
)
fun unitPhase(
name: String,
description: String,
prerequisite: Set,
preconditions: Set>,
op: Context.() -> Unit
) =
object : AbstractNamedPhaseWrapper(
name, description, prerequisite,
preconditions = preconditions,
nlevels = 0,
lower = object : CompilerPhase {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input) {
context.op()
}
}
) {}
fun unitSink() = object : CompilerPhase {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input) {}
}
// Intermediate phases to change the object of transformations
fun takeFromContext(op: (Context) -> NewData) =
object : CompilerPhase {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: OldData) = op(context)
}
fun transform(op: (OldData) -> NewData) =
object : CompilerPhase {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: OldData) = op(input)
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy