From d7e44dc46a05886c1ab13d361a7738b487831ced Mon Sep 17 00:00:00 2001 From: Sergey Bogolepov Date: Tue, 24 Jan 2023 15:44:55 +0200 Subject: [PATCH] [K/N] Port lowerings from old builders to the new ones --- .../backend/konan/KonanLoweringPhases.kt | 391 ---------------- .../kotlin/backend/konan/ToplevelPhases.kt | 84 +--- .../kotlin/backend/konan/driver/Machinery.kt | 3 - .../backend/konan/driver/phases/Lowerings.kt | 431 ++++++++++++++++-- .../konan/driver/phases/TopLevelPhases.kt | 2 +- 5 files changed, 392 insertions(+), 519 deletions(-) delete mode 100644 kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLoweringPhases.kt diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLoweringPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLoweringPhases.kt deleted file mode 100644 index b7a17e854cf..00000000000 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/KonanLoweringPhases.kt +++ /dev/null @@ -1,391 +0,0 @@ -package org.jetbrains.kotlin.backend.konan - -import org.jetbrains.kotlin.backend.common.FileLoweringPass -import org.jetbrains.kotlin.backend.common.lower.* -import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesExtractionFromInlineFunctionsLowering -import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineFunctionsLowering -import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineLambdasLowering -import org.jetbrains.kotlin.backend.common.lower.loops.ForLoopsLowering -import org.jetbrains.kotlin.backend.common.lower.optimizations.FoldConstantLowering -import org.jetbrains.kotlin.backend.common.phaser.* -import org.jetbrains.kotlin.backend.common.runOnFilePostfix -import org.jetbrains.kotlin.backend.konan.ir.FunctionsWithoutBoundCheckGenerator -import org.jetbrains.kotlin.backend.konan.lower.* -import org.jetbrains.kotlin.backend.konan.lower.InitializersLowering -import org.jetbrains.kotlin.backend.konan.optimizations.KonanBCEForLoopBodyTransformer -import org.jetbrains.kotlin.ir.IrElement -import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.declarations.IrFunction -import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid -import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid - -private val validateAll = false - -private val filePhaseActions = setOfNotNull( - defaultDumper, - ::fileValidationCallback.takeIf { validateAll } -) -private val modulePhaseActions = setOfNotNull( - defaultDumper, -// ::llvmIrDumpCallback, - ::moduleValidationCallback.takeIf { validateAll } -) - -private fun makeKonanFileLoweringPhase( - lowering: (Context) -> FileLoweringPass, - name: String, - description: String, - prerequisite: Set> = emptySet() -) = makeIrFilePhase(lowering, name, description, prerequisite, actions = filePhaseActions) - -private fun makeKonanModuleLoweringPhase( - lowering: (Context) -> FileLoweringPass, - name: String, - description: String, - prerequisite: Set> = emptySet() -) = makeIrModulePhase(lowering, name, description, prerequisite, actions = modulePhaseActions) - -internal fun makeKonanFileOpPhase( - op: (Context, IrFile) -> Unit, - name: String, - description: String, - prerequisite: Set> = emptySet() -) = SameTypeNamedCompilerPhase( - name, description, prerequisite, nlevels = 0, - lower = object : SameTypeCompilerPhase { - override fun invoke(phaseConfig: PhaseConfigurationService, phaserState: PhaserState, context: Context, input: IrFile): IrFile { - op(context, input) - return input - } - }, - actions = filePhaseActions -) - -/* IrFile phases */ - -internal val removeExpectDeclarationsPhase = makeKonanFileLoweringPhase( - ::ExpectDeclarationsRemoving, - name = "RemoveExpectDeclarations", - description = "Expect declarations removing" -) - -internal val stripTypeAliasDeclarationsPhase = makeKonanFileLoweringPhase( - { StripTypeAliasDeclarationsLowering() }, - name = "StripTypeAliasDeclarations", - description = "Strip typealias declarations" -) - -internal val annotationImplementationPhase = makeKonanFileLoweringPhase( - { context -> AnnotationImplementationLowering { NativeAnnotationImplementationTransformer(context, it) } }, - name = "AnnotationImplementation", - description = "Create synthetic annotations implementations and use them in annotations constructor calls" -) - -internal val lowerBeforeInlinePhase = makeKonanFileLoweringPhase( - ::PreInlineLowering, - name = "LowerBeforeInline", - description = "Special operations processing before inlining" -) - -internal val arrayConstructorPhase = makeKonanFileLoweringPhase( - ::ArrayConstructorLowering, - name = "ArrayConstructor", - description = "Transform `Array(size) { index -> value }` into a loop" -) - -internal val lateinitPhase = makeKonanFileOpPhase( - { context, irFile -> - NullableFieldsForLateinitCreationLowering(context).lower(irFile) - NullableFieldsDeclarationLowering(context).lower(irFile) - LateinitUsageLowering(context).lower(irFile) - }, - name = "Lateinit", - description = "Lateinit properties lowering" -) - -internal val sharedVariablesPhase = makeKonanFileLoweringPhase( - ::SharedVariablesLowering, - name = "SharedVariables", - description = "Shared variable lowering", - prerequisite = setOf(lateinitPhase) -) - -internal val extractLocalClassesFromInlineBodies = makeKonanFileOpPhase( - { context, irFile -> - irFile.acceptChildrenVoid(object : IrElementVisitorVoid { - override fun visitElement(element: IrElement) { - element.acceptChildrenVoid(this) - } - - override fun visitFunction(declaration: IrFunction) { - if (declaration.isInline) - context.inlineFunctionsSupport.saveNonLoweredInlineFunction(declaration) - declaration.acceptChildrenVoid(this) - } - }) - - LocalClassesInInlineLambdasLowering(context).lower(irFile) - LocalClassesInInlineFunctionsLowering(context).lower(irFile) - LocalClassesExtractionFromInlineFunctionsLowering(context).lower(irFile) - }, - name = "ExtractLocalClassesFromInlineBodies", - description = "Extraction of local classes from inline bodies", - prerequisite = setOf(sharedVariablesPhase), // TODO: add "soft" dependency on inventNamesForLocalClasses -) - -internal val wrapInlineDeclarationsWithReifiedTypeParametersLowering = makeKonanFileLoweringPhase( - ::WrapInlineDeclarationsWithReifiedTypeParametersLowering, - name = "WrapInlineDeclarationsWithReifiedTypeParameters", - description = "Wrap inline declarations with reified type parameters" -) - -internal val postInlinePhase = makeKonanFileLoweringPhase( - { PostInlineLowering(it) }, - name = "PostInline", - description = "Post-processing after inlining" -) - -internal val contractsDslRemovePhase = makeKonanFileLoweringPhase( - { ContractsDslRemover(it) }, - name = "RemoveContractsDsl", - description = "Contracts dsl removing" -) - -// TODO make all lambda-related stuff work with IrFunctionExpression and drop this phase (see kotlin: dd3f8ecaacd) -internal val provisionalFunctionExpressionPhase = makeKonanFileLoweringPhase( - { ProvisionalFunctionExpressionLowering() }, - name = "FunctionExpression", - description = "Transform IrFunctionExpression to a local function reference" -) - -internal val flattenStringConcatenationPhase = makeKonanFileLoweringPhase( - ::FlattenStringConcatenationLowering, - name = "FlattenStringConcatenationLowering", - description = "Flatten nested string concatenation expressions into a single IrStringConcatenation" -) - -internal val stringConcatenationPhase = makeKonanFileLoweringPhase( - ::StringConcatenationLowering, - name = "StringConcatenation", - description = "String concatenation lowering" -) - -internal val stringConcatenationTypeNarrowingPhase = makeKonanFileLoweringPhase( - ::StringConcatenationTypeNarrowing, - name = "StringConcatenationTypeNarrowing", - description = "String concatenation type narrowing", - prerequisite = setOf(stringConcatenationPhase) -) - -internal val kotlinNothingValueExceptionPhase = makeKonanFileLoweringPhase( - ::KotlinNothingValueExceptionLowering, - name = "KotlinNothingValueException", - description = "Throw proper exception for calls returning value of type 'kotlin.Nothing'" -) - -internal val enumConstructorsPhase = makeKonanFileLoweringPhase( - ::EnumConstructorsLowering, - name = "EnumConstructors", - description = "Enum constructors lowering" -) - -internal val initializersPhase = makeKonanFileLoweringPhase( - ::InitializersLowering, - name = "Initializers", - description = "Initializers lowering", - prerequisite = setOf(enumConstructorsPhase) -) - -internal val localFunctionsPhase = makeKonanFileOpPhase( - op = { context, irFile -> - LocalDelegatedPropertiesLowering().lower(irFile) - LocalDeclarationsLowering(context).lower(irFile) - LocalClassPopupLowering(context).lower(irFile) - }, - name = "LocalFunctions", - description = "Local function lowering", - prerequisite = setOf(sharedVariablesPhase) // TODO: add "soft" dependency on inventNamesForLocalClasses -) - -internal val tailrecPhase = makeKonanFileLoweringPhase( - ::TailrecLowering, - name = "Tailrec", - description = "Tailrec lowering", - prerequisite = setOf(localFunctionsPhase) -) - -internal val volatilePhase = makeKonanFileLoweringPhase( - ::VolatileFieldsLowering, - name = "VolatileFields", - description = "Volatile fields processing", - prerequisite = setOf(localFunctionsPhase) -) - -internal val defaultParameterExtentPhase = makeKonanFileOpPhase( - { context, irFile -> - KonanDefaultArgumentStubGenerator(context).lower(irFile) - DefaultParameterCleaner(context, replaceDefaultValuesWithStubs = true).lower(irFile) - KonanDefaultParameterInjector(context).lower(irFile) - }, - name = "DefaultParameterExtent", - description = "Default parameter extent lowering", - prerequisite = setOf(tailrecPhase, enumConstructorsPhase) -) - -internal val innerClassPhase = makeKonanFileLoweringPhase( - ::InnerClassLowering, - name = "InnerClasses", - description = "Inner classes lowering", - prerequisite = setOf(defaultParameterExtentPhase) -) - -internal val rangeContainsLoweringPhase = makeKonanFileLoweringPhase( - ::RangeContainsLowering, - name = "RangeContains", - description = "Optimizes calls to contains() for ClosedRanges" -) - -internal val functionsWithoutBoundCheck = konanUnitPhase( - name = "FunctionsWithoutBoundCheckGenerator", - description = "Functions without bounds check generation", - op = { FunctionsWithoutBoundCheckGenerator(this).generate() } -) - -internal val forLoopsPhase = makeKonanFileOpPhase( - { context, irFile -> - ForLoopsLowering(context, KonanBCEForLoopBodyTransformer()).lower(irFile) - }, - name = "ForLoops", - description = "For loops lowering", - prerequisite = setOf(functionsWithoutBoundCheck) -) - -internal val dataClassesPhase = makeKonanFileLoweringPhase( - ::DataClassOperatorsLowering, - name = "DataClasses", - description = "Data classes lowering" -) - -internal val finallyBlocksPhase = makeKonanFileOpPhase( - { context, irFile -> FinallyBlocksLowering(context, context.irBuiltIns.throwableType).lower(irFile) }, - name = "FinallyBlocks", - description = "Finally blocks lowering", - prerequisite = setOf(initializersPhase, localFunctionsPhase, tailrecPhase) -) - -internal val testProcessorPhase = makeKonanFileOpPhase( - { context, irFile -> TestProcessor(context).process(irFile) }, - name = "TestProcessor", - description = "Unit test processor" -) - -internal val enumWhenPhase = makeKonanFileLoweringPhase( - ::NativeEnumWhenLowering, - name = "EnumWhen", - description = "Enum when lowering", -// prerequisite = setOf(enumConstructorsPhase, functionReferencePhase) -) - -internal val enumClassPhase = makeKonanFileLoweringPhase( - ::EnumClassLowering, - name = "Enums", - description = "Enum classes lowering", -// prerequisite = setOf(enumConstructorsPhase, functionReferencePhase, enumWhenPhase) // TODO: make weak dependency on `testProcessorPhase` -) - -internal val enumUsagePhase = makeKonanFileLoweringPhase( - ::EnumUsageLowering, - name = "EnumUsage", - description = "Enum usage lowering", -// prerequisite = setOf(enumConstructorsPhase, functionReferencePhase, enumClassPhase) -) - - -internal val singleAbstractMethodPhase = makeKonanFileLoweringPhase( - ::NativeSingleAbstractMethodLowering, - name = "SingleAbstractMethod", - description = "Replace SAM conversions with instances of interface-implementing classes", -// prerequisite = setOf(functionReferencePhase) -) - -internal val builtinOperatorPhase = makeKonanFileLoweringPhase( - ::BuiltinOperatorLowering, - name = "BuiltinOperators", - description = "BuiltIn operators lowering", - prerequisite = setOf(defaultParameterExtentPhase, singleAbstractMethodPhase, enumWhenPhase) -) - -internal val varargPhase = makeKonanFileLoweringPhase( - ::VarargInjectionLowering, - name = "Vararg", - description = "Vararg lowering", -// prerequisite = setOf(functionReferencePhase, defaultParameterExtentPhase, interopPhase, functionsWithoutBoundCheck) -) - -internal val typeOperatorPhase = makeKonanFileLoweringPhase( - ::TypeOperatorLowering, - name = "TypeOperators", - description = "Type operators lowering", -// prerequisite = setOf(coroutinesPhase) -) - -internal val bridgesPhase = makeKonanFileOpPhase( - { context, irFile -> - BridgesBuilding(context).runOnFilePostfix(irFile) - WorkersBridgesBuilding(context).lower(irFile) - }, - name = "Bridges", - description = "Bridges building", -// prerequisite = setOf(coroutinesPhase) -) - -internal val autoboxPhase = makeKonanFileLoweringPhase( - ::Autoboxing, - name = "Autobox", - description = "Autoboxing of primitive types", -// prerequisite = setOf(bridgesPhase, coroutinesPhase) -) - -internal val expressionBodyTransformPhase = makeKonanFileLoweringPhase( - ::ExpressionBodyTransformer, - name = "ExpressionBodyTransformer", - description = "Replace IrExpressionBody with IrBlockBody" -) - -internal val constantInliningPhase = makeKonanFileLoweringPhase( - ::ConstLowering, - name = "ConstantInlining", - description = "Inline const fields reads", -) - -internal val staticInitializersPhase = makeKonanFileLoweringPhase( - ::StaticInitializersLowering, - name = "StaticInitializers", - description = "Add calls to static initializers", - prerequisite = setOf(expressionBodyTransformPhase) -) - -internal val ifNullExpressionsFusionPhase = makeKonanFileLoweringPhase( - ::IfNullExpressionsFusionLowering, - name = "IfNullExpressionsFusionLowering", - description = "Simplify '?.' and '?:' operator chains" -) - -internal val foldConstantLoweringPhase = makeKonanFileOpPhase( - { context, irFile -> FoldConstantLowering(context).lower(irFile) }, - name = "FoldConstantLowering", - description = "Constant Folding", - prerequisite = setOf(flattenStringConcatenationPhase) -) - -internal val computeStringTrimPhase = makeKonanFileLoweringPhase( - ::StringTrimLowering, - name = "StringTrimLowering", - description = "Compute trimIndent and trimMargin operations on constant strings" -) - -internal val exportInternalAbiPhase = makeKonanFileLoweringPhase( - ::ExportCachesAbiVisitor, - name = "ExportInternalAbi", - description = "Add accessors to private entities" -) \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt index a789898b1a5..829d0d67d0f 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/ToplevelPhases.kt @@ -5,64 +5,6 @@ package org.jetbrains.kotlin.backend.konan -import org.jetbrains.kotlin.backend.common.IrValidator -import org.jetbrains.kotlin.backend.common.IrValidatorConfig -import org.jetbrains.kotlin.backend.common.checkDeclarationParents -import org.jetbrains.kotlin.backend.common.phaser.* -import org.jetbrains.kotlin.backend.konan.descriptors.isFromInteropLibrary -import org.jetbrains.kotlin.backend.konan.llvm.* -import org.jetbrains.kotlin.backend.konan.lower.CacheInfoBuilder -import org.jetbrains.kotlin.backend.konan.lower.SamSuperTypesChecker -import org.jetbrains.kotlin.ir.declarations.IrFile -import org.jetbrains.kotlin.ir.declarations.IrModuleFragment -import org.jetbrains.kotlin.ir.util.* -import org.jetbrains.kotlin.konan.target.CompilerOutputKind -import org.jetbrains.kotlin.name.FqName - -internal fun moduleValidationCallback(state: ActionState, module: IrModuleFragment, context: Context) { - if (!context.config.needVerifyIr) return - - val validatorConfig = IrValidatorConfig( - abortOnError = false, - ensureAllNodesAreDifferent = true, - checkTypes = true, - checkDescriptors = false - ) - try { - module.accept(IrValidator(context, validatorConfig), null) - module.checkDeclarationParents() - } 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.checkDeclarationParents() - } 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, - prerequisite: Set> = emptySet(), - op: Context.() -> Unit -) = namedOpUnitPhase(name, description, prerequisite, op) /* * Sometimes psi2ir produces IR with non-trivial variance in super types of SAM conversions (this is a language design issue). @@ -91,24 +33,8 @@ internal fun konanUnitPhase( // description = "Check SAM conversions super types" //) - -internal fun PhaseConfigurationService.disableIf(phase: AnyNamedPhase, condition: Boolean) { - if (condition) disable(phase) -} - -internal fun PhaseConfigurationService.disableUnless(phase: AnyNamedPhase, condition: Boolean) { - if (!condition) disable(phase) -} - -internal fun PhaseConfigurationService.konanPhasesConfig(config: KonanConfig) { - with(config.configuration) { - // The original comment around [checkSamSuperTypesPhase] still holds, but in order to be on par with JVM_IR - // (which doesn't report error for these corner cases), we turn off the checker for now (the problem with variances - // is workarounded in [FunctionReferenceLowering] by taking erasure of SAM conversion type). - // Also see https://youtrack.jetbrains.com/issue/KT-50399 for more details. -// disable(checkSamSuperTypesPhase) - disableUnless(exportInternalAbiPhase, config.produce.isCache) - disableUnless(stringConcatenationTypeNarrowingPhase, config.optimizationsEnabled) - disableIf(testProcessorPhase, getNotNull(KonanConfigKeys.GENERATE_TEST_RUNNER) == TestRunnerKind.NONE) - } -} +// The original comment around [checkSamSuperTypesPhase] still holds, but in order to be on par with JVM_IR +// (which doesn't report error for these corner cases), we turn off the checker for now (the problem with variances +// is workarounded in [FunctionReferenceLowering] by taking erasure of SAM conversion type). +// Also see https://youtrack.jetbrains.com/issue/KT-50399 for more details. +// disable(checkSamSuperTypesPhase) \ No newline at end of file diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/Machinery.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/Machinery.kt index 7b7ae052c1a..80223c29bf1 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/Machinery.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/Machinery.kt @@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.phaser.* import org.jetbrains.kotlin.backend.konan.ConfigChecks import org.jetbrains.kotlin.backend.konan.KonanConfig import org.jetbrains.kotlin.backend.konan.getCompilerMessageLocation -import org.jetbrains.kotlin.backend.konan.konanPhasesConfig import org.jetbrains.kotlin.cli.common.CLIConfigurationKeys import org.jetbrains.kotlin.cli.common.messages.CompilerMessageSeverity import org.jetbrains.kotlin.cli.common.messages.MessageCollector @@ -89,8 +88,6 @@ internal class PhaseEngine( val phaserState = PhaserState() val phaseConfig = config.flexiblePhaseConfig val context = BasicPhaseContext(config) - // TODO: Get rid of when transition to the dynamic driver complete. - phaseConfig.konanPhasesConfig(config) val topLevelPhase = object : SimpleNamedCompilerPhase( "Compiler", "The whole compilation process", diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/Lowerings.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/Lowerings.kt index 3fd4c348c99..a8b9dc284f9 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/Lowerings.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/Lowerings.kt @@ -6,22 +6,36 @@ package org.jetbrains.kotlin.backend.konan.driver.phases import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.lower.coroutines.AddContinuationToNonLocalSuspendFunctionsLowering import org.jetbrains.kotlin.backend.common.lower.inline.FunctionInlining +import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesExtractionFromInlineFunctionsLowering +import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineFunctionsLowering +import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineLambdasLowering +import org.jetbrains.kotlin.backend.common.lower.loops.ForLoopsLowering +import org.jetbrains.kotlin.backend.common.lower.optimizations.FoldConstantLowering import org.jetbrains.kotlin.backend.common.lower.optimizations.PropertyAccessorInlineLowering import org.jetbrains.kotlin.backend.common.phaser.* +import org.jetbrains.kotlin.backend.common.runOnFilePostfix import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.NativeGenerationState import org.jetbrains.kotlin.backend.konan.driver.PhaseEngine import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrModuleFragment import org.jetbrains.kotlin.backend.konan.* +import org.jetbrains.kotlin.backend.konan.ir.FunctionsWithoutBoundCheckGenerator import org.jetbrains.kotlin.backend.konan.lower.* import org.jetbrains.kotlin.backend.konan.lower.ImportCachesAbiTransformer +import org.jetbrains.kotlin.backend.konan.lower.InitializersLowering import org.jetbrains.kotlin.backend.konan.lower.InlineClassPropertyAccessorsLowering import org.jetbrains.kotlin.backend.konan.lower.RedundantCoercionsCleaner import org.jetbrains.kotlin.backend.konan.lower.ReturnsInsertionLowering import org.jetbrains.kotlin.backend.konan.lower.UnboxInlineLowering +import org.jetbrains.kotlin.backend.konan.optimizations.KonanBCEForLoopBodyTransformer +import org.jetbrains.kotlin.ir.IrElement +import org.jetbrains.kotlin.ir.declarations.IrFunction +import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid +import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid /** * Run whole IR lowering pipeline over [irModuleFragment]. @@ -48,6 +62,333 @@ internal val modulePhaseActions: Set( + name = "FunctionsWithoutBoundCheckGenerator", + description = "Functions without bounds check generation", + op = { context, _ -> FunctionsWithoutBoundCheckGenerator(context).generate() } +) + +private val removeExpectDeclarationsPhase = createFileLoweringPhase( + ::ExpectDeclarationsRemoving, + name = "RemoveExpectDeclarations", + description = "Expect declarations removing" +) + +private val stripTypeAliasDeclarationsPhase = createFileLoweringPhase( + { _: Context -> StripTypeAliasDeclarationsLowering() }, + name = "StripTypeAliasDeclarations", + description = "Strip typealias declarations" +) + +private val annotationImplementationPhase = createFileLoweringPhase( + { context -> AnnotationImplementationLowering { NativeAnnotationImplementationTransformer(context, it) } }, + name = "AnnotationImplementation", + description = "Create synthetic annotations implementations and use them in annotations constructor calls" +) + +private val lowerBeforeInlinePhase = createFileLoweringPhase( + ::PreInlineLowering, + name = "LowerBeforeInline", + description = "Special operations processing before inlining" +) + +private val arrayConstructorPhase = createFileLoweringPhase( + ::ArrayConstructorLowering, + name = "ArrayConstructor", + description = "Transform `Array(size) { index -> value }` into a loop" +) + +private val lateinitPhase = createFileLoweringPhase( + { context, irFile -> + NullableFieldsForLateinitCreationLowering(context).lower(irFile) + NullableFieldsDeclarationLowering(context).lower(irFile) + LateinitUsageLowering(context).lower(irFile) + }, + name = "Lateinit", + description = "Lateinit properties lowering" +) + +private val sharedVariablesPhase = createFileLoweringPhase( + ::SharedVariablesLowering, + name = "SharedVariables", + description = "Shared variable lowering", + prerequisite = setOf(lateinitPhase) +) + +private val extractLocalClassesFromInlineBodies = createFileLoweringPhase( + { context, irFile -> + irFile.acceptChildrenVoid(object : IrElementVisitorVoid { + override fun visitElement(element: IrElement) { + element.acceptChildrenVoid(this) + } + + override fun visitFunction(declaration: IrFunction) { + if (declaration.isInline) + context.inlineFunctionsSupport.saveNonLoweredInlineFunction(declaration) + declaration.acceptChildrenVoid(this) + } + }) + + LocalClassesInInlineLambdasLowering(context).lower(irFile) + LocalClassesInInlineFunctionsLowering(context).lower(irFile) + LocalClassesExtractionFromInlineFunctionsLowering(context).lower(irFile) + }, + name = "ExtractLocalClassesFromInlineBodies", + description = "Extraction of local classes from inline bodies", + prerequisite = setOf(sharedVariablesPhase), // TODO: add "soft" dependency on inventNamesForLocalClasses +) + +private val wrapInlineDeclarationsWithReifiedTypeParametersLowering = createFileLoweringPhase( + ::WrapInlineDeclarationsWithReifiedTypeParametersLowering, + name = "WrapInlineDeclarationsWithReifiedTypeParameters", + description = "Wrap inline declarations with reified type parameters" +) + +private val postInlinePhase = createFileLoweringPhase( + { context: Context -> PostInlineLowering(context) }, + name = "PostInline", + description = "Post-processing after inlining" +) + +private val contractsDslRemovePhase = createFileLoweringPhase( + { context: Context -> ContractsDslRemover(context) }, + name = "RemoveContractsDsl", + description = "Contracts dsl removing" +) + +// TODO make all lambda-related stuff work with IrFunctionExpression and drop this phase (see kotlin: dd3f8ecaacd) +private val provisionalFunctionExpressionPhase = createFileLoweringPhase( + { _: Context -> ProvisionalFunctionExpressionLowering() }, + name = "FunctionExpression", + description = "Transform IrFunctionExpression to a local function reference" +) + +private val flattenStringConcatenationPhase = createFileLoweringPhase( + ::FlattenStringConcatenationLowering, + name = "FlattenStringConcatenationLowering", + description = "Flatten nested string concatenation expressions into a single IrStringConcatenation" +) + +private val stringConcatenationPhase = createFileLoweringPhase( + ::StringConcatenationLowering, + name = "StringConcatenation", + description = "String concatenation lowering" +) + +private val stringConcatenationTypeNarrowingPhase = createFileLoweringPhase( + ::StringConcatenationTypeNarrowing, + name = "StringConcatenationTypeNarrowing", + description = "String concatenation type narrowing", + prerequisite = setOf(stringConcatenationPhase) +) + +private val kotlinNothingValueExceptionPhase = createFileLoweringPhase( + ::KotlinNothingValueExceptionLowering, + name = "KotlinNothingValueException", + description = "Throw proper exception for calls returning value of type 'kotlin.Nothing'" +) + +private val enumConstructorsPhase = createFileLoweringPhase( + ::EnumConstructorsLowering, + name = "EnumConstructors", + description = "Enum constructors lowering" +) + +private val initializersPhase = createFileLoweringPhase( + ::InitializersLowering, + name = "Initializers", + description = "Initializers lowering", + prerequisite = setOf(enumConstructorsPhase) +) + +private val localFunctionsPhase = createFileLoweringPhase( + op = { context, irFile -> + LocalDelegatedPropertiesLowering().lower(irFile) + LocalDeclarationsLowering(context).lower(irFile) + LocalClassPopupLowering(context).lower(irFile) + }, + name = "LocalFunctions", + description = "Local function lowering", + prerequisite = setOf(sharedVariablesPhase) // TODO: add "soft" dependency on inventNamesForLocalClasses +) + +private val tailrecPhase = createFileLoweringPhase( + ::TailrecLowering, + name = "Tailrec", + description = "Tailrec lowering", + prerequisite = setOf(localFunctionsPhase) +) + +private val volatilePhase = createFileLoweringPhase( + ::VolatileFieldsLowering, + name = "VolatileFields", + description = "Volatile fields processing", + prerequisite = setOf(localFunctionsPhase) +) + +private val defaultParameterExtentPhase = createFileLoweringPhase( + { context, irFile -> + KonanDefaultArgumentStubGenerator(context).lower(irFile) + DefaultParameterCleaner(context, replaceDefaultValuesWithStubs = true).lower(irFile) + KonanDefaultParameterInjector(context).lower(irFile) + }, + name = "DefaultParameterExtent", + description = "Default parameter extent lowering", + prerequisite = setOf(tailrecPhase, enumConstructorsPhase) +) + +private val innerClassPhase = createFileLoweringPhase( + ::InnerClassLowering, + name = "InnerClasses", + description = "Inner classes lowering", + prerequisite = setOf(defaultParameterExtentPhase) +) + +private val rangeContainsLoweringPhase = createFileLoweringPhase( + ::RangeContainsLowering, + name = "RangeContains", + description = "Optimizes calls to contains() for ClosedRanges" +) + +private val forLoopsPhase = createFileLoweringPhase( + { context, irFile -> + ForLoopsLowering(context, KonanBCEForLoopBodyTransformer()).lower(irFile) + }, + name = "ForLoops", + description = "For loops lowering", + prerequisite = setOf(FunctionsWithoutBoundCheck) +) + +private val dataClassesPhase = createFileLoweringPhase( + ::DataClassOperatorsLowering, + name = "DataClasses", + description = "Data classes lowering" +) + +private val finallyBlocksPhase = createFileLoweringPhase( + { context, irFile -> FinallyBlocksLowering(context, context.irBuiltIns.throwableType).lower(irFile) }, + name = "FinallyBlocks", + description = "Finally blocks lowering", + prerequisite = setOf(initializersPhase, localFunctionsPhase, tailrecPhase) +) + +private val testProcessorPhase = createFileLoweringPhase( + { context, irFile -> TestProcessor(context).process(irFile) }, + name = "TestProcessor", + description = "Unit test processor" +) + +private val enumWhenPhase = createFileLoweringPhase( + ::NativeEnumWhenLowering, + name = "EnumWhen", + description = "Enum when lowering", +// prerequisite = setOf(enumConstructorsPhase, functionReferencePhase) +) + +private val enumClassPhase = createFileLoweringPhase( + ::EnumClassLowering, + name = "Enums", + description = "Enum classes lowering", +// prerequisite = setOf(enumConstructorsPhase, functionReferencePhase, enumWhenPhase) // TODO: make weak dependency on `testProcessorPhase` +) + +private val enumUsagePhase = createFileLoweringPhase( + ::EnumUsageLowering, + name = "EnumUsage", + description = "Enum usage lowering", +// prerequisite = setOf(enumConstructorsPhase, functionReferencePhase, enumClassPhase) +) + + +private val singleAbstractMethodPhase = createFileLoweringPhase( + ::NativeSingleAbstractMethodLowering, + name = "SingleAbstractMethod", + description = "Replace SAM conversions with instances of interface-implementing classes", +// prerequisite = setOf(functionReferencePhase) +) + +private val builtinOperatorPhase = createFileLoweringPhase( + ::BuiltinOperatorLowering, + name = "BuiltinOperators", + description = "BuiltIn operators lowering", + prerequisite = setOf(defaultParameterExtentPhase, singleAbstractMethodPhase, enumWhenPhase) +) + +private val varargPhase = createFileLoweringPhase( + ::VarargInjectionLowering, + name = "Vararg", + description = "Vararg lowering", +// prerequisite = setOf(functionReferencePhase, defaultParameterExtentPhase, interopPhase, functionsWithoutBoundCheck) +) + +private val typeOperatorPhase = createFileLoweringPhase( + ::TypeOperatorLowering, + name = "TypeOperators", + description = "Type operators lowering", +// prerequisite = setOf(coroutinesPhase) +) + +private val bridgesPhase = createFileLoweringPhase( + { context, irFile -> + BridgesBuilding(context).runOnFilePostfix(irFile) + WorkersBridgesBuilding(context).lower(irFile) + }, + name = "Bridges", + description = "Bridges building", +// prerequisite = setOf(coroutinesPhase) +) + +private val autoboxPhase = createFileLoweringPhase( + ::Autoboxing, + name = "Autobox", + description = "Autoboxing of primitive types", +// prerequisite = setOf(bridgesPhase, coroutinesPhase) +) + +private val expressionBodyTransformPhase = createFileLoweringPhase( + ::ExpressionBodyTransformer, + name = "ExpressionBodyTransformer", + description = "Replace IrExpressionBody with IrBlockBody" +) + +private val constantInliningPhase = createFileLoweringPhase( + ::ConstLowering, + name = "ConstantInlining", + description = "Inline const fields reads", +) + +private val staticInitializersPhase = createFileLoweringPhase( + ::StaticInitializersLowering, + name = "StaticInitializers", + description = "Add calls to static initializers", + prerequisite = setOf(expressionBodyTransformPhase) +) + +private val ifNullExpressionsFusionPhase = createFileLoweringPhase( + ::IfNullExpressionsFusionLowering, + name = "IfNullExpressionsFusionLowering", + description = "Simplify '?.' and '?:' operator chains" +) + +private val foldConstantLoweringPhase = createFileLoweringPhase( + { context, irFile -> FoldConstantLowering(context).lower(irFile) }, + name = "FoldConstantLowering", + description = "Constant Folding", + prerequisite = setOf(flattenStringConcatenationPhase) +) + +private val computeStringTrimPhase = createFileLoweringPhase( + ::StringTrimLowering, + name = "StringTrimLowering", + description = "Compute trimIndent and trimMargin operations on constant strings" +) + +private val exportInternalAbiPhase = createFileLoweringPhase( + ::ExportCachesAbiVisitor, + name = "ExportInternalAbi", + description = "Add accessors to private entities" +) + internal val ReturnsInsertionPhase = createFileLoweringPhase( name = "ReturnsInsertion", description = "Returns insertion for Unit functions", @@ -151,59 +492,59 @@ private val InteropPhase = createFileLoweringPhase( // prerequisite = setOf(inlinePhase, localFunctionsPhase, functionReferencePhase) ) -private fun PhaseEngine.getAllLowerings() = listOf>( - convertToNativeGeneration(removeExpectDeclarationsPhase), - convertToNativeGeneration(stripTypeAliasDeclarationsPhase), - convertToNativeGeneration(lowerBeforeInlinePhase), - convertToNativeGeneration(arrayConstructorPhase), - convertToNativeGeneration(lateinitPhase), - convertToNativeGeneration(sharedVariablesPhase), +private fun PhaseEngine.getAllLowerings() = listOfNotNull>( + removeExpectDeclarationsPhase, + stripTypeAliasDeclarationsPhase, + lowerBeforeInlinePhase, + arrayConstructorPhase, + lateinitPhase, + sharedVariablesPhase, InventNamesForLocalClasses, - convertToNativeGeneration(extractLocalClassesFromInlineBodies), - convertToNativeGeneration(wrapInlineDeclarationsWithReifiedTypeParametersLowering), + extractLocalClassesFromInlineBodies, + wrapInlineDeclarationsWithReifiedTypeParametersLowering, InlinePhase, - convertToNativeGeneration(provisionalFunctionExpressionPhase), - convertToNativeGeneration(postInlinePhase), - convertToNativeGeneration(contractsDslRemovePhase), - convertToNativeGeneration(annotationImplementationPhase), - convertToNativeGeneration(rangeContainsLoweringPhase), - convertToNativeGeneration(forLoopsPhase), - convertToNativeGeneration(flattenStringConcatenationPhase), - convertToNativeGeneration(foldConstantLoweringPhase), - convertToNativeGeneration(computeStringTrimPhase), - convertToNativeGeneration(stringConcatenationPhase), - convertToNativeGeneration(stringConcatenationTypeNarrowingPhase), - convertToNativeGeneration(enumConstructorsPhase), - convertToNativeGeneration(initializersPhase), - convertToNativeGeneration(localFunctionsPhase), - convertToNativeGeneration(volatilePhase), - convertToNativeGeneration(tailrecPhase), - convertToNativeGeneration(defaultParameterExtentPhase), - convertToNativeGeneration(innerClassPhase), - convertToNativeGeneration(dataClassesPhase), - convertToNativeGeneration(ifNullExpressionsFusionPhase), - convertToNativeGeneration(testProcessorPhase), + provisionalFunctionExpressionPhase, + postInlinePhase, + contractsDslRemovePhase, + annotationImplementationPhase, + rangeContainsLoweringPhase, + forLoopsPhase, + flattenStringConcatenationPhase, + foldConstantLoweringPhase, + computeStringTrimPhase, + stringConcatenationPhase, + stringConcatenationTypeNarrowingPhase.takeIf { context.config.optimizationsEnabled }, + enumConstructorsPhase, + initializersPhase, + localFunctionsPhase, + volatilePhase, + tailrecPhase, + defaultParameterExtentPhase, + innerClassPhase, + dataClassesPhase, + ifNullExpressionsFusionPhase, + testProcessorPhase.takeIf { context.config.configuration.getNotNull(KonanConfigKeys.GENERATE_TEST_RUNNER) != TestRunnerKind.NONE }, DelegationPhase, FunctionReferencePhase, - convertToNativeGeneration(singleAbstractMethodPhase), - convertToNativeGeneration(enumWhenPhase), - convertToNativeGeneration(builtinOperatorPhase), - convertToNativeGeneration(finallyBlocksPhase), - convertToNativeGeneration(enumClassPhase), - convertToNativeGeneration(enumUsagePhase), + singleAbstractMethodPhase, + enumWhenPhase, + builtinOperatorPhase, + finallyBlocksPhase, + enumClassPhase, + enumUsagePhase, InteropPhase, - convertToNativeGeneration(varargPhase), - convertToNativeGeneration(kotlinNothingValueExceptionPhase), + varargPhase, + kotlinNothingValueExceptionPhase, CoroutinesPhase, - convertToNativeGeneration(typeOperatorPhase), - convertToNativeGeneration(expressionBodyTransformPhase), + typeOperatorPhase, + expressionBodyTransformPhase, ObjectClassesPhase, - convertToNativeGeneration(constantInliningPhase), - convertToNativeGeneration(staticInitializersPhase), - convertToNativeGeneration(bridgesPhase), - convertToNativeGeneration(exportInternalAbiPhase), + constantInliningPhase, + staticInitializersPhase, + bridgesPhase, + exportInternalAbiPhase.takeIf { context.config.produce.isCache }, UseInternalAbiPhase, - convertToNativeGeneration(autoboxPhase), + autoboxPhase, ) /** diff --git a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/TopLevelPhases.kt b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/TopLevelPhases.kt index 6ec1bc2ed18..b2f3e17ee1e 100644 --- a/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/TopLevelPhases.kt +++ b/kotlin-native/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/driver/phases/TopLevelPhases.kt @@ -51,7 +51,7 @@ internal fun PhaseEngine.runPsiToIr( internal fun PhaseEngine.runBackend(backendContext: Context, irModule: IrModuleFragment) { useContext(backendContext) { backendEngine -> - backendEngine.runPhase(functionsWithoutBoundCheck) + backendEngine.runPhase(FunctionsWithoutBoundCheck) val fragments = backendEngine.splitIntoFragments(irModule) fragments.forEach { (generationState, fragment) -> backendEngine.useContext(generationState) { generationStateEngine ->