[Wasm] Cache down-casted dispatcher receiver in virtual functions

This commit is contained in:
Igor Yakovlev
2022-12-09 14:06:26 +01:00
committed by teamcity
parent 3be3ae4895
commit 4e24a9caa5
2 changed files with 20 additions and 11 deletions
@@ -634,12 +634,12 @@ val wasmPhases = SameTypeNamedCompilerPhase(
inlineClassDeclarationLoweringPhase then inlineClassDeclarationLoweringPhase then
inlineClassUsageLoweringPhase then inlineClassUsageLoweringPhase then
expressionBodyTransformer then
eraseVirtualDispatchReceiverParametersTypes then eraseVirtualDispatchReceiverParametersTypes then
bridgesConstructionPhase then bridgesConstructionPhase then
objectDeclarationLoweringPhase then objectDeclarationLoweringPhase then
fieldInitializersLoweringPhase then fieldInitializersLoweringPhase then
genericReturnTypeLowering then genericReturnTypeLowering then
expressionBodyTransformer then
unitToVoidLowering then unitToVoidLowering then
// Replace builtins before autoboxing // Replace builtins before autoboxing
@@ -9,16 +9,14 @@ import org.jetbrains.kotlin.backend.common.CommonBackendContext
import org.jetbrains.kotlin.backend.common.FileLoweringPass import org.jetbrains.kotlin.backend.common.FileLoweringPass
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrElement
import org.jetbrains.kotlin.ir.UNDEFINED_OFFSET
import org.jetbrains.kotlin.ir.builders.buildStatement import org.jetbrains.kotlin.ir.builders.buildStatement
import org.jetbrains.kotlin.ir.builders.irGet import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.builders.irImplicitCast import org.jetbrains.kotlin.ir.builders.irImplicitCast
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.declarations.IrSimpleFunction import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.IrBlockBody import org.jetbrains.kotlin.ir.expressions.*
import org.jetbrains.kotlin.ir.expressions.IrBody
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.expressions.IrGetValue
import org.jetbrains.kotlin.ir.types.isAny import org.jetbrains.kotlin.ir.types.isAny
import org.jetbrains.kotlin.ir.util.copyTo import org.jetbrains.kotlin.ir.util.copyTo
import org.jetbrains.kotlin.ir.util.isInterface import org.jetbrains.kotlin.ir.util.isInterface
@@ -80,18 +78,29 @@ class EraseVirtualDispatchReceiverParametersTypes(val context: CommonBackendCont
val newReceiver = oldReceiver.copyTo(irFunction, type = context.irBuiltIns.anyType) val newReceiver = oldReceiver.copyTo(irFunction, type = context.irBuiltIns.anyType)
irFunction.dispatchReceiverParameter = newReceiver irFunction.dispatchReceiverParameter = newReceiver
val blockBody = irFunction.body as? IrBlockBody ?: return
val classThisReceiverSymbol = irFunction.parentAsClass.thisReceiver?.symbol val classThisReceiverSymbol = irFunction.parentAsClass.thisReceiver?.symbol
val lazyCastedThis = lazy(LazyThreadSafetyMode.NONE) {
builder.buildStatement(UNDEFINED_OFFSET, UNDEFINED_OFFSET) {
scope.createTemporaryVariable(
builder.irImplicitCast(builder.irGet(newReceiver), originalReceiverType),
oldReceiver.name.asString()
)
}
}
// Cast receiver usages back to original type // Cast receiver usages back to original type
irFunction.transformChildrenVoid(object : IrElementTransformerVoid() { irFunction.transformChildrenVoid(object : IrElementTransformerVoid() {
override fun visitGetValue(expression: IrGetValue): IrExpression { override fun visitGetValue(expression: IrGetValue): IrExpression {
if (expression.symbol == oldReceiver.symbol || expression.symbol == classThisReceiverSymbol) { if (expression.type.isAny()) return expression
return with(builder) { if (expression.symbol != oldReceiver.symbol && expression.symbol != classThisReceiverSymbol) return expression
irImplicitCast(irGet(newReceiver), originalReceiverType) return builder.irGet(lazyCastedThis.value)
}
}
return expression
} }
}) })
if (lazyCastedThis.isInitialized()) {
blockBody.statements.add(0, lazyCastedThis.value)
}
} }
} }