[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.coverage.CoverageManager
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.objcexport.ObjCExport
import org.jetbrains.kotlin.backend.konan.optimizations.DevirtualizationAnalysis
@@ -51,15 +52,17 @@ import java.lang.System.out
import kotlin.LazyThreadSafetyMode.PUBLICATION
import kotlin.reflect.KProperty
internal class InlineFunctionOriginInfo(val irFunction: IrFunction, val irFile: IrFile, val startOffset: Int, val endOffset: Int)
internal class NativeMapping : DefaultMapping() {
data class BridgeKey(val target: IrSimpleFunction, val bridgeDirections: BridgeDirections)
val outerThisFields = DefaultDelegateFactory.newDeclarationToDeclarationMapping<IrClass, IrField>()
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.
*/
@@ -69,14 +72,6 @@ internal class SpecialDeclarationsFactory(val context: Context) {
private val internalLoweredEnums = mutableMapOf<IrClass, InternalLoweredEnum>()
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? {
assert(enumClass.kind == ClassKind.ENUM_CLASS) { "Expected enum class but was: ${enumClass.descriptor}" }
return if (!context.llvmModuleSpecification.containsDeclaration(enumClass)) {
@@ -148,6 +143,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) }
val inlineFunctionsSupport by lazy { InlineFunctionsSupport(mapping) }
open class LazyMember<T>(val initializer: Context.() -> T) {
operator fun getValue(thisRef: Context, property: KProperty<*>): T = thisRef.getValue(this)
@@ -167,7 +167,7 @@ internal val inlinePhase = makeKonanFileOpPhase(
override fun visitFunction(declaration: IrFunction) {
if (declaration.isInline)
context.specialDeclarationsFactory.getNonLoweredInlineFunction(declaration)
context.inlineFunctionsSupport.getNonLoweredInlineFunction(declaration)
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?) :
FileScope(returnableBlock.inlineFunctionSymbol?.owner?.let {
context.specialDeclarationsFactory.loweredInlineFunctions[it]?.irFile ?: it.fileOrNull
context.mapping.loweredInlineFunctions[it]?.irFile ?: it.fileOrNull
}
?: (currentCodeContext.fileScope() as? FileScope)?.file
?: 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
private val functionScope by lazy {
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 {
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 {
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.konan.Context
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.IrFile
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.IrFunctionSymbol
import org.jetbrains.kotlin.ir.util.*
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.
internal class NativeInlineFunctionResolver(override val context: Context) : DefaultInlineFunctionResolver(context) {
override fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction {
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 notLoweredFunction = if (packageFragment !is IrExternalPackageFragment) {
context.specialDeclarationsFactory.getNonLoweredInlineFunction(function).also {
context.specialDeclarationsFactory.loweredInlineFunctions[function] =
context.inlineFunctionsSupport.getNonLoweredInlineFunction(function).also {
context.mapping.loweredInlineFunctions[function] =
InlineFunctionOriginInfo(it, packageFragment as IrFile, function.startOffset, function.endOffset)
}
} else {
@@ -39,13 +48,13 @@ internal class NativeInlineFunctionResolver(override val context: Context) : Def
require(context.config.cachedLibraries.isLibraryCached(moduleDeserializer.klib)) {
"No IR and no cache for ${function.render()}"
}
context.specialDeclarationsFactory.loweredInlineFunctions[function] = moduleDeserializer.deserializeInlineFunction(function)
context.mapping.loweredInlineFunctions[function] = moduleDeserializer.deserializeInlineFunction(function)
function
}
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)