From 5012aeba7c6ce1839aecddb854429452c2658e30 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Tue, 16 Nov 2021 00:17:34 +0100 Subject: [PATCH] JVM IR: move codegen out of the main phases This is needed in order to be able to invoke lowerings and codegen separately, for cyclically dependent modules (KT-49575). A side effect is that the two codegen phases are no longer configurable via the phaser, i.e. absent in the -Xlist-phases and can't be disabled or made verbose. --- .../kotlin/backend/jvm/JvmIrCodegenFactory.kt | 13 ++--- .../jetbrains/kotlin/backend/jvm/JvmPhases.kt | 56 ++++++++----------- .../jetbrains/kotlin/backend/jvm/JvmLower.kt | 1 + .../kotlin/backend/jvm/JvmBackendContext.kt | 1 - 4 files changed, 31 insertions(+), 40 deletions(-) diff --git a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt index 200eebc11a6..005e680fb5b 100644 --- a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt +++ b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmIrCodegenFactory.kt @@ -221,22 +221,21 @@ open class JvmIrCodegenFactory( ) JvmIrSerializerImpl(state.configuration) else null - val phases = prefixPhases?.then(jvmPhases) ?: jvmPhases + val phases = prefixPhases?.then(jvmLoweringPhases) ?: jvmLoweringPhases val phaseConfig = customPhaseConfig ?: PhaseConfig(phases) val context = JvmBackendContext( state, irModuleFragment.irBuiltins, irModuleFragment, symbolTable, phaseConfig, extensions, backendExtension, irSerializer, - notifyCodegenStart, ) /* JvmBackendContext creates new unbound symbols, have to resolve them. */ ExternalDependenciesGenerator(symbolTable, irProviders).generateUnboundSymbolsAsDependencies() context.state.factory.registerSourceFiles(irModuleFragment.files.map(IrFile::getKtFile)) - phases.invokeToplevel( - phaseConfig, - context, - irModuleFragment - ) + phases.invokeToplevel(phaseConfig, context, irModuleFragment) + + notifyCodegenStart() + + jvmCodegenPhases.invokeToplevel(phaseConfig, context, irModuleFragment) // TODO: split classes into groups connected by inline calls; call this after every group // and clear `JvmBackendContext.classCodegens` diff --git a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmPhases.kt b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmPhases.kt index c7681e5ef45..46c1cdff7e9 100644 --- a/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmPhases.kt +++ b/compiler/ir/backend.jvm/entrypoint/src/org/jetbrains/kotlin/backend/jvm/JvmPhases.kt @@ -6,19 +6,16 @@ package org.jetbrains.kotlin.backend.jvm import org.jetbrains.kotlin.backend.common.FileLoweringPass -import org.jetbrains.kotlin.backend.common.phaser.* +import org.jetbrains.kotlin.backend.common.phaser.NamedCompilerPhase +import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase +import org.jetbrains.kotlin.backend.common.phaser.performByIrFile +import org.jetbrains.kotlin.backend.common.phaser.then import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.ir.util.render -private val notifyCodegenStartPhase = makeCustomPhase( - op = { context, _ -> context.notifyCodegenStart() }, - name = "NotifyCodegenStart", - description = "Notify time measuring subsystem that code generation is being started", -) - private fun codegenPhase(generateMultifileFacade: Boolean): NamedCompilerPhase { val suffix = if (generateMultifileFacade) "MultifileFacades" else "Regular" val descriptionSuffix = if (generateMultifileFacade) ", multifile facades" else ", regular files" @@ -28,21 +25,7 @@ private fun codegenPhase(generateMultifileFacade: Boolean): NamedCompilerPhase - object : FileLoweringPass { - override fun lower(irFile: IrFile) { - val isMultifileFacade = irFile.fileEntry is MultifileFacadeFileEntry - if (isMultifileFacade == generateMultifileFacade) { - for (loweredClass in irFile.declarations) { - if (loweredClass !is IrClass) { - throw AssertionError("File-level declaration should be IrClass after JvmLower, got: " + loweredClass.render()) - } - ClassCodegen.getOrCreate(loweredClass, context).generate() - } - } - } - } - }, + { context -> FileCodegen(context, generateMultifileFacade) }, name = "Codegen$suffix", description = "Code generation" ) @@ -50,10 +33,24 @@ private fun codegenPhase(generateMultifileFacade: Boolean): NamedCompilerPhase + get() = jvmLoweringPhases diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 8f9acab1cbf..dd30a8abcf2 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -390,6 +390,7 @@ val jvmLoweringPhases = NamedCompilerPhase( name = "IrLowering", description = "IR lowering", nlevels = 1, + actions = setOf(defaultDumper, validationAction), lower = validateIrBeforeLowering then processOptionalAnnotationsPhase then expectDeclarationsRemovingPhase then diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index b974b5bdd1d..764c615d724 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -48,7 +48,6 @@ class JvmBackendContext( val generatorExtensions: JvmGeneratorExtensions, val backendExtension: JvmBackendExtension, val irSerializer: JvmIrSerializer?, - val notifyCodegenStart: () -> Unit ) : CommonBackendContext { // If the JVM fqname of a class differs from what is implied by its parent, e.g. if it's a file class // annotated with @JvmPackageName, the correct name is recorded here.