From 583b51aa1e9805c8614d85c91b1d9d7fe310c5c6 Mon Sep 17 00:00:00 2001 From: Igor Chevdar Date: Tue, 14 Jul 2020 12:30:29 +0500 Subject: [PATCH] [optmz] Some tests on escape analysis --- .../konan/optimizations/EscapeAnalysis.kt | 1 + backend.native/tests/build.gradle | 4 ++ .../tests/codegen/escapeAnalysis/test1.kt | 20 +++++++ .../tests/codegen/escapeAnalysis/test10.kt | 41 +++++++++++++++ .../tests/codegen/escapeAnalysis/test11.kt | 31 +++++++++++ .../tests/codegen/escapeAnalysis/test12.kt | 20 +++++++ .../tests/codegen/escapeAnalysis/test13.kt | 20 +++++++ .../tests/codegen/escapeAnalysis/test2.kt | 20 +++++++ .../tests/codegen/escapeAnalysis/test3.kt | 28 ++++++++++ .../tests/codegen/escapeAnalysis/test4.kt | 30 +++++++++++ .../tests/codegen/escapeAnalysis/test5.kt | 35 +++++++++++++ .../tests/codegen/escapeAnalysis/test6.kt | 40 ++++++++++++++ .../tests/codegen/escapeAnalysis/test7.kt | 52 +++++++++++++++++++ .../tests/codegen/escapeAnalysis/test8.kt | 43 +++++++++++++++ .../tests/codegen/escapeAnalysis/test9.kt | 36 +++++++++++++ .../escapeAnalysis/zeroOutObjectOnAlloc.kt | 25 +++++++++ 16 files changed, 446 insertions(+) create mode 100644 backend.native/tests/codegen/escapeAnalysis/test1.kt create mode 100644 backend.native/tests/codegen/escapeAnalysis/test10.kt create mode 100644 backend.native/tests/codegen/escapeAnalysis/test11.kt create mode 100644 backend.native/tests/codegen/escapeAnalysis/test12.kt create mode 100644 backend.native/tests/codegen/escapeAnalysis/test13.kt create mode 100644 backend.native/tests/codegen/escapeAnalysis/test2.kt create mode 100644 backend.native/tests/codegen/escapeAnalysis/test3.kt create mode 100644 backend.native/tests/codegen/escapeAnalysis/test4.kt create mode 100644 backend.native/tests/codegen/escapeAnalysis/test5.kt create mode 100644 backend.native/tests/codegen/escapeAnalysis/test6.kt create mode 100644 backend.native/tests/codegen/escapeAnalysis/test7.kt create mode 100644 backend.native/tests/codegen/escapeAnalysis/test8.kt create mode 100644 backend.native/tests/codegen/escapeAnalysis/test9.kt create mode 100644 backend.native/tests/codegen/escapeAnalysis/zeroOutObjectOnAlloc.kt diff --git a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/EscapeAnalysis.kt b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/EscapeAnalysis.kt index 8f815027a4a..75f4aef2717 100644 --- a/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/EscapeAnalysis.kt +++ b/backend.native/compiler/ir/backend.native/src/org/jetbrains/kotlin/backend/konan/optimizations/EscapeAnalysis.kt @@ -1416,6 +1416,7 @@ internal object EscapeAnalysis { // opposite subgraph: [d -> v; d -> w; v !-> w; w !-> v] is not interesting, because [d] // can't hold both values simultaneously, but two references can hold the same value // at the same time, that's the difference. + // For concrete example see [codegen/escapeAnalysis/test10.kt]. val connectedNodes = mutableSetOf>() allNodes.filter { nodeIds[it] != null && nodeIds[it.drain] == null /* The drain has been optimized away */ } .forEach { node -> diff --git a/backend.native/tests/build.gradle b/backend.native/tests/build.gradle index ccc7eb832c5..728e63401e1 100644 --- a/backend.native/tests/build.gradle +++ b/backend.native/tests/build.gradle @@ -2770,6 +2770,10 @@ task expression_as_statement(type: KonanLocalTest) { source = "codegen/basics/expression_as_statement.kt" } +task codegen_escapeAnalysis_zeroOutObjectOnAlloc(type: KonanLocalTest) { + source = "codegen/escapeAnalysis/zeroOutObjectOnAlloc.kt" +} + task memory_var1(type: KonanLocalTest) { source = "runtime/memory/var1.kt" } diff --git a/backend.native/tests/codegen/escapeAnalysis/test1.kt b/backend.native/tests/codegen/escapeAnalysis/test1.kt new file mode 100644 index 00000000000..99284436de1 --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/test1.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.test1 + +class A(val s: String) + +// ----- Agressive ----- +// PointsTo: +// RET.v@lue -> P0 +// Escapes: +// ----- Passive ----- +// PointsTo: +// RET.v@lue -> P0 +// Escapes: +fun foo(a: A) = a + +fun main() = println(foo(A("zzz"))) \ No newline at end of file diff --git a/backend.native/tests/codegen/escapeAnalysis/test10.kt b/backend.native/tests/codegen/escapeAnalysis/test10.kt new file mode 100644 index 00000000000..a1ddef9774f --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/test10.kt @@ -0,0 +1,41 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.test10 + +class G(val x: Int) + +class F(val s: String) { + var g = G(0) +} + +class A { + var f = F("") +} + +// ----- Agressive ----- +// PointsTo: +// P0.f -> D0 +// RET.v@lue -> D0 +// Escapes: +// ----- Passive ----- +// PointsTo: +// P0.f -> D0 +// RET.v@lue -> D0 +// Escapes: D0 +fun foo(a: A): F { + val v = F("zzz") + a.f = v + return v +} + +fun bar(): F { + val w = A() + val u = foo(w) + w.f.g = G(42) + return u +} + +fun main() = println(bar().g.x) \ No newline at end of file diff --git a/backend.native/tests/codegen/escapeAnalysis/test11.kt b/backend.native/tests/codegen/escapeAnalysis/test11.kt new file mode 100644 index 00000000000..1e8730a8db5 --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/test11.kt @@ -0,0 +1,31 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.test11 + +class F(val x: Int) + +class A(val s: String) { + var f = F(0) +} + +var f: F? = null + +// ----- Agressive ----- +// PointsTo: +// RET.v@lue -> P0.f +// D0 -> P0.f +// Escapes: D0 +// ----- Passive ----- +// PointsTo: +// RET.v@lue -> P0.f +// D0 -> P0.f +// Escapes: D0 +fun foo(a: A): F { + f = a.f + return a.f +} + +fun main() = println(foo(A("zzz"))) \ No newline at end of file diff --git a/backend.native/tests/codegen/escapeAnalysis/test12.kt b/backend.native/tests/codegen/escapeAnalysis/test12.kt new file mode 100644 index 00000000000..44785fb24e2 --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/test12.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.test12 + +class A(val s: String) + +// ----- Agressive ----- +// PointsTo: +// RET.v@lue -> P0.inte$tines +// Escapes: +// ----- Passive ----- +// PointsTo: +// RET.v@lue -> P0.inte$tines +// Escapes: +fun foo(arr: Array) = arr[0] + +fun main() = println(foo(arrayOf(A("zzz"))).s) \ No newline at end of file diff --git a/backend.native/tests/codegen/escapeAnalysis/test13.kt b/backend.native/tests/codegen/escapeAnalysis/test13.kt new file mode 100644 index 00000000000..e07456a3333 --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/test13.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.test13 + +class A { + var f: A? = null +} + +fun foo(a: A, k: Int): A { + return if (k == 0) a else foo(a.f!!, k - 1) +} + +fun main() { + val a = A() + a.f = A() + println(foo(a, 1)) +} \ No newline at end of file diff --git a/backend.native/tests/codegen/escapeAnalysis/test2.kt b/backend.native/tests/codegen/escapeAnalysis/test2.kt new file mode 100644 index 00000000000..d9068afb897 --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/test2.kt @@ -0,0 +1,20 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.test2 + +class A(val s: String) + +// ----- Agressive ----- +// PointsTo: +// RET.v@lue -> P0.s +// Escapes: +// ----- Passive ----- +// PointsTo: +// RET.v@lue -> P0.s +// Escapes: +fun foo(a: A) = a.s + +fun main() = println(foo(A("zzz"))) \ No newline at end of file diff --git a/backend.native/tests/codegen/escapeAnalysis/test3.kt b/backend.native/tests/codegen/escapeAnalysis/test3.kt new file mode 100644 index 00000000000..85ceb956100 --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/test3.kt @@ -0,0 +1,28 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.test3 + +class A(val s: String) +class B { + var s: String? = null +} + +// ----- Agressive ----- +// PointsTo: +// P1.s -> P0.s +// RET.v@lue -> P0.s +// Escapes: +// ----- Passive ----- +// PointsTo: +// P1.s -> P0.s +// RET.v@lue -> P0.s +// Escapes: +fun foo(a: A, b: B): String { + b.s = a.s + return a.s +} + +fun main() = println(foo(A("zzz"), B())) \ No newline at end of file diff --git a/backend.native/tests/codegen/escapeAnalysis/test4.kt b/backend.native/tests/codegen/escapeAnalysis/test4.kt new file mode 100644 index 00000000000..34eee09a3a8 --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/test4.kt @@ -0,0 +1,30 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.test4 + +class A(val s: String) +class B { + var f: A = A("qzz") +} +class C { + var g: B = B() +} + +// ----- Agressive ----- +// PointsTo: +// P0.g.f -> P1.g.f +// RET.v@lue -> D0 +// Escapes: D0 +// ----- Passive ----- +// PointsTo: +// P0.g.f -> P1.g.f +// RET.v@lue -> D0 +// Escapes: D0 +fun foo(c1: C, c2: C) { + c1.g.f = c2.g.f +} + +fun main() = println(foo(C(), C())) \ No newline at end of file diff --git a/backend.native/tests/codegen/escapeAnalysis/test5.kt b/backend.native/tests/codegen/escapeAnalysis/test5.kt new file mode 100644 index 00000000000..d86bc22fac4 --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/test5.kt @@ -0,0 +1,35 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.test5 + +class A(val s: String) +class B { + var f: A = A("qzz") +} +class C { + var g: B = B() +} + +// ----- Agressive ----- +// PointsTo: +// RET.v@lue -> D0 +// D0.f -> P0.g.f +// Escapes: +// ----- Passive ----- +// PointsTo: +// P0.g.f -> D2 +// RET.v@lue -> D0 +// D0.f -> P0.g.f +// D0.f -> D1 +// D1 -> D2 +// Escapes: D0 D1 +fun foo(c1: C, c2: C): B { + val b = B() + b.f = c1.g.f + return b +} + +fun main() = println(foo(C(), C())) \ No newline at end of file diff --git a/backend.native/tests/codegen/escapeAnalysis/test6.kt b/backend.native/tests/codegen/escapeAnalysis/test6.kt new file mode 100644 index 00000000000..4d6798f48ef --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/test6.kt @@ -0,0 +1,40 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.test6 + +class A(val s: String) +class B { + var f: A = A("qzz") +} +class C { + var g: B = B() +} + +// ----- Agressive ----- +// PointsTo: +// P1.g -> D0 +// P2.g -> D0 +// RET.v@lue -> P1.g +// RET.v@lue -> P2.g +// RET.v@lue -> D0 +// D0.f -> P3 +// Escapes: +// ----- Passive ----- +// PointsTo: +// P1.g -> D0 +// P2.g -> D0 +// RET.v@lue -> P1.g +// RET.v@lue -> P2.g +// RET.v@lue -> D0 +// D0.f -> P3 +// Escapes: +fun foo(z: Boolean, c1: C, c2: C, a: A): B { + val v = if(z) c1.g else c2.g + v.f = a + return v +} + +fun main() = println(foo(true, C(), C(), A("zzz"))) \ No newline at end of file diff --git a/backend.native/tests/codegen/escapeAnalysis/test7.kt b/backend.native/tests/codegen/escapeAnalysis/test7.kt new file mode 100644 index 00000000000..f0952125e3a --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/test7.kt @@ -0,0 +1,52 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.test7 + +class A(val s: String) { + var h: String = "" + var p: C = C() +} +class B { + var f: A = A("qzz") +} +class C { + var g: A = A("") +} +class D { + var o: A = A("") +} + +// ----- Agressive ----- +// PointsTo: +// P1.g -> D0 +// P2.f -> D0 +// P4.o -> P1.g +// P4.o -> P2.f +// P4.o -> D0 +// RET.v@lue -> D1 +// D0.p -> P1 +// D0.h -> P3 +// Escapes: D1 +// ----- Passive ----- +// PointsTo: +// P1.g -> D0 +// P2.f -> D0 +// P4.o -> P1.g +// P4.o -> P2.f +// P4.o -> D0 +// RET.v@lue -> D1 +// D0.p -> P1 +// D0.h -> P3 +// Escapes: D1 +fun foo(z: Boolean, c: C, b: B, s: String, d: D) { + val v = if(z) c.g else b.f + v.h = s + d.o = v + val u = v + u.p = c +} + +fun main() = println(foo(true, C(), B(), "zzz", D())) \ No newline at end of file diff --git a/backend.native/tests/codegen/escapeAnalysis/test8.kt b/backend.native/tests/codegen/escapeAnalysis/test8.kt new file mode 100644 index 00000000000..5b95b1c4059 --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/test8.kt @@ -0,0 +1,43 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.test8 + +class F(val s: String) { + var g = F("") +} + +class A { + var f = F("qzz") +} + +// ----- Agressive ----- +// PointsTo: +// P0.f -> D0 +// RET.v@lue -> P0.f +// RET.v@lue -> D0 +// RET.v@lue -> D0.g +// D0.g -> P0.f +// D0.g -> D0 +// Escapes: +// ----- Passive ----- +// PointsTo: +// P0.f -> D0 +// RET.v@lue -> P0.f +// RET.v@lue -> D0 +// RET.v@lue -> D0.g +// D0.g -> P0.f +// D0.g -> D0 +// D0.g -> D2 +// D1 -> D0 +// D2 -> D0 +// Escapes: D1 D2 +fun foo(a: A): F { + a.f = F("zzz") + a.f.g = a.f + return a.f.g.g +} + +fun main() = println(foo(A()).s) \ No newline at end of file diff --git a/backend.native/tests/codegen/escapeAnalysis/test9.kt b/backend.native/tests/codegen/escapeAnalysis/test9.kt new file mode 100644 index 00000000000..ccbc9097872 --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/test9.kt @@ -0,0 +1,36 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.test9 + +class H(val x: Int) + +class F(val s: String) { + var g = F("") + var h = H(0) +} + +class A { + var f = F("qzz") +} + +// ----- Agressive ----- +// PointsTo: +// P0.f -> P1.g +// RET.v@lue -> P1.g.h +// Escapes: +// ----- Passive ----- +// PointsTo: +// P0.f -> P1.g +// P1.g.h -> D0 +// RET.v@lue -> P1.g.h +// Escapes: D0 +fun foo(a: A, f: F): H { + a.f = f.g + a.f.h = H(42) + return f.g.h +} + +fun main() = println(foo(A(), F("zzz")).x) \ No newline at end of file diff --git a/backend.native/tests/codegen/escapeAnalysis/zeroOutObjectOnAlloc.kt b/backend.native/tests/codegen/escapeAnalysis/zeroOutObjectOnAlloc.kt new file mode 100644 index 00000000000..b1a25997e3e --- /dev/null +++ b/backend.native/tests/codegen/escapeAnalysis/zeroOutObjectOnAlloc.kt @@ -0,0 +1,25 @@ +/* + * Copyright 2010-2020 JetBrains s.r.o. Use of this source code is governed by the Apache 2.0 license + * that can be found in the LICENSE file. + */ + +package codegen.escapeAnalysis.zeroOutObjectOnAlloc + +import kotlin.test.* + +class A { + var x = 0 +} + +@Test fun runTest() { + var sum1 = 0 + var sum2 = 0 + for (i in 0 until 10) { + val a = A() + sum1 += a.x + a.x = i + sum2 += a.x + } + assertEquals(0, sum1) + assertEquals(45, sum2) +} \ No newline at end of file