[K/N][IR] Refactored bridges building

This commit is contained in:
Igor Chevdar
2022-08-05 14:06:58 +03:00
committed by Space
parent 9f26f8f227
commit f7d389c9da
3 changed files with 61 additions and 66 deletions
@@ -13,7 +13,7 @@ import org.jetbrains.kotlin.backend.konan.descriptors.*
import org.jetbrains.kotlin.backend.konan.ir.KonanIr import org.jetbrains.kotlin.backend.konan.ir.KonanIr
import org.jetbrains.kotlin.backend.konan.llvm.* import org.jetbrains.kotlin.backend.konan.llvm.*
import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager import org.jetbrains.kotlin.backend.konan.llvm.coverage.CoverageManager
import org.jetbrains.kotlin.backend.konan.lower.DECLARATION_ORIGIN_BRIDGE_METHOD import org.jetbrains.kotlin.backend.konan.lower.BridgesSupport
import org.jetbrains.kotlin.backend.konan.lower.InnerClassesSupport import org.jetbrains.kotlin.backend.konan.lower.InnerClassesSupport
import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport import org.jetbrains.kotlin.backend.konan.objcexport.ObjCExport
import org.jetbrains.kotlin.backend.konan.optimizations.DevirtualizationAnalysis import org.jetbrains.kotlin.backend.konan.optimizations.DevirtualizationAnalysis
@@ -28,12 +28,10 @@ import org.jetbrains.kotlin.descriptors.*
import org.jetbrains.kotlin.incremental.components.NoLookupLocation import org.jetbrains.kotlin.incremental.components.NoLookupLocation
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass import org.jetbrains.kotlin.ir.declarations.lazy.IrLazyClass
import org.jetbrains.kotlin.ir.deepCopyWithVariables import org.jetbrains.kotlin.ir.deepCopyWithVariables
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.symbols.IrSymbol import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.types.IrTypeSystemContext import org.jetbrains.kotlin.ir.types.IrTypeSystemContext
import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl import org.jetbrains.kotlin.ir.types.IrTypeSystemContextImpl
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
@@ -54,7 +52,10 @@ import kotlin.LazyThreadSafetyMode.PUBLICATION
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
internal class NativeMapping : DefaultMapping() { internal class NativeMapping : DefaultMapping() {
data class BridgeKey(val target: IrSimpleFunction, val bridgeDirections: BridgeDirections)
val outerThisFields = DefaultDelegateFactory.newDeclarationToDeclarationMapping<IrClass, IrField>() val outerThisFields = DefaultDelegateFactory.newDeclarationToDeclarationMapping<IrClass, IrField>()
val bridges = mutableMapOf<BridgeKey, IrSimpleFunction>()
} }
internal class InlineFunctionOriginInfo(val irFunction: IrFunction, val irFile: IrFile, val startOffset: Int, val endOffset: Int) internal class InlineFunctionOriginInfo(val irFunction: IrFunction, val irFile: IrFile, val startOffset: Int, val endOffset: Int)
@@ -68,10 +69,6 @@ internal class SpecialDeclarationsFactory(val context: Context) {
private val internalLoweredEnums = mutableMapOf<IrClass, InternalLoweredEnum>() private val internalLoweredEnums = mutableMapOf<IrClass, InternalLoweredEnum>()
private val externalLoweredEnums = mutableMapOf<IrClass, ExternalLoweredEnum>() private val externalLoweredEnums = mutableMapOf<IrClass, ExternalLoweredEnum>()
private data class BridgeKey(val target: IrSimpleFunction, val bridgeDirections: BridgeDirections)
private val bridges = mutableMapOf<BridgeKey, IrSimpleFunction>()
private val notLoweredInlineFunctions = mutableMapOf<IrFunctionSymbol, IrFunction>() private val notLoweredInlineFunctions = mutableMapOf<IrFunctionSymbol, IrFunction>()
val loweredInlineFunctions = mutableMapOf<IrFunction, InlineFunctionOriginInfo>() val loweredInlineFunctions = mutableMapOf<IrFunction, InlineFunctionOriginInfo>()
fun getNonLoweredInlineFunction(function: IrFunction): IrFunction { fun getNonLoweredInlineFunction(function: IrFunction): IrFunction {
@@ -112,61 +109,6 @@ internal class SpecialDeclarationsFactory(val context: Context) {
fun getEnumEntryOrdinal(enumEntry: IrEnumEntry) = fun getEnumEntryOrdinal(enumEntry: IrEnumEntry) =
enumEntry.parentAsClass.declarations.filterIsInstance<IrEnumEntry>().indexOf(enumEntry) enumEntry.parentAsClass.declarations.filterIsInstance<IrEnumEntry>().indexOf(enumEntry)
fun getBridge(overriddenFunction: OverriddenFunctionInfo): IrSimpleFunction {
val irFunction = overriddenFunction.function
assert(overriddenFunction.needBridge) {
"Function ${irFunction.descriptor} is not needed in a bridge to call overridden function ${overriddenFunction.overriddenFunction.descriptor}"
}
val key = BridgeKey(irFunction, overriddenFunction.bridgeDirections)
return bridges.getOrPut(key) { createBridge(key) }
}
private fun createBridge(key: BridgeKey): IrSimpleFunction {
val (function, bridgeDirections) = key
val startOffset = function.startOffset
val endOffset = function.endOffset
fun BridgeDirection.type() =
if (this.kind == BridgeDirectionKind.NONE)
null
else this.irClass?.defaultType ?: context.irBuiltIns.anyNType
return IrFunctionImpl(
startOffset, endOffset,
DECLARATION_ORIGIN_BRIDGE_METHOD(function),
IrSimpleFunctionSymbolImpl(),
"<bridge-$bridgeDirections>${function.computeFunctionName()}".synthesizedName,
function.visibility,
function.modality,
isInline = false,
isExternal = false,
isTailrec = false,
isSuspend = function.isSuspend,
returnType = bridgeDirections.returnDirection.type() ?: function.returnType,
isExpect = false,
isFakeOverride = false,
isOperator = false,
isInfix = false
).apply {
val bridge = this
parent = function.parent
dispatchReceiverParameter = function.dispatchReceiverParameter?.let {
it.copyTo(bridge, type = bridgeDirections.dispatchReceiverDirection.type() ?: it.type)
}
extensionReceiverParameter = function.extensionReceiverParameter?.let {
it.copyTo(bridge, type = bridgeDirections.extensionReceiverDirection.type() ?: it.type)
}
valueParameters += function.valueParameters.map {
it.copyTo(bridge, type = bridgeDirections.parameterDirectionAt(it.index).type() ?: it.type)
}
typeParameters += function.typeParameters.map { parameter ->
parameter.copyToWithoutSuperTypes(bridge).also { it.superTypes += parameter.superTypes }
}
}
}
} }
internal class Context(config: KonanConfig) : KonanBackendContext(config) { internal class Context(config: KonanConfig) : KonanBackendContext(config) {
@@ -205,6 +147,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
val specialDeclarationsFactory = SpecialDeclarationsFactory(this) val specialDeclarationsFactory = SpecialDeclarationsFactory(this)
val innerClassesSupport by lazy { InnerClassesSupport(mapping, irFactory) } val innerClassesSupport by lazy { InnerClassesSupport(mapping, irFactory) }
val bridgesSupport by lazy { BridgesSupport(mapping, irBuiltIns, irFactory) }
open class LazyMember<T>(val initializer: Context.() -> T) { open class LazyMember<T>(val initializer: Context.() -> T) {
operator fun getValue(thisRef: Context, property: KProperty<*>): T = thisRef.getValue(this) operator fun getValue(thisRef: Context, property: KProperty<*>): T = thisRef.getValue(this)
@@ -57,7 +57,7 @@ internal class OverriddenFunctionInfo(
} else { } else {
function function
} }
context.specialDeclarationsFactory.getBridge(OverriddenFunctionInfo(bridgeOwner, overriddenFunction)) context.bridgesSupport.getBridge(OverriddenFunctionInfo(bridgeOwner, overriddenFunction))
} }
return if (implementation.modality == Modality.ABSTRACT) null else implementation return if (implementation.modality == Modality.ABSTRACT) null else implementation
} }
@@ -11,10 +11,14 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.backend.common.lower.irBlockBody import org.jetbrains.kotlin.backend.common.lower.irBlockBody
import org.jetbrains.kotlin.backend.common.lower.irIfThen import org.jetbrains.kotlin.backend.common.lower.irIfThen
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.NativeMapping
import org.jetbrains.kotlin.backend.konan.descriptors.* import org.jetbrains.kotlin.backend.konan.descriptors.*
import org.jetbrains.kotlin.backend.konan.llvm.computeFunctionName
import org.jetbrains.kotlin.descriptors.Modality import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.IrStatement import org.jetbrains.kotlin.ir.IrStatement
import org.jetbrains.kotlin.ir.builders.* import org.jetbrains.kotlin.ir.builders.*
import org.jetbrains.kotlin.ir.builders.declarations.buildFun
import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.*
import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl import org.jetbrains.kotlin.ir.declarations.impl.IrFunctionImpl
import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl import org.jetbrains.kotlin.ir.declarations.impl.IrValueParameterImpl
@@ -26,13 +30,61 @@ import org.jetbrains.kotlin.ir.symbols.impl.IrSimpleFunctionSymbolImpl
import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl import org.jetbrains.kotlin.ir.symbols.impl.IrValueParameterSymbolImpl
import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrType
import org.jetbrains.kotlin.ir.types.isNullableAny import org.jetbrains.kotlin.ir.types.isNullableAny
import org.jetbrains.kotlin.ir.util.simpleFunctions import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
import org.jetbrains.kotlin.load.java.SpecialGenericSignatures import org.jetbrains.kotlin.load.java.SpecialGenericSignatures
internal class BridgesSupport(mapping: NativeMapping, val irBuiltIns: IrBuiltIns, val irFactory: IrFactory) {
private val bridges = mapping.bridges
fun getBridge(overriddenFunction: OverriddenFunctionInfo): IrSimpleFunction {
val irFunction = overriddenFunction.function
assert(overriddenFunction.needBridge) {
"Function ${irFunction.render()} doesn't need a bridge to call overridden function ${overriddenFunction.overriddenFunction.render()}"
}
val key = NativeMapping.BridgeKey(irFunction, overriddenFunction.bridgeDirections)
return bridges.getOrPut(key) { createBridge(key) }
}
private fun BridgeDirection.type() =
if (this.kind == BridgeDirectionKind.NONE)
null
else this.irClass?.defaultType ?: irBuiltIns.anyNType
private fun createBridge(key: NativeMapping.BridgeKey): IrSimpleFunction {
val (function, bridgeDirections) = key
return irFactory.buildFun {
startOffset = function.startOffset
endOffset = function.endOffset
origin = DECLARATION_ORIGIN_BRIDGE_METHOD(function)
name = "<bridge-$bridgeDirections>${function.computeFunctionName()}".synthesizedName
visibility = function.visibility
modality = function.modality
returnType = bridgeDirections.returnDirection.type() ?: function.returnType
isSuspend = function.isSuspend
}.apply {
parent = function.parent
val bridge = this
dispatchReceiverParameter = function.dispatchReceiverParameter?.let {
it.copyTo(bridge, type = bridgeDirections.dispatchReceiverDirection.type() ?: it.type)
}
extensionReceiverParameter = function.extensionReceiverParameter?.let {
it.copyTo(bridge, type = bridgeDirections.extensionReceiverDirection.type() ?: it.type)
}
valueParameters = function.valueParameters.map {
it.copyTo(bridge, type = bridgeDirections.parameterDirectionAt(it.index).type() ?: it.type)
}
typeParameters = function.typeParameters.map { parameter ->
parameter.copyToWithoutSuperTypes(bridge).also { it.superTypes += parameter.superTypes }
}
}
}
}
internal class WorkersBridgesBuilding(val context: Context) : DeclarationContainerLoweringPass, IrElementTransformerVoid() { internal class WorkersBridgesBuilding(val context: Context) : DeclarationContainerLoweringPass, IrElementTransformerVoid() {
val symbols = context.ir.symbols val symbols = context.ir.symbols
@@ -230,7 +282,7 @@ private fun Context.buildBridge(startOffset: Int, endOffset: Int,
overriddenFunction: OverriddenFunctionInfo, targetSymbol: IrSimpleFunctionSymbol, overriddenFunction: OverriddenFunctionInfo, targetSymbol: IrSimpleFunctionSymbol,
superQualifierSymbol: IrClassSymbol? = null): IrFunction { superQualifierSymbol: IrClassSymbol? = null): IrFunction {
val bridge = specialDeclarationsFactory.getBridge(overriddenFunction) val bridge = bridgesSupport.getBridge(overriddenFunction)
if (bridge.modality == Modality.ABSTRACT) { if (bridge.modality == Modality.ABSTRACT) {
return bridge return bridge