Use tail call optimization if ARETURN has multiple sources
#KT-21977: Fixed
This commit is contained in:
+5
-6
@@ -701,12 +701,11 @@ private fun allSuspensionPointsAreTailCalls(
|
|||||||
if (insideTryBlock) return@all false
|
if (insideTryBlock) return@all false
|
||||||
|
|
||||||
safelyReachableReturns[endIndex + 1]?.all { returnIndex ->
|
safelyReachableReturns[endIndex + 1]?.all { returnIndex ->
|
||||||
val sourceInsn =
|
sourceFrames[returnIndex].top().sure {
|
||||||
sourceFrames[returnIndex].top().sure {
|
"There must be some value on stack to return"
|
||||||
"There must be some value on stack to return"
|
}.insns.all { sourceInsn ->
|
||||||
}.insns.singleOrNull()
|
sourceInsn?.let(instructions::indexOf) in beginIndex..endIndex
|
||||||
|
}
|
||||||
sourceInsn?.let(instructions::indexOf) in beginIndex..endIndex
|
|
||||||
} ?: false
|
} ?: false
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -0,0 +1,18 @@
|
|||||||
|
// WITH_RUNTIME
|
||||||
|
import kotlin.coroutines.experimental.*
|
||||||
|
import kotlin.coroutines.experimental.intrinsics.*
|
||||||
|
|
||||||
|
var p: Int = 5846814
|
||||||
|
private suspend fun withoutInline() {
|
||||||
|
val c = { c: Continuation<Unit> ->
|
||||||
|
if (p > 52158) Unit else COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
|
||||||
|
return suspendCoroutineOrReturn(c)
|
||||||
|
}
|
||||||
|
|
||||||
|
private suspend fun withInline() {
|
||||||
|
return suspendCoroutineOrReturn { c ->
|
||||||
|
if (p > 52158) Unit else COROUTINE_SUSPENDED
|
||||||
|
}
|
||||||
|
}
|
||||||
@@ -0,0 +1,20 @@
|
|||||||
|
@kotlin.Metadata
|
||||||
|
final class TailCallIntrinsicsKt$withoutInline$c$1 {
|
||||||
|
public final static field INSTANCE: TailCallIntrinsicsKt$withoutInline$c$1
|
||||||
|
inner class TailCallIntrinsicsKt$withoutInline$c$1
|
||||||
|
static method <clinit>(): void
|
||||||
|
method <init>(): void
|
||||||
|
public final @org.jetbrains.annotations.NotNull method invoke(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
|
public synthetic method invoke(p0: java.lang.Object): java.lang.Object
|
||||||
|
}
|
||||||
|
|
||||||
|
@kotlin.Metadata
|
||||||
|
public final class TailCallIntrinsicsKt {
|
||||||
|
private static field p: int
|
||||||
|
inner class TailCallIntrinsicsKt$withoutInline$c$1
|
||||||
|
static method <clinit>(): void
|
||||||
|
public final static method getP(): int
|
||||||
|
public final static method setP(p0: int): void
|
||||||
|
final static @org.jetbrains.annotations.Nullable method withInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
|
final static @org.jetbrains.annotations.Nullable method withoutInline(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.experimental.Continuation): java.lang.Object
|
||||||
|
}
|
||||||
+6
@@ -151,6 +151,12 @@ public class BytecodeListingTestGenerated extends AbstractBytecodeListingTest {
|
|||||||
doTest(fileName);
|
doTest(fileName);
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@TestMetadata("tailCallIntrinsics.kt")
|
||||||
|
public void testTailCallIntrinsics() throws Exception {
|
||||||
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/tailCallIntrinsics.kt");
|
||||||
|
doTest(fileName);
|
||||||
|
}
|
||||||
|
|
||||||
@TestMetadata("tailSuspendUnitFun.kt")
|
@TestMetadata("tailSuspendUnitFun.kt")
|
||||||
public void testTailSuspendUnitFun() throws Exception {
|
public void testTailSuspendUnitFun() throws Exception {
|
||||||
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/tailSuspendUnitFun.kt");
|
String fileName = KotlinTestUtils.navigationMetadata("compiler/testData/codegen/bytecodeListing/tailSuspendUnitFun.kt");
|
||||||
|
|||||||
Reference in New Issue
Block a user