[K/N] Port lowerings from old builders to the new ones

This commit is contained in:
Sergey Bogolepov
2023-01-24 15:44:55 +02:00
committed by Space Team
parent f9d0755f94
commit d7e44dc46a
5 changed files with 392 additions and 519 deletions
@@ -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<AbstractNamedCompilerPhase<Context, *, *>> = emptySet()
) = makeIrFilePhase(lowering, name, description, prerequisite, actions = filePhaseActions)
private fun makeKonanModuleLoweringPhase(
lowering: (Context) -> FileLoweringPass,
name: String,
description: String,
prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>> = emptySet()
) = makeIrModulePhase(lowering, name, description, prerequisite, actions = modulePhaseActions)
internal fun makeKonanFileOpPhase(
op: (Context, IrFile) -> Unit,
name: String,
description: String,
prerequisite: Set<AbstractNamedCompilerPhase<Context, *, *>> = emptySet()
) = SameTypeNamedCompilerPhase(
name, description, prerequisite, nlevels = 0,
lower = object : SameTypeCompilerPhase<Context, IrFile> {
override fun invoke(phaseConfig: PhaseConfigurationService, phaserState: PhaserState<IrFile>, 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"
)
@@ -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<AbstractNamedCompilerPhase<Context, *, *>> = 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)
@@ -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<C : PhaseContext>(
val phaserState = PhaserState<Any>()
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<PhaseContext, Any, Unit>(
"Compiler",
"The whole compilation process",
@@ -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<Action<IrModuleFragment, NativeGenerationSt
nativeStateIrValidator.takeIf { validateAll }
)
internal val FunctionsWithoutBoundCheck = createSimpleNamedCompilerPhase<Context, Unit>(
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<NativeGenerationState>.getAllLowerings() = listOf<AbstractNamedCompilerPhase<NativeGenerationState, IrFile, IrFile>>(
convertToNativeGeneration(removeExpectDeclarationsPhase),
convertToNativeGeneration(stripTypeAliasDeclarationsPhase),
convertToNativeGeneration(lowerBeforeInlinePhase),
convertToNativeGeneration(arrayConstructorPhase),
convertToNativeGeneration(lateinitPhase),
convertToNativeGeneration(sharedVariablesPhase),
private fun PhaseEngine<NativeGenerationState>.getAllLowerings() = listOfNotNull<AbstractNamedCompilerPhase<NativeGenerationState, IrFile, IrFile>>(
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,
)
/**
@@ -51,7 +51,7 @@ internal fun <T> PhaseEngine<PhaseContext>.runPsiToIr(
internal fun <C : PhaseContext> PhaseEngine<C>.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 ->