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
@@ -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)
}
}