Turned on IR validation
This commit is contained in:
-8
@@ -10,10 +10,8 @@ import llvm.LLVMModuleRef
|
||||
import org.jetbrains.kotlin.backend.common.DumpIrTreeWithDescriptorsVisitor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedSimpleFunctionDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.descriptors.WrappedTypeParameterDescriptor
|
||||
import org.jetbrains.kotlin.backend.common.validateIrModule
|
||||
import org.jetbrains.kotlin.backend.konan.descriptors.*
|
||||
import org.jetbrains.kotlin.backend.konan.ir.KonanIr
|
||||
import org.jetbrains.kotlin.backend.konan.library.KonanLibraryWriter
|
||||
import org.jetbrains.kotlin.library.SerializedMetadata
|
||||
import org.jetbrains.kotlin.backend.konan.llvm.*
|
||||
import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_BRIDGE_METHOD
|
||||
@@ -351,11 +349,6 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
moduleDescriptor.deepPrint()
|
||||
}
|
||||
|
||||
fun verifyIr() {
|
||||
val module = irModule ?: return
|
||||
validateIrModule(this, module)
|
||||
}
|
||||
|
||||
fun printIr() {
|
||||
if (irModule == null) return
|
||||
separator("IR:")
|
||||
@@ -418,7 +411,6 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
|
||||
|
||||
fun verify() {
|
||||
verifyDescriptors()
|
||||
verifyIr()
|
||||
verifyBitCode()
|
||||
}
|
||||
|
||||
|
||||
+14
-30
@@ -10,22 +10,24 @@ import org.jetbrains.kotlin.backend.konan.lower.InitializersLowering
|
||||
import org.jetbrains.kotlin.backend.konan.lower.loops.ForLoopsLowering
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.checkDeclarationParents
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
|
||||
private val validateAll = false
|
||||
private val filePhaseActions = if (validateAll) setOf(defaultDumper, ::fileValidationCallback) else setOf(defaultDumper)
|
||||
private val modulePhaseActions = if (validateAll) setOf(defaultDumper, ::moduleValidationCallback) else setOf(defaultDumper)
|
||||
|
||||
private fun makeKonanFileLoweringPhase(
|
||||
lowering: (Context) -> FileLoweringPass,
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet()
|
||||
) = makeIrFilePhase(lowering, name, description, prerequisite)
|
||||
) = makeIrFilePhase(lowering, name, description, prerequisite, actions = filePhaseActions)
|
||||
|
||||
private fun makeKonanModuleLoweringPhase(
|
||||
lowering: (Context) -> FileLoweringPass,
|
||||
name: String,
|
||||
description: String,
|
||||
prerequisite: Set<AnyNamedPhase> = emptySet()
|
||||
) = makeIrModulePhase(lowering, name, description, prerequisite)
|
||||
) = makeIrModulePhase(lowering, name, description, prerequisite, actions = modulePhaseActions)
|
||||
|
||||
internal fun makeKonanFileOpPhase(
|
||||
op: (Context, IrFile) -> Unit,
|
||||
@@ -39,7 +41,8 @@ internal fun makeKonanFileOpPhase(
|
||||
op(context, input)
|
||||
return input
|
||||
}
|
||||
}
|
||||
},
|
||||
actions = filePhaseActions
|
||||
)
|
||||
|
||||
internal fun makeKonanModuleOpPhase(
|
||||
@@ -54,7 +57,8 @@ internal fun makeKonanModuleOpPhase(
|
||||
op(context, input)
|
||||
return input
|
||||
}
|
||||
}
|
||||
},
|
||||
actions = modulePhaseActions
|
||||
)
|
||||
|
||||
internal val removeExpectDeclarationsPhase = makeKonanModuleLoweringPhase(
|
||||
@@ -79,7 +83,8 @@ internal val inlinePhase = namedIrModulePhase(
|
||||
name = "Inline",
|
||||
description = "Functions inlining",
|
||||
prerequisite = setOf(lowerBeforeInlinePhase),
|
||||
nlevels = 0
|
||||
nlevels = 0,
|
||||
actions = modulePhaseActions
|
||||
)
|
||||
|
||||
internal val lowerAfterInlinePhase = makeKonanModuleOpPhase(
|
||||
@@ -99,24 +104,6 @@ internal val interopPart1Phase = makeKonanModuleLoweringPhase(
|
||||
prerequisite = setOf(inlinePhase)
|
||||
)
|
||||
|
||||
internal val patchDeclarationParents1Phase = makeKonanModuleOpPhase(
|
||||
{ _, irModule -> irModule.patchDeclarationParents() },
|
||||
name = "PatchDeclarationParents1",
|
||||
description = "Patch declaration parents 1"
|
||||
)
|
||||
|
||||
internal val checkDeclarationParentsPhase = makeKonanModuleOpPhase(
|
||||
{ _, irModule -> irModule.checkDeclarationParents() },
|
||||
name = "CheckDeclarationParents",
|
||||
description = "Check declaration parents"
|
||||
)
|
||||
|
||||
internal val validateIrModulePhase = makeKonanModuleOpPhase(
|
||||
{ context, irModule -> validateIrModule(context, irModule) },
|
||||
name = "ValidateIrModule",
|
||||
description = "Validate generated module"
|
||||
)
|
||||
|
||||
/* IrFile phases */
|
||||
|
||||
internal val lateinitPhase = makeKonanFileLoweringPhase(
|
||||
@@ -284,11 +271,8 @@ internal val bridgesPhase = makeKonanFileOpPhase(
|
||||
prerequisite = setOf(coroutinesPhase)
|
||||
)
|
||||
|
||||
internal val autoboxPhase = makeKonanFileOpPhase(
|
||||
{ context, irFile ->
|
||||
// validateIrFile(context, irFile) // Temporarily disabled until moving to new IR finished.
|
||||
Autoboxing(context).lower(irFile)
|
||||
},
|
||||
internal val autoboxPhase = makeKonanFileLoweringPhase(
|
||||
::Autoboxing,
|
||||
name = "Autobox",
|
||||
description = "Autoboxing of primitive types",
|
||||
prerequisite = setOf(bridgesPhase, coroutinesPhase)
|
||||
|
||||
+39
-15
@@ -1,6 +1,6 @@
|
||||
package org.jetbrains.kotlin.backend.konan
|
||||
|
||||
import org.jetbrains.kotlin.backend.common.LoggingContext
|
||||
import org.jetbrains.kotlin.backend.common.*
|
||||
import org.jetbrains.kotlin.backend.common.extensions.IrGenerationExtension
|
||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||
import org.jetbrains.kotlin.backend.common.serialization.DescriptorTable
|
||||
@@ -20,12 +20,47 @@ import org.jetbrains.kotlin.config.languageVersionSettings
|
||||
import org.jetbrains.kotlin.ir.declarations.IrFile
|
||||
import org.jetbrains.kotlin.ir.declarations.IrModuleFragment
|
||||
import org.jetbrains.kotlin.ir.util.SymbolTable
|
||||
import org.jetbrains.kotlin.ir.util.patchDeclarationParents
|
||||
import org.jetbrains.kotlin.konan.target.CompilerOutputKind
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrConfiguration
|
||||
import org.jetbrains.kotlin.psi2ir.Psi2IrTranslator
|
||||
import java.util.Collections.emptySet
|
||||
|
||||
internal fun moduleValidationCallback(state: ActionState, module: IrModuleFragment, context: Context) {
|
||||
val validatorConfig = IrValidatorConfig(
|
||||
abortOnError = false,
|
||||
ensureAllNodesAreDifferent = true,
|
||||
checkTypes = true,
|
||||
checkDescriptors = false
|
||||
)
|
||||
try {
|
||||
module.accept(IrValidator(context, validatorConfig), null)
|
||||
module.accept(CheckDeclarationParentsVisitor, null)
|
||||
} catch (t: Throwable) {
|
||||
// TODO: Add reference to source.
|
||||
if (validatorConfig.abortOnError)
|
||||
throw IllegalStateException("Failed IR validation ${state.beforeOrAfter} ${state.phase}", t)
|
||||
else context.reportCompilationWarning("[IR VALIDATION] ${state.beforeOrAfter} ${state.phase}: ${t.message}")
|
||||
}
|
||||
}
|
||||
|
||||
internal fun fileValidationCallback(state: ActionState, irFile: IrFile, context: Context) {
|
||||
val validatorConfig = IrValidatorConfig(
|
||||
abortOnError = false,
|
||||
ensureAllNodesAreDifferent = true,
|
||||
checkTypes = true,
|
||||
checkDescriptors = false
|
||||
)
|
||||
try {
|
||||
irFile.accept(IrValidator(context, validatorConfig), null)
|
||||
irFile.accept(CheckDeclarationParentsVisitor, null)
|
||||
} catch (t: Throwable) {
|
||||
// TODO: Add reference to source.
|
||||
if (validatorConfig.abortOnError)
|
||||
throw IllegalStateException("Failed IR validation ${state.beforeOrAfter} ${state.phase}", t)
|
||||
else context.reportCompilationWarning("[IR VALIDATION] ${state.beforeOrAfter} ${state.phase}: ${t.message}")
|
||||
}
|
||||
}
|
||||
|
||||
internal fun konanUnitPhase(
|
||||
name: String,
|
||||
description: String,
|
||||
@@ -128,8 +163,6 @@ internal val psiToIrPhase = konanUnitPhase(
|
||||
irModule = module
|
||||
irModules = deserializer.modules
|
||||
ir.symbols = symbols
|
||||
|
||||
// validateIrModule(this, module)
|
||||
},
|
||||
name = "Psi2Ir",
|
||||
description = "Psi to IR conversion",
|
||||
@@ -169,12 +202,6 @@ internal val copyDefaultValuesToActualPhase = konanUnitPhase(
|
||||
description = "Copy default values from expect to actual declarations"
|
||||
)
|
||||
|
||||
internal val patchDeclarationParents0Phase = konanUnitPhase(
|
||||
op = { irModule!!.patchDeclarationParents() }, // why do we need it?
|
||||
name = "PatchDeclarationParents0",
|
||||
description = "Patch declaration parents"
|
||||
)
|
||||
|
||||
internal val serializerPhase = konanUnitPhase(
|
||||
op = {
|
||||
val declarationTable = KonanDeclarationTable(irModule!!.irBuiltins, DescriptorTable())
|
||||
@@ -213,7 +240,6 @@ internal val allLoweringsPhase = namedIrModulePhase(
|
||||
inlinePhase then
|
||||
lowerAfterInlinePhase then
|
||||
interopPart1Phase then
|
||||
patchDeclarationParents1Phase then
|
||||
performByIrFile(
|
||||
name = "IrLowerByFile",
|
||||
description = "IR Lowering by file",
|
||||
@@ -242,9 +268,8 @@ internal val allLoweringsPhase = namedIrModulePhase(
|
||||
bridgesPhase then
|
||||
autoboxPhase then
|
||||
returnsInsertionPhase
|
||||
) then
|
||||
checkDeclarationParentsPhase
|
||||
// validateIrModulePhase // Temporarily disabled until moving to new IR finished.
|
||||
),
|
||||
actions = setOf(defaultDumper, ::moduleValidationCallback)
|
||||
)
|
||||
|
||||
internal val dependenciesLowerPhase = SameTypeNamedPhaseWrapper(
|
||||
@@ -313,7 +338,6 @@ val toplevelPhase: CompilerPhase<*, Unit, Unit> = namedUnitPhase(
|
||||
destroySymbolTablePhase then
|
||||
irGeneratorPluginsPhase then
|
||||
copyDefaultValuesToActualPhase then
|
||||
patchDeclarationParents0Phase then
|
||||
serializerPhase then
|
||||
namedUnitPhase(
|
||||
name = "Backend",
|
||||
|
||||
-33
@@ -123,39 +123,6 @@ object SetDeclarationsParentVisitor : IrElementVisitor<Unit, IrDeclarationParent
|
||||
}
|
||||
}
|
||||
|
||||
fun IrModuleFragment.checkDeclarationParents() {
|
||||
this.accept(CheckDeclarationParentsVisitor, null)
|
||||
}
|
||||
|
||||
object CheckDeclarationParentsVisitor : IrElementVisitor<Unit, IrDeclarationParent?> {
|
||||
|
||||
override fun visitElement(element: IrElement, data: IrDeclarationParent?) {
|
||||
element.acceptChildren(this, element as? IrDeclarationParent ?: data)
|
||||
}
|
||||
|
||||
override fun visitDeclaration(declaration: IrDeclaration, data: IrDeclarationParent?) {
|
||||
if (declaration !is IrVariable && declaration !is IrValueParameter && declaration !is IrTypeParameter) {
|
||||
checkParent(declaration, data)
|
||||
} else {
|
||||
// Don't check IrVariable parent.
|
||||
}
|
||||
|
||||
super.visitDeclaration(declaration, data)
|
||||
}
|
||||
|
||||
private fun checkParent(declaration: IrDeclaration, expectedParent: IrDeclarationParent?) {
|
||||
val parent = try {
|
||||
declaration.parent
|
||||
} catch (e: Throwable) {
|
||||
error("$declaration for ${declaration.descriptor} has no parent")
|
||||
}
|
||||
|
||||
if (parent != expectedParent) {
|
||||
error("$declaration for ${declaration.descriptor} has unexpected parent $parent")
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
tailrec fun IrDeclaration.getContainingFile(): IrFile? {
|
||||
val parent = this.parent
|
||||
|
||||
|
||||
Reference in New Issue
Block a user