It was only used as a superclass in IrInlineReferenceLocator and
LocalDeclarationsLowering. In both cases it's clearer and more optimal
to pass the necessary data via the visitor 'data' variable.
NB some cases such as captured extension receiver for an extension
lambda are not supported yet; to be discussed, to what extent should we
actually follow JVM code shape here.
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.
Implement no-op acceptChildren/transformChildren in the base class
IrExpressionBase instead. This doesn't change behavior because all other
implementations of acceptChildren/transformChildren are not affected.
Do not store these as properties in IrElementBase, IrExpressionBase and
similar classes. This helps to reduce boilerplate in implementations
(just "override val" in the constructor, instead of taking a parameter
and passing it to the superclass), and also slightly optimizes memory in
cases where the value is trivial (UNDEFINED_OFFSET, 0, etc) and thus
does not need to be stored.
For IrProperty, IrSimpleFunction we need to pass information about
original declaration to JVM_IR codegen. Instead of descriptors, use
the attributeOwnerId field.
The main purpose of this class is to improve performance of IR visitors
and transformers. `IrElementVisitor.visitDeclaration` now takes
IrDeclarationBase as a parameter, and therefore the call to `accept`
there is now a virtual class call, instead of an interface call.