[JVM_IR] Move all stickyPostconditions into single lowering

`stickyPostconditions` are such conditions that are checked
every time after applying when a new lowering finishes its execution.
Right now we are using them only in JVM, and this is a blocker
for adopting Native approach for lowering execution.

In Native we are using
`SimpleNamedCompilerPhase<in Context : LoggingContext, Input, Output>`
as the common super type for all lowerings. Here we have `Input` and
`Output` that can potentially be different and `stickyPostconditions`
don't have much sense in that case.
This commit is contained in:
Ivan Kylchik
2023-09-20 20:32:34 +02:00
committed by Space Team
parent 6a02a26db8
commit f5bb477459
4 changed files with 39 additions and 34 deletions
@@ -43,20 +43,6 @@ class PropertiesLowering : DeclarationTransformer {
return null
}
companion object {
fun checkNoProperties(irFile: IrFile) {
irFile.acceptVoid(object : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitProperty(declaration: IrProperty) {
error("No properties should remain at this stage")
}
})
}
}
}
class LocalDelegatedPropertiesLowering : IrElementTransformerVoid(), BodyLoweringPass {
@@ -83,6 +83,12 @@ private val validateIrAfterLowering = makeCustomPhase(
description = "Validate IR after lowering"
)
private val validateJvmIrAfterLowering = makeCustomPhase<JvmBackendContext>(
{ _, module -> validateJvmIr(module) },
name = "ValidateJvmIrAfterLowering",
description = "Validate that IR after lowering is correctly structured by Kotlin JVM rules"
)
// TODO make all lambda-related stuff work with IrFunctionExpression and drop this phase
private val provisionalFunctionExpressionPhase = makeIrFilePhase<CommonBackendContext>(
{ ProvisionalFunctionExpressionLowering() },
@@ -112,7 +118,6 @@ internal val propertiesPhase = makeIrFilePhase(
description = "Move fields and accessors for properties to their classes, " +
"replace calls to default property accessors with field accesses, " +
"remove unused accessors and create synthetic methods for property annotations",
stickyPostconditions = setOf(PropertiesLowering.Companion::checkNoProperties)
)
internal val IrClass.isGeneratedLambdaClass: Boolean
@@ -243,17 +248,6 @@ private val initializersCleanupPhase = makeIrFilePhase(
},
name = "InitializersCleanup",
description = "Remove non-static anonymous initializers and non-constant non-static field init expressions",
stickyPostconditions = setOf(fun(irFile: IrFile) {
irFile.acceptVoid(object : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) {
error("No anonymous initializers should remain at this stage")
}
})
}),
prerequisite = setOf(initializersPhase)
)
@@ -487,7 +481,8 @@ private fun buildJvmLoweringPhases(
buildLoweringsPhase(phases) then
generateMultifileFacadesPhase then
resolveInlineCallsPhase then
validateIrAfterLowering
validateIrAfterLowering then
validateJvmIrAfterLowering
)
}
@@ -54,15 +54,8 @@ internal val fileClassPhase = makeIrModulePhase(
::FileClassLowering,
name = "FileClass",
description = "Put file level function and property declaration into a class",
stickyPostconditions = setOf(::checkAllFileLevelDeclarationsAreClasses)
)
internal fun checkAllFileLevelDeclarationsAreClasses(irModuleFragment: IrModuleFragment) {
assert(irModuleFragment.files.all { irFile ->
irFile.declarations.all { it is IrClass }
})
}
private class FileClassLowering(val context: JvmBackendContext) : FileLoweringPass {
override fun lower(irFile: IrFile) {
val classes = ArrayList<IrClass>()
@@ -7,9 +7,40 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.phaser.validationCallback
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrAnonymousInitializer
import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
import org.jetbrains.kotlin.ir.declarations.IrProperty
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid
fun validateIr(context: JvmBackendContext, module: IrModuleFragment) {
if (!context.config.shouldValidateIr) return
validationCallback(context, module, checkProperties = true)
}
private fun checkAllFileLevelDeclarationsAreClasses(module: IrModuleFragment) {
assert(module.files.all { irFile ->
irFile.declarations.all { it is IrClass }
})
}
fun validateJvmIr(module: IrModuleFragment) {
checkAllFileLevelDeclarationsAreClasses(module)
val validator = object : IrElementVisitorVoid {
override fun visitElement(element: IrElement) {
element.acceptChildrenVoid(this)
}
override fun visitProperty(declaration: IrProperty) {
error("No properties should remain at this stage")
}
override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) {
error("No anonymous initializers should remain at this stage")
}
}
module.acceptVoid(validator)
}