Report the input module name and size once before any measurements
instead of duplicating it in all of them. Also, render measurements in a
table to improve readability.
Before:
info: PERF: INIT: Compiler initialized in 467 ms
info: PERF: ANALYZE: 1 files (2 lines) target main-java-production in 277 ms - 7.220 loc/s
info: PERF: IR: Translation 1 files (2 lines) target main-java-production in 291 ms - 6.873 loc/s
info: PERF: GENERATE: 1 files (2 lines) target main-java-production in 513 ms - 3.899 loc/s
info: PERF: IR: Generation 1 files (2 lines) target main-java-production in 142 ms - 14.085 loc/s
After:
info: PERF: main-java-production, 1 files (2 lines)
info: PERF: INIT: Compiler initialized in 421 ms
info: PERF: ANALYZE 342 ms 5.848 loc/s
info: PERF: IR TRANSLATION 296 ms 6.757 loc/s
info: PERF: GENERATE 453 ms 4.415 loc/s
info: PERF: IR GENERATION 137 ms 14.599 loc/s
In JVM IR, both `valueParameters` and `isFromJavaOrBuiltins` take
noticeable time (1% of all compilation) because the logic for these in
IrBasedDescriptors is not trivial.
This takes BridgeLowering time percentage from 1.3% to 1.0% of all
compiler time on a sample project, perhaps due to better data locality.
In addition, it simplifies stack traces by effectively merging all
bridge generation call sites into one, helping in future performance
investigations.
First of all, put method signature caches of BridgeLowering into
JvmBackendContext. Since method hierarchies can span several files, and
a new instance of BridgeLowering is created to lower each file, keeping
them cached for the whole module makes BridgeLowering faster.
Also, do not attempt to compute special bridges if the method is
irrelevant, which can be deduced by its name. With this optimization,
the special method cache is no longer needed.
This brings BridgeLowering time from 3.8% down to 1.5% of all compiler
time on a sample project.
Default implementation of `IrStatement.transform` contained a cast to
`IrStatement`. Since almost all IR elements inherit from IrStatement,
this implementation was used in many subclasses. However, checkcast to
interface is slow and this place was indeed noticeable in the profiler
snapshot. Since not that many places really expected to get IrStatement
out of IrStatement.transform, introduce a new method
`transformStatement` that does this cast, and use it in all those
places. Meanwhile, most implementations will use the IrElement's
implementation of `transform` which merely invokes `accept` without
casts.
Also, inherit IrDeclarationBase from IrElementBase to be able to use a
cast to IrElementBase, which is faster than a cast to IrElement or
IrDeclaration.
IrElementTransformer.visitDeclaration/visitExpression are very prominent
hotspots, and it seems that HotSpot doesn't optimize the inlined Kotlin
bytecode there well enough. Reduce the bytecode in these and similar
methods by inlining calls to also/apply/transformChildrenVoid.