Youssef Shoaib [MOD]
05/08/2021, 7:49 PMudalov
Youssef Shoaib [MOD]
05/11/2021, 7:54 PMconstexpr
feature is actually incredibly promising because it'll add a lot of the things I possibly stumbled with directly to the compiler (namely the inlining bit but also deserialising specific portions of IR). I do wonder, though, how the serialised IR will be stored inside a .class
file, because I figured you would go for a similar approach to JS and Native and store it inside of the jar
itself instead (maybe as a sibling file to the .class
file). Is there any possibility that you could distribute JVM jars that include everything as IR, including non-inline functions? or would that be too much of an overhead on library size?
constexpr
can even work for my "inlining returned lambdas" use case in some scenarios, but usually in most scenarios more complex logic is required that, quite aptly, isn't `const`ant. I wonder if that'll make that use case easier though (and solve some oddities like having an IrBlock
around an IrFunctionExpression
causing it not to be inlined for whatever reason). I guess only time will tell.
I thought, btw, that you do technically have access to the dependencies of other modules because they are on your module's classpath because like for example if a library uses another library as implementation
in Gradle, that other library is still on your classpath (I think), but maybe its only exposed if its api
.
A strong reason for supporting it is clearly `constexpr`s, but also, IIRC, some optimisations are IR specific and aren't applied to JVM bytecode, and so by inlining IR you could possibly get more optimisations for free.udalov
I do wonder, though, how the serialised IR will be stored inside a .class fileIn the current prototype, it’s serialized via protobuf, converted to modified UTF-8 and stored inside an annotation on the class file.
Is there any possibility that you could distribute JVM jars that include everything as IR, including non-inline functions? or would that be too much of an overhead on library size?Currently we don’t have plans for this, mostly because we don’t have enough use cases in the compiler itself, and indeed the overhead would be large. Those use cases may appear in the future though, mostly in the multiplatform support.
I thought, btw, that you do technically have access to the dependencies of other modules because they are on your module’s classpath because like for example if a library uses another library as implementation in Gradle, that other library is still on your classpath (I think), but maybe its only exposed if its api.The implementation dependency is used precisely if you need to use something, for example, in a function body (not in the signature), yet your clients may know nothing about it. Such dependency is not carried transitively to your clients. The problem is that with current Kotlin and bytecode inliner, you can have a public inline function which references something from an implementation dependency, and it will get inlined correctly at call sites in other modules. With IR this won’t work out of the box, because the IR still needs to be lowered at a call site, and for that we need to know a lot about the declarations referenced in the inline function body (whether they are declared in Kotlin or Java, which annotations they have, etc).
A strong reason for supporting it is clearly constexprs, but also, IIRC, some optimisations are IR specific and aren’t applied to JVM bytecode, and so by inlining IR you could possibly get more optimisations for free.Yeah, those are our main candidates so far as well. We managed to achieve a lot already with the bytecode inliner and post-processing transformations, but some things, like potential ideas of loop fusion optimizations or some advanced elimination of unnecessary boxing/unboxing, are just extremely cumbersome to do on the bytecode.