[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.llvm.*
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.objcexport.ObjCExport
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.ir.IrElement
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.deepCopyWithVariables
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
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.IrTypeSystemContextImpl
import org.jetbrains.kotlin.ir.util.*
@@ -54,7 +52,10 @@ import kotlin.LazyThreadSafetyMode.PUBLICATION
import kotlin.reflect.KProperty
internal class NativeMapping : DefaultMapping() {
data class BridgeKey(val target: IrSimpleFunction, val bridgeDirections: BridgeDirections)
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)
@@ -68,10 +69,6 @@ internal class SpecialDeclarationsFactory(val context: Context) {
private val internalLoweredEnums = mutableMapOf<IrClass, InternalLoweredEnum>()
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>()
val loweredInlineFunctions = mutableMapOf<IrFunction, InlineFunctionOriginInfo>()
fun getNonLoweredInlineFunction(function: IrFunction): IrFunction {
@@ -112,61 +109,6 @@ internal class SpecialDeclarationsFactory(val context: Context) {
fun getEnumEntryOrdinal(enumEntry: IrEnumEntry) =
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) {
@@ -205,6 +147,7 @@ internal class Context(config: KonanConfig) : KonanBackendContext(config) {
val specialDeclarationsFactory = SpecialDeclarationsFactory(this)
val innerClassesSupport by lazy { InnerClassesSupport(mapping, irFactory) }
val bridgesSupport by lazy { BridgesSupport(mapping, irBuiltIns, irFactory) }
open class LazyMember<T>(val initializer: Context.() -> T) {
operator fun getValue(thisRef: Context, property: KProperty<*>): T = thisRef.getValue(this)
@@ -57,7 +57,7 @@ internal class OverriddenFunctionInfo(
} else {
function
}
context.specialDeclarationsFactory.getBridge(OverriddenFunctionInfo(bridgeOwner, overriddenFunction))
context.bridgesSupport.getBridge(OverriddenFunctionInfo(bridgeOwner, overriddenFunction))
}
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.irIfThen
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.llvm.computeFunctionName
import org.jetbrains.kotlin.descriptors.Modality
import org.jetbrains.kotlin.ir.IrBuiltIns
import org.jetbrains.kotlin.ir.IrStatement
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.impl.IrFunctionImpl
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.types.IrType
import org.jetbrains.kotlin.ir.types.isNullableAny
import org.jetbrains.kotlin.ir.util.simpleFunctions
import org.jetbrains.kotlin.ir.util.transformFlat
import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.ir.visitors.IrElementTransformerVoid
import org.jetbrains.kotlin.ir.visitors.transformChildrenVoid
import org.jetbrains.kotlin.load.java.BuiltinMethodsWithSpecialGenericSignature
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() {
val symbols = context.ir.symbols
@@ -230,7 +282,7 @@ private fun Context.buildBridge(startOffset: Int, endOffset: Int,
overriddenFunction: OverriddenFunctionInfo, targetSymbol: IrSimpleFunctionSymbol,
superQualifierSymbol: IrClassSymbol? = null): IrFunction {
val bridge = specialDeclarationsFactory.getBridge(overriddenFunction)
val bridge = bridgesSupport.getBridge(overriddenFunction)
if (bridge.modality == Modality.ABSTRACT) {
return bridge