[K/N][IR] Refactored inline function bodies resolving

This commit is contained in:
Igor Chevdar
2022-08-05 14:33:20 +03:00
committed by Space
parent f7d389c9da
commit 60ea26750e
4 changed files with 24 additions and 19 deletions
@@ -14,6 +14,7 @@ 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.BridgesSupport import org.jetbrains.kotlin.backend.konan.lower.BridgesSupport
import org.jetbrains.kotlin.backend.konan.lower.InlineFunctionsSupport
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
@@ -51,15 +52,17 @@ import java.lang.System.out
import kotlin.LazyThreadSafetyMode.PUBLICATION import kotlin.LazyThreadSafetyMode.PUBLICATION
import kotlin.reflect.KProperty import kotlin.reflect.KProperty
internal class InlineFunctionOriginInfo(val irFunction: IrFunction, val irFile: IrFile, val startOffset: Int, val endOffset: Int)
internal class NativeMapping : DefaultMapping() { internal class NativeMapping : DefaultMapping() {
data class BridgeKey(val target: IrSimpleFunction, val bridgeDirections: BridgeDirections) 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>() val bridges = mutableMapOf<BridgeKey, IrSimpleFunction>()
val notLoweredInlineFunctions = mutableMapOf<IrFunctionSymbol, IrFunction>()
val loweredInlineFunctions = mutableMapOf<IrFunction, InlineFunctionOriginInfo>()
} }
internal class InlineFunctionOriginInfo(val irFunction: IrFunction, val irFile: IrFile, val startOffset: Int, val endOffset: Int)
/** /**
* Offset for synthetic elements created by lowerings and not attributable to other places in the source code. * Offset for synthetic elements created by lowerings and not attributable to other places in the source code.
*/ */
@@ -69,14 +72,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 val notLoweredInlineFunctions = mutableMapOf<IrFunctionSymbol, IrFunction>()
val loweredInlineFunctions = mutableMapOf<IrFunction, InlineFunctionOriginInfo>()
fun getNonLoweredInlineFunction(function: IrFunction): IrFunction {
return notLoweredInlineFunctions.getOrPut(function.symbol) {
function.deepCopyWithVariables().also { it.patchDeclarationParents(function.parent) }
}
}
fun getLoweredEnumOrNull(enumClass: IrClass): LoweredEnumAccess? { fun getLoweredEnumOrNull(enumClass: IrClass): LoweredEnumAccess? {
assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" } assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" }
return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) { return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) {
@@ -148,6 +143,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) } val bridgesSupport by lazy { BridgesSupport(mapping, irBuiltIns, irFactory) }
val inlineFunctionsSupport by lazy { InlineFunctionsSupport(mapping) }
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)
@@ -167,7 +167,7 @@ internal val inlinePhase = makeKonanFileOpPhase(
override fun visitFunction(declaration: IrFunction) { override fun visitFunction(declaration: IrFunction) {
if (declaration.isInline) if (declaration.isInline)
context.specialDeclarationsFactory.getNonLoweredInlineFunction(declaration) context.inlineFunctionsSupport.getNonLoweredInlineFunction(declaration)
declaration.acceptChildrenVoid(this) declaration.acceptChildrenVoid(this)
} }
}) })
@@ -1947,7 +1947,7 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
//-------------------------------------------------------------------------// //-------------------------------------------------------------------------//
private inner class ReturnableBlockScope(val returnableBlock: IrReturnableBlock, val resultSlot: LLVMValueRef?) : private inner class ReturnableBlockScope(val returnableBlock: IrReturnableBlock, val resultSlot: LLVMValueRef?) :
FileScope(returnableBlock.inlineFunctionSymbol?.owner?.let { FileScope(returnableBlock.inlineFunctionSymbol?.owner?.let {
context.specialDeclarationsFactory.loweredInlineFunctions[it]?.irFile ?: it.fileOrNull context.mapping.loweredInlineFunctions[it]?.irFile ?: it.fileOrNull
} }
?: (currentCodeContext.fileScope() as? FileScope)?.file ?: (currentCodeContext.fileScope() as? FileScope)?.file
?: error("returnable block should belong to current file at least")) { ?: error("returnable block should belong to current file at least")) {
@@ -1956,13 +1956,13 @@ internal class CodeGeneratorVisitor(val context: Context, val lifetimes: Map<IrE
var resultPhi : LLVMValueRef? = null var resultPhi : LLVMValueRef? = null
private val functionScope by lazy { private val functionScope by lazy {
returnableBlock.inlineFunctionSymbol?.owner?.let { returnableBlock.inlineFunctionSymbol?.owner?.let {
it.scope(file().fileEntry.line(context.specialDeclarationsFactory.loweredInlineFunctions[it]?.startOffset ?: it.startOffset)) it.scope(file().fileEntry.line(context.mapping.loweredInlineFunctions[it]?.startOffset ?: it.startOffset))
} }
} }
private fun getExit(): LLVMBasicBlockRef { private fun getExit(): LLVMBasicBlockRef {
val location = returnableBlock.inlineFunctionSymbol?.owner?.let { val location = returnableBlock.inlineFunctionSymbol?.owner?.let {
location(context.specialDeclarationsFactory.loweredInlineFunctions[it]?.endOffset ?: it.endOffset) location(context.mapping.loweredInlineFunctions[it]?.endOffset ?: it.endOffset)
} ?: returnableBlock.statements.lastOrNull()?.let { } ?: returnableBlock.statements.lastOrNull()?.let {
location(it.endOffset) location(it.endOffset)
} }
@@ -10,25 +10,34 @@ import org.jetbrains.kotlin.backend.common.lower.*
import org.jetbrains.kotlin.backend.common.lower.inline.* import org.jetbrains.kotlin.backend.common.lower.inline.*
import org.jetbrains.kotlin.backend.konan.Context import org.jetbrains.kotlin.backend.konan.Context
import org.jetbrains.kotlin.backend.konan.InlineFunctionOriginInfo import org.jetbrains.kotlin.backend.konan.InlineFunctionOriginInfo
import org.jetbrains.kotlin.backend.konan.NativeMapping
import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment import org.jetbrains.kotlin.ir.declarations.IrExternalPackageFragment
import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.declarations.IrFile
import org.jetbrains.kotlin.ir.declarations.IrFunction import org.jetbrains.kotlin.ir.declarations.IrFunction
import org.jetbrains.kotlin.ir.deepCopyWithVariables
import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrClassSymbol
import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol import org.jetbrains.kotlin.ir.symbols.IrFunctionSymbol
import org.jetbrains.kotlin.ir.util.* import org.jetbrains.kotlin.ir.util.*
import org.jetbrains.kotlin.name.Name import org.jetbrains.kotlin.name.Name
internal class InlineFunctionsSupport(mapping: NativeMapping) {
private val notLoweredInlineFunctions = mapping.notLoweredInlineFunctions
fun getNonLoweredInlineFunction(function: IrFunction) = notLoweredInlineFunctions.getOrPut(function.symbol) {
function.deepCopyWithVariables().also { it.patchDeclarationParents(function.parent) }
}
}
// TODO: This is a bit hacky. Think about adopting persistent IR ideas. // TODO: This is a bit hacky. Think about adopting persistent IR ideas.
internal class NativeInlineFunctionResolver(override val context: Context) : DefaultInlineFunctionResolver(context) { internal class NativeInlineFunctionResolver(override val context: Context) : DefaultInlineFunctionResolver(context) {
override fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction { override fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction {
val function = super.getFunctionDeclaration(symbol) val function = super.getFunctionDeclaration(symbol)
context.specialDeclarationsFactory.loweredInlineFunctions[function]?.let { return it.irFunction } context.mapping.loweredInlineFunctions[function]?.let { return it.irFunction }
val packageFragment = function.getPackageFragment() val packageFragment = function.getPackageFragment()
val notLoweredFunction = if (packageFragment !is IrExternalPackageFragment) { val notLoweredFunction = if (packageFragment !is IrExternalPackageFragment) {
context.specialDeclarationsFactory.getNonLoweredInlineFunction(function).also { context.inlineFunctionsSupport.getNonLoweredInlineFunction(function).also {
context.specialDeclarationsFactory.loweredInlineFunctions[function] = context.mapping.loweredInlineFunctions[function] =
InlineFunctionOriginInfo(it, packageFragment as IrFile, function.startOffset, function.endOffset) InlineFunctionOriginInfo(it, packageFragment as IrFile, function.startOffset, function.endOffset)
} }
} else { } else {
@@ -39,13 +48,13 @@ internal class NativeInlineFunctionResolver(override val context: Context) : Def
require(context.config.cachedLibraries.isLibraryCached(moduleDeserializer.klib)) { require(context.config.cachedLibraries.isLibraryCached(moduleDeserializer.klib)) {
"No IR and no cache for ${function.render()}" "No IR and no cache for ${function.render()}"
} }
context.specialDeclarationsFactory.loweredInlineFunctions[function] = moduleDeserializer.deserializeInlineFunction(function) context.mapping.loweredInlineFunctions[function] = moduleDeserializer.deserializeInlineFunction(function)
function function
} }
val body = notLoweredFunction.body ?: return notLoweredFunction val body = notLoweredFunction.body ?: return notLoweredFunction
PreInlineLowering(context).lower(body, notLoweredFunction, context.specialDeclarationsFactory.loweredInlineFunctions[function]!!.irFile) PreInlineLowering(context).lower(body, notLoweredFunction, context.mapping.loweredInlineFunctions[function]!!.irFile)
ArrayConstructorLowering(context).lower(body, notLoweredFunction) ArrayConstructorLowering(context).lower(body, notLoweredFunction)