IR: make mapOptimized non-inline, rename to transformIfNeeded

This seems to have no effect on performance, however it clearly shows
that this method is a hotspot now with regard to own CPU samples.
Furthermore, it somewhat decreases the bytecode size at call sites and
might actually allow the HotSpot to inline those methods earlier and
hopefully deoptimize less frequently.
This commit is contained in:
Alexander Udalov
2020-06-22 22:53:42 +02:00
parent 6a699c9384
commit ccac23f5b2
10 changed files with 33 additions and 31 deletions
@@ -6,8 +6,9 @@
package org.jetbrains.kotlin.fir.lazy package org.jetbrains.kotlin.fir.lazy
import org.jetbrains.kotlin.descriptors.* import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.fir.backend.* import org.jetbrains.kotlin.fir.backend.Fir2IrComponents
import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter import org.jetbrains.kotlin.fir.backend.declareThisReceiverParameter
import org.jetbrains.kotlin.fir.backend.toIrType
import org.jetbrains.kotlin.fir.declarations.* import org.jetbrains.kotlin.fir.declarations.*
import org.jetbrains.kotlin.fir.resolve.buildUseSiteMemberScope import org.jetbrains.kotlin.fir.resolve.buildUseSiteMemberScope
import org.jetbrains.kotlin.fir.symbols.Fir2IrClassSymbol import org.jetbrains.kotlin.fir.symbols.Fir2IrClassSymbol
@@ -19,8 +20,8 @@ import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl import org.jetbrains.kotlin.ir.types.impl.IrSimpleTypeImpl
import org.jetbrains.kotlin.ir.util.mapOptimized
import org.jetbrains.kotlin.ir.util.transform import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.util.transformIfNeeded
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -190,7 +191,7 @@ class Fir2IrLazyClass(
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) { override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
thisReceiver = thisReceiver?.transform(transformer, data) thisReceiver = thisReceiver?.transform(transformer, data)
typeParameters = typeParameters.mapOptimized { it.transform(transformer, data) } typeParameters = typeParameters.transformIfNeeded(transformer, data)
declarations.transform { it.transform(transformer, data) } declarations.transform { it.transform(transformer, data) }
} }
} }
@@ -20,8 +20,8 @@ import org.jetbrains.kotlin.ir.declarations.IrValueParameter
import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar import org.jetbrains.kotlin.ir.declarations.lazy.lazyVar
import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.mapOptimized
import org.jetbrains.kotlin.ir.util.parentClassOrNull import org.jetbrains.kotlin.ir.util.parentClassOrNull
import org.jetbrains.kotlin.ir.util.transformIfNeeded
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -125,11 +125,11 @@ class Fir2IrLazyConstructor(
} }
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) { override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
typeParameters = typeParameters.mapOptimized { it.transform(transformer, data) } typeParameters = typeParameters.transformIfNeeded(transformer, data)
dispatchReceiverParameter = dispatchReceiverParameter?.transform(transformer, data) dispatchReceiverParameter = dispatchReceiverParameter?.transform(transformer, data)
extensionReceiverParameter = extensionReceiverParameter?.transform(transformer, data) extensionReceiverParameter = extensionReceiverParameter?.transform(transformer, data)
valueParameters = valueParameters.mapOptimized { it.transform(transformer, data) } valueParameters = valueParameters.transformIfNeeded(transformer, data)
body = body?.transform(transformer, data) body = body?.transform(transformer, data)
} }
@@ -21,7 +21,7 @@ import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.mapOptimized import org.jetbrains.kotlin.ir.util.transformIfNeeded
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -147,11 +147,11 @@ class Fir2IrLazySimpleFunction(
} }
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) { override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
typeParameters = typeParameters.mapOptimized { it.transform(transformer, data) } typeParameters = typeParameters.transformIfNeeded(transformer, data)
dispatchReceiverParameter = dispatchReceiverParameter?.transform(transformer, data) dispatchReceiverParameter = dispatchReceiverParameter?.transform(transformer, data)
extensionReceiverParameter = extensionReceiverParameter?.transform(transformer, data) extensionReceiverParameter = extensionReceiverParameter?.transform(transformer, data)
valueParameters = valueParameters.mapOptimized { it.transform(transformer, data) } valueParameters = valueParameters.transformIfNeeded(transformer, data)
body = body?.transform(transformer, data) body = body?.transform(transformer, data)
} }
@@ -23,7 +23,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.carriers.ClassCarrier
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.transform import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.util.mapOptimized import org.jetbrains.kotlin.ir.util.transformIfNeeded
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -177,7 +177,7 @@ class IrClassImpl(
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) { override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
thisReceiver = thisReceiver?.transform(transformer, data) thisReceiver = thisReceiver?.transform(transformer, data)
typeParameters = typeParameters.mapOptimized { it.transform(transformer, data) } typeParameters = typeParameters.transformIfNeeded(transformer, data)
declarations.transform { it.transform(transformer, data) } declarations.transform { it.transform(transformer, data) }
} }
} }
@@ -22,7 +22,7 @@ import org.jetbrains.kotlin.ir.declarations.impl.carriers.FunctionBaseCarrier
import org.jetbrains.kotlin.ir.expressions.IrBody import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType import org.jetbrains.kotlin.ir.types.impl.IrUninitializedType
import org.jetbrains.kotlin.ir.util.mapOptimized import org.jetbrains.kotlin.ir.util.transformIfNeeded
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -144,12 +144,11 @@ abstract class IrFunctionBase<T : FunctionBaseCarrier<T>>(
} }
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) { override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
typeParameters = typeParameters.transformIfNeeded(transformer, data)
typeParameters = typeParameters.mapOptimized { it.transform(transformer, data) }
dispatchReceiverParameter = dispatchReceiverParameter?.transform(transformer, data) dispatchReceiverParameter = dispatchReceiverParameter?.transform(transformer, data)
extensionReceiverParameter = extensionReceiverParameter?.transform(transformer, data) extensionReceiverParameter = extensionReceiverParameter?.transform(transformer, data)
valueParameters = valueParameters.mapOptimized { it.transform(transformer, data) } valueParameters = valueParameters.transformIfNeeded(transformer, data)
body = body?.transform(transformer, data) body = body?.transform(transformer, data)
} }
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.ir.declarations.IrTypeParameter
import org.jetbrains.kotlin.ir.declarations.impl.carriers.TypeAliasCarrier import org.jetbrains.kotlin.ir.declarations.impl.carriers.TypeAliasCarrier
import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.mapOptimized import org.jetbrains.kotlin.ir.util.transformIfNeeded
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -59,7 +59,7 @@ class IrTypeAliasImpl(
} }
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) { override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
typeParameters = typeParameters.mapOptimized { it.transform(transformer, data) } typeParameters = typeParameters.transformIfNeeded(transformer, data)
} }
companion object { companion object {
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.ir.util.transform import org.jetbrains.kotlin.ir.util.transform
import org.jetbrains.kotlin.ir.util.mapOptimized import org.jetbrains.kotlin.ir.util.transformIfNeeded
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.metadata.ProtoBuf import org.jetbrains.kotlin.metadata.ProtoBuf
@@ -102,7 +102,7 @@ class IrLazyClass(
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) { override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
thisReceiver = thisReceiver?.transform(transformer, data) thisReceiver = thisReceiver?.transform(transformer, data)
typeParameters = typeParameters.mapOptimized { it.transform(transformer, data) } typeParameters = typeParameters.transformIfNeeded(transformer, data)
declarations.transform { it.transform(transformer, data) } declarations.transform { it.transform(transformer, data) }
} }
} }
@@ -14,7 +14,7 @@ import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.ir.util.mapOptimized import org.jetbrains.kotlin.ir.util.transformIfNeeded
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -77,11 +77,11 @@ abstract class IrLazyFunctionBase(
} }
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) { override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
typeParameters = typeParameters.mapOptimized { it.transform(transformer, data) } typeParameters = typeParameters.transformIfNeeded(transformer, data)
dispatchReceiverParameter = dispatchReceiverParameter?.transform(transformer, data) dispatchReceiverParameter = dispatchReceiverParameter?.transform(transformer, data)
extensionReceiverParameter = extensionReceiverParameter?.transform(transformer, data) extensionReceiverParameter = extensionReceiverParameter?.transform(transformer, data)
valueParameters = valueParameters.mapOptimized { it.transform(transformer, data) } valueParameters = valueParameters.transformIfNeeded(transformer, data)
body = body?.transform(transformer, data) body = body?.transform(transformer, data)
} }
@@ -16,7 +16,7 @@ import org.jetbrains.kotlin.ir.symbols.IrTypeAliasSymbol
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator import org.jetbrains.kotlin.ir.util.DeclarationStubGenerator
import org.jetbrains.kotlin.ir.util.TypeTranslator import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.ir.util.mapOptimized import org.jetbrains.kotlin.ir.util.transformIfNeeded
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
@@ -63,6 +63,6 @@ class IrLazyTypeAlias(
} }
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) { override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
typeParameters = typeParameters.mapOptimized { it.transform(transformer, data) } typeParameters = typeParameters.transformIfNeeded(transformer, data)
} }
} }
@@ -19,6 +19,7 @@ package org.jetbrains.kotlin.ir.util
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.IrDeclaration import org.jetbrains.kotlin.ir.declarations.IrDeclaration
import org.jetbrains.kotlin.ir.declarations.IrDeclarationContainer 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) { inline fun <reified T : IrElement> MutableList<T>.transform(transformation: (T) -> IrElement) {
forEachIndexed { i, item -> forEachIndexed { i, item ->
@@ -65,12 +66,13 @@ fun IrDeclarationContainer.transformDeclarationsFlat(transformation: (IrDeclarat
} }
/** /**
* Similar to `map`. Return the same List instance if no element instances have changed. * Transforms the list of elements with the given transformer. Return the same List instance if no element instances have changed.
*/ */
inline fun <reified T : IrElement> List<T>.mapOptimized(transformation: (T) -> IrElement): List<T> { fun <T : IrElement, D> List<T>.transformIfNeeded(transformer: IrElementTransformer<D>, data: D): List<T> {
var result: ArrayList<T>? = null var result: ArrayList<T>? = null
for ((i, item) in withIndex()) { for ((i, item) in withIndex()) {
val transformed = transformation(item) as T @Suppress("UNCHECKED_CAST")
val transformed = item.transform(transformer, data) as T
if (transformed !== item && result == null) { if (transformed !== item && result == null) {
result = ArrayList(this) result = ArrayList(this)
} }