[IR] Extract some local classes from inline bodies

Among other things, this fixes https://github.com/JetBrains/kotlin-native/issues/3956
This commit is contained in:
Igor Chevdar
2020-03-26 14:34:46 +03:00
parent cc69f11e0d
commit 3261fda3d2
2 changed files with 48 additions and 25 deletions
@@ -3,6 +3,9 @@ package org.jetbrains.kotlin.backend.konan
import org.jetbrains.kotlin.backend.common.* import org.jetbrains.kotlin.backend.common.*
import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.common.lower.inline.FunctionInlining 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.loops.ForLoopsLowering
import org.jetbrains.kotlin.backend.common.phaser.* import org.jetbrains.kotlin.backend.common.phaser.*
import org.jetbrains.kotlin.backend.konan.lower.* import org.jetbrains.kotlin.backend.konan.lower.*
@@ -86,20 +89,57 @@ internal val arrayConstructorPhase = makeKonanModuleLoweringPhase(
description = "Transform `Array(size) { index -> value }` into a loop" description = "Transform `Array(size) { index -> value }` into a loop"
) )
internal val lateinitPhase = makeKonanModuleOpPhase(
{ context, irModule ->
NullableFieldsForLateinitCreationLowering(context).lower(irModule)
NullableFieldsDeclarationLowering(context).lower(irModule)
LateinitUsageLowering(context).lower(irModule)
},
name = "Lateinit",
description = "Lateinit properties lowering"
)
internal val sharedVariablesPhase = makeKonanModuleLoweringPhase(
::SharedVariablesLowering,
name = "SharedVariables",
description = "Shared variable lowering",
prerequisite = setOf(lateinitPhase)
)
internal val extractLocalClassesFromInlineBodies = namedIrModulePhase(
lower = object : SameTypeCompilerPhase<Context, IrModuleFragment> {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<IrModuleFragment>, context: Context, input: IrModuleFragment): IrModuleFragment {
LocalClassesInInlineLambdasLowering(context).run {
input.files.forEach { lower(it) }
}
LocalClassesInInlineFunctionsLowering(context).run {
input.files.forEach { lower(it) }
}
LocalClassesExtractionFromInlineFunctionsLowering(context).run {
input.files.forEach { lower(it) }
}
return input
}
},
name = "ExtractLocalClassesFromInlineBodies",
description = "Extraction of local classes from inline bodies",
prerequisite = setOf(sharedVariablesPhase),
nlevels = 0,
actions = modulePhaseActions
)
internal val inlinePhase = namedIrModulePhase( internal val inlinePhase = namedIrModulePhase(
lower = object : SameTypeCompilerPhase<Context, IrModuleFragment> { lower = object : SameTypeCompilerPhase<Context, IrModuleFragment> {
override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<IrModuleFragment>, context: Context, input: IrModuleFragment): IrModuleFragment { override fun invoke(phaseConfig: PhaseConfig, phaserState: PhaserState<IrModuleFragment>, context: Context, input: IrModuleFragment): IrModuleFragment {
FunctionInlining(context).run { FunctionInlining(context).run {
input.files.forEach { input.files.forEach { lower(it) }
lower(it)
}
} }
return input return input
} }
}, },
name = "Inline", name = "Inline",
description = "Functions inlining", description = "Functions inlining",
prerequisite = setOf(lowerBeforeInlinePhase, arrayConstructorPhase), prerequisite = setOf(lowerBeforeInlinePhase, arrayConstructorPhase, extractLocalClassesFromInlineBodies),
nlevels = 0, nlevels = 0,
actions = modulePhaseActions actions = modulePhaseActions
) )
@@ -116,17 +156,6 @@ internal val lowerAfterInlinePhase = makeKonanModuleOpPhase(
/* IrFile phases */ /* IrFile phases */
internal val lateinitPhase = makeKonanFileOpPhase(
{ context, irFile ->
NullableFieldsForLateinitCreationLowering(context).lower(irFile)
NullableFieldsDeclarationLowering(context).lower(irFile)
LateinitUsageLowering(context).lower(irFile)
},
name = "Lateinit",
description = "Lateinit properties lowering",
prerequisite = setOf(inlinePhase)
)
// TODO make all lambda-related stuff work with IrFunctionExpression and drop this phase (see kotlin: dd3f8ecaacd) // TODO make all lambda-related stuff work with IrFunctionExpression and drop this phase (see kotlin: dd3f8ecaacd)
internal val provisionalFunctionExpressionPhase = makeKonanModuleLoweringPhase( internal val provisionalFunctionExpressionPhase = makeKonanModuleLoweringPhase(
{ ProvisionalFunctionExpressionLowering() }, { ProvisionalFunctionExpressionLowering() },
@@ -153,13 +182,6 @@ internal val initializersPhase = makeKonanFileLoweringPhase(
prerequisite = setOf(enumConstructorsPhase) prerequisite = setOf(enumConstructorsPhase)
) )
internal val sharedVariablesPhase = makeKonanFileLoweringPhase(
::SharedVariablesLowering,
name = "SharedVariables",
description = "Shared variable lowering",
prerequisite = setOf(initializersPhase)
)
internal val localFunctionsPhase = makeKonanFileOpPhase( internal val localFunctionsPhase = makeKonanFileOpPhase(
op = { context, irFile -> op = { context, irFile ->
LocalDelegatedPropertiesLowering().lower(irFile) LocalDelegatedPropertiesLowering().lower(irFile)
@@ -326,18 +326,19 @@ internal val allLoweringsPhase = namedIrModulePhase(
stripTypeAliasDeclarationsPhase then stripTypeAliasDeclarationsPhase then
lowerBeforeInlinePhase then lowerBeforeInlinePhase then
arrayConstructorPhase then arrayConstructorPhase then
lateinitPhase then
sharedVariablesPhase then
extractLocalClassesFromInlineBodies then
inlinePhase then inlinePhase then
provisionalFunctionExpressionPhase then provisionalFunctionExpressionPhase then
lowerAfterInlinePhase then lowerAfterInlinePhase then
performByIrFile( performByIrFile(
name = "IrLowerByFile", name = "IrLowerByFile",
description = "IR Lowering by file", description = "IR Lowering by file",
lower = lateinitPhase then lower = forLoopsPhase then
forLoopsPhase then
stringConcatenationPhase then stringConcatenationPhase then
enumConstructorsPhase then enumConstructorsPhase then
initializersPhase then initializersPhase then
sharedVariablesPhase then
localFunctionsPhase then localFunctionsPhase then
tailrecPhase then tailrecPhase then
defaultParameterExtentPhase then defaultParameterExtentPhase then