[JVM IR] Drop ConstLowering

It basically can be replaced with IR interpreter. The only half-hack
was required in `PropertyReferenceLowering`. Const interpreter is
running before it, so we can't optimize some calls on const
properties that appear after this lowering. Solution is to inline
constants manually during property reference lowering.
This commit is contained in:
Ivan Kylchik
2023-06-15 17:15:07 +02:00
committed by Space Team
parent 1bf3bde4f8
commit d1a54a522d
7 changed files with 84 additions and 51 deletions
@@ -0,0 +1,69 @@
/*
* Copyright 2010-2023 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.ir.interpreter.preprocessor
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin
import org.jetbrains.kotlin.ir.declarations.IrField
import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetObjectValueImpl
import org.jetbrains.kotlin.ir.types.classOrFail
class IrInterpreterConstGetterPreprocessor : IrInterpreterPreprocessor {
override fun visitFunction(declaration: IrFunction, data: IrInterpreterPreprocessorData): IrStatement {
// It is useless to visit default accessor, we probably want to leave code there as it is
if (declaration.origin == IrDeclarationOrigin.DEFAULT_PROPERTY_ACCESSOR) return declaration
return super.visitFunction(declaration, data)
}
override fun visitCall(expression: IrCall, data: IrInterpreterPreprocessorData): IrElement {
val function = (expression.symbol.owner as? IrSimpleFunction) ?: return super.visitCall(expression, data)
val field = function.correspondingPropertySymbol?.owner?.backingField ?: return super.visitCall(expression, data)
return expression.lowerConstRead(field, data) ?: super.visitCall(expression, data)
}
override fun visitGetField(expression: IrGetField, data: IrInterpreterPreprocessorData): IrExpression {
return expression.lowerConstRead(expression.symbol.owner, data) ?: super.visitGetField(expression, data)
}
private fun IrExpression.lowerConstRead(field: IrField, data: IrInterpreterPreprocessorData): IrExpression? {
val receiver = when (this) {
is IrCall -> dispatchReceiver
is IrGetField -> receiver
else -> return null
}
if (receiver == null || !field.hasConstantValue()) return null
transformChildren(this@IrInterpreterConstGetterPreprocessor, data)
val getObject = IrGetObjectValueImpl(UNDEFINED_OFFSET, UNDEFINED_OFFSET, receiver.type, receiver.type.classOrFail)
when (this) {
is IrCall -> this.dispatchReceiver = getObject
is IrGetField -> this.receiver = getObject
}
return if (receiver.shouldDropConstReceiver()) {
this
} else {
IrCompositeImpl(startOffset, endOffset, this.type, null, listOf(receiver, this))
}
}
private fun IrExpression.shouldDropConstReceiver(): Boolean {
return this is IrGetValue || this is IrGetObjectValue
}
fun IrField.hasConstantValue(): Boolean {
val implicitConst = isFinal && isStatic && origin == IrDeclarationOrigin.IR_EXTERNAL_JAVA_DECLARATION_STUB && initializer != null
return implicitConst || correspondingPropertySymbol?.owner?.isConst == true
}
}
@@ -5,7 +5,6 @@
package org.jetbrains.kotlin.ir.interpreter.preprocessor
import org.jetbrains.kotlin.builtins.StandardNames
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrClass
@@ -18,7 +17,6 @@ import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl
import org.jetbrains.kotlin.ir.interpreter.property
import org.jetbrains.kotlin.ir.types.IrSimpleType
import org.jetbrains.kotlin.ir.types.classFqName
import org.jetbrains.kotlin.ir.types.typeOrNull
import org.jetbrains.kotlin.ir.types.typeWith
import org.jetbrains.kotlin.ir.util.isKFunction
@@ -15,6 +15,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration
import org.jetbrains.kotlin.ir.interpreter.checker.*
import org.jetbrains.kotlin.ir.interpreter.preprocessor.IrInterpreterConstGetterPreprocessor
import org.jetbrains.kotlin.ir.interpreter.preprocessor.IrInterpreterKCallableNamePreprocessor
import org.jetbrains.kotlin.ir.interpreter.preprocessor.IrInterpreterPreprocessorData
import org.jetbrains.kotlin.ir.interpreter.property
@@ -72,7 +73,7 @@ fun IrFile.preprocessForConstTransformer(
interpreter: IrInterpreter,
mode: EvaluationMode,
): IrFile {
val preprocessors = setOf(IrInterpreterKCallableNamePreprocessor())
val preprocessors = setOf(IrInterpreterKCallableNamePreprocessor(), IrInterpreterConstGetterPreprocessor())
val preprocessedFile = preprocessors.fold(this) { file, preprocessor ->
preprocessor.preprocess(file, IrInterpreterPreprocessorData(mode, interpreter.irBuiltIns))
}