diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/DumperVerifier.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/DumperVerifier.kt index 6235c1f6f1e..4da8b8b5d93 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/DumperVerifier.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/phaser/DumperVerifier.kt @@ -5,6 +5,10 @@ package org.jetbrains.kotlin.backend.common.phaser +import org.jetbrains.kotlin.backend.common.CheckDeclarationParentsVisitor +import org.jetbrains.kotlin.backend.common.CommonBackendContext +import org.jetbrains.kotlin.backend.common.IrValidator +import org.jetbrains.kotlin.backend.common.IrValidatorConfig import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.util.dump @@ -117,4 +121,17 @@ fun dumpToStdout( println() } -val defaultDumper = makeDumpAction(dumpToStdout(::dumpIrElement) + dumpToFile("ir", ::dumpIrElement)) \ No newline at end of file +val defaultDumper = makeDumpAction(dumpToStdout(::dumpIrElement) + dumpToFile("ir", ::dumpIrElement)) + +fun validationCallback(context: CommonBackendContext, fragment: Fragment) { + val validatorConfig = IrValidatorConfig( + abortOnError = true, + ensureAllNodesAreDifferent = true, + checkTypes = false, + checkDescriptors = false + ) + fragment.accept(IrValidator(context, validatorConfig), null) + fragment.accept(CheckDeclarationParentsVisitor, null) +} + +val validationAction = makeVerifyAction(::validationCallback) 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 907559eaf7f..2be814a01a9 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 @@ -8,6 +8,7 @@ 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.IrElement import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment @@ -54,7 +55,7 @@ fun namedIrModulePhase( preconditions: Set> = emptySet(), postconditions: Set> = emptySet(), stickyPostconditions: Set> = lower.stickyPostconditions, - actions: Set> = setOf(defaultDumper), + actions: Set> = setOf(defaultDumper, validationAction), nlevels: Int = 1 ) = SameTypeNamedPhaseWrapper( name, @@ -76,7 +77,7 @@ fun namedIrFilePhase( preconditions: Set> = emptySet(), postconditions: Set> = emptySet(), stickyPostconditions: Set> = lower.stickyPostconditions, - actions: Set> = setOf(defaultDumper), + actions: Set> = setOf(defaultDumper, validationAction), nlevels: Int = 1 ) = SameTypeNamedPhaseWrapper( name, @@ -90,6 +91,38 @@ fun namedIrFilePhase( nlevels ) +fun makeCustomPhase( + op: (Context, Element) -> Unit, + description: String, + name: String, + prerequisite: Set = emptySet(), + preconditions: Set> = emptySet(), + postconditions: Set> = emptySet(), + stickyPostconditions: Set> = emptySet(), + actions: Set> = setOf(defaultDumper, validationAction), + nlevels: Int = 1 +) = SameTypeNamedPhaseWrapper( + name, + description, + prerequisite, + preconditions = preconditions, + postconditions = postconditions, + stickyPostconditions = stickyPostconditions, + actions = actions, + nlevels = nlevels, + lower = object : SameTypeCompilerPhase { + override fun invoke( + phaseConfig: PhaseConfig, + phaserState: PhaserState, + context: Context, + input: Element + ): Element { + op(context, input) + return input + } + } +) + fun namedUnitPhase( name: String, description: String, @@ -160,7 +193,7 @@ fun makeIrFilePhase( preconditions: Set> = emptySet(), postconditions: Set> = emptySet(), stickyPostconditions: Set> = emptySet(), - actions: Set> = setOf(defaultDumper) + actions: Set> = setOf(defaultDumper, validationAction) ) = namedIrFilePhase( name, description, prerequisite, preconditions = preconditions, @@ -184,7 +217,7 @@ fun makeIrModulePhase( preconditions: Set> = emptySet(), postconditions: Set> = emptySet(), stickyPostconditions: Set> = emptySet(), - actions: Set> = setOf(defaultDumper) + actions: Set> = setOf(defaultDumper, validationAction) ) = namedIrModulePhase( name, description, prerequisite, preconditions=preconditions, 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 3c7b228b584..b779fbade36 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 @@ -21,19 +21,6 @@ private fun DeclarationContainerLoweringPass.runOnFilesPostfix(files: Iterable FileLoweringPass, name: String, diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index 75f3cbea682..b51279cdf36 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -37,6 +37,18 @@ private fun makePatchParentsPhase(number: Int) = namedIrFilePhase( nlevels = 0 ) +private val validateIrBeforeLowering = makeCustomPhase( + { context, module -> validationCallback(context, module) }, + name = "ValidateIrBeforeLowering", + description = "Validate IR before lowering" +) + +private val validateIrAfterLowering = makeCustomPhase( + { context, module -> validationCallback(context, module) }, + name = "ValidateIrAfterLowering", + description = "Validate IR after lowering" +) + private val stripTypeAliasDeclarationsPhase = makeIrFilePhase( { StripTypeAliasDeclarationsLowering() }, name = "StripTypeAliasDeclarations", @@ -231,10 +243,12 @@ private val jvmFilePhases = val jvmPhases = namedIrModulePhase( name = "IrLowering", description = "IR lowering", - lower = expectDeclarationsRemovingPhase then + lower = validateIrBeforeLowering then + expectDeclarationsRemovingPhase then fileClassPhase then performByIrFile(lower = jvmFilePhases) then - generateMultifileFacadesPhase + generateMultifileFacadesPhase then + validateIrAfterLowering ) class JvmLower(val context: JvmBackendContext) { diff --git a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt index cd82dc7243c..02efa614790 100644 --- a/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt +++ b/compiler/ir/backend.wasm/src/org/jetbrains/kotlin/backend/wasm/WasmLoweringPhases.kt @@ -20,19 +20,6 @@ import org.jetbrains.kotlin.ir.util.patchDeclarationParents private fun ClassLoweringPass.runOnFilesPostfix(moduleFragment: IrModuleFragment) = moduleFragment.files.forEach { runOnFilePostfix(it) } -private fun validationCallback(context: WasmBackendContext, module: IrModuleFragment) { - val validatorConfig = IrValidatorConfig( - abortOnError = true, - ensureAllNodesAreDifferent = true, - checkTypes = false, - checkDescriptors = false - ) - module.accept(IrValidator(context, validatorConfig), null) - module.accept(CheckDeclarationParentsVisitor, null) -} - -val validationAction = makeVerifyAction(::validationCallback) - private fun makeWasmModulePhase( lowering: (WasmBackendContext) -> FileLoweringPass, name: String,