IR: remove IrBuiltInOperator, use IrFunctionImpl instead

It seems that this is no longer needed. This change in particular helps
to avoid megamorphic interface call on IrValueParameter.accept, which
happens a lot because there are usually many value parameters.
This commit is contained in:
Alexander Udalov
2020-06-22 19:36:21 +02:00
parent 988226a90e
commit 7013becda5
2 changed files with 37 additions and 166 deletions
@@ -16,6 +16,9 @@ import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.IrDeclarationOriginImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrExternalPackageFragmentImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrTypeParameterImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrTypeParameterSymbolImpl
@@ -27,7 +30,8 @@ import org.jetbrains.kotlin.ir.types.impl.buildSimpleType
import org.jetbrains.kotlin.ir.types.impl.originalKotlinType
import org.jetbrains.kotlin.ir.types.makeNullable
import org.jetbrains.kotlin.ir.types.withHasQuestionMark
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.SymbolTable
import org.jetbrains.kotlin.ir.util.TypeTranslator
import org.jetbrains.kotlin.name.FqName
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.storage.LockBasedStorageManager
@@ -52,23 +56,33 @@ class IrBuiltIns(
private fun KotlinType.toIrType() = typeTranslator.translateType(this)
fun defineOperator(name: String, returnType: IrType, valueParameterTypes: List<IrType>): IrSimpleFunctionSymbol {
val operatorDescriptor = IrSimpleBuiltinOperatorDescriptorImpl(packageFragmentDescriptor, Name.identifier(name), returnType.originalKotlinType!!)
val operatorDescriptor =
IrSimpleBuiltinOperatorDescriptorImpl(packageFragmentDescriptor, Name.identifier(name), returnType.originalKotlinType!!)
for ((i, valueParameterType) in valueParameterTypes.withIndex()) {
val valueParameterDescriptor =
IrBuiltinValueParameterDescriptorImpl(operatorDescriptor, Name.identifier("arg$i"), i, valueParameterType.originalKotlinType!!)
operatorDescriptor.addValueParameter(valueParameterDescriptor)
operatorDescriptor.addValueParameter(
IrBuiltinValueParameterDescriptorImpl(
operatorDescriptor, Name.identifier("arg$i"), i, valueParameterType.originalKotlinType!!
)
)
}
val symbol = symbolTable.declareSimpleFunctionIfNotExists(operatorDescriptor) {
val operator = IrBuiltInOperator(it, Name.identifier(name), returnType)
val operator = IrFunctionImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, it, Name.identifier(name), Visibilities.PUBLIC, Modality.FINAL,
returnType, isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isOperator = false,
isExpect = false, isFakeOverride = false
)
operator.parent = packageFragment
packageFragment.declarations += operator
operator.valueParameters = valueParameterTypes.withIndex().map { (i, valueParameterType) ->
val valueParameterDescriptor = operatorDescriptor.valueParameters[i]
val valueParameterSymbol = IrValueParameterSymbolImpl(valueParameterDescriptor)
IrBuiltInOperatorValueParameter(valueParameterSymbol, i, valueParameterType).apply {
IrValueParameterImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, valueParameterSymbol, Name.identifier("arg$i"), i,
valueParameterType, null, false, false
).apply {
parent = operator
}
}
@@ -112,11 +126,16 @@ class IrBuiltIns(
returnKotlinType = typeParameterDescriptor.typeConstructor.makeNonNullType()
initialize(null, null, listOf(typeParameterDescriptor), listOf(valueParameterDescriptor), returnKotlinType, Modality.FINAL, Visibilities.PUBLIC)
initialize(
null, null, listOf(typeParameterDescriptor), listOf(valueParameterDescriptor), returnKotlinType,
Modality.FINAL, Visibilities.PUBLIC
)
}
val typeParameterSymbol = IrTypeParameterSymbolImpl(typeParameterDescriptor)
val typeParameter = IrBuiltInOperatorTypeParameter(typeParameterSymbol, Variance.INVARIANT, 0, true).apply {
val typeParameter = IrTypeParameterImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, typeParameterSymbol, Name.identifier("T0"), 0, true, Variance.INVARIANT
).apply {
superTypes += anyType
}
@@ -135,12 +154,19 @@ class IrBuiltIns(
}
return symbolTable.declareSimpleFunctionIfNotExists(operatorDescriptor) {
val operator = IrBuiltInOperator(it, name, returnIrType)
val operator = IrFunctionImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, it, name, Visibilities.PUBLIC, Modality.FINAL, returnIrType,
isInline = false, isExternal = false, isTailrec = false, isSuspend = false, isOperator = false, isExpect = false,
isFakeOverride = false
)
operator.parent = packageFragment
packageFragment.declarations += operator
val valueParameterSymbol = IrValueParameterSymbolImpl(valueParameterDescriptor)
val valueParameter = IrBuiltInOperatorValueParameter(valueParameterSymbol, 0, valueIrType)
val valueParameter = IrValueParameterImpl(
UNDEFINED_OFFSET, UNDEFINED_OFFSET, BUILTIN_OPERATOR, valueParameterSymbol, Name.identifier("arg0"), 0,
valueIrType, null, isCrossinline = false, isNoinline = false
)
valueParameter.parent = operator
typeParameter.parent = operator
@@ -1,155 +0,0 @@
/*
* Copyright 2010-2019 JetBrains s.r.o. and Kotlin Programming Language contributors.
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
*/
package org.jetbrains.kotlin.ir.descriptors
import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.ir.ObsoleteDescriptorBasedAPI
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
import org.jetbrains.kotlin.ir.expressions.IrExpressionBody
import org.jetbrains.kotlin.ir.symbols.IrPropertySymbol
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrTypeParameterSymbol
import org.jetbrains.kotlin.ir.symbols.IrValueParameterSymbol
import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.visitors.IrElementTransformer
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
import org.jetbrains.kotlin.name.Name
import org.jetbrains.kotlin.types.Variance
import org.jetbrains.kotlin.utils.SmartList
import kotlin.reflect.KProperty
abstract class IrBuiltInOperatorBase : IrDeclaration {
override val startOffset: Int get() = UNDEFINED_OFFSET
override val endOffset: Int get() = UNDEFINED_OFFSET
override var origin: IrDeclarationOrigin
get() = IrBuiltIns.BUILTIN_OPERATOR
set(_) {}
private var _parent: IrDeclarationParent? = null
override var parent: IrDeclarationParent
get() = _parent
?: throw UninitializedPropertyAccessException("Parent not initialized: $this")
set(v) {
_parent = v
}
override var annotations: List<IrConstructorCall> = emptyList()
override val metadata: MetadataSource? get() = null
}
private class NullValueDelegate<T> {
operator fun getValue(thisRef: Any?, property: KProperty<*>): T? = null
operator fun setValue(thisRef: Any?, property: KProperty<*>, v: T?) {
error("IrBuiltInOperators are not supposed to be mutated")
}
}
class IrBuiltInOperator(
override val symbol: IrSimpleFunctionSymbol,
override val name: Name,
override var returnType: IrType
) :
IrSimpleFunction,
IrFunction,
IrBuiltInOperatorBase() {
override val visibility: Visibility get() = Visibilities.PUBLIC
override val isInline: Boolean get() = false
override val isExternal: Boolean get() = false
override val isExpect: Boolean get() = false
override var dispatchReceiverParameter: IrValueParameter? by NullValueDelegate()
override var extensionReceiverParameter: IrValueParameter? by NullValueDelegate()
override var body: IrBody? by NullValueDelegate()
override var valueParameters: List<IrValueParameter> = emptyList()
override var typeParameters: List<IrTypeParameter> = emptyList()
override val modality get() = Modality.FINAL
override val isTailrec get() = false
override val isSuspend get() = false
override val isFakeOverride get() = false
override val isOperator: Boolean get() = false
override var correspondingPropertySymbol: IrPropertySymbol? by NullValueDelegate()
@ObsoleteDescriptorBasedAPI
override val descriptor: FunctionDescriptor get() = symbol.descriptor
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R {
return visitor.visitSimpleFunction(this, data)
}
override var overriddenSymbols: List<IrSimpleFunctionSymbol> = emptyList()
override var attributeOwnerId: IrAttributeContainer = this
init {
symbol.bind(this)
}
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {
// Do nothing
}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {
// Do nothing
}
}
class IrBuiltInOperatorValueParameter(override val symbol: IrValueParameterSymbol, override val index: Int, override val type: IrType) :
IrValueParameter, IrBuiltInOperatorBase() {
@ObsoleteDescriptorBasedAPI
override val descriptor: ParameterDescriptor get() = symbol.descriptor
override val varargElementType: IrType? get() = null
override val isCrossinline: Boolean get() = false
override val isNoinline: Boolean get() = false
override var defaultValue: IrExpressionBody? by NullValueDelegate()
override val name: Name = Name.identifier("arg$index")
override fun <D> transform(transformer: IrElementTransformer<D>, data: D) =
transformer.visitValueParameter(this, data) as IrValueParameter
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = visitor.visitValueParameter(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {}
init {
symbol.bind(this)
}
}
class IrBuiltInOperatorTypeParameter(
override val symbol: IrTypeParameterSymbol,
override val variance: Variance,
override val index: Int,
override val isReified: Boolean
) : IrTypeParameter, IrBuiltInOperatorBase() {
@ObsoleteDescriptorBasedAPI
override val descriptor: TypeParameterDescriptor get() = symbol.descriptor
override val superTypes: MutableList<IrType> = SmartList()
override val name: Name = Name.identifier("T$index")
override fun <D> transform(transformer: IrElementTransformer<D>, data: D): IrTypeParameter =
transformer.visitTypeParameter(this, data) as IrTypeParameter
override fun <R, D> accept(visitor: IrElementVisitor<R, D>, data: D): R = visitor.visitTypeParameter(this, data)
override fun <D> acceptChildren(visitor: IrElementVisitor<Unit, D>, data: D) {}
override fun <D> transformChildren(transformer: IrElementTransformer<D>, data: D) {}
init {
symbol.bind(this)
}
}