[IR] Added possibility to customize inline functions resolver
This commit is contained in:
+31
-20
@@ -32,7 +32,36 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
|
|||||||
fun IrValueParameter.isInlineParameter(type: IrType = this.type) =
|
fun IrValueParameter.isInlineParameter(type: IrType = this.type) =
|
||||||
index >= 0 && !isNoinline && !type.isNullable() && (type.isFunction() || type.isSuspendFunction())
|
index >= 0 && !isNoinline && !type.isNullable() && (type.isFunction() || type.isSuspendFunction())
|
||||||
|
|
||||||
class FunctionInlining(val context: CommonBackendContext) : IrElementTransformerVoidWithContext(), BodyLoweringPass {
|
interface InlineFunctionResolver {
|
||||||
|
fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction
|
||||||
|
}
|
||||||
|
|
||||||
|
open class DefaultInlineFunctionResolver(open val context: CommonBackendContext) : InlineFunctionResolver {
|
||||||
|
override fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction {
|
||||||
|
val descriptor = symbol.descriptor.original
|
||||||
|
val languageVersionSettings = context.configuration.languageVersionSettings
|
||||||
|
// TODO: Remove these hacks when coroutine intrinsics are fixed.
|
||||||
|
return when {
|
||||||
|
descriptor.isBuiltInIntercepted(languageVersionSettings) ->
|
||||||
|
error("Continuation.intercepted is not available with release coroutines")
|
||||||
|
|
||||||
|
descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings) ->
|
||||||
|
context.ir.symbols.suspendCoroutineUninterceptedOrReturn.owner
|
||||||
|
|
||||||
|
symbol == context.ir.symbols.coroutineContextGetter ->
|
||||||
|
context.ir.symbols.coroutineGetContext.owner
|
||||||
|
|
||||||
|
else -> (symbol.owner as? IrSimpleFunction)?.resolveFakeOverride() ?: symbol.owner
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
class FunctionInlining(
|
||||||
|
val context: CommonBackendContext,
|
||||||
|
val inlineFunctionResolver: InlineFunctionResolver
|
||||||
|
) : IrElementTransformerVoidWithContext(), BodyLoweringPass {
|
||||||
|
|
||||||
|
constructor(context: CommonBackendContext): this(context, DefaultInlineFunctionResolver(context))
|
||||||
|
|
||||||
private var containerScope: ScopeWithIr? = null
|
private var containerScope: ScopeWithIr? = null
|
||||||
|
|
||||||
@@ -61,7 +90,7 @@ class FunctionInlining(val context: CommonBackendContext) : IrElementTransformer
|
|||||||
if (Symbols.isTypeOfIntrinsic(callee.symbol))
|
if (Symbols.isTypeOfIntrinsic(callee.symbol))
|
||||||
return expression
|
return expression
|
||||||
|
|
||||||
val actualCallee = getFunctionDeclaration(callee.symbol)
|
val actualCallee = inlineFunctionResolver.getFunctionDeclaration(callee.symbol)
|
||||||
|
|
||||||
val parent = allScopes.map { it.irElement }.filterIsInstance<IrDeclarationParent>().lastOrNull()
|
val parent = allScopes.map { it.irElement }.filterIsInstance<IrDeclarationParent>().lastOrNull()
|
||||||
?: allScopes.map { it.irElement }.filterIsInstance<IrDeclaration>().lastOrNull()?.parent
|
?: allScopes.map { it.irElement }.filterIsInstance<IrDeclaration>().lastOrNull()?.parent
|
||||||
@@ -72,24 +101,6 @@ class FunctionInlining(val context: CommonBackendContext) : IrElementTransformer
|
|||||||
return inliner.inline()
|
return inliner.inline()
|
||||||
}
|
}
|
||||||
|
|
||||||
private fun getFunctionDeclaration(symbol: IrFunctionSymbol): IrFunction {
|
|
||||||
val descriptor = symbol.descriptor.original
|
|
||||||
val languageVersionSettings = context.configuration.languageVersionSettings
|
|
||||||
// TODO: Remove these hacks when coroutine intrinsics are fixed.
|
|
||||||
return when {
|
|
||||||
descriptor.isBuiltInIntercepted(languageVersionSettings) ->
|
|
||||||
error("Continuation.intercepted is not available with release coroutines")
|
|
||||||
|
|
||||||
descriptor.isBuiltInSuspendCoroutineUninterceptedOrReturn(languageVersionSettings) ->
|
|
||||||
context.ir.symbols.suspendCoroutineUninterceptedOrReturn.owner
|
|
||||||
|
|
||||||
symbol == context.ir.symbols.coroutineContextGetter ->
|
|
||||||
context.ir.symbols.coroutineGetContext.owner
|
|
||||||
|
|
||||||
else -> (symbol.owner as? IrSimpleFunction)?.resolveFakeOverride() ?: symbol.owner
|
|
||||||
}
|
|
||||||
}
|
|
||||||
|
|
||||||
private val IrFunction.needsInlining get() = this.isInline && !this.isExternal
|
private val IrFunction.needsInlining get() = this.isInline && !this.isExternal
|
||||||
|
|
||||||
private inner class Inliner(
|
private inner class Inliner(
|
||||||
|
|||||||
Reference in New Issue
Block a user