diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt index 735f41496e8..854df6896d6 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt +++ b/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/Fir2IrConverter.kt @@ -15,7 +15,6 @@ import org.jetbrains.kotlin.config.AnalysisFlags import org.jetbrains.kotlin.config.LanguageVersionSettings import org.jetbrains.kotlin.descriptors.ModuleDescriptor import org.jetbrains.kotlin.fir.FirSession -import org.jetbrains.kotlin.fir.backend.evaluate.evaluateConstants import org.jetbrains.kotlin.fir.backend.generators.* import org.jetbrains.kotlin.fir.backend.generators.DataClassMembersGenerator import org.jetbrains.kotlin.fir.declarations.* @@ -38,6 +37,9 @@ import org.jetbrains.kotlin.ir.PsiIrFileEntry import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl +import org.jetbrains.kotlin.ir.interpreter.IrInterpreter +import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode +import org.jetbrains.kotlin.ir.interpreter.checker.IrConstTransformer import org.jetbrains.kotlin.ir.linkage.IrDeserializer import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.util.* @@ -424,6 +426,13 @@ class Fir2IrConverter( } companion object { + private fun evaluateConstants(irModuleFragment: IrModuleFragment) { + val interpreter = IrInterpreter(irModuleFragment.irBuiltins) + irModuleFragment.files.forEach { + it.transformChildren(IrConstTransformer(interpreter, it, mode = EvaluationMode.ONLY_BUILTINS), null) + } + } + @OptIn(ObsoleteDescriptorBasedAPI::class) fun createModuleFragment( session: FirSession, diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ConstEvaluationLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ConstEvaluationLowering.kt new file mode 100644 index 00000000000..3a365922938 --- /dev/null +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/ConstEvaluationLowering.kt @@ -0,0 +1,29 @@ +/* + * Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. + */ + +package org.jetbrains.kotlin.backend.common.lower + +import org.jetbrains.kotlin.backend.common.CommonBackendContext +import org.jetbrains.kotlin.backend.common.FileLoweringPass +import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase +import org.jetbrains.kotlin.ir.declarations.IrFile +import org.jetbrains.kotlin.ir.interpreter.IrInterpreter +import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode +import org.jetbrains.kotlin.ir.interpreter.checker.IrConstTransformer + +val constEvaluationPhase = makeIrModulePhase( + ::ConstEvaluationLowering, + name = "ConstEvaluationLowering", + description = "Evaluate functions that are marked as `Foldable`" +) + +class ConstEvaluationLowering(val context: CommonBackendContext) : FileLoweringPass { + val interpreter = IrInterpreter(context.irBuiltIns) + + override fun lower(irFile: IrFile) { + irFile.transformChildren(IrConstTransformer(interpreter, irFile, mode = EvaluationMode.ONLY_INTRINSIC_CONST), null) + } +} + diff --git a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt index dc8455422d1..d39099d327d 100644 --- a/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt +++ b/compiler/ir/backend.jvm/lower/src/org/jetbrains/kotlin/backend/jvm/JvmLower.kt @@ -407,6 +407,7 @@ private fun buildJvmLoweringPhases( validateIrBeforeLowering then processOptionalAnnotationsPhase then expectDeclarationsRemovingPhase then + constEvaluationPhase then serializeIrPhase then scriptsToClassesPhase then fileClassPhase then diff --git a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/evaluate/IrConstTransformer.kt b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstTransformer.kt similarity index 79% rename from compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/evaluate/IrConstTransformer.kt rename to compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstTransformer.kt index ac6b310d338..875ed81808b 100644 --- a/compiler/fir/fir2ir/src/org/jetbrains/kotlin/fir/backend/evaluate/IrConstTransformer.kt +++ b/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/checker/IrConstTransformer.kt @@ -1,36 +1,32 @@ /* - * Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors. + * Copyright 2010-2021 JetBrains s.r.o. and Kotlin Programming Language contributors. * Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file. */ -package org.jetbrains.kotlin.fir.backend.evaluate +package org.jetbrains.kotlin.ir.interpreter.checker import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.IrAnnotationContainer +import org.jetbrains.kotlin.ir.declarations.IrDeclarationBase +import org.jetbrains.kotlin.ir.declarations.IrField +import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl import org.jetbrains.kotlin.ir.interpreter.IrInterpreter -import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode -import org.jetbrains.kotlin.ir.interpreter.checker.IrCompileTimeChecker +import org.jetbrains.kotlin.ir.interpreter.isPrimitiveArray import org.jetbrains.kotlin.ir.interpreter.toIrConst import org.jetbrains.kotlin.ir.types.* -import org.jetbrains.kotlin.ir.util.isPrimitiveArray import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid -fun evaluateConstants(irModuleFragment: IrModuleFragment) { - val interpreter = IrInterpreter(irModuleFragment.irBuiltins) - irModuleFragment.files.forEach { it.transformChildren(IrConstTransformer(interpreter, it), null) } -} - -//TODO create abstract class that will be common for this and lowering -class IrConstTransformer(private val interpreter: IrInterpreter, private val irFile: IrFile) : IrElementTransformerVoid() { - +class IrConstTransformer( + private val interpreter: IrInterpreter, private val irFile: IrFile, private val mode: EvaluationMode +) : IrElementTransformerVoid() { private fun IrExpression.replaceIfError(original: IrExpression): IrExpression { return if (this !is IrErrorExpression) this else original } override fun visitCall(expression: IrCall): IrExpression { - if (expression.accept(IrCompileTimeChecker(mode = EvaluationMode.ONLY_BUILTINS), null)) { + if (expression.accept(IrCompileTimeChecker(mode = mode), null)) { return interpreter.interpret(expression, irFile).replaceIfError(expression) } return super.visitCall(expression) @@ -43,7 +39,7 @@ class IrConstTransformer(private val interpreter: IrInterpreter, private val irF val expression = initializer?.expression ?: return declaration if (expression is IrConst<*>) return declaration val isConst = declaration.correspondingPropertySymbol?.owner?.isConst == true - if (isConst && expression.accept(IrCompileTimeChecker(declaration, mode = EvaluationMode.ONLY_BUILTINS), null)) { + if (isConst && expression.accept(IrCompileTimeChecker(declaration, mode), null)) { initializer.expression = interpreter.interpret(expression, irFile).replaceIfError(expression) } @@ -89,7 +85,7 @@ class IrConstTransformer(private val interpreter: IrInterpreter, private val irF } private fun IrExpression.transformSingleArg(expectedType: IrType): IrExpression { - if (this.accept(IrCompileTimeChecker(mode = EvaluationMode.ONLY_BUILTINS), null)) { + if (this.accept(IrCompileTimeChecker(mode = mode), null)) { val const = interpreter.interpret(this, irFile).replaceIfError(this) return const.convertToConstIfPossible(expectedType) } else if (this is IrConstructorCall) { @@ -106,4 +102,4 @@ class IrConstTransformer(private val interpreter: IrInterpreter, private val irF else -> this.value.toIrConst(type, this.startOffset, this.endOffset) } } -} +} \ No newline at end of file