Add FunctionInlining lowering to JvmLower

This commit is contained in:
Ivan Kylchik
2021-12-27 14:58:40 +03:00
committed by Space Team
parent ef78196cbc
commit ce6084302f
3 changed files with 48 additions and 7 deletions
@@ -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)
} }
} }
@@ -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