[FIR2IR] Don't run interpreter's preprocessors on fir2ir stage
In IR interpreter we have "preprocessors". Preprocessor is a transformer that changes IR expressions in a way that we can interpret them at least partially. We have two places where interpretation is happening: 1. Right after fir2ir where we evaluate only strictly necessary expression for `const val` and annotations. 2. In lowering for every backend where we are doing some constant folding. Earlier, to avoid double work, we didn't launch preprocessors in backend if we were using K2. But this approach breaks compilation for MPP projects where one module is compiled with K1 into klib and the overall project is compiled with K2. On the backend side, we are mistakenly assuming that preprocessors were launched, but they were not. The solution is to run preprocessors only on the backend side. If we think about it, interpretation on fir2ir doesn't require any preprocessing because we are working only with expressions that are correct and must be fully evaluated. #KT-62126 Fixed
This commit is contained in:
+1
-6
@@ -13,7 +13,6 @@ import org.jetbrains.kotlin.ir.interpreter.IrInterpreter
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterConfiguration
|
||||
import org.jetbrains.kotlin.ir.interpreter.IrInterpreterEnvironment
|
||||
import org.jetbrains.kotlin.ir.interpreter.checker.EvaluationMode
|
||||
import org.jetbrains.kotlin.ir.interpreter.transformer.preprocessForConstTransformer
|
||||
import org.jetbrains.kotlin.ir.interpreter.transformer.runConstOptimizations
|
||||
|
||||
class ConstEvaluationLowering(
|
||||
@@ -27,11 +26,7 @@ class ConstEvaluationLowering(
|
||||
private val mode = EvaluationMode.ONLY_INTRINSIC_CONST
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
val useFir = context.configuration[CommonConfigurationKeys.USE_FIR] == true
|
||||
val preprocessedFile = if (useFir) irFile else irFile.preprocessForConstTransformer(interpreter, mode)
|
||||
preprocessedFile.runConstOptimizations(
|
||||
interpreter, mode, evaluatedConstTracker, inlineConstTracker, suppressErrors
|
||||
)
|
||||
irFile.runConstOptimizations(interpreter, mode, evaluatedConstTracker, inlineConstTracker, suppressErrors)
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
+13
-11
@@ -40,23 +40,21 @@ fun IrFile.transformConst(
|
||||
onError: (IrFile, IrElement, IrErrorExpression) -> Unit = { _, _, _ -> },
|
||||
suppressExceptions: Boolean = false,
|
||||
) {
|
||||
val preprocessedFile = this.preprocessForConstTransformer(interpreter, mode)
|
||||
|
||||
val checker = IrInterpreterCommonChecker()
|
||||
val irConstExpressionTransformer = IrConstOnlyNecessaryTransformer(
|
||||
interpreter, preprocessedFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
|
||||
interpreter, this, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
|
||||
)
|
||||
preprocessedFile.transform(irConstExpressionTransformer, IrConstTransformer.Data())
|
||||
this.transform(irConstExpressionTransformer, IrConstTransformer.Data())
|
||||
|
||||
val irConstDeclarationAnnotationTransformer = IrConstDeclarationAnnotationTransformer(
|
||||
interpreter, preprocessedFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
|
||||
interpreter, this, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
|
||||
)
|
||||
preprocessedFile.transform(irConstDeclarationAnnotationTransformer, IrConstTransformer.Data())
|
||||
this.transform(irConstDeclarationAnnotationTransformer, IrConstTransformer.Data())
|
||||
|
||||
val irConstTypeAnnotationTransformer = IrConstTypeAnnotationTransformer(
|
||||
interpreter, preprocessedFile, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
|
||||
interpreter, this, mode, checker, evaluatedConstTracker, inlineConstTracker, onWarning, onError, suppressExceptions
|
||||
)
|
||||
preprocessedFile.transform(irConstTypeAnnotationTransformer, IrConstTransformer.Data())
|
||||
this.transform(irConstTypeAnnotationTransformer, IrConstTransformer.Data())
|
||||
}
|
||||
|
||||
fun IrFile.runConstOptimizations(
|
||||
@@ -66,14 +64,18 @@ fun IrFile.runConstOptimizations(
|
||||
inlineConstTracker: InlineConstTracker? = null,
|
||||
suppressExceptions: Boolean = false,
|
||||
) {
|
||||
val preprocessedFile = this.preprocessForConstTransformer(interpreter, mode)
|
||||
|
||||
val checker = IrInterpreterCommonChecker()
|
||||
val irConstExpressionTransformer = IrConstAllTransformer(
|
||||
interpreter, this, mode, checker, evaluatedConstTracker, inlineConstTracker, { _, _, _ -> }, { _, _, _ -> }, suppressExceptions
|
||||
interpreter, preprocessedFile, mode, checker, evaluatedConstTracker, inlineConstTracker,
|
||||
{ _, _, _ -> }, { _, _, _ -> },
|
||||
suppressExceptions
|
||||
)
|
||||
this.transform(irConstExpressionTransformer, IrConstTransformer.Data())
|
||||
preprocessedFile.transform(irConstExpressionTransformer, IrConstTransformer.Data())
|
||||
}
|
||||
|
||||
fun IrFile.preprocessForConstTransformer(
|
||||
private fun IrFile.preprocessForConstTransformer(
|
||||
interpreter: IrInterpreter,
|
||||
mode: EvaluationMode,
|
||||
): IrFile {
|
||||
|
||||
Vendored
+10
@@ -0,0 +1,10 @@
|
||||
package lib
|
||||
|
||||
public class Plot {
|
||||
public val layout: Int = 0
|
||||
}
|
||||
|
||||
public fun plotFun(plot: Plot): String {
|
||||
val mustBeOptimizedByCompiler = plot::layout.name
|
||||
return mustBeOptimizedByCompiler
|
||||
}
|
||||
Vendored
+4
@@ -0,0 +1,4 @@
|
||||
info: produce executable: $TMP_DIR$/usage.js
|
||||
info: cache directory: null
|
||||
info: executable production duration: [time]
|
||||
OK
|
||||
Vendored
+8
@@ -712,6 +712,14 @@ abstract class AbstractCompileKotlinAgainstCustomBinariesTest : AbstractKotlinCo
|
||||
output.lines().filterNot { "argument -Xexpect-actual-linker is deprecated" in it }.joinToString("\n")
|
||||
}
|
||||
|
||||
fun testConstEvaluationWithDifferentLV() {
|
||||
val library = compileJsLibrary("library", additionalOptions = listOf("-language-version", "1.9"))
|
||||
compileKotlin(
|
||||
"src", File(tmpdir, "usage.js"), emptyList(), K2JSCompiler(),
|
||||
additionalOptions = listOf("-Xinclude=${library.absolutePath}", "-Xir-produce-js"),
|
||||
)
|
||||
}
|
||||
|
||||
private fun doTestAnonymousObjectTypeMetadata(
|
||||
extraCommandLineArguments: List<String> = emptyList(),
|
||||
filterOutput: (String) -> String = { output -> output }
|
||||
|
||||
Reference in New Issue
Block a user