[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))
|
if (!isLambdaCall(expression))
|
||||||
return super.visitCall(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)
|
val functionArgument = substituteMap[dispatchReceiver.symbol.owner] ?: return super.visitCall(expression)
|
||||||
if ((dispatchReceiver.symbol.owner as? IrValueParameter)?.isNoinline == true)
|
if ((dispatchReceiver.symbol.owner as? IrValueParameter)?.isNoinline == true)
|
||||||
return super.visitCall(expression)
|
return super.visitCall(expression)
|
||||||
@@ -414,6 +414,16 @@ class FunctionInlining(
|
|||||||
else
|
else
|
||||||
IrTypeOperatorCallImpl(startOffset, endOffset, type, IrTypeOperator.IMPLICIT_CAST, type, this)
|
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 {
|
private fun isLambdaCall(irCall: IrCall): Boolean {
|
||||||
val callee = irCall.symbol.owner
|
val callee = irCall.symbol.owner
|
||||||
val dispatchReceiver = callee.dispatchReceiverParameter ?: return false
|
val dispatchReceiver = callee.dispatchReceiverParameter ?: return false
|
||||||
@@ -421,7 +431,7 @@ class FunctionInlining(
|
|||||||
|
|
||||||
return (dispatchReceiver.type.isFunction() || dispatchReceiver.type.isSuspendFunction())
|
return (dispatchReceiver.type.isFunction() || dispatchReceiver.type.isSuspendFunction())
|
||||||
&& callee.name == OperatorNameConventions.INVOKE
|
&& callee.name == OperatorNameConventions.INVOKE
|
||||||
&& irCall.dispatchReceiver is IrGetValue
|
&& irCall.dispatchReceiver?.unwrapAdditionalImplicitCastsIfNeeded() is IrGetValue
|
||||||
}
|
}
|
||||||
|
|
||||||
private inner class ParameterToArgument(
|
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.*
|
||||||
import org.jetbrains.kotlin.backend.common.lower.coroutines.AddContinuationToNonLocalSuspendFunctionsLowering
|
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.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.loops.ForLoopsLowering
|
||||||
import org.jetbrains.kotlin.backend.common.lower.optimizations.PropertyAccessorInlineLowering
|
import org.jetbrains.kotlin.backend.common.lower.optimizations.PropertyAccessorInlineLowering
|
||||||
import org.jetbrains.kotlin.backend.common.phaser.*
|
import org.jetbrains.kotlin.backend.common.phaser.*
|
||||||
@@ -110,6 +113,36 @@ private val lateinitUsageLoweringPhase = makeWasmModulePhase(
|
|||||||
description = "Insert checks for lateinit field references"
|
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(
|
private val wrapInlineDeclarationsWithReifiedTypeParametersPhase = makeWasmModulePhase(
|
||||||
::WrapInlineDeclarationsWithReifiedTypeParametersLowering,
|
::WrapInlineDeclarationsWithReifiedTypeParametersLowering,
|
||||||
name = "WrapInlineDeclarationsWithReifiedTypeParametersPhase",
|
name = "WrapInlineDeclarationsWithReifiedTypeParametersPhase",
|
||||||
@@ -118,14 +151,20 @@ private val wrapInlineDeclarationsWithReifiedTypeParametersPhase = makeWasmModul
|
|||||||
|
|
||||||
private val functionInliningPhase = makeCustomWasmModulePhase(
|
private val functionInliningPhase = makeCustomWasmModulePhase(
|
||||||
{ context, module ->
|
{ context, module ->
|
||||||
FunctionInlining(context, null, true).inline(module)
|
FunctionInlining(
|
||||||
|
context = context,
|
||||||
|
innerClassesSupport = context.innerClassesSupport,
|
||||||
|
insertAdditionalImplicitCasts = true,
|
||||||
|
).inline(module)
|
||||||
module.patchDeclarationParents()
|
module.patchDeclarationParents()
|
||||||
},
|
},
|
||||||
name = "FunctionInliningPhase",
|
name = "FunctionInliningPhase",
|
||||||
description = "Perform function inlining",
|
description = "Perform function inlining",
|
||||||
prerequisite = setOf(
|
prerequisite = setOf(
|
||||||
expectDeclarationsRemovingPhase,
|
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(
|
private val propertyReferenceLowering = makeWasmModulePhase(
|
||||||
::WasmPropertyReferenceLowering,
|
::WasmPropertyReferenceLowering,
|
||||||
name = "WasmPropertyReferenceLowering",
|
name = "WasmPropertyReferenceLowering",
|
||||||
@@ -563,6 +596,14 @@ val wasmPhases = SameTypeNamedCompilerPhase(
|
|||||||
excludeDeclarationsFromCodegenPhase then
|
excludeDeclarationsFromCodegenPhase then
|
||||||
expectDeclarationsRemovingPhase then
|
expectDeclarationsRemovingPhase then
|
||||||
|
|
||||||
|
lateinitNullableFieldsPhase then
|
||||||
|
lateinitDeclarationLoweringPhase then
|
||||||
|
lateinitUsageLoweringPhase then
|
||||||
|
sharedVariablesLoweringPhase then
|
||||||
|
localClassesInInlineLambdasPhase then
|
||||||
|
localClassesInInlineFunctionsPhase then
|
||||||
|
localClassesExtractionFromInlineFunctionsPhase then
|
||||||
|
|
||||||
// TODO: Need some helpers from stdlib
|
// TODO: Need some helpers from stdlib
|
||||||
// arrayConstructorPhase then
|
// arrayConstructorPhase then
|
||||||
wrapInlineDeclarationsWithReifiedTypeParametersPhase then
|
wrapInlineDeclarationsWithReifiedTypeParametersPhase then
|
||||||
@@ -570,9 +611,6 @@ val wasmPhases = SameTypeNamedCompilerPhase(
|
|||||||
functionInliningPhase then
|
functionInliningPhase then
|
||||||
removeInlineDeclarationsWithReifiedTypeParametersLoweringPhase then
|
removeInlineDeclarationsWithReifiedTypeParametersLoweringPhase then
|
||||||
|
|
||||||
lateinitNullableFieldsPhase then
|
|
||||||
lateinitDeclarationLoweringPhase then
|
|
||||||
lateinitUsageLoweringPhase then
|
|
||||||
tailrecLoweringPhase then
|
tailrecLoweringPhase then
|
||||||
|
|
||||||
enumClassConstructorLoweringPhase then
|
enumClassConstructorLoweringPhase then
|
||||||
@@ -583,7 +621,6 @@ val wasmPhases = SameTypeNamedCompilerPhase(
|
|||||||
enumEntryCreateGetInstancesFunsLoweringPhase then
|
enumEntryCreateGetInstancesFunsLoweringPhase then
|
||||||
enumSyntheticFunsLoweringPhase then
|
enumSyntheticFunsLoweringPhase then
|
||||||
|
|
||||||
sharedVariablesLoweringPhase then
|
|
||||||
propertyReferenceLowering then
|
propertyReferenceLowering then
|
||||||
callableReferencePhase then
|
callableReferencePhase then
|
||||||
singleAbstractMethodPhase then
|
singleAbstractMethodPhase then
|
||||||
|
|||||||
@@ -1,6 +1,4 @@
|
|||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// WASM_MUTE_REASON: UNKNOWN
|
|
||||||
// WITH_STDLIB
|
// WITH_STDLIB
|
||||||
|
|
||||||
interface Runnable {
|
interface Runnable {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// MODULE: lib
|
// MODULE: lib
|
||||||
// FILE: lib.kt
|
// FILE: lib.kt
|
||||||
interface I {
|
interface I {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// KT-33992
|
// KT-33992
|
||||||
|
|
||||||
class P<T>(val a: T, val b: T)
|
class P<T>(val a: T, val b: T)
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// NO_CHECK_LAMBDA_INLINING
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
|
|
||||||
// FILE: utils.kt
|
// FILE: utils.kt
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
||||||
// NO_CHECK_LAMBDA_INLINING
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
||||||
// NO_CHECK_LAMBDA_INLINING
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// NO_CHECK_LAMBDA_INLINING
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// NO_CHECK_LAMBDA_INLINING
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
// IGNORE_BACKEND: JVM, WASM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
||||||
|
|
||||||
import kotlin.IllegalStateException
|
import kotlin.IllegalStateException
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// NO_CHECK_LAMBDA_INLINING
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
// IGNORE_BACKEND: JVM, WASM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
||||||
|
|
||||||
import kotlin.IllegalStateException
|
import kotlin.IllegalStateException
|
||||||
|
|||||||
@@ -1,5 +1,5 @@
|
|||||||
// NO_CHECK_LAMBDA_INLINING
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
// IGNORE_BACKEND: JVM, WASM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
||||||
|
|
||||||
import kotlin.IllegalStateException
|
import kotlin.IllegalStateException
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// NO_CHECK_LAMBDA_INLINING
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_OLD_AGAINST_IR
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// NO_CHECK_LAMBDA_INLINING
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
package test
|
package test
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
class E(val x: String) {
|
class E(val x: String) {
|
||||||
inner class Inner {
|
inner class Inner {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
class O(val a: String) {
|
class O(val a: String) {
|
||||||
inner class I1(val b: String) {
|
inner class I1(val b: String) {
|
||||||
|
|||||||
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
class E(val x: String) {
|
class E(val x: String) {
|
||||||
fun bar() = x
|
fun bar() = x
|
||||||
|
|||||||
Vendored
-1
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
class E<T>(val x: T) {
|
class E<T>(val x: T) {
|
||||||
inner class Inner {
|
inner class Inner {
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// IGNORE_BACKEND: JVM
|
// IGNORE_BACKEND: JVM
|
||||||
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_IR_AGAINST_OLD
|
// IGNORE_BACKEND_MULTI_MODULE: JVM, JVM_MULTI_MODULE_IR_AGAINST_OLD
|
||||||
// FILE: a.kt
|
// FILE: a.kt
|
||||||
|
|||||||
@@ -1,4 +1,3 @@
|
|||||||
// IGNORE_BACKEND: WASM
|
|
||||||
// NO_CHECK_LAMBDA_INLINING
|
// NO_CHECK_LAMBDA_INLINING
|
||||||
// FILE: 1.kt
|
// FILE: 1.kt
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user