Add lowering that will evaluate all intrinsic const expressions
This commit is contained in:
@@ -15,7 +15,6 @@ import org.jetbrains.kotlin.config.AnalysisFlags
|
|||||||
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
import org.jetbrains.kotlin.config.LanguageVersionSettings
|
||||||
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
import org.jetbrains.kotlin.descriptors.ModuleDescriptor
|
||||||
import org.jetbrains.kotlin.fir.FirSession
|
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.*
|
||||||
import org.jetbrains.kotlin.fir.backend.generators.DataClassMembersGenerator
|
import org.jetbrains.kotlin.fir.backend.generators.DataClassMembersGenerator
|
||||||
import org.jetbrains.kotlin.fir.declarations.*
|
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.*
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
import org.jetbrains.kotlin.ir.declarations.impl.IrFileImpl
|
||||||
import org.jetbrains.kotlin.ir.declarations.impl.IrModuleFragmentImpl
|
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.linkage.IrDeserializer
|
||||||
import org.jetbrains.kotlin.ir.symbols.*
|
import org.jetbrains.kotlin.ir.symbols.*
|
||||||
import org.jetbrains.kotlin.ir.util.*
|
import org.jetbrains.kotlin.ir.util.*
|
||||||
@@ -424,6 +426,13 @@ class Fir2IrConverter(
|
|||||||
}
|
}
|
||||||
|
|
||||||
companion object {
|
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)
|
@OptIn(ObsoleteDescriptorBasedAPI::class)
|
||||||
fun createModuleFragment(
|
fun createModuleFragment(
|
||||||
session: FirSession,
|
session: FirSession,
|
||||||
|
|||||||
+29
@@ -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)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
@@ -407,6 +407,7 @@ private fun buildJvmLoweringPhases(
|
|||||||
validateIrBeforeLowering then
|
validateIrBeforeLowering then
|
||||||
processOptionalAnnotationsPhase then
|
processOptionalAnnotationsPhase then
|
||||||
expectDeclarationsRemovingPhase then
|
expectDeclarationsRemovingPhase then
|
||||||
|
constEvaluationPhase then
|
||||||
serializeIrPhase then
|
serializeIrPhase then
|
||||||
scriptsToClassesPhase then
|
scriptsToClassesPhase then
|
||||||
fileClassPhase then
|
fileClassPhase then
|
||||||
|
|||||||
+13
-17
@@ -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.
|
* 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.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.*
|
||||||
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
import org.jetbrains.kotlin.ir.expressions.impl.IrVarargImpl
|
||||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||||
import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode
|
import org.jetbrains.kotlin.ir.interpreter.isPrimitiveArray
|
||||||
import org.jetbrains.kotlin.ir.interpreter.checker.IrCompileTimeChecker
|
|
||||||
import org.jetbrains.kotlin.ir.interpreter.toIrConst
|
import org.jetbrains.kotlin.ir.interpreter.toIrConst
|
||||||
import org.jetbrains.kotlin.ir.types.*
|
import org.jetbrains.kotlin.ir.types.*
|
||||||
import org.jetbrains.kotlin.ir.util.isPrimitiveArray
|
|
||||||
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
|
||||||
|
|
||||||
fun evaluateConstants(irModuleFragment: IrModuleFragment) {
|
class IrConstTransformer(
|
||||||
val interpreter = IrInterpreter(irModuleFragment.irBuiltins)
|
private val interpreter: IrInterpreter, private val irFile: IrFile, private val mode: EvaluationMode
|
||||||
irModuleFragment.files.forEach { it.transformChildren(IrConstTransformer(interpreter, it), null) }
|
) : IrElementTransformerVoid() {
|
||||||
}
|
|
||||||
|
|
||||||
//TODO create abstract class that will be common for this and lowering
|
|
||||||
class IrConstTransformer(private val interpreter: IrInterpreter, private val irFile: IrFile) : IrElementTransformerVoid() {
|
|
||||||
|
|
||||||
private fun IrExpression.replaceIfError(original: IrExpression): IrExpression {
|
private fun IrExpression.replaceIfError(original: IrExpression): IrExpression {
|
||||||
return if (this !is IrErrorExpression) this else original
|
return if (this !is IrErrorExpression) this else original
|
||||||
}
|
}
|
||||||
|
|
||||||
override fun visitCall(expression: IrCall): IrExpression {
|
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 interpreter.interpret(expression, irFile).replaceIfError(expression)
|
||||||
}
|
}
|
||||||
return super.visitCall(expression)
|
return super.visitCall(expression)
|
||||||
@@ -43,7 +39,7 @@ class IrConstTransformer(private val interpreter: IrInterpreter, private val irF
|
|||||||
val expression = initializer?.expression ?: return declaration
|
val expression = initializer?.expression ?: return declaration
|
||||||
if (expression is IrConst<*>) return declaration
|
if (expression is IrConst<*>) return declaration
|
||||||
val isConst = declaration.correspondingPropertySymbol?.owner?.isConst == true
|
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)
|
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 {
|
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)
|
val const = interpreter.interpret(this, irFile).replaceIfError(this)
|
||||||
return const.convertToConstIfPossible(expectedType)
|
return const.convertToConstIfPossible(expectedType)
|
||||||
} else if (this is IrConstructorCall) {
|
} else if (this is IrConstructorCall) {
|
||||||
Reference in New Issue
Block a user