Inline properties accessors for release builds (#4570)

This commit is contained in:
LepilkinaElena
2020-12-08 08:17:26 +03:00
committed by Stanislav Erokhin
parent eaa7cf44c8
commit b6497d07cf
4 changed files with 39 additions and 1 deletions
@@ -8,6 +8,7 @@ import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineFunc
import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineLambdasLowering
import org.jetbrains.kotlin.backend.common.lower.loops.ForLoopsLowering
import org.jetbrains.kotlin.backend.common.lower.optimizations.FoldConstantLowering
import org.jetbrains.kotlin.backend.common.lower.optimizations.PropertyAccessorInlineLowering
import org.jetbrains.kotlin.backend.common.phaser.*
import org.jetbrains.kotlin.backend.konan.lower.*
import org.jetbrains.kotlin.backend.konan.lower.FinallyBlocksLowering
@@ -106,6 +107,12 @@ internal val lateinitPhase = makeKonanModuleOpPhase(
description = "Lateinit properties lowering"
)
internal val propertyAccessorInlinePhase = makeKonanModuleLoweringPhase(
::PropertyAccessorInlineLowering,
name = "PropertyAccessorInline",
description = "Property accessor inline lowering"
)
internal val sharedVariablesPhase = makeKonanModuleLoweringPhase(
::SharedVariablesLowering,
name = "SharedVariables",
@@ -391,6 +391,8 @@ internal val bitcodePhase = NamedCompilerPhase(
ghaPhase then
RTTIPhase then
generateDebugInfoHeaderPhase then
propertyAccessorInlinePhase then // Have to run after link dependencies phase, because fields
// from dependencies can be changed during lowerings.
escapeAnalysisPhase then
localEscapeAnalysisPhase then
codegenPhase then
@@ -468,6 +470,9 @@ internal fun PhaseConfig.konanPhasesConfig(config: KonanConfig) {
disableUnless(buildDFGPhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
disableUnless(devirtualizationPhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
disableUnless(escapeAnalysisPhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
// Inline accessors only in optimized builds due to separate compilation and possibility to get broken
// debug information.
disableUnless(propertyAccessorInlinePhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
disableUnless(dcePhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
disableUnless(ghaPhase, getBoolean(KonanConfigKeys.OPTIMIZATION))
disableUnless(verifyBitcodePhase, config.needCompilerVerification || getBoolean(KonanConfigKeys.VERIFY_BITCODE))
@@ -309,6 +309,30 @@ private class InlineClassTransformer(private val context: Context) : IrBuildingT
return declaration
}
override fun visitCall(expression: IrCall): IrExpression {
expression.transformChildrenVoid(this)
// Make replacement only in optimized builds due to separate compilation and possibility to get broken
// debug information.
if (!context.shouldOptimize())
return expression
val property = expression.symbol.owner.correspondingPropertySymbol?.owner ?: return expression
property.parent.let {
if (it is IrClass && it.isInline && property.backingField != null) {
expression.dispatchReceiver?.let { receiver ->
return builder.at(expression)
.irCall(symbols.reinterpret, expression.type, listOf(receiver.type, expression.type))
.apply {
extensionReceiver = receiver
}
}
}
}
return expression
}
private fun IrBuilderWithScope.irIsNull(expression: IrExpression): IrExpression {
val binary = expression.type.computeBinaryType()
return when (binary) {
@@ -82,9 +82,11 @@ internal class InitializersLowering(val context: CommonBackendContext) : ClassLo
)
// We shall keep initializer for constants for compile-time instantiation.
// We suppose that if the property is const, then its initializer is IrConst.
// If this requirement isn't satisfied, then PropertyAccessorInlineLowering can fail.
declaration.initializer =
if (initExpression is IrConst<*> &&
(initExpression.type.isPrimitiveType() || initExpression.type.isString())) {
declaration.correspondingPropertySymbol?.owner?.isConst == true) {
IrExpressionBodyImpl(initExpression.copy())
} else {
null