From 4f0585950e44e15a10eb37f94ec2fcdafe1cd2b7 Mon Sep 17 00:00:00 2001 From: Alexander Udalov Date: Thu, 23 Jul 2020 21:57:14 +0200 Subject: [PATCH] IR: inline some transformChildren calls in IrElementTransformer{,Void} IrElementTransformer.visitDeclaration/visitExpression are very prominent hotspots, and it seems that HotSpot doesn't optimize the inlined Kotlin bytecode there well enough. Reduce the bytecode in these and similar methods by inlining calls to also/apply/transformChildrenVoid. --- .../js/lower/BlockDecomposerLowering.kt | 2 +- .../ir/visitors/IrElementTransformer.kt | 72 +++++++++++-------- .../ir/visitors/IrElementTransformerVoid.kt | 60 +++++++++++++--- 3 files changed, 94 insertions(+), 40 deletions(-) diff --git a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt index d52863b0af6..564bbc6e64e 100644 --- a/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt +++ b/compiler/ir/backend.js/src/org/jetbrains/kotlin/ir/backend/js/lower/BlockDecomposerLowering.kt @@ -439,7 +439,7 @@ class BlockDecomposerTransformer( private inner class ExpressionTransformer : IrElementTransformerVoid() { - override fun visitExpression(expression: IrExpression) = expression.transformChildren() + override fun visitExpression(expression: IrExpression) = expression.apply { transformChildrenVoid() } override fun visitGetField(expression: IrGetField): IrExpression { expression.transformChildrenVoid(expressionTransformer) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformer.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformer.kt index 090a4396ef4..945d12dddd8 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformer.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformer.kt @@ -22,20 +22,30 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* interface IrElementTransformer : IrElementVisitor { - override fun visitElement(element: IrElement, data: D): IrElement = - element.also { it.transformChildren(this, data) } + override fun visitElement(element: IrElement, data: D): IrElement { + element.transformChildren(this, data) + return element + } - override fun visitModuleFragment(declaration: IrModuleFragment, data: D): IrModuleFragment = - declaration.also { it.transformChildren(this, data) } + override fun visitModuleFragment(declaration: IrModuleFragment, data: D): IrModuleFragment { + declaration.transformChildren(this, data) + return declaration + } - override fun visitFile(declaration: IrFile, data: D): IrFile = - declaration.also { it.transformChildren(this, data) } + override fun visitFile(declaration: IrFile, data: D): IrFile { + declaration.transformChildren(this, data) + return declaration + } - override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment, data: D): IrExternalPackageFragment = - declaration.also { it.transformChildren(this, data) } + override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment, data: D): IrExternalPackageFragment { + declaration.transformChildren(this, data) + return declaration + } - override fun visitDeclaration(declaration: IrDeclarationBase, data: D): IrStatement = - declaration.also { it.transformChildren(this, data) } + override fun visitDeclaration(declaration: IrDeclarationBase, data: D): IrStatement { + declaration.transformChildren(this, data) + return declaration + } override fun visitScript(declaration: IrScript, data: D) = visitDeclaration(declaration, data) override fun visitClass(declaration: IrClass, data: D) = visitDeclaration(declaration, data) @@ -52,8 +62,10 @@ interface IrElementTransformer : IrElementVisitor { override fun visitValueParameter(declaration: IrValueParameter, data: D) = visitDeclaration(declaration, data) override fun visitTypeAlias(declaration: IrTypeAlias, data: D) = visitDeclaration(declaration, data) - override fun visitBody(body: IrBody, data: D): IrBody = - body.also { it.transformChildren(this, data) } + override fun visitBody(body: IrBody, data: D): IrBody { + body.transformChildren(this, data) + return body + } override fun visitExpressionBody(body: IrExpressionBody, data: D) = visitBody(body, data) override fun visitBlockBody(body: IrBlockBody, data: D) = visitBody(body, data) @@ -62,14 +74,18 @@ interface IrElementTransformer : IrElementVisitor { override fun visitSuspendableExpression(expression: IrSuspendableExpression, data: D) = visitExpression(expression, data) override fun visitSuspensionPoint(expression: IrSuspensionPoint, data: D) = visitExpression(expression, data) - override fun visitExpression(expression: IrExpression, data: D): IrExpression = - expression.also { it.transformChildren(this, data) } + override fun visitExpression(expression: IrExpression, data: D): IrExpression { + expression.transformChildren(this, data) + return expression + } override fun visitConst(expression: IrConst, data: D) = visitExpression(expression, data) override fun visitVararg(expression: IrVararg, data: D) = visitExpression(expression, data) - override fun visitSpreadElement(spread: IrSpreadElement, data: D): IrSpreadElement = - spread.also { it.transformChildren(this, data) } + override fun visitSpreadElement(spread: IrSpreadElement, data: D): IrSpreadElement { + spread.transformChildren(this, data) + return spread + } override fun visitContainerExpression(expression: IrContainerExpression, data: D) = visitExpression(expression, data) override fun visitBlock(expression: IrBlock, data: D) = visitContainerExpression(expression, data) @@ -112,25 +128,25 @@ interface IrElementTransformer : IrElementVisitor { override fun visitWhen(expression: IrWhen, data: D) = visitExpression(expression, data) - override fun visitBranch(branch: IrBranch, data: D): IrBranch = - branch.also { - it.condition = it.condition.transform(this, data) - it.result = it.result.transform(this, data) - } + override fun visitBranch(branch: IrBranch, data: D): IrBranch { + branch.transformChildren(this, data) + return branch + } - override fun visitElseBranch(branch: IrElseBranch, data: D): IrElseBranch = - branch.also { - it.condition = it.condition.transform(this, data) - it.result = it.result.transform(this, data) - } + override fun visitElseBranch(branch: IrElseBranch, data: D): IrElseBranch { + branch.transformChildren(this, data) + return branch + } override fun visitLoop(loop: IrLoop, data: D) = visitExpression(loop, data) override fun visitWhileLoop(loop: IrWhileLoop, data: D) = visitLoop(loop, data) override fun visitDoWhileLoop(loop: IrDoWhileLoop, data: D) = visitLoop(loop, data) override fun visitTry(aTry: IrTry, data: D) = visitExpression(aTry, data) - override fun visitCatch(aCatch: IrCatch, data: D): IrCatch = - aCatch.also { it.transformChildren(this, data) } + override fun visitCatch(aCatch: IrCatch, data: D): IrCatch { + aCatch.transformChildren(this, data) + return aCatch + } override fun visitBreakContinue(jump: IrBreakContinue, data: D) = visitExpression(jump, data) override fun visitBreak(jump: IrBreak, data: D) = visitBreakContinue(jump, data) diff --git a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformerVoid.kt b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformerVoid.kt index 57e00d08c20..2c44fcf9d0e 100644 --- a/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformerVoid.kt +++ b/compiler/ir/ir.tree/src/org/jetbrains/kotlin/ir/visitors/IrElementTransformerVoid.kt @@ -22,16 +22,26 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.expressions.* abstract class IrElementTransformerVoid : IrElementTransformer { - protected fun T.transformChildren() = apply { transformChildrenVoid() } + open fun visitElement(element: IrElement): IrElement { + element.transformChildren(this, null) + return element + } - open fun visitElement(element: IrElement): IrElement = element.transformChildren() final override fun visitElement(element: IrElement, data: Nothing?): IrElement = visitElement(element) - open fun visitModuleFragment(declaration: IrModuleFragment): IrModuleFragment = declaration.transformChildren() + open fun visitModuleFragment(declaration: IrModuleFragment): IrModuleFragment { + declaration.transformChildren(this, null) + return declaration + } + final override fun visitModuleFragment(declaration: IrModuleFragment, data: Nothing?): IrModuleFragment = visitModuleFragment(declaration) - open fun visitPackageFragment(declaration: IrPackageFragment): IrPackageFragment = declaration.transformChildren() + open fun visitPackageFragment(declaration: IrPackageFragment): IrPackageFragment { + declaration.transformChildren(this, null) + return declaration + } + final override fun visitPackageFragment(declaration: IrPackageFragment, data: Nothing?): IrElement = visitPackageFragment(declaration) open fun visitFile(declaration: IrFile): IrFile = visitPackageFragment(declaration) as IrFile @@ -43,7 +53,11 @@ abstract class IrElementTransformerVoid : IrElementTransformer { final override fun visitExternalPackageFragment(declaration: IrExternalPackageFragment, data: Nothing?): IrExternalPackageFragment = visitExternalPackageFragment(declaration) - open fun visitDeclaration(declaration: IrDeclarationBase): IrStatement = declaration.transformChildren() + open fun visitDeclaration(declaration: IrDeclarationBase): IrStatement { + declaration.transformChildren(this, null) + return declaration + } + final override fun visitDeclaration(declaration: IrDeclarationBase, data: Nothing?): IrStatement = visitDeclaration(declaration) open fun visitScript(declaration: IrScript) = visitDeclaration(declaration) @@ -90,7 +104,11 @@ abstract class IrElementTransformerVoid : IrElementTransformer { open fun visitTypeAlias(declaration: IrTypeAlias) = visitDeclaration(declaration) final override fun visitTypeAlias(declaration: IrTypeAlias, data: Nothing?) = visitTypeAlias(declaration) - open fun visitBody(body: IrBody): IrBody = body.transformChildren() + open fun visitBody(body: IrBody): IrBody { + body.transformChildren(this, null) + return body + } + final override fun visitBody(body: IrBody, data: Nothing?): IrBody = visitBody(body) open fun visitExpressionBody(body: IrExpressionBody) = visitBody(body) @@ -109,7 +127,11 @@ abstract class IrElementTransformerVoid : IrElementTransformer { open fun visitSuspensionPoint(expression: IrSuspensionPoint) = visitExpression(expression) final override fun visitSuspensionPoint(expression: IrSuspensionPoint, data: Nothing?) = visitSuspensionPoint(expression) - open fun visitExpression(expression: IrExpression): IrExpression = expression.transformChildren() + open fun visitExpression(expression: IrExpression): IrExpression { + expression.transformChildren(this, null) + return expression + } + final override fun visitExpression(expression: IrExpression, data: Nothing?): IrExpression = visitExpression(expression) open fun visitConst(expression: IrConst) = visitExpression(expression) @@ -118,7 +140,11 @@ abstract class IrElementTransformerVoid : IrElementTransformer { open fun visitVararg(expression: IrVararg) = visitExpression(expression) final override fun visitVararg(expression: IrVararg, data: Nothing?) = visitVararg(expression) - open fun visitSpreadElement(spread: IrSpreadElement) = spread.transformChildren() + open fun visitSpreadElement(spread: IrSpreadElement): IrSpreadElement { + spread.transformChildren(this, null) + return spread + } + final override fun visitSpreadElement(spread: IrSpreadElement, data: Nothing?): IrSpreadElement = visitSpreadElement(spread) open fun visitContainerExpression(expression: IrContainerExpression) = visitExpression(expression) @@ -221,10 +247,18 @@ abstract class IrElementTransformerVoid : IrElementTransformer { open fun visitWhen(expression: IrWhen) = visitExpression(expression) final override fun visitWhen(expression: IrWhen, data: Nothing?) = visitWhen(expression) - open fun visitBranch(branch: IrBranch) = branch.transformChildren() + open fun visitBranch(branch: IrBranch): IrBranch { + branch.transformChildren(this, null) + return branch + } + final override fun visitBranch(branch: IrBranch, data: Nothing?): IrBranch = visitBranch(branch) - open fun visitElseBranch(branch: IrElseBranch) = branch.transformChildren() + open fun visitElseBranch(branch: IrElseBranch): IrElseBranch { + branch.transformChildren(this, null) + return branch + } + final override fun visitElseBranch(branch: IrElseBranch, data: Nothing?): IrElseBranch = visitElseBranch(branch) open fun visitLoop(loop: IrLoop) = visitExpression(loop) @@ -239,7 +273,11 @@ abstract class IrElementTransformerVoid : IrElementTransformer { open fun visitTry(aTry: IrTry) = visitExpression(aTry) final override fun visitTry(aTry: IrTry, data: Nothing?) = visitTry(aTry) - open fun visitCatch(aCatch: IrCatch): IrCatch = aCatch.apply { transformChildrenVoid() } + open fun visitCatch(aCatch: IrCatch): IrCatch { + aCatch.transformChildren(this, null) + return aCatch + } + final override fun visitCatch(aCatch: IrCatch, data: Nothing?): IrCatch = visitCatch(aCatch) open fun visitBreakContinue(jump: IrBreakContinue) = visitExpression(jump)