[Wasm] Fix inliner issues (KT-56584)
* Fix objects in inline functions and lambdas: * Add common lowerings used in K/JS and K/Native * Fix inline lambda call detection logic in presence of additional casts Merge-request: KT-MR-8791 Merged-by: Svyatoslav Kuzmich <svyatoslav.kuzmich@jetbrains.com>
This commit is contained in:
committed by
Space Team
parent
1b5210b870
commit
26c1098a4f
+12
-2
@@ -258,7 +258,7 @@ class FunctionInlining(
|
||||
if (!isLambdaCall(expression))
|
||||
return super.visitCall(expression)
|
||||
|
||||
val dispatchReceiver = expression.dispatchReceiver as IrGetValue
|
||||
val dispatchReceiver = expression.dispatchReceiver?.unwrapAdditionalImplicitCastsIfNeeded() as IrGetValue
|
||||
val functionArgument = substituteMap[dispatchReceiver.symbol.owner] ?: return super.visitCall(expression)
|
||||
if ((dispatchReceiver.symbol.owner as? IrValueParameter)?.isNoinline == true)
|
||||
return super.visitCall(expression)
|
||||
@@ -414,6 +414,16 @@ class FunctionInlining(
|
||||
else
|
||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, this)
|
||||
|
||||
// With `insertAdditionalImplicitCasts` flag we sometimes insert
|
||||
// casts to inline lambda parameters before calling `invoke` on them.
|
||||
// Unwrapping these casts helps us satisfy inline lambda call detection logic.
|
||||
private fun IrExpression.unwrapAdditionalImplicitCastsIfNeeded(): IrExpression {
|
||||
if (insertAdditionalImplicitCasts && this is IrTypeOperatorCall && this.operator == IrTypeOperator.IMPLICIT_CAST) {
|
||||
return this.argument.unwrapAdditionalImplicitCastsIfNeeded()
|
||||
}
|
||||
return this
|
||||
}
|
||||
|
||||
private fun isLambdaCall(irCall: IrCall): Boolean {
|
||||
val callee = irCall.symbol.owner
|
||||
val dispatchReceiver = callee.dispatchReceiverParameter ?: return false
|
||||
@@ -421,7 +431,7 @@ class FunctionInlining(
|
||||
|
||||
return (dispatchReceiver.type.isFunction() || dispatchReceiver.type.isSuspendFunction())
|
||||
&& callee.name == OperatorNameConventions.INVOKE
|
||||
&& irCall.dispatchReceiver is IrGetValue
|
||||
&& irCall.dispatchReceiver?.unwrapAdditionalImplicitCastsIfNeeded() is IrGetValue
|
||||
}
|
||||
|
||||
private inner class ParameterToArgument(
|
||||
|
||||
+49
-12
@@ -10,6 +10,9 @@ import org.jetbrains.kotlin.backend.common.lower
|
||||
import org.jetbrains.kotlin.backend.common.lower.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.coroutines.AddContinuationToNonLocalSuspendFunctionsLowering
|
||||
import org.jetbrains.kotlin.backend.common.lower.inline.FunctionInlining
|
||||
import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesExtractionFromInlineFunctionsLowering
|
||||
import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineFunctionsLowering
|
||||
import org.jetbrains.kotlin.backend.common.lower.inline.LocalClassesInInlineLambdasLowering
|
||||
import org.jetbrains.kotlin.backend.common.lower.loops.ForLoopsLowering
|
||||
import org.jetbrains.kotlin.backend.common.lower.optimizations.PropertyAccessorInlineLowering
|
||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||
@@ -110,6 +113,36 @@ private val lateinitUsageLoweringPhase = makeWasmModulePhase(
|
||||
description = "Insert checks for lateinit field references"
|
||||
)
|
||||
|
||||
private val sharedVariablesLoweringPhase = makeWasmModulePhase(
|
||||
::SharedVariablesLowering,
|
||||
name = "SharedVariablesLowering",
|
||||
description = "Box captured mutable variables",
|
||||
prerequisite = setOf(
|
||||
lateinitDeclarationLoweringPhase,
|
||||
lateinitUsageLoweringPhase
|
||||
)
|
||||
)
|
||||
|
||||
private val localClassesInInlineLambdasPhase = makeWasmModulePhase(
|
||||
::LocalClassesInInlineLambdasLowering,
|
||||
name = "LocalClassesInInlineLambdasPhase",
|
||||
description = "Extract local classes from inline lambdas",
|
||||
)
|
||||
|
||||
private val localClassesInInlineFunctionsPhase = makeWasmModulePhase(
|
||||
::LocalClassesInInlineFunctionsLowering,
|
||||
name = "LocalClassesInInlineFunctionsPhase",
|
||||
description = "Extract local classes from inline functions",
|
||||
)
|
||||
|
||||
private val localClassesExtractionFromInlineFunctionsPhase = makeWasmModulePhase(
|
||||
{ context -> LocalClassesExtractionFromInlineFunctionsLowering(context) },
|
||||
name = "localClassesExtractionFromInlineFunctionsPhase",
|
||||
description = "Move local classes from inline functions into nearest declaration container",
|
||||
prerequisite = setOf(localClassesInInlineFunctionsPhase)
|
||||
)
|
||||
|
||||
|
||||
private val wrapInlineDeclarationsWithReifiedTypeParametersPhase = makeWasmModulePhase(
|
||||
::WrapInlineDeclarationsWithReifiedTypeParametersLowering,
|
||||
name = "WrapInlineDeclarationsWithReifiedTypeParametersPhase",
|
||||
@@ -118,14 +151,20 @@ private val wrapInlineDeclarationsWithReifiedTypeParametersPhase = makeWasmModul
|
||||
|
||||
private val functionInliningPhase = makeCustomWasmModulePhase(
|
||||
{ context, module ->
|
||||
FunctionInlining(context, null, true).inline(module)
|
||||
FunctionInlining(
|
||||
context = context,
|
||||
innerClassesSupport = context.innerClassesSupport,
|
||||
insertAdditionalImplicitCasts = true,
|
||||
).inline(module)
|
||||
module.patchDeclarationParents()
|
||||
},
|
||||
name = "FunctionInliningPhase",
|
||||
description = "Perform function inlining",
|
||||
prerequisite = setOf(
|
||||
expectDeclarationsRemovingPhase,
|
||||
wrapInlineDeclarationsWithReifiedTypeParametersPhase
|
||||
wrapInlineDeclarationsWithReifiedTypeParametersPhase,
|
||||
localClassesInInlineLambdasPhase,
|
||||
localClassesInInlineFunctionsPhase,
|
||||
)
|
||||
)
|
||||
|
||||
@@ -238,12 +277,6 @@ private val enumEntryRemovalLoweringPhase = makeWasmModulePhase(
|
||||
)
|
||||
|
||||
|
||||
private val sharedVariablesLoweringPhase = makeWasmModulePhase(
|
||||
::SharedVariablesLowering,
|
||||
name = "SharedVariablesLowering",
|
||||
description = "Box captured mutable variables"
|
||||
)
|
||||
|
||||
private val propertyReferenceLowering = makeWasmModulePhase(
|
||||
::WasmPropertyReferenceLowering,
|
||||
name = "WasmPropertyReferenceLowering",
|
||||
@@ -563,6 +596,14 @@ val wasmPhases = SameTypeNamedCompilerPhase(
|
||||
excludeDeclarationsFromCodegenPhase then
|
||||
expectDeclarationsRemovingPhase then
|
||||
|
||||
lateinitNullableFieldsPhase then
|
||||
lateinitDeclarationLoweringPhase then
|
||||
lateinitUsageLoweringPhase then
|
||||
sharedVariablesLoweringPhase then
|
||||
localClassesInInlineLambdasPhase then
|
||||
localClassesInInlineFunctionsPhase then
|
||||
localClassesExtractionFromInlineFunctionsPhase then
|
||||
|
||||
// TODO: Need some helpers from stdlib
|
||||
// arrayConstructorPhase then
|
||||
wrapInlineDeclarationsWithReifiedTypeParametersPhase then
|
||||
@@ -570,9 +611,6 @@ val wasmPhases = SameTypeNamedCompilerPhase(
|
||||
functionInliningPhase then
|
||||
removeInlineDeclarationsWithReifiedTypeParametersLoweringPhase then
|
||||
|
||||
lateinitNullableFieldsPhase then
|
||||
lateinitDeclarationLoweringPhase then
|
||||
lateinitUsageLoweringPhase then
|
||||
tailrecLoweringPhase then
|
||||
|
||||
enumClassConstructorLoweringPhase then
|
||||
@@ -583,7 +621,6 @@ val wasmPhases = SameTypeNamedCompilerPhase(
|
||||
enumEntryCreateGetInstancesFunsLoweringPhase then
|
||||
enumSyntheticFunsLoweringPhase then
|
||||
|
||||
sharedVariablesLoweringPhase then
|
||||
propertyReferenceLowering then
|
||||
callableReferencePhase then
|
||||
singleAbstractMethodPhase then
|
||||
|
||||
@@ -1,6 +1,4 @@
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND: WASM
|
||||
// WASM_MUTE_REASON: UNKNOWN
|
||||
// WITH_STDLIB
|
||||
|
||||
interface Runnable {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// MODULE: lib
|
||||
// FILE: lib.kt
|
||||
interface I {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// KT-33992
|
||||
|
||||
class P<T>(val a: T, val b: T)
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
|
||||
// FILE: utils.kt
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// IGNORE_BACKEND: JVM, WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
||||
|
||||
import kotlin.IllegalStateException
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// IGNORE_BACKEND: JVM, WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
||||
|
||||
import kotlin.IllegalStateException
|
||||
|
||||
@@ -1,5 +1,5 @@
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// IGNORE_BACKEND: JVM, WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
||||
|
||||
import kotlin.IllegalStateException
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// FILE: 1.kt
|
||||
|
||||
package test
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// FILE: 1.kt
|
||||
class E(val x: String) {
|
||||
inner class Inner {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// FILE: 1.kt
|
||||
class O(val a: String) {
|
||||
inner class I1(val b: String) {
|
||||
|
||||
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// FILE: 1.kt
|
||||
class E(val x: String) {
|
||||
fun bar() = x
|
||||
|
||||
Vendored
-1
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// FILE: 1.kt
|
||||
class E<T>(val x: T) {
|
||||
inner class Inner {
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// IGNORE_BACKEND: JVM
|
||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_IR_AGAINST_OLD
|
||||
// FILE: a.kt
|
||||
|
||||
@@ -1,4 +1,3 @@
|
||||
// IGNORE_BACKEND: WASM
|
||||
// NO_CHECK_LAMBDA_INLINING
|
||||
// FILE: 1.kt
|
||||
|
||||
|
||||
Reference in New Issue
Block a user