Add FunctionInlining lowering to JvmLower
This commit is contained in:
+19
-7
@@ -8,12 +8,12 @@ package org.jetbrains.kotlin.backend.common.lower
|
|||||||
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
import org.jetbrains.kotlin.backend.common.BodyLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||||
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext
|
||||||
|
import org.jetbrains.kotlin.ir.IrStatement
|
||||||
import org.jetbrains.kotlin.ir.builders.*
|
import org.jetbrains.kotlin.ir.builders.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
|
||||||
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
|
import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner
|
||||||
import org.jetbrains.kotlin.ir.expressions.*
|
import org.jetbrains.kotlin.ir.expressions.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrBlockImpl
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
|
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrDoWhileLoopImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrDoWhileLoopImpl
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
@@ -113,14 +113,26 @@ class ReturnableBlockTransformer(val context: CommonBackendContext, val containe
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
val newStatements = expression.statements.mapIndexed { i, s ->
|
|
||||||
if (i == expression.statements.lastIndex && s is IrReturn && s.returnTargetSymbol == expression.symbol) {
|
fun transformSingleStatement(statement: IrStatement, isLastInList: Boolean): IrStatement {
|
||||||
s.transformChildrenVoid()
|
return if (isLastInList && statement is IrReturn && statement.returnTargetSymbol == expression.symbol) {
|
||||||
if (!hasReturned) s.value else {
|
statement.transformChildrenVoid()
|
||||||
builder.irSet(variable.symbol, s.value)
|
if (!hasReturned) statement.value else {
|
||||||
|
builder.irSet(variable.symbol, statement.value)
|
||||||
}
|
}
|
||||||
} else {
|
} else {
|
||||||
s.transformStatement(this)
|
statement.transformStatement(this)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
val newStatements = expression.statements.mapIndexed { i, s ->
|
||||||
|
if (expression.statements.size == 1 && s is IrInlinedFunctionBlock) {
|
||||||
|
val transformed = s.statements.mapIndexed { j, it -> transformSingleStatement(it, j == s.statements.lastIndex) }
|
||||||
|
s.statements.clear()
|
||||||
|
s.statements.addAll(transformed)
|
||||||
|
s
|
||||||
|
} else {
|
||||||
|
transformSingleStatement(s, i == expression.statements.lastIndex)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
+3
@@ -128,6 +128,9 @@ class FunctionInlining(
|
|||||||
return expression
|
return expression
|
||||||
|
|
||||||
val actualCallee = inlineFunctionResolver.getFunctionDeclaration(callee.symbol)
|
val actualCallee = inlineFunctionResolver.getFunctionDeclaration(callee.symbol)
|
||||||
|
if (actualCallee.body == null) {
|
||||||
|
return expression
|
||||||
|
}
|
||||||
|
|
||||||
val parent = allScopes.map { it.irElement }.filterIsInstance<IrDeclarationParent>().lastOrNull()
|
val parent = allScopes.map { it.irElement }.filterIsInstance<IrDeclarationParent>().lastOrNull()
|
||||||
?: allScopes.map { it.irElement }.filterIsInstance<IrDeclaration>().lastOrNull()?.parent
|
?: allScopes.map { it.irElement }.filterIsInstance<IrDeclaration>().lastOrNull()?.parent
|
||||||
|
|||||||
@@ -9,6 +9,7 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
|||||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||||
import org.jetbrains.kotlin.backend.common.checkDeclarationParents
|
import org.jetbrains.kotlin.backend.common.checkDeclarationParents
|
||||||
import org.jetbrains.kotlin.backend.common.lower.*
|
import org.jetbrains.kotlin.backend.common.lower.*
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.inline.*
|
||||||
import org.jetbrains.kotlin.backend.common.lower.loops.forLoopsPhase
|
import org.jetbrains.kotlin.backend.common.lower.loops.forLoopsPhase
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.constantValue
|
import org.jetbrains.kotlin.backend.jvm.ir.constantValue
|
||||||
@@ -19,10 +20,12 @@ import org.jetbrains.kotlin.descriptors.DescriptorVisibilities
|
|||||||
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
import org.jetbrains.kotlin.descriptors.DescriptorVisibility
|
||||||
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.symbols.IrFunctionSymbol
|
||||||
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
import org.jetbrains.kotlin.ir.symbols.IrValueSymbol
|
||||||
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
|
import org.jetbrains.kotlin.ir.util.PatchDeclarationParentsVisitor
|
||||||
import org.jetbrains.kotlin.ir.util.isAnonymousObject
|
import org.jetbrains.kotlin.ir.util.isAnonymousObject
|
||||||
import org.jetbrains.kotlin.ir.util.parentAsClass
|
import org.jetbrains.kotlin.ir.util.parentAsClass
|
||||||
|
import org.jetbrains.kotlin.ir.util.resolveFakeOverride
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementVisitorVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptChildrenVoid
|
||||||
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
import org.jetbrains.kotlin.ir.visitors.acceptVoid
|
||||||
@@ -277,6 +280,26 @@ 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'"
|
||||||
)
|
)
|
||||||
|
|
||||||
|
private val functionInliningPhase = makeIrModulePhase<JvmBackendContext>(
|
||||||
|
{ context ->
|
||||||
|
class JvmInlineFunctionResolver : InlineFunctionResolver {
|
||||||
|
override fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction {
|
||||||
|
return (symbol.owner as? IrSimpleFunction)?.resolveFakeOverride() ?: symbol.owner
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun getFunctionSymbol(irFunction: IrFunction): IrFunctionSymbol {
|
||||||
|
return irFunction.symbol
|
||||||
|
}
|
||||||
|
}
|
||||||
|
FunctionInlining(context, JvmInlineFunctionResolver(), context.innerClassesSupport)
|
||||||
|
},
|
||||||
|
name = "FunctionInliningPhase",
|
||||||
|
description = "Perform function inlining",
|
||||||
|
prerequisite = setOf(
|
||||||
|
expectDeclarationsRemovingPhase,
|
||||||
|
)
|
||||||
|
)
|
||||||
|
|
||||||
private val jvmFilePhases = listOf(
|
private val jvmFilePhases = listOf(
|
||||||
typeAliasAnnotationMethodsPhase,
|
typeAliasAnnotationMethodsPhase,
|
||||||
provisionalFunctionExpressionPhase,
|
provisionalFunctionExpressionPhase,
|
||||||
@@ -412,6 +435,9 @@ private fun buildJvmLoweringPhases(
|
|||||||
fileClassPhase then
|
fileClassPhase then
|
||||||
jvmStaticInObjectPhase then
|
jvmStaticInObjectPhase then
|
||||||
repeatedAnnotationPhase then
|
repeatedAnnotationPhase then
|
||||||
|
|
||||||
|
functionInliningPhase then
|
||||||
|
|
||||||
buildLoweringsPhase(phases) then
|
buildLoweringsPhase(phases) then
|
||||||
generateMultifileFacadesPhase then
|
generateMultifileFacadesPhase then
|
||||||
resolveInlineCallsPhase then
|
resolveInlineCallsPhase then
|
||||||
|
|||||||
Reference in New Issue
Block a user