JVM IR: move jvmPhases to backend.jvm.entrypoint
This will be used for two purposes: 1) call lowerings and codegen separately from KotlinToJVMBytecodeCompiler to support cyclical module dependencies (KT-49575) 2) split lowerings and codegen into separate modules
This commit is contained in:
@@ -12,7 +12,6 @@ dependencies {
|
|||||||
api(project(":compiler:backend-common"))
|
api(project(":compiler:backend-common"))
|
||||||
api(project(":compiler:backend"))
|
api(project(":compiler:backend"))
|
||||||
api(project(":compiler:backend.jvm"))
|
api(project(":compiler:backend.jvm"))
|
||||||
implementation(project(":compiler:backend.jvm.lower"))
|
|
||||||
implementation(project(":compiler:backend.jvm.entrypoint"))
|
implementation(project(":compiler:backend.jvm.entrypoint"))
|
||||||
api(project(":compiler:ir.backend.common"))
|
api(project(":compiler:ir.backend.common"))
|
||||||
api(project(":compiler:light-classes"))
|
api(project(":compiler:light-classes"))
|
||||||
|
|||||||
@@ -0,0 +1,72 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2021 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.jvm
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
|
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||||
|
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<JvmBackendContext, IrModuleFragment>(
|
||||||
|
op = { context, _ -> context.notifyCodegenStart() },
|
||||||
|
name = "NotifyCodegenStart",
|
||||||
|
description = "Notify time measuring subsystem that code generation is being started",
|
||||||
|
)
|
||||||
|
|
||||||
|
private fun codegenPhase(generateMultifileFacade: Boolean): NamedCompilerPhase<JvmBackendContext, IrModuleFragment> {
|
||||||
|
val suffix = if (generateMultifileFacade) "MultifileFacades" else "Regular"
|
||||||
|
val descriptionSuffix = if (generateMultifileFacade) ", multifile facades" else ", regular files"
|
||||||
|
return performByIrFile(
|
||||||
|
name = "CodegenByIrFile$suffix",
|
||||||
|
description = "Code generation by IrFile$descriptionSuffix",
|
||||||
|
copyBeforeLowering = false,
|
||||||
|
lower = listOf(
|
||||||
|
makeIrFilePhase(
|
||||||
|
{ context ->
|
||||||
|
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()
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
},
|
||||||
|
name = "Codegen$suffix",
|
||||||
|
description = "Code generation"
|
||||||
|
)
|
||||||
|
)
|
||||||
|
)
|
||||||
|
}
|
||||||
|
|
||||||
|
// 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
|
||||||
|
private val jvmCodegenPhases = NamedCompilerPhase(
|
||||||
|
name = "Codegen",
|
||||||
|
description = "Code generation",
|
||||||
|
nlevels = 1,
|
||||||
|
lower = codegenPhase(generateMultifileFacade = true) then
|
||||||
|
codegenPhase(generateMultifileFacade = false)
|
||||||
|
)
|
||||||
|
|
||||||
|
val jvmPhases = NamedCompilerPhase(
|
||||||
|
name = "IrBackend",
|
||||||
|
description = "IR Backend for JVM",
|
||||||
|
nlevels = 1,
|
||||||
|
actions = setOf(defaultDumper, validationAction),
|
||||||
|
lower = jvmLoweringPhases then
|
||||||
|
notifyCodegenStartPhase then
|
||||||
|
jvmCodegenPhases
|
||||||
|
)
|
||||||
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.lower.*
|
|||||||
import org.jetbrains.kotlin.backend.common.lower.loops.forLoopsPhase
|
import org.jetbrains.kotlin.backend.common.lower.loops.forLoopsPhase
|
||||||
import org.jetbrains.kotlin.backend.common.lower.optimizations.foldConstantLoweringPhase
|
import org.jetbrains.kotlin.backend.common.lower.optimizations.foldConstantLoweringPhase
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.ClassCodegen
|
|
||||||
import org.jetbrains.kotlin.backend.jvm.codegen.shouldContainSuspendMarkers
|
import org.jetbrains.kotlin.backend.jvm.codegen.shouldContainSuspendMarkers
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.constantValue
|
import org.jetbrains.kotlin.backend.jvm.ir.constantValue
|
||||||
import org.jetbrains.kotlin.backend.jvm.lower.*
|
import org.jetbrains.kotlin.backend.jvm.lower.*
|
||||||
@@ -23,7 +22,6 @@ import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
|||||||
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
|
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
|
||||||
import org.jetbrains.kotlin.ir.util.isAnonymousObject
|
import org.jetbrains.kotlin.ir.util.isAnonymousObject
|
||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
import org.jetbrains.kotlin.ir.util.render
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
@@ -277,43 +275,6 @@ private val kotlinNothingValueExceptionPhase = makeIrFilePhase<CommonBackendCont
|
|||||||
description = "Throw proper exception for calls returning value of type 'kotlin.Nothing'"
|
description = "Throw proper exception for calls returning value of type 'kotlin.Nothing'"
|
||||||
)
|
)
|
||||||
|
|
||||||
private val notifyCodegenStartPhase = makeCustomPhase<JvmBackendContext, IrModuleFragment>(
|
|
||||||
op = { context, _ -> context.notifyCodegenStart() },
|
|
||||||
name = "NotifyCodegenStart",
|
|
||||||
description = "Notify time measuring subsystem that code generation is being started",
|
|
||||||
)
|
|
||||||
|
|
||||||
private fun codegenPhase(generateMultifileFacade: Boolean): NamedCompilerPhase<JvmBackendContext, IrModuleFragment> {
|
|
||||||
val suffix = if (generateMultifileFacade) "MultifileFacades" else "Regular"
|
|
||||||
val descriptionSuffix = if (generateMultifileFacade) ", multifile facades" else ", regular files"
|
|
||||||
return performByIrFile(
|
|
||||||
name = "CodegenByIrFile$suffix",
|
|
||||||
description = "Code generation by IrFile$descriptionSuffix",
|
|
||||||
copyBeforeLowering = false,
|
|
||||||
lower = listOf(
|
|
||||||
makeIrFilePhase(
|
|
||||||
{ context ->
|
|
||||||
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()
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
}
|
|
||||||
},
|
|
||||||
name = "Codegen$suffix",
|
|
||||||
description = "Code generation"
|
|
||||||
)
|
|
||||||
)
|
|
||||||
)
|
|
||||||
}
|
|
||||||
|
|
||||||
private val jvmFilePhases = listOf(
|
private val jvmFilePhases = listOf(
|
||||||
typeAliasAnnotationMethodsPhase,
|
typeAliasAnnotationMethodsPhase,
|
||||||
stripTypeAliasDeclarationsPhase,
|
stripTypeAliasDeclarationsPhase,
|
||||||
@@ -425,7 +386,7 @@ private val jvmFilePhases = listOf(
|
|||||||
makePatchParentsPhase(4)
|
makePatchParentsPhase(4)
|
||||||
)
|
)
|
||||||
|
|
||||||
private val jvmLoweringPhases = NamedCompilerPhase(
|
val jvmLoweringPhases = NamedCompilerPhase(
|
||||||
name = "IrLowering",
|
name = "IrLowering",
|
||||||
description = "IR lowering",
|
description = "IR lowering",
|
||||||
nlevels = 1,
|
nlevels = 1,
|
||||||
@@ -444,26 +405,3 @@ private val jvmLoweringPhases = NamedCompilerPhase(
|
|||||||
prepareForBytecodeInlining then
|
prepareForBytecodeInlining then
|
||||||
validateIrAfterLowering
|
validateIrAfterLowering
|
||||||
)
|
)
|
||||||
|
|
||||||
// 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
|
|
||||||
private val jvmCodegenPhases = NamedCompilerPhase(
|
|
||||||
name = "Codegen",
|
|
||||||
description = "Code generation",
|
|
||||||
nlevels = 1,
|
|
||||||
lower = codegenPhase(generateMultifileFacade = true) then
|
|
||||||
codegenPhase(generateMultifileFacade = false)
|
|
||||||
|
|
||||||
)
|
|
||||||
|
|
||||||
val jvmPhases = NamedCompilerPhase(
|
|
||||||
name = "IrBackend",
|
|
||||||
description = "IR Backend for JVM",
|
|
||||||
nlevels = 1,
|
|
||||||
actions = setOf(defaultDumper, validationAction),
|
|
||||||
lower = jvmLoweringPhases then
|
|
||||||
notifyCodegenStartPhase then
|
|
||||||
jvmCodegenPhases
|
|
||||||
)
|
|
||||||
|
|
||||||
|
|||||||
@@ -9,7 +9,6 @@ dependencies {
|
|||||||
testApi(project(":compiler:fir:entrypoint"))
|
testApi(project(":compiler:fir:entrypoint"))
|
||||||
testApi(project(":compiler:cli"))
|
testApi(project(":compiler:cli"))
|
||||||
testImplementation(project(":compiler:ir.tree.impl"))
|
testImplementation(project(":compiler:ir.tree.impl"))
|
||||||
testImplementation(project(":compiler:backend.jvm.lower"))
|
|
||||||
testImplementation(project(":compiler:backend.jvm.entrypoint"))
|
testImplementation(project(":compiler:backend.jvm.entrypoint"))
|
||||||
testImplementation(intellijCoreDep()) { includeJars("intellij-core") }
|
testImplementation(intellijCoreDep()) { includeJars("intellij-core") }
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user