[IR] Added possibility to customize inline functions resolver

This commit is contained in:
Igor Chevdar
2020-04-06 18:50:56 +03:00
parent b548c5bf93
commit ae906c163d
@@ -32,7 +32,36 @@ import org.jetbrains.kotlin.util.OperatorNameConventions
fun IrValueParameter.isInlineParameter(type: IrType = this.type) =
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
@@ -61,7 +90,7 @@ class FunctionInlining(val context: CommonBackendContext) : IrElementTransformer
if (Symbols.isTypeOfIntrinsic(callee.symbol))
return expression
val actualCallee = getFunctionDeclaration(callee.symbol)
val actualCallee = inlineFunctionResolver.getFunctionDeclaration(callee.symbol)
val parent = allScopes.map { it.irElement }.filterIsInstance<IrDeclarationParent>().lastOrNull()
?: allScopes.map { it.irElement }.filterIsInstance<IrDeclaration>().lastOrNull()?.parent
@@ -72,24 +101,6 @@ class FunctionInlining(val context: CommonBackendContext) : IrElementTransformer
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 inner class Inliner(