diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt index acddc15949a..556e38eaa0a 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/codegen/ExpressionCodegen.kt @@ -427,11 +427,13 @@ class ExpressionCodegen( override fun visitFieldAccess(expression: IrFieldAccessExpression, data: BlockInfo): PromisedValue { val callee = expression.symbol.owner callee.constantValue()?.let { - // Handling const reads before codegen is important for constant folding. - assert(expression is IrSetField) { "read of const val ${callee.name} not inlined by ConstLowering" } - // This can only be the field's initializer; JVM implementations are required - // to generate those for ConstantValue-marked fields automatically, so this is redundant. - return defaultValue(expression.type) + if (context.state.shouldInlineConstVals) { + // Handling const reads before codegen is important for constant folding. + assert(expression is IrSetField) { "read of const val ${callee.name} not inlined by ConstLowering" } + // This can only be the field's initializer; JVM implementations are required + // to generate those for ConstantValue-marked fields automatically, so this is redundant. + return defaultValue(expression.type) + } } val realField = callee.resolveFakeOverride()!! diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ConstLowering.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ConstLowering.kt index f398f2ef96b..0f83133b443 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ConstLowering.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/lower/ConstLowering.kt @@ -5,9 +5,9 @@ package org.jetbrains.kotlin.backend.jvm.lower -import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase +import org.jetbrains.kotlin.backend.jvm.JvmBackendContext import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrField import org.jetbrains.kotlin.ir.declarations.IrFile @@ -16,9 +16,8 @@ import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrConst import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrGetField -import org.jetbrains.kotlin.ir.util.deepCopyWithSymbols +import org.jetbrains.kotlin.ir.expressions.impl.IrGetFieldImpl import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid -import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid internal val constPhase = makeIrFilePhase( ::ConstLowering, @@ -34,9 +33,17 @@ fun IrField.constantValue(implicitConst: Boolean = false): IrConst<*>? { return if (inline) (initializer?.expression as? IrConst<*>)?.copy() else null } -class ConstLowering(val context: CommonBackendContext) : IrElementTransformerVoid(), FileLoweringPass { - override fun lower(irFile: IrFile) { - irFile.transformChildrenVoid(this) +class ConstLowering(val context: JvmBackendContext) : IrElementTransformerVoid(), FileLoweringPass { + override fun lower(irFile: IrFile) = irFile.transformChildrenVoid() + + private fun IrExpression.lowerConstRead(field: IrField?): IrExpression? { + val value = field?.constantValue() + ?: return null + + return if (context.state.shouldInlineConstVals) + value + else + IrGetFieldImpl(startOffset, endOffset, field.symbol, field.type) } override fun visitCall(expression: IrCall): IrExpression { @@ -44,9 +51,9 @@ class ConstLowering(val context: CommonBackendContext) : IrElementTransformerVoi val property = function.correspondingPropertySymbol?.owner ?: return super.visitCall(expression) if (function != property.getter) return super.visitCall(expression) - return property.backingField?.constantValue() ?: super.visitCall(expression) + return expression.lowerConstRead(property.backingField) ?: super.visitCall(expression) } override fun visitGetField(expression: IrGetField): IrExpression = - expression.symbol.owner.constantValue() ?: super.visitGetField(expression) + expression.lowerConstRead(expression.symbol.owner) ?: super.visitGetField(expression) } diff --git a/compiler/testData/codegen/box/constants/kt9532_lv10.kt b/compiler/testData/codegen/box/constants/kt9532_lv10.kt index 4f322ab65a2..b78cc1db13f 100644 --- a/compiler/testData/codegen/box/constants/kt9532_lv10.kt +++ b/compiler/testData/codegen/box/constants/kt9532_lv10.kt @@ -1,5 +1,5 @@ // !LANGUAGE: -InlineConstVals -// IGNORE_BACKEND: JVM_IR, JS_IR, NATIVE +// IGNORE_BACKEND: JS_IR, NATIVE // TODO: muted automatically, investigate should it be ran for JS or not // IGNORE_BACKEND: JS diff --git a/compiler/testData/codegen/bytecodeText/constProperty/noInline.kt b/compiler/testData/codegen/bytecodeText/constProperty/noInline.kt index 12f3766f8b3..08f5f827381 100644 --- a/compiler/testData/codegen/bytecodeText/constProperty/noInline.kt +++ b/compiler/testData/codegen/bytecodeText/constProperty/noInline.kt @@ -1,5 +1,4 @@ // !LANGUAGE: -InlineConstVals -// IGNORE_BACKEND: JVM_IR const val z = 0 diff --git a/compiler/testData/codegen/bytecodeText/constProperty/noInlineInCmp.kt b/compiler/testData/codegen/bytecodeText/constProperty/noInlineInCmp.kt index f97192cdd5c..39d32f49641 100644 --- a/compiler/testData/codegen/bytecodeText/constProperty/noInlineInCmp.kt +++ b/compiler/testData/codegen/bytecodeText/constProperty/noInlineInCmp.kt @@ -1,5 +1,4 @@ // !LANGUAGE: -InlineConstVals -// IGNORE_BACKEND: JVM_IR const val z = 0 diff --git a/compiler/testData/codegen/bytecodeText/lazyCodegen/negateConstantCompare.kt b/compiler/testData/codegen/bytecodeText/lazyCodegen/negateConstantCompare.kt index f2c80b077cf..f52ff9efb75 100644 --- a/compiler/testData/codegen/bytecodeText/lazyCodegen/negateConstantCompare.kt +++ b/compiler/testData/codegen/bytecodeText/lazyCodegen/negateConstantCompare.kt @@ -1,5 +1,4 @@ // !LANGUAGE: -InlineConstVals -// IGNORE_BACKEND: JVM_IR const val one = 1 const val two = 2 diff --git a/compiler/testData/codegen/bytecodeText/whenStringOptimization/nonInlinedConst.kt b/compiler/testData/codegen/bytecodeText/whenStringOptimization/nonInlinedConst.kt index 5011f63ad1c..e44503c1d45 100644 --- a/compiler/testData/codegen/bytecodeText/whenStringOptimization/nonInlinedConst.kt +++ b/compiler/testData/codegen/bytecodeText/whenStringOptimization/nonInlinedConst.kt @@ -1,5 +1,4 @@ // !LANGUAGE: -InlineConstVals -// IGNORE_BACKEND: JVM_IR const val y = "cde"