From ef58f1e72e1c2a39e2281b416e2c7366b018b365 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Wed, 1 Jul 2020 01:18:07 +0200 Subject: [PATCH] IR: simplify phaser code a little - merge NamedCompilerPhase, SameTypeNamedPhaseWrapper, AbstractNamedPhaseWrapper and inherit it from SameTypeCompilerPhase - inline some functions to simplify stacktraces - reformat and fix inspections --- .../backend/common/phaser/CompilerPhase.kt | 104 ++++++------------ .../backend/common/phaser/PhaseBuilders.kt | 33 ++---- .../kotlin/ir/backend/js/JsLoweringPhases.kt | 10 +- .../lower/StaticDefaultFunctionLowering.kt | 9 +- 4 files changed, 53 insertions(+), 103 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/CompilerPhase.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/CompilerPhase.kt index 32acb020512..213d58ee145 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/CompilerPhase.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/CompilerPhase.kt @@ -18,8 +18,7 @@ class PhaserState( // Copy state, forgetting the sticky postconditions (which will not be applicable to the new type) fun PhaserState.changeType() = PhaserState(alreadyDone, depth, phaseCount, mutableSetOf()) - -fun PhaserState.downlevel(nlevels: Int = 1, block: () -> R): R { +inline fun PhaserState.downlevel(nlevels: Int, block: () -> R): R { depth += nlevels val result = block() depth -= nlevels @@ -35,28 +34,19 @@ interface CompilerPhase { val stickyPostconditions: Set> get() = emptySet() } -fun CompilerPhase.invokeToplevel( +fun CompilerPhase.invokeToplevel( phaseConfig: PhaseConfig, context: Context, input: Input ): Output = invoke(phaseConfig, PhaserState(), context, input) -interface SameTypeCompilerPhase : CompilerPhase +interface SameTypeCompilerPhase : CompilerPhase // A failing checker should just throw an exception. typealias Checker = (Data) -> Unit -interface NamedCompilerPhase : CompilerPhase { - val name: String - val description: String - val prerequisite: Set get() = emptySet() - val preconditions: Set> - val postconditions: Set> - val actionsBefore: Set> - val actionsAfter: Set> -} +typealias AnyNamedPhase = NamedCompilerPhase<*, *> -typealias AnyNamedPhase = NamedCompilerPhase<*, *, *> enum class BeforeOrAfter { BEFORE, AFTER } data class ActionState( @@ -74,25 +64,20 @@ infix operator fun Action.plus(other: Action( - override val name: String, - override val description: String, - override val prerequisite: Set, - private val lower: CompilerPhase, - override val preconditions: Set> = emptySet(), - override val postconditions: Set> = emptySet(), - override val stickyPostconditions: Set> = emptySet(), - override val actionsBefore: Set> = emptySet(), - override val actionsAfter: Set> = emptySet(), +class NamedCompilerPhase( + val name: String, + val description: String, + val prerequisite: Set, + private val lower: CompilerPhase, + val preconditions: Set> = emptySet(), + val postconditions: Set> = emptySet(), + override val stickyPostconditions: Set> = emptySet(), + private val actions: Set> = emptySet(), private val nlevels: Int = 0 -) : NamedCompilerPhase { - - override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input): Output { - if (this is SameTypeCompilerPhase<*, *> && - this !in phaseConfig.enabled - ) { - @Suppress("UNCHECKED_CAST") - return input as Output +) : SameTypeCompilerPhase { + override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Data): Data { + if (this !in phaseConfig.enabled) { + return input } assert(phaserState.alreadyDone.containsAll(prerequisite)) { @@ -102,7 +87,13 @@ abstract class AbstractNamedPhaseWrapper, context: Context, input: Input) { + private fun runBefore(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Data) { val state = ActionState(phaseConfig, this, phaserState.phaseCount, BeforeOrAfter.BEFORE) - for (action in actionsBefore) action(state, input, context) + for (action in actions) action(state, input, context) if (phaseConfig.checkConditions) { for (pre in preconditions) pre(input) } } - private fun runBody(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input): Output { - return if (phaseConfig.needProfiling) { - runAndProfile(phaseConfig, phaserState, context, input) - } else { - phaserState.downlevel(nlevels) { - lower.invoke(phaseConfig, phaserState, context, input) - } - } - } - - private fun runAfter(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, output: Output) { + private fun runAfter(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, output: Data) { val state = ActionState(phaseConfig, this, phaserState.phaseCount, BeforeOrAfter.AFTER) - for (action in actionsAfter) action(state, output, context) + for (action in actions) action(state, output, context) if (phaseConfig.checkConditions) { for (post in postconditions) post(output) for (post in stickyPostconditions) post(output) - if (phaseConfig.checkStickyConditions && this is SameTypeCompilerPhase<*, *>) { - @Suppress("UNCHECKED_CAST") val phaserStateO = phaserState as PhaserState - for (post in phaserStateO.stickyPostconditions) post(output) + if (phaseConfig.checkStickyConditions) { + for (post in phaserState.stickyPostconditions) post(output) } } } - private fun runAndProfile(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, source: Input): Output { - var result: Output? = null + private fun runAndProfile(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, source: Data): Data { + var result: Data? = null val msec = measureTimeMillis { result = phaserState.downlevel(nlevels) { lower.invoke(phaseConfig, phaserState, context, source) @@ -156,26 +136,8 @@ abstract class AbstractNamedPhaseWrapper, block: () -> Unit) { - if (this in set) block() - } - - override fun getNamedSubphases(startDepth: Int): List>> = + override fun getNamedSubphases(startDepth: Int): List>> = listOf(startDepth to this) + lower.getNamedSubphases(startDepth + nlevels) override fun toString() = "Compiler Phase @$name" } - -class SameTypeNamedPhaseWrapper( - name: String, - description: String, - prerequisite: Set, - lower: CompilerPhase, - preconditions: Set> = emptySet(), - postconditions: Set> = emptySet(), - stickyPostconditions: Set> = lower.stickyPostconditions, - actions: Set> = emptySet(), - nlevels: Int = 0 -) : AbstractNamedPhaseWrapper( - name, description, prerequisite, lower, preconditions, postconditions, stickyPostconditions, actions, actions, nlevels -), SameTypeCompilerPhase diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/PhaseBuilders.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/PhaseBuilders.kt index 27c7c41ed1a..0fbf52eae56 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/PhaseBuilders.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/PhaseBuilders.kt @@ -23,7 +23,7 @@ private class CompositePhase( 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. + // Discard `stickyPostconditions`, they are useless since data type is changing. currentState = currentState.changeType() } currentState.stickyPostconditions.addAll(previous.stickyPostconditions) @@ -58,7 +58,7 @@ fun namedIrModulePhase( stickyPostconditions: Set> = lower.stickyPostconditions, actions: Set> = setOf(defaultDumper, validationAction), nlevels: Int = 1 -) = SameTypeNamedPhaseWrapper( +) = NamedCompilerPhase( name, description, prerequisite, @@ -80,7 +80,7 @@ fun namedIrFilePhase( stickyPostconditions: Set> = lower.stickyPostconditions, actions: Set> = setOf(defaultDumper, validationAction), nlevels: Int = 1 -) = SameTypeNamedPhaseWrapper( +) = NamedCompilerPhase( name, description, prerequisite, @@ -102,7 +102,7 @@ fun makeCustomPhase( stickyPostconditions: Set> = emptySet(), actions: Set> = setOf(defaultDumper, validationAction), nlevels: Int = 1 -) = SameTypeNamedPhaseWrapper( +) = NamedCompilerPhase( name, description, prerequisite, @@ -130,12 +130,13 @@ fun namedUnitPhase( prerequisite: Set = emptySet(), nlevels: Int = 1, lower: CompilerPhase -) = SameTypeNamedPhaseWrapper( +) = NamedCompilerPhase( name, description, prerequisite, lower = lower, nlevels = nlevels ) +@Suppress("unused") // Used in kotlin-native fun namedOpUnitPhase( name: String, description: String, @@ -225,7 +226,7 @@ fun makeIrModulePhase( actions: Set> = setOf(defaultDumper, validationAction) ) = namedIrModulePhase( name, description, prerequisite, - preconditions=preconditions, + preconditions = preconditions, postconditions = postconditions, stickyPostconditions = stickyPostconditions, actions = actions, @@ -243,29 +244,13 @@ fun makeIrModulePhase( } ) -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() - } - } - ) {} - +@Suppress("unused") // Used in kotlin-native fun unitSink() = object : CompilerPhase { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: Input) {} } // Intermediate phases to change the object of transformations +@Suppress("unused") // Used in kotlin-native fun takeFromContext(op: (Context) -> NewData) = object : CompilerPhase { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState, context: Context, input: OldData) = op(context) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt index 8cfbe620fc6..7da43d3d09a 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/JsLoweringPhases.kt @@ -46,7 +46,7 @@ private fun makeCustomJsModulePhase( description: String, name: String, prerequisite: Set = emptySet() -) = SameTypeNamedPhaseWrapper( +) = NamedCompilerPhase( name = name, description = description, prerequisite = prerequisite, @@ -79,7 +79,7 @@ private fun Action.toMultiModuleAction(): Action> + abstract val modulePhase: NamedCompilerPhase> } class DeclarationLowering( @@ -110,7 +110,7 @@ class BodyLowering( class ModuleLowering( name: String, - override val modulePhase: SameTypeNamedPhaseWrapper> + override val modulePhase: NamedCompilerPhase> ) : Lowering(name) private fun makeDeclarationTransformerPhase( @@ -127,7 +127,7 @@ private fun makeBodyLoweringPhase( prerequisite: Set = emptySet() ) = BodyLowering(name, description, prerequisite.map { it.modulePhase }.toSet(), lowering) -fun SameTypeNamedPhaseWrapper>.toModuleLowering() = ModuleLowering(this.name, this) +fun NamedCompilerPhase>.toModuleLowering() = ModuleLowering(this.name, this) private val validateIrBeforeLowering = makeCustomJsModulePhase( { context, module -> validationCallback(context, module) }, @@ -732,7 +732,7 @@ val loweringList = listOf( // TODO comment? Eliminate ModuleLowering's? Don't filter them here? val pirLowerings = loweringList.filter { it is DeclarationLowering || it is BodyLowering } + staticMembersLoweringPhase -val jsPhases = SameTypeNamedPhaseWrapper( +val jsPhases = NamedCompilerPhase( name = "IrModuleLowering", description = "IR module lowering", prerequisite = emptySet(), diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticDefaultFunctionLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticDefaultFunctionLowering.kt index 986b7309e33..09aede0ccb7 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticDefaultFunctionLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/StaticDefaultFunctionLowering.kt @@ -20,12 +20,15 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.ir.createStaticFunctionWithReceivers import org.jetbrains.kotlin.backend.common.ir.moveBodyTo -import org.jetbrains.kotlin.backend.common.phaser.SameTypeNamedPhaseWrapper +import org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.then import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.IrClass +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin +import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrReturn @@ -45,7 +48,7 @@ private val callLoweringPhase = makeIrFilePhase( description = "Generate calls of static functions for default parameters" ) -internal val staticDefaultFunctionPhase = SameTypeNamedPhaseWrapper( +internal val staticDefaultFunctionPhase = NamedCompilerPhase( name = "StaticDefaultFunction", description = "Make function adapters for default arguments static", lower = functionDefinitionLoweringPhase then callLoweringPhase,