Is there a way to evaluate expression to constant ...
# compiler
c
Is there a way to evaluate expression to constant value in IR? There is a
ConstantExpressionEvaluator
in the frontend. Is there something similar in the backend?
r
IrConst.value
? Is what you're trying to access not an
IrConst
?
c
I mean evaluate an expression as a constant. frontend automatically evaluates possible
CompileTimeValue
calls to an expression as constant
Copy code
val a = "abc"
val b = a + ".bb"
the example above will be automatically evaluated as
<http://abc.bb|abc.bb>
I want to know is that possible in IR? If not, I might look at sharing between frontend and IR, maybe fileEntry and startOffset/endOffset as identifiers
y
I don't quite think it's possible right now, but I did need something similar in a plugin, so I did this: (lines 100 to 200 roughly) It only performs simple checks for equality of constants and enums. I believe in your case that would inline "most" of it. I think the "abc" surely will be inlined into b so b would be
"abc" + ".bb"
, but then you need an extra check to inline an IrConcat into one string if all of its arguments are IrConst
c
@Youssef Shoaib [MOD] Cool! Another great solution, thanks for your code! I am currently analyzing and evaluating the expression as constant through the frontend, then recording the constant according to the offset of the expression, and then replacing the expression as constant according to the offset in the IR, maybe I will try to solve it your way 👍 btw, it seems like a fun project!
y
That's really really clever! I might legitimately try that myself. I'd say be a little bit careful though since you gotta play nice with other compiler plugins, and who knows what they could do, and so the link between frontend and backend could sometimes be broken. A good tip, however, is that you can register your plugin to be the first one used, thus guaranteeing that the frontend represents the backend. In fact, your solution actually is perfect for any user-written code (or just any code that you have a front-end representation for). For IR-only code it is a bit more complex which is why my solution isn't comprehensive enough, but oh well it works for most of what I need it to (which is just cutting down compilation times)
Thank you! It really is a fun project. On the surface it seems a bit small or insignificant, but my ultimate vision for it is to straight up have struct-like objects in kotlin at no over-head, amongst other nicities, and I'm getting really close to that. Take a look at KT-44530 if you're interested in the use cases that the plugin opens up
K 1
c
Thanks for reminding me! Indeed, my solution might run into problems if some compiler modifies the AST structure before the backend😢...registering plugin first may not be the best approach, so maybe I need to do all of this with IR
d
There is an IR interpreter in developent in compiler itself. Besides it is WIP it already works for most kotlin expressions and you can try to use it https://github.com/JetBrains/kotlin/blob/master/compiler/ir/ir.interpreter/src/org/jetbrains/kotlin/ir/interpreter/IrInterpreter.kt
c
@dmitriy.novozhilov Amazing! I see the only
interpret
method in this class and there is a
IrConstTransfomer
. Can you briefly summarize what they will do? I will be grateful!
d
interpret
gets some expression and evaluates it to some constant expression if it can Assume following code:
Copy code
fun pow(x: Int, p: Int): Int {
    var res = 1
    for (_ in 1..p) {
        res *= x
    }
    return res
}

fun test() {
    val x = pow(2, 10) // (1)
}
If you pass
IrCall
for
pow(2, 10)
it will return
IrConstExpression(1024)
It's better to ask
@Ivan Kylchik
for specific details
c
It even supports evaluating complex functions?! It’s exciting. I’m going to try it now and hope it can solve my needs
👌 1
r
Very interesting, could this be used for scripting eventually?
d
Never thought about it. IMO current scripting scheme is better than adding another level of virtualization (IR intermereter "VM") above JVM which runs kotlin compiler
y
@dmitriy.novozhilov Oh nice! I had no idea that this existed! This could actually simplify things a lottt for a plugin I'm writing. Does it handle lambdas in inline functions per chance? Or at the very least, will it eventually? Because currently sure FunctionInlining is a thing but it's kinda not made for the JVM and you need a Backend Context which is usually a no-go. Looking around the file it seems like it handles Sam conversions and other things, but I'm not sure whether it would inline a function.
d
It's better to ask @Ivan Kylchik  for specific details
😁 1
i
Yes, it can evaluate lambdas in inline function. But it is not fully tested for now and there can be bugs. If you find one you can create a ticket or write me directly.
🙏 1