[JVM IR] Fix performance issue caused by support of IR Inliner

This commit is contained in:
Ivan Kylchik
2023-03-15 14:59:01 +01:00
committed by Space Team
parent e8272fa02e
commit 7cf70e7b15
21 changed files with 127 additions and 117 deletions
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.common.lower
import org.jetbrains.kotlin.backend.common.BackendContext import org.jetbrains.kotlin.backend.common.BackendContext
import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrProperty import org.jetbrains.kotlin.ir.declarations.IrProperty
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
val kCallableNamePropertyPhase = makeIrModulePhase( val kCallableNamePropertyPhase = makeIrFilePhase(
::KCallableNamePropertyLowering, ::KCallableNamePropertyLowering,
name = "KCallableNameProperty", name = "KCallableNameProperty",
description = "Replace name references for callables with constants" description = "Replace name references for callables with constants"
@@ -57,6 +57,10 @@ private fun makeCheckParentsPhase(): SameTypeNamedCompilerPhase<CommonBackendCon
) )
} }
internal fun JvmBackendContext.irInlinerIsEnabled(): Boolean {
return configuration.getBoolean(JVMConfigurationKeys.ENABLE_IR_INLINER)
}
private class PatchDeclarationParents : FileLoweringPass { private class PatchDeclarationParents : FileLoweringPass {
override fun lower(irFile: IrFile) { override fun lower(irFile: IrFile) {
irFile.acceptVoid(PatchDeclarationParentsVisitor()) irFile.acceptVoid(PatchDeclarationParentsVisitor())
@@ -82,7 +86,7 @@ private val validateIrAfterLowering = makeCustomPhase(
) )
// TODO make all lambda-related stuff work with IrFunctionExpression and drop this phase // TODO make all lambda-related stuff work with IrFunctionExpression and drop this phase
private val provisionalFunctionExpressionPhase = makeIrModulePhase<CommonBackendContext>( private val provisionalFunctionExpressionPhase = makeIrFilePhase<CommonBackendContext>(
{ ProvisionalFunctionExpressionLowering() }, { ProvisionalFunctionExpressionLowering() },
name = "FunctionExpression", name = "FunctionExpression",
description = "Transform IrFunctionExpression to a local function reference" description = "Transform IrFunctionExpression to a local function reference"
@@ -283,7 +287,7 @@ private val kotlinNothingValueExceptionPhase = makeIrFilePhase<CommonBackendCont
description = "Throw proper exception for calls returning value of type 'kotlin.Nothing'" description = "Throw proper exception for calls returning value of type 'kotlin.Nothing'"
) )
internal val functionInliningPhase = makeIrModulePhase<JvmBackendContext>( internal val functionInliningPhase = makeIrModulePhase(
{ context -> { context ->
class JvmInlineFunctionResolver : InlineFunctionResolver { class JvmInlineFunctionResolver : InlineFunctionResolver {
override fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction { override fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction {
@@ -295,9 +299,7 @@ internal val functionInliningPhase = makeIrModulePhase<JvmBackendContext>(
} }
} }
if (!context.configuration.getBoolean(JVMConfigurationKeys.ENABLE_IR_INLINER)) { if (!context.irInlinerIsEnabled()) return@makeIrModulePhase FileLoweringPass.Empty
return@makeIrModulePhase FileLoweringPass.Empty
}
FunctionInlining( FunctionInlining(
context, JvmInlineFunctionResolver(), context.innerClassesSupport, context, JvmInlineFunctionResolver(), context.innerClassesSupport,
@@ -314,6 +316,25 @@ internal val functionInliningPhase = makeIrModulePhase<JvmBackendContext>(
) )
private val jvmFilePhases = listOf( private val jvmFilePhases = listOf(
typeAliasAnnotationMethodsPhase,
provisionalFunctionExpressionPhase,
jvmOverloadsAnnotationPhase,
mainMethodGenerationPhase,
kCallableNamePropertyPhase,
annotationPhase,
annotationImplementationPhase,
polymorphicSignaturePhase,
varargPhase,
jvmLateinitLowering,
inventNamesForLocalClassesPhase,
inlineCallableReferenceToLambdaPhase,
directInvokeLowering,
functionReferencePhase,
suspendLambdaPhase, suspendLambdaPhase,
propertyReferenceDelegationPhase, propertyReferenceDelegationPhase,
singletonOrConstantDelegationPhase, singletonOrConstantDelegationPhase,
@@ -439,28 +460,6 @@ private fun buildJvmLoweringPhases(
createSeparateCallForInlinedLambdas then createSeparateCallForInlinedLambdas then
markNecessaryInlinedClassesAsRegenerated then markNecessaryInlinedClassesAsRegenerated then
// Note: following phases can be moved to file level, but are located here because of `functionInliningPhase`
// This is needed, for example, for `kt42408` test.
// Function expression there must be transformed into ir class before moving to file level phases.
typeAliasAnnotationMethodsPhase then
provisionalFunctionExpressionPhase then
jvmOverloadsAnnotationPhase then
mainMethodGenerationPhase then
kCallableNamePropertyPhase then
annotationPhase then
annotationImplementationPhase then
polymorphicSignaturePhase then
varargPhase then
jvmLateinitLowering then
inventNamesForLocalClassesPhase then
inlineCallableReferenceToLambdaPhase then
directInvokeLowering then
functionReferencePhase then
buildLoweringsPhase(phases) then buildLoweringsPhase(phases) then
generateMultifileFacadesPhase then generateMultifileFacadesPhase then
resolveInlineCallsPhase then resolveInlineCallsPhase then
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.backend.jvm.lower package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.ir.util.isAnnotationClass
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
internal val annotationPhase = makeIrModulePhase<JvmBackendContext>( internal val annotationPhase = makeIrFilePhase<JvmBackendContext>(
{ AnnotationLowering() }, { AnnotationLowering() },
name = "Annotation", name = "Annotation",
description = "Remove constructors of annotation classes" description = "Remove constructors of annotation classes"
@@ -14,6 +14,7 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.functionInliningPhase import org.jetbrains.kotlin.backend.jvm.functionInliningPhase
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter
import org.jetbrains.kotlin.backend.jvm.irInlinerIsEnabled
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
@@ -22,7 +23,10 @@ import org.jetbrains.kotlin.ir.util.getArgumentsWithIr
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
internal val createSeparateCallForInlinedLambdas = makeIrModulePhase( internal val createSeparateCallForInlinedLambdas = makeIrModulePhase(
::CreateSeparateCallForInlinedLambdasLowering, { context ->
if (!context.irInlinerIsEnabled()) return@makeIrModulePhase FileLoweringPass.Empty
CreateSeparateCallForInlinedLambdasLowering(context)
},
name = "CreateSeparateCallForInlinedLambdasLowering", name = "CreateSeparateCallForInlinedLambdasLowering",
description = "This lowering will create separate call `singleArgumentInlineFunction` with previously inlined lambda as argument", description = "This lowering will create separate call `singleArgumentInlineFunction` with previously inlined lambda as argument",
prerequisite = setOf(functionInliningPhase) prerequisite = setOf(functionInliningPhase)
@@ -11,7 +11,7 @@ import org.jetbrains.kotlin.backend.common.ir.asInlinableFunctionReference
import org.jetbrains.kotlin.backend.common.ir.inline import org.jetbrains.kotlin.backend.common.ir.inline
import org.jetbrains.kotlin.backend.common.lower.at import org.jetbrains.kotlin.backend.common.lower.at
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.ir.builders.irBlock import org.jetbrains.kotlin.ir.builders.irBlock
import org.jetbrains.kotlin.ir.declarations.IrConstructor import org.jetbrains.kotlin.ir.declarations.IrConstructor
@@ -28,7 +28,7 @@ import org.jetbrains.kotlin.ir.util.explicitParameters
import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
internal val directInvokeLowering = makeIrModulePhase( internal val directInvokeLowering = makeIrFilePhase(
::DirectInvokeLowering, ::DirectInvokeLowering,
name = "DirectInvokes", name = "DirectInvokes",
description = "Inline directly invoked lambdas and replace invoked function references with calls" description = "Inline directly invoked lambdas and replace invoked function references with calls"
@@ -11,6 +11,7 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.ir.isInlineOnly import org.jetbrains.kotlin.backend.jvm.ir.isInlineOnly
import org.jetbrains.kotlin.backend.jvm.irInlinerIsEnabled
import org.jetbrains.kotlin.codegen.inline.INLINE_FUN_VAR_SUFFIX import org.jetbrains.kotlin.codegen.inline.INLINE_FUN_VAR_SUFFIX
import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX import org.jetbrains.kotlin.codegen.inline.coroutines.FOR_INLINE_SUFFIX
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
@@ -27,8 +28,11 @@ import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
internal val fakeInliningLocalVariablesAfterInlineLowering = makeIrFilePhase( internal val fakeInliningLocalVariablesAfterInlineLowering = makeIrFilePhase<JvmBackendContext>(
::FakeInliningLocalVariablesAfterInlineLowering, { context ->
if (!context.irInlinerIsEnabled()) return@makeIrFilePhase FileLoweringPass.Empty
FakeInliningLocalVariablesAfterInlineLowering(context)
},
name = "FakeInliningLocalVariablesAfterInlineLowering", name = "FakeInliningLocalVariablesAfterInlineLowering",
description = """Add fake locals to identify the range of inlined functions and lambdas. description = """Add fake locals to identify the range of inlined functions and lambdas.
|This lowering adds fake locals into already inlined blocks.""".trimMargin() |This lowering adds fake locals into already inlined blocks.""".trimMargin()
@@ -11,7 +11,6 @@ import org.jetbrains.kotlin.backend.common.ir.moveBodyTo
import org.jetbrains.kotlin.backend.common.lower.SamEqualsHashCodeMethodsGenerator import org.jetbrains.kotlin.backend.common.lower.SamEqualsHashCodeMethodsGenerator
import org.jetbrains.kotlin.backend.common.lower.VariableRemapper import org.jetbrains.kotlin.backend.common.lower.VariableRemapper
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
@@ -40,7 +39,7 @@ import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.name.SpecialNames import org.jetbrains.kotlin.name.SpecialNames
import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SERIALIZABLE_LAMBDA_ANNOTATION_FQ_NAME import org.jetbrains.kotlin.resolve.jvm.annotations.JVM_SERIALIZABLE_LAMBDA_ANNOTATION_FQ_NAME
internal val functionReferencePhase = makeIrModulePhase( internal val functionReferencePhase = makeIrFilePhase(
::FunctionReferenceLowering, ::FunctionReferenceLowering,
name = "FunctionReference", name = "FunctionReference",
description = "Construct instances of anonymous KFunction subclasses for function references" description = "Construct instances of anonymous KFunction subclasses for function references"
@@ -8,7 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.ir.addExtensionReceiver import org.jetbrains.kotlin.backend.common.ir.addExtensionReceiver
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredStatementOrigin
@@ -30,7 +30,7 @@ import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
internal val inlineCallableReferenceToLambdaPhase = makeIrModulePhase( internal val inlineCallableReferenceToLambdaPhase = makeIrFilePhase(
::InlineCallableReferenceToLambdaPhase, ::InlineCallableReferenceToLambdaPhase,
name = "InlineCallableReferenceToLambdaPhase", name = "InlineCallableReferenceToLambdaPhase",
description = "Transform callable reference to inline lambdas, mark inline lambdas for later passes" description = "Transform callable reference to inline lambdas, mark inline lambdas for later passes"
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ir.BuiltinSymbolsBase import org.jetbrains.kotlin.backend.common.ir.BuiltinSymbolsBase
import org.jetbrains.kotlin.backend.common.lower.* import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
import org.jetbrains.kotlin.backend.jvm.ir.isInPublicInlineScope import org.jetbrains.kotlin.backend.jvm.ir.isInPublicInlineScope
@@ -32,7 +31,7 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.util.OperatorNameConventions import org.jetbrains.kotlin.util.OperatorNameConventions
internal val annotationImplementationPhase = makeIrModulePhase<JvmBackendContext>( internal val annotationImplementationPhase = makeIrFilePhase<JvmBackendContext>(
{ ctxt -> AnnotationImplementationLowering { JvmAnnotationImplementationTransformer(ctxt, it) } }, { ctxt -> AnnotationImplementationLowering { JvmAnnotationImplementationTransformer(ctxt, it) } },
name = "AnnotationImplementation", name = "AnnotationImplementation",
description = "Create synthetic annotations implementations and use them in annotations constructor calls" description = "Create synthetic annotations implementations and use them in annotations constructor calls"
@@ -5,10 +5,11 @@
package org.jetbrains.kotlin.backend.jvm.lower package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.lower.InventNamesForLocalClasses import org.jetbrains.kotlin.backend.common.lower.InventNamesForLocalClasses
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.irInlinerIsEnabled
import org.jetbrains.kotlin.codegen.JvmCodegenUtil import org.jetbrains.kotlin.codegen.JvmCodegenUtil
import org.jetbrains.kotlin.ir.declarations.IrAttributeContainer import org.jetbrains.kotlin.ir.declarations.IrAttributeContainer
import org.jetbrains.kotlin.ir.declarations.IrClass import org.jetbrains.kotlin.ir.declarations.IrClass
@@ -18,7 +19,7 @@ import org.jetbrains.kotlin.ir.util.render
import org.jetbrains.kotlin.resolve.jvm.JvmClassName import org.jetbrains.kotlin.resolve.jvm.JvmClassName
import org.jetbrains.org.objectweb.asm.Type import org.jetbrains.org.objectweb.asm.Type
val inventNamesForLocalClassesPhase = makeIrModulePhase( val inventNamesForLocalClassesPhase = makeIrFilePhase(
{ context -> JvmInventNamesForLocalClasses(context) }, { context -> JvmInventNamesForLocalClasses(context) },
name = "InventNamesForLocalClasses", name = "InventNamesForLocalClasses",
description = "Invent names for local classes and anonymous objects", description = "Invent names for local classes and anonymous objects",
@@ -27,7 +28,10 @@ val inventNamesForLocalClassesPhase = makeIrModulePhase(
) )
val inventNamesForInlinedLocalClassesPhase = makeIrFilePhase( val inventNamesForInlinedLocalClassesPhase = makeIrFilePhase(
{ context -> JvmInventNamesForInlinedAnonymousObjects(context) }, { context ->
if (!context.irInlinerIsEnabled()) return@makeIrFilePhase FileLoweringPass.Empty
JvmInventNamesForInlinedAnonymousObjects(context)
},
name = "InventNamesForInlinedLocalClasses", name = "InventNamesForInlinedLocalClasses",
description = "Invent names for INLINED local classes and anonymous objects", description = "Invent names for INLINED local classes and anonymous objects",
prerequisite = setOf(inventNamesForLocalClassesPhase, removeDuplicatedInlinedLocalClasses) prerequisite = setOf(inventNamesForLocalClassesPhase, removeDuplicatedInlinedLocalClasses)
@@ -6,24 +6,16 @@
package org.jetbrains.kotlin.backend.jvm.lower package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.getOrPut
import org.jetbrains.kotlin.backend.common.ir.Symbols import org.jetbrains.kotlin.backend.common.ir.Symbols
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.replaceTailExpression import org.jetbrains.kotlin.backend.common.lower.replaceTailExpression
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.buildField
import org.jetbrains.kotlin.ir.builders.declarations.buildVariable
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrSetValueImpl
import org.jetbrains.kotlin.ir.types.isMarkedNullable
import org.jetbrains.kotlin.ir.types.isPrimitiveType import org.jetbrains.kotlin.ir.types.isPrimitiveType
import org.jetbrains.kotlin.ir.types.makeNullable import org.jetbrains.kotlin.ir.types.makeNullable
import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.dump
@@ -32,7 +24,7 @@ import org.jetbrains.kotlin.ir.util.resolveFakeOverride
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
internal val jvmLateinitLowering = makeIrModulePhase( internal val jvmLateinitLowering = makeIrFilePhase(
::JvmLateinitLowering, ::JvmLateinitLowering,
name = "JvmLateinitLowering", name = "JvmLateinitLowering",
description = "Lower lateinit properties and variables" description = "Lower lateinit properties and variables"
@@ -7,7 +7,6 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
@@ -21,7 +20,7 @@ import org.jetbrains.kotlin.ir.types.defaultType
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.JvmNames.JVM_OVERLOADS_FQ_NAME import org.jetbrains.kotlin.name.JvmNames.JVM_OVERLOADS_FQ_NAME
internal val jvmOverloadsAnnotationPhase = makeIrModulePhase( internal val jvmOverloadsAnnotationPhase = makeIrFilePhase(
::JvmOverloadsAnnotationLowering, ::JvmOverloadsAnnotationLowering,
name = "JvmOverloadsAnnotation", name = "JvmOverloadsAnnotation",
description = "Handle JvmOverloads annotations" description = "Handle JvmOverloads annotations"
@@ -9,7 +9,6 @@ import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.lower.LocalDeclarationsLowering import org.jetbrains.kotlin.backend.common.lower.LocalDeclarationsLowering
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.backend.jvm.ir.getJvmNameFromAnnotation import org.jetbrains.kotlin.backend.jvm.ir.getJvmNameFromAnnotation
@@ -31,7 +30,7 @@ import org.jetbrains.kotlin.load.java.JavaDescriptorVisibilities
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance import org.jetbrains.kotlin.types.Variance
internal val mainMethodGenerationPhase = makeIrModulePhase( internal val mainMethodGenerationPhase = makeIrFilePhase(
::MainMethodGenerationLowering, ::MainMethodGenerationLowering,
name = "MainMethodGeneration", name = "MainMethodGeneration",
description = "Generate main bridges to parameterless mains, and wrappers for suspend mains.", description = "Generate main bridges to parameterless mains, and wrappers for suspend mains.",
@@ -13,6 +13,7 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.functionInliningPhase import org.jetbrains.kotlin.backend.jvm.functionInliningPhase
import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter import org.jetbrains.kotlin.backend.jvm.ir.isInlineParameter
import org.jetbrains.kotlin.backend.jvm.irInlinerIsEnabled
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
@@ -26,7 +27,10 @@ import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
import org.jetbrains.kotlin.ir.visitors.acceptVoid import org.jetbrains.kotlin.ir.visitors.acceptVoid
internal val markNecessaryInlinedClassesAsRegenerated = makeIrModulePhase( internal val markNecessaryInlinedClassesAsRegenerated = makeIrModulePhase(
::MarkNecessaryInlinedClassesAsRegeneratedLowering, { context ->
if (!context.irInlinerIsEnabled()) return@makeIrModulePhase FileLoweringPass.Empty
MarkNecessaryInlinedClassesAsRegeneratedLowering(context)
},
name = "MarkNecessaryInlinedClassesAsRegeneratedLowering", name = "MarkNecessaryInlinedClassesAsRegeneratedLowering",
description = "Will scan all inlined functions and mark anonymous objects that must be later regenerated at backend", description = "Will scan all inlined functions and mark anonymous objects that must be later regenerated at backend",
prerequisite = setOf(functionInliningPhase, createSeparateCallForInlinedLambdas) prerequisite = setOf(functionInliningPhase, createSeparateCallForInlinedLambdas)
@@ -6,7 +6,7 @@
package org.jetbrains.kotlin.backend.jvm.lower package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.config.LanguageFeature import org.jetbrains.kotlin.config.LanguageFeature
@@ -24,7 +24,7 @@ import org.jetbrains.kotlin.ir.util.hasAnnotation
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.resolve.jvm.checkers.PolymorphicSignatureCallChecker import org.jetbrains.kotlin.resolve.jvm.checkers.PolymorphicSignatureCallChecker
internal val polymorphicSignaturePhase = makeIrModulePhase( internal val polymorphicSignaturePhase = makeIrFilePhase(
::PolymorphicSignatureLowering, ::PolymorphicSignatureLowering,
name = "PolymorphicSignature", name = "PolymorphicSignature",
description = "Replace polymorphic methods with fake ones according to types at the call site" description = "Replace polymorphic methods with fake ones according to types at the call site"
@@ -15,7 +15,9 @@ import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.* import org.jetbrains.kotlin.backend.jvm.*
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.IrClass
import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
@@ -24,7 +26,10 @@ import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.name.NameUtils import org.jetbrains.kotlin.name.NameUtils
internal val removeDuplicatedInlinedLocalClasses = makeIrFilePhase( internal val removeDuplicatedInlinedLocalClasses = makeIrFilePhase(
::RemoveDuplicatedInlinedLocalClassesLowering, { context ->
if (!context.irInlinerIsEnabled()) return@makeIrFilePhase FileLoweringPass.Empty
RemoveDuplicatedInlinedLocalClassesLowering(context)
},
name = "RemoveDuplicatedInlinedLocalClasses", name = "RemoveDuplicatedInlinedLocalClasses",
description = "Drop excess local classes that were copied by ir inliner", description = "Drop excess local classes that were copied by ir inliner",
prerequisite = setOf(functionInliningPhase, localDeclarationsPhase) prerequisite = setOf(functionInliningPhase, localDeclarationsPhase)
@@ -39,7 +44,7 @@ data class Data(
// There are three types of inlined local classes: // There are three types of inlined local classes:
// 1. MUST BE regenerated according to set of rules in AnonymousObjectTransformationInfo. // 1. MUST BE regenerated according to set of rules in AnonymousObjectTransformationInfo.
// They all have `originalBeforeInline != null`. // They all have `originalBeforeInline != null`.
// 2. MUST NOT BE regenerated and MUST BE CREATED only once because they are copied from call site. // 2. MUST NOT BE regenerated and MUST BE CREATED only once because they are copied from call site, for example, from lambda.
// This lambda will not exist after inline, so we copy declaration into new temporary inline call `singleArgumentInlineFunction`. // This lambda will not exist after inline, so we copy declaration into new temporary inline call `singleArgumentInlineFunction`.
// 3. MUST NOT BE created at all because will be created at callee site. // 3. MUST NOT BE created at all because will be created at callee site.
// This lowering drops declarations that correspond to second and third type. // This lowering drops declarations that correspond to second and third type.
@@ -123,7 +128,7 @@ class RemoveDuplicatedInlinedLocalClassesLowering(val context: JvmBackendContext
// Basically we want to remove all anonymous classes after inline. Exceptions are: // Basically we want to remove all anonymous classes after inline. Exceptions are:
// 1. classes that must be regenerated (declaration.originalBeforeInline != null) // 1. classes that must be regenerated (declaration.originalBeforeInline != null)
// 2. classes that are originally declared on call site or are default lambdas (data == true) // 2. classes that are originally declared on call site or are default lambdas (data.classDeclaredOnCallSiteOrIsDefaultLambda == false)
override fun visitClass(declaration: IrClass, data: Data): IrStatement { override fun visitClass(declaration: IrClass, data: Data): IrStatement {
if (!data.insideInlineBlock || declaration.originalBeforeInline != null || !data.classDeclaredOnCallSiteOrIsDefaultLambda) { if (!data.insideInlineBlock || declaration.originalBeforeInline != null || !data.classDeclaredOnCallSiteOrIsDefaultLambda) {
return super.visitClass(declaration, data) return super.visitClass(declaration, data)
@@ -8,7 +8,6 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.ClassLoweringPass import org.jetbrains.kotlin.backend.common.ClassLoweringPass
import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin import org.jetbrains.kotlin.backend.jvm.JvmLoweredDeclarationOrigin
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
@@ -19,7 +18,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrBlockBodyImpl
import org.jetbrains.kotlin.load.java.JvmAbi import org.jetbrains.kotlin.load.java.JvmAbi
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
internal val typeAliasAnnotationMethodsPhase = makeIrModulePhase( internal val typeAliasAnnotationMethodsPhase = makeIrFilePhase(
::TypeAliasAnnotationMethodsLowering, ::TypeAliasAnnotationMethodsLowering,
name = "TypeAliasAnnotationMethodsLowering", name = "TypeAliasAnnotationMethodsLowering",
description = "Generate method stubs for type alias annotations" description = "Generate method stubs for type alias annotations"
@@ -7,7 +7,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
import org.jetbrains.kotlin.backend.jvm.ir.IrArrayBuilder import org.jetbrains.kotlin.backend.jvm.ir.IrArrayBuilder
import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder import org.jetbrains.kotlin.backend.jvm.ir.createJvmIrBuilder
@@ -26,7 +26,7 @@ import org.jetbrains.kotlin.ir.types.makeNotNull
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly import org.jetbrains.kotlin.util.capitalizeDecapitalize.toLowerCaseAsciiOnly
val varargPhase = makeIrModulePhase( val varargPhase = makeIrFilePhase(
::VarargLowering, ::VarargLowering,
name = "VarargLowering", name = "VarargLowering",
description = "Replace varargs with array arguments and lower arrayOf and emptyArray calls", description = "Replace varargs with array arguments and lower arrayOf and emptyArray calls",
+12 -11
View File
@@ -1,3 +1,4 @@
// IGNORE_INLINER: IR
// FILE: test.kt // FILE: test.kt
fun box() { fun box() {
@@ -8,18 +9,18 @@ fun box() {
inline fun foo() = { inline fun foo() = {
} }
// EXPECTATIONS JVM JVM_IR // EXPECTATIONS JVM JVM_IR
// test.kt:4 box
// test1.kt:8 box
// test1.kt:9 box
// EXPECTATIONS JVM_IR
// test.kt:4 box
// test1.kt:9 invoke
// test.kt:4 box
// EXPECTATIONS JVM JVM_IR
// test.kt:5 box // test.kt:5 box
// test1.kt:9 box
// test1.kt:10 box
// EXPECTATIONS JVM_IR
// test.kt:5 box
// test1.kt:10 invoke
// test.kt:5 box
// EXPECTATIONS JVM JVM_IR
// test.kt:6 box
// EXPECTATIONS JS_IR // EXPECTATIONS JS_IR
// test1.kt:9 box // test1.kt:10 box
// test.kt:4 box
// test1.kt:6 box$lambda
// test.kt:5 box // test.kt:5 box
// test1.kt:7 box$lambda
// test.kt:6 box
+11 -10
View File
@@ -1,3 +1,4 @@
// IGNORE_INLINER: IR
// FILE: test.kt // FILE: test.kt
fun box() { fun box() {
@@ -9,24 +10,24 @@ fun box() {
inline fun foo() = { inline fun foo() = {
} }
// EXPECTATIONS JVM JVM_IR // EXPECTATIONS JVM JVM_IR
// test.kt:4 box // test.kt:5 box
// test1.kt:9 box
// test1.kt:10 box // test1.kt:10 box
// test1.kt:11 box
// EXPECTATIONS JVM_IR // EXPECTATIONS JVM_IR
// test.kt:4 box
// test.kt:5 box // test.kt:5 box
// test1.kt:10 invoke
// test.kt:5 box
// EXPECTATIONS JVM_IR
// test.kt:6 box // test.kt:6 box
// test1.kt:11 invoke
// test.kt:6 box
// EXPECTATIONS JVM_IR
// test.kt:7 box
// EXPECTATIONS JVM // EXPECTATIONS JVM
// test.kt:4 box
// test.kt:5 box // test.kt:5 box
// test.kt:6 box // test.kt:6 box
// test.kt:7 box
// EXPECTATIONS JS_IR // EXPECTATIONS JS_IR
// test1.kt:10 box // test1.kt:11 box
// test.kt:4 box
// test.kt:5 box // test.kt:5 box
// test1.kt:7 box$lambda
// test.kt:6 box // test.kt:6 box
// test1.kt:8 box$lambda
// test.kt:7 box
+28 -27
View File
@@ -1,3 +1,4 @@
// IGNORE_INLINER: IR
// FILE: test.kt // FILE: test.kt
fun box() { fun box() {
@@ -14,39 +15,39 @@ fun baz(v:(() -> Unit)) {
v() v()
} }
// EXPECTATIONS JVM JVM_IR // EXPECTATIONS JVM JVM_IR
// test.kt:4 box // test.kt:5 box
// test1.kt:10 box
// test1.kt:11 box // test1.kt:11 box
// test.kt:4 box // test1.kt:12 box
// test3.kt:14 baz // test.kt:5 box
// EXPECTATIONS JVM_IR
// test1.kt:11 invoke
// test3.kt:14 baz
// EXPECTATIONS JVM JVM_IR
// test3.kt:15 baz // test3.kt:15 baz
// test.kt:5 box // EXPECTATIONS JVM_IR
// test1.kt:10 box // test1.kt:12 invoke
// test1.kt:11 box // test3.kt:15 baz
// test.kt:5 box // EXPECTATIONS JVM JVM_IR
// test3.kt:16 baz
// test.kt:6 box
// test1.kt:11 box
// test1.kt:12 box
// test.kt:6 box // test.kt:6 box
// EXPECTATIONS JVM_IR
// test3.kt:14 baz
// test1.kt:11 invoke
// EXPECTATIONS JVM JVM_IR
// test3.kt:14 baz
// test3.kt:15 baz
// test.kt:7 box // test.kt:7 box
// EXPECTATIONS JVM_IR
// test3.kt:15 baz
// test1.kt:12 invoke
// EXPECTATIONS JVM JVM_IR
// test3.kt:15 baz
// test3.kt:16 baz
// test.kt:8 box
// EXPECTATIONS JS_IR // EXPECTATIONS JS_IR
// test1.kt:11 box // test1.kt:12 box
// test.kt:4 box
// test3.kt:14 baz
// test1.kt:8 box$lambda
// test3.kt:15 baz
// test1.kt:11 box
// test.kt:5 box // test.kt:5 box
// test.kt:6 box
// test3.kt:14 baz
// test1.kt:8 box$lambda
// test3.kt:15 baz // test3.kt:15 baz
// test1.kt:9 box$lambda
// test3.kt:16 baz
// test1.kt:12 box
// test.kt:6 box
// test.kt:7 box // test.kt:7 box
// test3.kt:15 baz
// test1.kt:9 box$lambda
// test3.kt:16 baz
// test.kt:8 box