FunctionInlining

This commit is contained in:
Anton Bannykh
2019-12-24 22:39:22 +03:00
committed by Anton Bannykh
parent 86a4e17dc4
commit e2d16d5096
4 changed files with 66 additions and 9 deletions
@@ -68,6 +68,20 @@ abstract class IrElementTransformerVoidWithContext : IrElementTransformerVoid()
return result return result
} }
final override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer): IrStatement {
scopeStack.push(createScope(declaration))
val result = visitAnonymousInitializerNew(declaration)
scopeStack.pop()
return result
}
final override fun visitValueParameter(declaration: IrValueParameter): IrStatement {
scopeStack.push(createScope(declaration))
val result = visitValueParameterNew(declaration)
scopeStack.pop()
return result
}
final override fun visitScript(declaration: IrScript): IrStatement { final override fun visitScript(declaration: IrScript): IrStatement {
scopeStack.push(createScope(declaration)) scopeStack.push(createScope(declaration))
val result = visitScriptNew(declaration) val result = visitScriptNew(declaration)
@@ -80,6 +94,8 @@ abstract class IrElementTransformerVoidWithContext : IrElementTransformerVoid()
protected val currentClass get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrClassSymbol } protected val currentClass get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrClassSymbol }
protected val currentFunction get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrFunctionSymbol } protected val currentFunction get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrFunctionSymbol }
protected val currentProperty get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrPropertySymbol } protected val currentProperty get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrPropertySymbol }
protected val currentAnonymousInitializer get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrAnonymousInitializer }
protected val currentValueParameter get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrValueParameter }
protected val currentScope get() = scopeStack.peek() protected val currentScope get() = scopeStack.peek()
protected val parentScope get() = if (scopeStack.size < 2) null else scopeStack[scopeStack.size - 2] protected val parentScope get() = if (scopeStack.size < 2) null else scopeStack[scopeStack.size - 2]
protected val allScopes get() = scopeStack protected val allScopes get() = scopeStack
@@ -109,6 +125,14 @@ abstract class IrElementTransformerVoidWithContext : IrElementTransformerVoid()
return super.visitField(declaration) return super.visitField(declaration)
} }
open fun visitAnonymousInitializerNew(declaration: IrAnonymousInitializer): IrStatement {
return super.visitAnonymousInitializer(declaration)
}
open fun visitValueParameterNew(declaration: IrValueParameter): IrStatement {
return super.visitValueParameter(declaration)
}
open fun visitScriptNew(declaration: IrScript): IrStatement { open fun visitScriptNew(declaration: IrScript): IrStatement {
return super.visitScript(declaration) return super.visitScript(declaration)
} }
@@ -152,10 +176,24 @@ abstract class IrElementVisitorVoidWithContext : IrElementVisitorVoid {
scopeStack.pop() scopeStack.pop()
} }
final override fun visitAnonymousInitializer(declaration: IrAnonymousInitializer) {
scopeStack.push(createScope(declaration))
visitAnonymousInitializerNew(declaration)
scopeStack.pop()
}
final override fun visitValueParameter(declaration: IrValueParameter) {
scopeStack.push(createScope(declaration))
visitValueParameterNew(declaration)
scopeStack.pop()
}
protected val currentFile get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrFileSymbol } protected val currentFile get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrFileSymbol }
protected val currentClass get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrClassSymbol } protected val currentClass get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrClassSymbol }
protected val currentFunction get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrFunctionSymbol } protected val currentFunction get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrFunctionSymbol }
protected val currentProperty get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrPropertySymbol } protected val currentProperty get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrPropertySymbol }
protected val currentAnonymousInitializer get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrAnonymousInitializer }
protected val currentValueParameter get() = scopeStack.lastOrNull { it.scope.scopeOwnerSymbol is IrValueParameter }
protected val currentScope get() = scopeStack.peek() protected val currentScope get() = scopeStack.peek()
protected val parentScope get() = if (scopeStack.size < 2) null else scopeStack[scopeStack.size - 2] protected val parentScope get() = if (scopeStack.size < 2) null else scopeStack[scopeStack.size - 2]
protected val allScopes get() = scopeStack protected val allScopes get() = scopeStack
@@ -183,4 +221,12 @@ abstract class IrElementVisitorVoidWithContext : IrElementVisitorVoid {
open fun visitFieldNew(declaration: IrField) { open fun visitFieldNew(declaration: IrField) {
super.visitField(declaration) super.visitField(declaration)
} }
open fun visitAnonymousInitializerNew(declaration: IrAnonymousInitializer) {
super.visitAnonymousInitializer(declaration)
}
open fun visitValueParameterNew(declaration: IrValueParameter) {
super.visitValueParameter(declaration)
}
} }
@@ -31,7 +31,18 @@ import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
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
class FunctionInlining(val context: CommonBackendContext) : IrElementTransformerVoidWithContext() { class FunctionInlining(val context: CommonBackendContext) : IrElementTransformerVoidWithContext(), BodyLoweringPass {
private var containerScope: ScopeWithIr? = null
override fun lower(irBody: IrBody, container: IrDeclaration) {
// TODO container: IrSymbolDeclaration
containerScope = createScope(container as IrSymbolOwner)
irBody.accept(this, null)
containerScope = null
irBody.patchDeclarationParents(container as? IrDeclarationParent ?: container.parent)
}
fun inline(irModule: IrModuleFragment) = irModule.accept(this, data = null) fun inline(irModule: IrModuleFragment) = irModule.accept(this, data = null)
@@ -52,8 +63,11 @@ class FunctionInlining(val context: CommonBackendContext) : IrElementTransformer
val actualCallee = getFunctionDeclaration(callee.symbol) val actualCallee = getFunctionDeclaration(callee.symbol)
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
?: containerScope?.irElement as? IrDeclarationParent
?: (containerScope?.irElement as? IrDeclaration)?.parent
val inliner = Inliner(expression, actualCallee, currentScope!!, parent, context) val inliner = Inliner(expression, actualCallee, currentScope ?: containerScope!!, parent, context)
return inliner.inline() return inliner.inline()
} }
@@ -111,11 +111,8 @@ private val arrayConstructorPhase = makeJsModulePhase(
description = "Transform `Array(size) { index -> value }` into a loop" description = "Transform `Array(size) { index -> value }` into a loop"
) )
private val functionInliningPhase = makeCustomJsModulePhase( private val functionInliningPhase = makeJsModulePhase(
{ context, module -> ::FunctionInlining,
FunctionInlining(context).inline(module)
module.patchDeclarationParents()
},
name = "FunctionInliningPhase", name = "FunctionInliningPhase",
description = "Perform function inlining", description = "Perform function inlining",
prerequisite = setOf(expectDeclarationsRemovingPhase) prerequisite = setOf(expectDeclarationsRemovingPhase)
@@ -39,7 +39,7 @@ private class RenameAnonymousParametersLowering(val context: JvmBackendContext)
override fun lower(irFile: IrFile) = irFile.transformChildrenVoid() override fun lower(irFile: IrFile) = irFile.transformChildrenVoid()
override fun visitValueParameter(declaration: IrValueParameter) = override fun visitValueParameterNew(declaration: IrValueParameter) =
declaration.computeNewParameterName()?.let { name -> declaration.computeNewParameterName()?.let { name ->
val descriptor = if (declaration.descriptor is ReceiverParameterDescriptor) { val descriptor = if (declaration.descriptor is ReceiverParameterDescriptor) {
WrappedReceiverParameterDescriptor(declaration.descriptor.annotations) WrappedReceiverParameterDescriptor(declaration.descriptor.annotations)
@@ -63,7 +63,7 @@ private class RenameAnonymousParametersLowering(val context: JvmBackendContext)
annotations += declaration.annotations annotations += declaration.annotations
oldParameterToNew[declaration] = this oldParameterToNew[declaration] = this
} }
} ?: super.visitValueParameter(declaration) } ?: super.visitValueParameterNew(declaration)
override fun visitGetValue(expression: IrGetValue): IrExpression { override fun visitGetValue(expression: IrGetValue): IrExpression {
val oldParameter = expression.symbol.owner val oldParameter = expression.symbol.owner