IR: optimize transformation of declarations/statements lists in-place

Also, inherit IrDeclarationBase from IrElementBase to be able to use a
cast to IrElementBase, which is faster than a cast to IrElement or
IrDeclaration.
This commit is contained in:
Alexander Udalov
2020-08-03 21:38:28 +02:00
parent 4f0585950e
commit fb8e39a621
9 changed files with 29 additions and 18 deletions
@@ -579,7 +579,7 @@ internal class IterableLoopHeader(
loopVariable: IrVariable?,
loopVariableComponents: Map<Int, IrVariable>,
builder: DeclarationIrBuilder
) =
): List<IrStatement> =
with(builder) {
// loopVariable = iteratorVar.next()
val iteratorClass = headerInfo.iteratorVariable.type.getClass()!!
@@ -386,7 +386,7 @@ private fun replaceCallToDefaultPrimary(context: JsIrBackendContext, constructor
val thisSymbol = (((constructor.body as IrBlockBody).statements
.find { it is IrVariable && it.origin === ES6_THIS_VARIABLE_ORIGIN }) as IrVariable?)?.symbol ?: return
(constructor.body as IrBlockBody).statements.transform {
(constructor.body as IrBlockBody).statements.transformInPlace {
if (it is IrDelegatingConstructorCall) {
val superCtor = it.symbol.owner
val initFunc = context.mapping.constructorToInitFunction[superCtor]!!
@@ -501,7 +501,7 @@ private class LowerCtorHelper(
origin = ES6_THIS_VARIABLE_ORIGIN
}
(constructor.body as IrBlockBody).statements.transform {
(constructor.body as IrBlockBody).statements.transformInPlace {
if (it === superCall) newThis
else it
}
@@ -561,7 +561,7 @@ private fun changeIrConstructorToIrFunction(context: JsIrBackendContext, contain
}, null)
}
container.parentAsClass.declarations.transform {
container.parentAsClass.declarations.transformInPlace {
if (it === container) newConstructor else it
}
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.ir.declarations.IrVariable
import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.impl.IrConstructorCallImpl
import org.jetbrains.kotlin.ir.expressions.impl.IrGetValueImpl
import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.util.transformInPlace
internal val anonymousObjectSuperConstructorPhase = makeIrFilePhase(
::AnonymousObjectSuperConstructorLowering,
@@ -91,7 +91,7 @@ private class AnonymousObjectSuperConstructorLowering(val context: JvmBackendCon
}
}
objectConstructorBody.statements.transform {
objectConstructorBody.statements.transformInPlace {
when {
it is IrDelegatingConstructorCall -> it.transform(listOf())
it is IrBlock && it.origin == IrStatementOrigin.ARGUMENTS_REORDERING_FOR_CALL && it.statements.last() is IrDelegatingConstructorCall ->
@@ -61,7 +61,7 @@ private class InheritedDefaultMethodsOnClassesLowering(val context: JvmBackendCo
}
private fun generateInterfaceMethods(irClass: IrClass) {
irClass.declarations.transform { declaration ->
irClass.declarations.transformInPlace { declaration ->
(declaration as? IrSimpleFunction)?.findInterfaceImplementation(context.state.jvmDefaultMode)?.let { implementation ->
generateDelegationToDefaultImpl(implementation, declaration)
} ?: declaration
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.descriptors.SourceElement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.util.transformInPlace
import org.jetbrains.kotlin.ir.util.transformIfNeeded
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -63,7 +63,7 @@ abstract class IrClass :
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
thisReceiver = thisReceiver?.transform(transformer, data)
typeParameters = typeParameters.transformIfNeeded(transformer, data)
declarations.transform { it.transform(transformer, data) }
declarations.transformInPlace(transformer, data)
}
}
@@ -20,6 +20,7 @@ import org.jetbrains.kotlin.descriptors.DeclarationDescriptor
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.descriptors.Visibility
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.symbols.IrSymbol
@@ -45,7 +46,7 @@ interface IrDeclaration : IrStatement, IrMutableAnnotationContainer {
val factory: IrFactory
}
abstract class IrDeclarationBase : IrDeclaration {
abstract class IrDeclarationBase : IrElementBase(), IrDeclaration {
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrStatement =
accept(transformer, data) as IrStatement
}
@@ -12,7 +12,7 @@ import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.symbols.IrScriptSymbol
import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.util.transformInPlace
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name
@@ -65,8 +65,8 @@ class IrScriptImpl(
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
declarations.transform { it.transform(transformer, data) }
statements.transform { it.transform(transformer, data) }
declarations.transformInPlace(transformer, data)
statements.transformInPlace(transformer, data)
thisReceiver = thisReceiver.transform(transformer, data)
}
}
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.ir.symbols.IrFileSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrReturnableBlockSymbol
import org.jetbrains.kotlin.ir.util.file
import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.util.transformInPlace
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
@@ -38,7 +38,7 @@ abstract class IrContainerExpression : IrExpression(), IrStatementContainer {
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
statements.transform { it.transform(transformer, data) }
statements.transformInPlace(transformer, data)
}
}
@@ -58,5 +58,6 @@ abstract class IrReturnableBlock : IrBlock(), IrSymbolOwner, IrReturnTarget {
abstract val inlineFunctionSymbol: IrFunctionSymbol?
}
@Suppress("unused") // Used in kotlin-native
val IrReturnableBlock.sourceFileSymbol: IrFileSymbol?
get() = inlineFunctionSymbol?.owner?.file?.symbol
@@ -17,13 +17,22 @@
package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.IrElementBase
import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
inline fun <reified T : IrElement> MutableList<T>.transform(transformation: (T) -> IrElement) {
forEachIndexed { i, item ->
set(i, transformation(item) as T)
inline fun <reified T : IrElement> MutableList<T>.transformInPlace(transformation: (T) -> IrElement) {
for (i in 0 until size) {
set(i, transformation(get(i)) as T)
}
}
fun <T : IrElement, D> MutableList<T>.transformInPlace(transformer: IrElementTransformer<D>, data: D) {
for (i in 0 until size) {
// Cast to IrElementBase to avoid casting to interface and invokeinterface, both of which are slow.
@Suppress("UNCHECKED_CAST")
set(i, (get(i) as IrElementBase).transform(transformer, data) as T)
}
}