From 45493b6542a02ba82e7fe3d79381da185bc7723a Mon Sep 17 00:00:00 2001 From: Elena Lepilkina Date: Tue, 14 Sep 2021 15:30:02 +0300 Subject: [PATCH] [IR] Support simple cases of inlining fake override getters/setters --- .../PropertyAccessorInlineLowering.kt | 46 +++++++++++++------ 1 file changed, 32 insertions(+), 14 deletions(-) diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/optimizations/PropertyAccessorInlineLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/optimizations/PropertyAccessorInlineLowering.kt index 3640f1a4cee..37f483a3cb8 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/optimizations/PropertyAccessorInlineLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/optimizations/PropertyAccessorInlineLowering.kt @@ -20,6 +20,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrSetFieldImpl import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols import org.jetbrains.kotlin.ir.util.isEffectivelyExternal import org.jetbrains.kotlin.backend.common.ir.isPure +import org.jetbrains.kotlin.ir.util.resolveFakeOverride import org.jetbrains.kotlin.ir.types.isUnit import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid @@ -33,23 +34,38 @@ class PropertyAccessorInlineLowering(private val context: CommonBackendContext) private val unitType = context.irBuiltIns.unitType - override fun visitCall(expression: IrCall): IrExpression { - expression.transformChildrenVoid(this) - - val callee = expression.symbol.owner - val property = callee.correspondingPropertySymbol?.owner ?: return expression + private fun canBeInlined(callee: IrSimpleFunction): Boolean { + val property = callee.correspondingPropertySymbol?.owner ?: return false // Some devirtualization required here - if (!property.isSafeToInline) return expression + if (!property.isSafeToInline) return false val parent = property.parent if (parent is IrClass) { // TODO: temporary workarounds - if (parent.isExpect || property.isExpect) return expression - if (parent.parent is IrExternalPackageFragment) return expression - if (parent.isInline) return expression + if (parent.isExpect || property.isExpect) return false + if (parent.parent is IrExternalPackageFragment) return false + if (parent.isInline) return false } - if (property.isEffectivelyExternal()) return expression + if (property.isEffectivelyExternal()) return false + return true + } + + override fun visitCall(expression: IrCall): IrExpression { + expression.transformChildrenVoid(this) + + val callee = expression.symbol.owner + + if (!canBeInlined(callee)) return expression + + var analyzedCallee = callee + while (analyzedCallee.isFakeOverride) { + analyzedCallee = analyzedCallee.resolveFakeOverride() ?: return expression + } + + if (!canBeInlined(analyzedCallee)) return expression + + val property = analyzedCallee.correspondingPropertySymbol?.owner ?: return expression val backingField = property.backingField ?: return expression @@ -59,8 +75,10 @@ class PropertyAccessorInlineLowering(private val context: CommonBackendContext) val constExpression = initializer.expression.deepCopyWithSymbols() val receiver = expression.dispatchReceiver if (receiver != null && !receiver.isPure(true)) { - val builder = context.createIrBuilder(expression.symbol, - expression.startOffset, expression.endOffset) + val builder = context.createIrBuilder( + expression.symbol, + expression.startOffset, expression.endOffset + ) return builder.irBlock(expression) { +receiver +constExpression @@ -72,11 +90,11 @@ class PropertyAccessorInlineLowering(private val context: CommonBackendContext) if (property.getter === callee) { - return tryInlineSimpleGetter(expression, callee, backingField) ?: expression + return tryInlineSimpleGetter(expression, analyzedCallee, backingField) ?: expression } if (property.setter === callee) { - return tryInlineSimpleSetter(expression, callee, backingField) ?: expression + return tryInlineSimpleSetter(expression, analyzedCallee, backingField) ?: expression } return expression