[K/N] Refactor default argument lowering to avoid boxing
Current inline classes API is not compatible between different backends. So implementing common function required for this optimization was not possible in Native backend. So, common default arguments lowering was refactored to make bigger piece of code replaceable in backends. ^KT-57860
This commit is contained in:
committed by
Space Team
parent
2aea5822b2
commit
f55fd481e9
@@ -26,14 +26,8 @@ abstract class Ir<out T : CommonBackendContext>(val context: T) {
|
||||
|
||||
abstract val symbols: Symbols
|
||||
|
||||
val defaultParameterDeclarationsCache = mutableMapOf<IrFunction, IrFunction>()
|
||||
|
||||
internal val localScopeWithCounterMap = LocalDeclarationsLowering.LocalScopeWithCounterMap()
|
||||
|
||||
// If irType is an inline class type, return the underlying type according to the
|
||||
// unfolding rules of the current backend. Otherwise, returns null.
|
||||
open fun unfoldInlineClassType(irType: IrType): IrType? = null
|
||||
|
||||
open fun shouldGenerateHandlerParameterForDefaultBodyFun() = false
|
||||
}
|
||||
|
||||
|
||||
+14
-4
@@ -15,12 +15,14 @@ import org.jetbrains.kotlin.ir.declarations.*
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstructorCall
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrErrorExpressionImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.makeNullable
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.utils.*
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
|
||||
abstract class DefaultArgumentFunctionFactory(open val context: CommonBackendContext) {
|
||||
abstract class DefaultArgumentFunctionFactory(val context: CommonBackendContext) {
|
||||
|
||||
protected fun IrFunction.generateDefaultArgumentsFunctionName() =
|
||||
Name.identifier("${name}\$default")
|
||||
|
||||
@@ -40,11 +42,19 @@ abstract class DefaultArgumentFunctionFactory(open val context: CommonBackendCon
|
||||
contextReceiverParametersCount = original.contextReceiverParametersCount
|
||||
}
|
||||
|
||||
protected fun IrFunction.copyValueParametersFrom(original: IrFunction, wrapWithNullable: Boolean = true) {
|
||||
/**
|
||||
* Whether `null` will be used for this type if no argument is passed.
|
||||
* In that case, the type of the default dispatch function will be made nullable.
|
||||
*
|
||||
* By default, always returns `true` – this is valid, but suboptimal.
|
||||
* Better performance can be achieved in a backend-specific way.
|
||||
*/
|
||||
protected open fun IrType.hasNullAsUndefinedValue(): Boolean = true
|
||||
|
||||
protected fun IrFunction.copyValueParametersFrom(original: IrFunction) {
|
||||
valueParameters = original.valueParameters.memoryOptimizedMap {
|
||||
val newType = it.type.remapTypeParameters(original.classIfConstructor, classIfConstructor)
|
||||
val makeNullable = wrapWithNullable && it.defaultValue != null &&
|
||||
(context.ir.unfoldInlineClassType(it.type) ?: it.type) !in context.irBuiltIns.primitiveIrTypes
|
||||
val makeNullable = it.defaultValue != null && it.type.hasNullAsUndefinedValue()
|
||||
it.copyTo(
|
||||
this,
|
||||
type = if (makeNullable) newType.makeNullable() else newType,
|
||||
|
||||
+9
-9
@@ -33,12 +33,12 @@ import org.jetbrains.kotlin.utils.memoryOptimizedPlus
|
||||
|
||||
// TODO: fix expect/actual default parameters
|
||||
|
||||
open class DefaultArgumentStubGenerator(
|
||||
open val context: CommonBackendContext,
|
||||
open class DefaultArgumentStubGenerator<TContext : CommonBackendContext>(
|
||||
val context: TContext,
|
||||
private val factory: DefaultArgumentFunctionFactory,
|
||||
private val skipInlineMethods: Boolean = true,
|
||||
private val skipExternalMethods: Boolean = false,
|
||||
private val forceSetOverrideSymbols: Boolean = true,
|
||||
private val factory: DefaultArgumentFunctionFactory = MaskedDefaultArgumentFunctionFactory(context)
|
||||
private val forceSetOverrideSymbols: Boolean = true
|
||||
) : DeclarationTransformer {
|
||||
override val withLocalDeclarations: Boolean get() = true
|
||||
|
||||
@@ -255,12 +255,12 @@ open class DefaultArgumentStubGenerator(
|
||||
private fun log(msg: () -> String) = context.log { "DEFAULT-REPLACER: ${msg()}" }
|
||||
}
|
||||
|
||||
open class DefaultParameterInjector(
|
||||
open val context: CommonBackendContext,
|
||||
open class DefaultParameterInjector<TContext : CommonBackendContext>(
|
||||
protected val context: TContext,
|
||||
protected val factory: DefaultArgumentFunctionFactory,
|
||||
protected val skipInline: Boolean = true,
|
||||
protected val skipExternalMethods: Boolean = false,
|
||||
protected val forceSetOverrideSymbols: Boolean = true,
|
||||
protected val factory: DefaultArgumentFunctionFactory = MaskedDefaultArgumentFunctionFactory(context),
|
||||
) : IrElementTransformerVoid(), BodyLoweringPass {
|
||||
|
||||
override fun lower(irBody: IrBody, container: IrDeclaration) {
|
||||
@@ -499,8 +499,8 @@ class DefaultParameterPatchOverridenSymbolsLowering(
|
||||
}
|
||||
}
|
||||
|
||||
private class MaskedDefaultArgumentFunctionFactory(context: CommonBackendContext) : DefaultArgumentFunctionFactory(context) {
|
||||
override fun IrFunction.generateDefaultArgumentStubFrom(original: IrFunction, useConstructorMarker: Boolean) {
|
||||
open class MaskedDefaultArgumentFunctionFactory(context: CommonBackendContext) : DefaultArgumentFunctionFactory(context) {
|
||||
final override fun IrFunction.generateDefaultArgumentStubFrom(original: IrFunction, useConstructorMarker: Boolean) {
|
||||
copyAttributesFrom(original)
|
||||
copyTypeParametersFrom(original)
|
||||
copyReturnTypeFrom(original)
|
||||
|
||||
Reference in New Issue
Block a user