[IR] Eliminate redundant boxing/unboxing of MFVC after inlining

Signed-off-by: Evgeniy.Zhelenskiy <Evgeniy.Zhelenskiy@jetbrains.com>

#KT-1179
This commit is contained in:
Evgeniy.Zhelenskiy
2022-11-13 21:57:15 +01:00
committed by Space Team
parent a3e396e7e4
commit 40f38c8adb
25 changed files with 726 additions and 2292 deletions
@@ -1,7 +1,6 @@
@kotlin.Metadata
public final class ClassFlatteningKt {
// source: 'classFlattening.kt'
private final static method box$lambda$3$lambda$2(p0: int, p1: int, p2: java.lang.String, p3: int, p4: int, p5: java.lang.String, p6: int, p7: int, p8: java.lang.String): void
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
public final static method gmfvc-Ket90g4(p0: int, p1: int, p2: int, @org.jetbrains.annotations.NotNull p3: java.lang.String, p4: int, p5: int, p6: int, @org.jetbrains.annotations.NotNull p7: java.lang.String, p8: int): int
public final static method ic-K5cTq2M(p0: int): int
@@ -63,7 +63,6 @@ public final class DefaultParametersKt {
public final static @org.jetbrains.annotations.NotNull method complexFun-552ch2I(p0: double, p1: double, p2: double, p3: double, p4: double, p5: double): java.lang.String
public synthetic static method complexInlineFun-552ch2I$default(p0: double, p1: double, p2: double, p3: double, p4: double, p5: double, p6: int, p7: java.lang.Object): java.lang.String
public final static @org.jetbrains.annotations.NotNull method complexInlineFun-552ch2I(p0: double, p1: double, p2: double, p3: double, p4: double, p5: double): java.lang.String
public final inner class kotlin/jvm/internal/Ref$DoubleRef
}
@kotlin.Metadata
File diff suppressed because it is too large Load Diff
@@ -3,38 +3,13 @@
// WITH_COROUTINES
// TARGET_BACKEND: JVM_IR
// LANGUAGE: +ValueClasses
// FIR_IDENTICAL
// FILE: caller.kt
import kotlin.coroutines.*
fun runSuspend(block: suspend () -> Unit) {
val run = RunSuspend()
block.startCoroutine(run)
run.await()
}
private class RunSuspend : Continuation<Unit> {
override val context: CoroutineContext
get() = EmptyCoroutineContext
var result: Result<Unit>? = null
override fun resumeWith(result: Result<Unit>) = synchronized(this) {
this.result = result
@Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).notifyAll()
}
fun await() = synchronized(this) {
while (true) {
when (val result = this.result) {
null -> @Suppress("PLATFORM_CLASS_MAPPED_TO_KOTLIN") (this as Object).wait()
else -> {
result.getOrThrow() // throw up failure
return
}
}
}
}
block.startCoroutine(Continuation(EmptyCoroutineContext) { it.getOrThrow() })
}
// FILE: test.kt
@@ -233,6 +233,17 @@ public final class AnotherKt {
public final static @org.jetbrains.annotations.Nullable method requiresF-lIoT8es(p0: double, p1: double, @org.jetbrains.annotations.NotNull p2: F, @org.jetbrains.annotations.NotNull p3: kotlin.coroutines.Continuation): java.lang.Object
}
@kotlin.Metadata
public final class CallerKt$runSuspend$$inlined$Continuation$1 {
// source: 'Continuation.kt'
enclosing method CallerKt.runSuspend(Lkotlin/jvm/functions/Function1;)V
synthetic final field $context: kotlin.coroutines.CoroutineContext
inner (anonymous) class CallerKt$runSuspend$$inlined$Continuation$1
public method <init>(p0: kotlin.coroutines.CoroutineContext): void
public @org.jetbrains.annotations.NotNull method getContext(): kotlin.coroutines.CoroutineContext
public method resumeWith(@org.jetbrains.annotations.NotNull p0: java.lang.Object): void
}
@kotlin.Metadata
public final class CallerKt {
// source: 'caller.kt'
@@ -306,18 +317,6 @@ public interface F {
public abstract @org.jetbrains.annotations.Nullable method run-GPBa7dw(p0: double, p1: double, @org.jetbrains.annotations.NotNull p2: kotlin.coroutines.Continuation): java.lang.Object
}
@kotlin.Metadata
final class RunSuspend {
// source: 'caller.kt'
private @org.jetbrains.annotations.Nullable field result: kotlin.Result
public method <init>(): void
public final method await(): void
public @org.jetbrains.annotations.NotNull method getContext(): kotlin.coroutines.CoroutineContext
public final @org.jetbrains.annotations.Nullable method getResult-xLWZpok(): kotlin.Result
public method resumeWith(@org.jetbrains.annotations.NotNull p0: java.lang.Object): void
public final method setResult(@org.jetbrains.annotations.Nullable p0: kotlin.Result): void
}
@kotlin.coroutines.jvm.internal.DebugMetadata
@kotlin.Metadata
final class TestKt$box$10 {
@@ -2049,11 +2048,6 @@ public final class TestKt {
inner (anonymous) class TestKt$box$97
inner (anonymous) class TestKt$box$98
inner (anonymous) class TestKt$box$99
private final static method box$lambda$2$lambda$1(p0: double, p1: double, p2: double, p3: double): DPoint
private final static method box$lambda$4$lambda$3(p0: double, p1: double, p2: double, p3: double): DPoint
private final static method box$lambda$7$lambda$6(p0: double, p1: double): DPoint
private final static method box$stub_for_inlining$0$stub_for_inlining(p0: double, p1: double, p2: double, p3: double): DPoint
private final static method box$stub_for_inlining$9$stub_for_inlining$8(p0: double, p1: double): DPoint
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
public final static @org.jetbrains.annotations.NotNull method consume-lIoT8es(p0: double, p1: double, p2: double, p3: double, @org.jetbrains.annotations.NotNull p4: kotlin.jvm.functions.Function2): DPoint
public final static @org.jetbrains.annotations.NotNull method consumeInline-lIoT8es(p0: double, p1: double, p2: double, p3: double, @org.jetbrains.annotations.NotNull p4: kotlin.jvm.functions.Function2): DPoint
@@ -0,0 +1,85 @@
// LANGUAGE: +ValueClasses
// TARGET_BACKEND: JVM_IR
// CHECK_BYTECODE_LISTING
// WITH_STDLIB
// CHECK_BYTECODE_TEXT
// FIR_IDENTICAL
// FILE: caller.kt
import kotlin.coroutines.*
fun runSuspend(block: suspend () -> Unit) {
block.startCoroutine(Continuation(EmptyCoroutineContext) { it.getOrThrow() })
}
// FILE: dependency.kt
@JvmInline
value class DPoint(val x: Double, val y: Double)
@JvmInline
value class DSegment(val p1: DPoint, val p2: DPoint)
inline fun DSegment.myLet(f: (DSegment) -> DPoint) = f(this)
// FILE: test.kt
import kotlin.coroutines.suspendCoroutine
import kotlin.coroutines.resume
fun supply(x: Any?) = Unit
fun box(): String {
val point = DPoint(1.0, 2.0)
val pointX2 = DPoint(2.0, 4.0)
val segment = DSegment(point, pointX2)
supply("a")
point.let { it.x }
supply("b")
point.let { it }
supply("c")
run { DPoint (1.0, 2.0) }
supply("d")
val x = run { DPoint(100.0, 200.0) }
supply("e")
require(x == DPoint(100.0, 200.0))
supply("f")
point.let { DPoint(2 * it.x, 2 * it.y) }
supply("g")
require(point == point.let { it })
supply("h")
require(pointX2 == point.let { DPoint(2 * it.x, 2 * it.y) })
supply("i")
segment.myLet { it.p1 }
supply("j")
segment.myLet { it.p2 }
supply("k")
require(segment.myLet { it.p1 } == point)
supply("l")
require(segment.myLet { it.p2 } == pointX2)
supply("m")
require(segment.let { it.let { it } } == segment)
supply("n")
var a = 1
segment.let { a++ }
val b = segment.let { ++a }
require(a == 3)
supply("o")
runSuspend { require(suspendFun() == DPoint(1.0, 2.0).toString()) }
supply("p")
return "OK"
}
suspend fun f() = suspendCoroutine { it.resume(Unit) }
suspend fun suspendFun(): String {
val x = run { f(); DPoint(1.0, 2.0) }
return x.toString()
}
// @TestKt.class:
// 0 valueOf
// 0 INVOKE(STATIC|VIRTUAL) (DPoint|DSegment).*\.(un)?box
// 0 INVOKE(STATIC|VIRTUAL) .*(stub_for_inlining|lambda)
// 0 DCONST_0
@@ -0,0 +1,110 @@
@kotlin.Metadata
public final class CallerKt$runSuspend$$inlined$Continuation$1 {
// source: 'Continuation.kt'
enclosing method CallerKt.runSuspend(Lkotlin/jvm/functions/Function1;)V
synthetic final field $context: kotlin.coroutines.CoroutineContext
inner (anonymous) class CallerKt$runSuspend$$inlined$Continuation$1
public method <init>(p0: kotlin.coroutines.CoroutineContext): void
public @org.jetbrains.annotations.NotNull method getContext(): kotlin.coroutines.CoroutineContext
public method resumeWith(@org.jetbrains.annotations.NotNull p0: java.lang.Object): void
}
@kotlin.Metadata
public final class CallerKt {
// source: 'caller.kt'
public final static method runSuspend(@org.jetbrains.annotations.NotNull p0: kotlin.jvm.functions.Function1): void
}
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class DPoint {
// source: 'dependency.kt'
private final field x: double
private final field y: double
private synthetic method <init>(p0: double, p1: double): void
public synthetic final static method box-impl(p0: double, p1: double): DPoint
public final static method constructor-impl(p0: double, p1: double): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: double, p1: double, p2: java.lang.Object): boolean
public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double): boolean
public final method getX(): double
public final method getY(): double
public method hashCode(): int
public static method hashCode-impl(p0: double, p1: double): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: double, p1: double): java.lang.String
public synthetic final method unbox-impl-x(): double
public synthetic final method unbox-impl-y(): double
}
@kotlin.jvm.JvmInline
@kotlin.Metadata
public final class DSegment {
// source: 'dependency.kt'
private final field p1-x: double
private final field p1-y: double
private final field p2-x: double
private final field p2-y: double
private synthetic method <init>(p0: double, p1: double, p2: double, p3: double): void
public synthetic final static method box-impl(p0: double, p1: double, p2: double, p3: double): DSegment
public final static method constructor-impl(p0: double, p1: double, p2: double, p3: double): void
public method equals(@org.jetbrains.annotations.Nullable p0: java.lang.Object): boolean
public static method equals-impl(p0: double, p1: double, p2: double, p3: double, p4: java.lang.Object): boolean
public final static method equals-impl0(p0: double, p1: double, p2: double, p3: double, p4: double, p5: double, p6: double, p7: double): boolean
public final @org.jetbrains.annotations.NotNull method getP1(): DPoint
public final @org.jetbrains.annotations.NotNull method getP2(): DPoint
public method hashCode(): int
public static method hashCode-impl(p0: double, p1: double, p2: double, p3: double): int
public @org.jetbrains.annotations.NotNull method toString(): java.lang.String
public static method toString-impl(p0: double, p1: double, p2: double, p3: double): java.lang.String
public synthetic final method unbox-impl-p1(): DPoint
public synthetic final method unbox-impl-p1-x(): double
public synthetic final method unbox-impl-p1-y(): double
public synthetic final method unbox-impl-p2(): DPoint
public synthetic final method unbox-impl-p2-x(): double
public synthetic final method unbox-impl-p2-y(): double
}
@kotlin.Metadata
public final class DependencyKt {
// source: 'dependency.kt'
public final static @org.jetbrains.annotations.NotNull method myLet-GPBa7dw(p0: double, p1: double, p2: double, p3: double, @org.jetbrains.annotations.NotNull p4: kotlin.jvm.functions.Function1): DPoint
}
@kotlin.coroutines.jvm.internal.DebugMetadata
@kotlin.Metadata
final class TestKt$box$13 {
// source: 'test.kt'
enclosing method TestKt.box()Ljava/lang/String;
field label: int
inner (anonymous) class TestKt$box$13
method <init>(p0: 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 @org.jetbrains.annotations.Nullable method invoke(@org.jetbrains.annotations.Nullable p0: kotlin.coroutines.Continuation): java.lang.Object
public synthetic bridge 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.coroutines.jvm.internal.DebugMetadata
@kotlin.Metadata
final class TestKt$suspendFun$1 {
// source: 'test.kt'
enclosing method TestKt.suspendFun(Lkotlin/coroutines/Continuation;)Ljava/lang/Object;
field label: int
synthetic field result: java.lang.Object
inner (anonymous) class TestKt$suspendFun$1
method <init>(p0: kotlin.coroutines.Continuation): void
public final @org.jetbrains.annotations.Nullable method invokeSuspend(@org.jetbrains.annotations.NotNull p0: java.lang.Object): java.lang.Object
}
@kotlin.Metadata
public final class TestKt {
// source: 'test.kt'
inner (anonymous) class TestKt$box$13
inner (anonymous) class TestKt$suspendFun$1
public final static @org.jetbrains.annotations.NotNull method box(): java.lang.String
public final static @org.jetbrains.annotations.Nullable method f(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object
public final static method supply(@org.jetbrains.annotations.Nullable p0: java.lang.Object): void
public final static @org.jetbrains.annotations.Nullable method suspendFun(@org.jetbrains.annotations.NotNull p0: kotlin.coroutines.Continuation): java.lang.Object
public final inner class kotlin/jvm/internal/Ref$IntRef
}