JVM_IR: treat suspend-converted references as lambdas for inlining
Again, this is consistent with adapted function references, since they're pretty much the same anyway.
This commit is contained in:
Generated
+5
@@ -8678,6 +8678,11 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("onInlineArgument.kt")
|
||||
public void testOnInlineArgument() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onInlineArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("subtypeOfFunctionalTypeToSuspendConversion.kt")
|
||||
public void testSubtypeOfFunctionalTypeToSuspendConversion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt");
|
||||
|
||||
+8
-7
@@ -76,7 +76,7 @@ class IrInlineCodegen(
|
||||
blockInfo: BlockInfo
|
||||
) {
|
||||
val isInlineParameter = irValueParameter.isInlineParameter()
|
||||
if (isInlineParameter && isInlineIrExpression(argumentExpression)) {
|
||||
if (isInlineParameter && argumentExpression.isInlineIrExpression()) {
|
||||
val irReference = (argumentExpression as IrBlock).statements.filterIsInstance<IrFunctionReference>().single()
|
||||
val lambdaInfo = IrExpressionLambdaImpl(codegen, irReference, irValueParameter)
|
||||
val closureInfo = invocationParamBuilder.addNextValueParameter(parameterType, true, null, irValueParameter.index)
|
||||
@@ -245,18 +245,19 @@ class IrDefaultLambda(
|
||||
}.toIrBasedDescriptor()
|
||||
}
|
||||
|
||||
fun isInlineIrExpression(argumentExpression: IrExpression) =
|
||||
when (argumentExpression) {
|
||||
is IrBlock -> argumentExpression.isInlineIrBlock()
|
||||
fun IrExpression.isInlineIrExpression() =
|
||||
when (this) {
|
||||
is IrBlock -> origin.isInlineIrExpression()
|
||||
is IrCallableReference<*> -> true.also {
|
||||
assert((0 until argumentExpression.valueArgumentsCount).count { argumentExpression.getValueArgument(it) != null } == 0) {
|
||||
"Expecting 0 value arguments for bounded callable reference: ${argumentExpression.dump()}"
|
||||
assert((0 until valueArgumentsCount).count { getValueArgument(it) != null } == 0) {
|
||||
"Expecting 0 value arguments for bounded callable reference: ${dump()}"
|
||||
}
|
||||
}
|
||||
else -> false
|
||||
}
|
||||
|
||||
fun IrBlock.isInlineIrBlock(): Boolean = origin.isLambda || origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE
|
||||
fun IrStatementOrigin?.isInlineIrExpression() =
|
||||
isLambda || this == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE || this == IrStatementOrigin.SUSPEND_CONVERSION
|
||||
|
||||
fun IrFunction.isInlineFunctionCall(context: JvmBackendContext) =
|
||||
(!context.state.isInlineDisabled || typeParameters.any { it.isReified }) && isInline
|
||||
|
||||
+1
-1
@@ -36,7 +36,7 @@ internal open class IrInlineReferenceLocator(private val context: JvmBackendCont
|
||||
continue
|
||||
|
||||
val valueArgument = expression.getValueArgument(parameter.index) ?: continue
|
||||
if (!isInlineIrExpression(valueArgument))
|
||||
if (!valueArgument.isInlineIrExpression())
|
||||
continue
|
||||
|
||||
if (valueArgument is IrBlock) {
|
||||
|
||||
+1
-1
@@ -54,7 +54,7 @@ internal class FunctionReferenceLowering(private val context: JvmBackendContext)
|
||||
// because they are also their own continuation classes.
|
||||
// TODO: Currently, origin of callable references explicitly written in source code is null. Do we need to create one?
|
||||
private fun IrFunctionReference.isSuspendFunctionReference(): Boolean = isSuspend &&
|
||||
(origin == null || origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE)
|
||||
(origin == null || origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE || origin == IrStatementOrigin.SUSPEND_CONVERSION)
|
||||
|
||||
override fun lower(irFile: IrFile) {
|
||||
ignoredFunctionReferences.addAll(IrInlineReferenceLocator.scan(context, irFile))
|
||||
|
||||
+2
-1
@@ -8,6 +8,7 @@ package org.jetbrains.kotlin.backend.jvm.lower
|
||||
import org.jetbrains.kotlin.backend.common.FileLoweringPass
|
||||
import org.jetbrains.kotlin.backend.common.phaser.makeIrModulePhase
|
||||
import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
||||
import org.jetbrains.kotlin.backend.jvm.codegen.isInlineIrExpression
|
||||
import org.jetbrains.kotlin.ir.IrElement
|
||||
import org.jetbrains.kotlin.ir.IrStatement
|
||||
import org.jetbrains.kotlin.ir.declarations.IrClass
|
||||
@@ -37,7 +38,7 @@ private class RemoveDeclarationsThatWouldBeInlinedLowering(val context: JvmBacke
|
||||
override fun visitElement(element: IrElement) = element.acceptChildrenVoid(this)
|
||||
|
||||
override fun visitFunctionReference(expression: IrFunctionReference) {
|
||||
if (expression.origin.isLambda || expression.origin == IrStatementOrigin.ADAPTED_FUNCTION_REFERENCE) {
|
||||
if (expression.origin.isInlineIrExpression()) {
|
||||
loweredLambdasToDelete.add(expression.symbol.owner)
|
||||
}
|
||||
|
||||
|
||||
+1
-4
@@ -109,12 +109,9 @@ private class SuspendLambdaLowering(context: JvmBackendContext) : SuspendLowerin
|
||||
override fun lower(irFile: IrFile) {
|
||||
val inlineReferences = IrInlineReferenceLocator.scan(context, irFile)
|
||||
irFile.transformChildrenVoid(object : IrElementTransformerVoidWithContext() {
|
||||
private fun IrFunctionReference.shouldBeTreatedAsSuspendLambda() =
|
||||
isSuspend && (origin == IrStatementOrigin.LAMBDA || origin == IrStatementOrigin.SUSPEND_CONVERSION)
|
||||
|
||||
override fun visitBlock(expression: IrBlock): IrExpression {
|
||||
val reference = expression.statements.lastOrNull() as? IrFunctionReference ?: return super.visitBlock(expression)
|
||||
if (reference.shouldBeTreatedAsSuspendLambda() && reference !in inlineReferences) {
|
||||
if (reference.isSuspend && reference.origin.isLambda && reference !in inlineReferences) {
|
||||
assert(expression.statements.size == 2 && expression.statements[0] is IrFunction)
|
||||
expression.transformChildrenVoid(this)
|
||||
val parent = currentDeclarationParent ?: error("No current declaration parent at ${reference.dump()}")
|
||||
|
||||
+21
@@ -0,0 +1,21 @@
|
||||
// !LANGUAGE: +SuspendConversion
|
||||
// WITH_RUNTIME
|
||||
// WITH_COROUTINES
|
||||
// IGNORE_BACKEND: JVM, NATIVE
|
||||
// IGNORE_LIGHT_ANALYSIS
|
||||
|
||||
// `lambda` should not be wrapped in yet another object (so no OnInlineArgumentKt$box$1$1).
|
||||
// CHECK_BYTECODE_LISTING
|
||||
|
||||
import helpers.*
|
||||
import kotlin.coroutines.*
|
||||
import kotlin.coroutines.intrinsics.*
|
||||
|
||||
inline suspend fun runS(fn: suspend (String) -> String) = fn("O")
|
||||
|
||||
fun box(): String {
|
||||
var test = "Failed"
|
||||
val lambda: (String) -> String = { it + "K" }
|
||||
suspend { test = runS(lambda) }.startCoroutine(EmptyContinuation)
|
||||
return test
|
||||
}
|
||||
+36
@@ -0,0 +1,36 @@
|
||||
@kotlin.coroutines.jvm.internal.DebugMetadata
|
||||
@kotlin.Metadata
|
||||
final class OnInlineArgumentKt$box$1 {
|
||||
// source: 'onInlineArgument.kt'
|
||||
enclosing method OnInlineArgumentKt.box()Ljava/lang/String;
|
||||
synthetic final field $lambda: kotlin.jvm.functions.Function1
|
||||
synthetic final field $test: kotlin.jvm.internal.Ref$ObjectRef
|
||||
field label: int
|
||||
inner (anonymous) class OnInlineArgumentKt$box$1
|
||||
method <init>(p0: kotlin.jvm.internal.Ref$ObjectRef, p1: kotlin.jvm.functions.Function1, p2: kotlin.coroutines.Continuation): void
|
||||
public final @org.jetbrains.annotations.NotNull method create(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): kotlin.coroutines.Continuation
|
||||
public final method invoke(p0: java.lang.Object): java.lang.Object
|
||||
public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
final class OnInlineArgumentKt$box$lambda$1 {
|
||||
// source: 'onInlineArgument.kt'
|
||||
enclosing method OnInlineArgumentKt.box()Ljava/lang/String;
|
||||
public final static field INSTANCE: OnInlineArgumentKt$box$lambda$1
|
||||
inner (anonymous) class OnInlineArgumentKt$box$lambda$1
|
||||
static method <clinit>(): void
|
||||
method <init>(): void
|
||||
public final @org.jetbrains.annotations.NotNull method invoke(@org.jetbrains.annotations.NotNull p0: java.lang.String): java.lang.String
|
||||
public synthetic bridge method invoke(p0: java.lang.Object): java.lang.Object
|
||||
}
|
||||
|
||||
@kotlin.Metadata
|
||||
public final class OnInlineArgumentKt {
|
||||
// source: 'onInlineArgument.kt'
|
||||
inner (anonymous) class OnInlineArgumentKt$box$1
|
||||
inner (anonymous) class OnInlineArgumentKt$box$lambda$1
|
||||
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
|
||||
private final static method runS$$forInline(p0: kotlin.jvm.functions.Function2, p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||
public final static @org.jetbrains.annotations.Nullable method runS(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function2, @org.jetbrains.annotations.NotNull p1: kotlin.coroutines.Continuation): java.lang.Object
|
||||
}
|
||||
+5
@@ -9893,6 +9893,11 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("onInlineArgument.kt")
|
||||
public void testOnInlineArgument() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onInlineArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("subtypeOfFunctionalTypeToSuspendConversion.kt")
|
||||
public void testSubtypeOfFunctionalTypeToSuspendConversion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt");
|
||||
|
||||
+5
@@ -9885,6 +9885,11 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("onInlineArgument.kt")
|
||||
public void ignoreOnInlineArgument() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onInlineArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("subtypeOfFunctionalTypeToSuspendConversion.kt")
|
||||
public void ignoreSubtypeOfFunctionalTypeToSuspendConversion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt");
|
||||
|
||||
+5
@@ -8678,6 +8678,11 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("onInlineArgument.kt")
|
||||
public void testOnInlineArgument() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onInlineArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("subtypeOfFunctionalTypeToSuspendConversion.kt")
|
||||
public void testSubtypeOfFunctionalTypeToSuspendConversion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt");
|
||||
|
||||
Generated
+5
@@ -7373,6 +7373,11 @@ public class IrJsCodegenBoxES6TestGenerated extends AbstractIrJsCodegenBoxES6Tes
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("onInlineArgument.kt")
|
||||
public void testOnInlineArgument() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onInlineArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("subtypeOfFunctionalTypeToSuspendConversion.kt")
|
||||
public void testSubtypeOfFunctionalTypeToSuspendConversion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt");
|
||||
|
||||
Generated
+5
@@ -7373,6 +7373,11 @@ public class IrJsCodegenBoxTestGenerated extends AbstractIrJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("onInlineArgument.kt")
|
||||
public void testOnInlineArgument() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onInlineArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("subtypeOfFunctionalTypeToSuspendConversion.kt")
|
||||
public void testSubtypeOfFunctionalTypeToSuspendConversion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt");
|
||||
|
||||
+5
@@ -7373,6 +7373,11 @@ public class JsCodegenBoxTestGenerated extends AbstractJsCodegenBoxTest {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("onInlineArgument.kt")
|
||||
public void testOnInlineArgument() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/onInlineArgument.kt");
|
||||
}
|
||||
|
||||
@TestMetadata("subtypeOfFunctionalTypeToSuspendConversion.kt")
|
||||
public void testSubtypeOfFunctionalTypeToSuspendConversion() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/coroutines/suspendConversion/subtypeOfFunctionalTypeToSuspendConversion.kt");
|
||||
|
||||
Reference in New Issue
Block a user