Pseudocode: Generate proper instructions for when conditions. Eliminate unnecessary magics

This commit is contained in:
Alexey Sedunov
2014-06-26 13:06:26 +04:00
parent fd21b6cbe9
commit d636d362b7
8 changed files with 180 additions and 20 deletions
@@ -14,6 +14,7 @@ L0:
mark(when(a) { is Int -> return a })
r(a) -> <v1>
mark(is Int -> return a)
mark(is Int)
magic(is Int|<v1>) -> <v2>
jmp?(L4|<v2>) NEXT:[<END>, r(a) -> <v3>]
L3:
@@ -5,8 +5,8 @@ fun illegalWhenBlock(a: Any): Any {
}
}
---------------------
<v0>: {<: Any} NEW: magic(a: Any) -> <v0>
<v2>: * NEW: magic(is Int|<v1>) -> <v2>
a <v1>: * NEW: r(a) -> <v1>
a <v3>: {<: Any} NEW: r(a) -> <v3>
<v0>: {<: Any} NEW: magic(a: Any) -> <v0>
a <v1>: * NEW: r(a) -> <v1>
is Int <v2>: * NEW: magic(is Int|<v1>) -> <v2>
a <v3>: {<: Any} NEW: r(a) -> <v3>
=====================
@@ -0,0 +1,89 @@
== foo ==
fun foo(a: Number) {
val t = when (a) {
1 -> "1"
in Collections.singleton(2) -> "2"
is Int -> "Int"
!in Collections.singleton(3) -> "!3"
!is Number -> "!Number"
else -> null
}
}
---------------------
L0:
1 <START>
v(a: Number)
magic(a: Number) -> <v0>
w(a|<v0>)
2 mark({ val t = when (a) { 1 -> "1" in Collections.singleton(2) -> "2" is Int -> "Int" !in Collections.singleton(3) -> "!3" !is Number -> "!Number" else -> null } })
v(val t = when (a) { 1 -> "1" in Collections.singleton(2) -> "2" is Int -> "Int" !in Collections.singleton(3) -> "!3" !is Number -> "!Number" else -> null })
mark(when (a) { 1 -> "1" in Collections.singleton(2) -> "2" is Int -> "Int" !in Collections.singleton(3) -> "!3" !is Number -> "!Number" else -> null })
r(a) -> <v1>
mark(1 -> "1")
mark(1)
r(1) -> <v2>
magic(1|<v1>, <v2>) -> <v3>
jmp?(L4|<v3>) NEXT:[mark(in Collections.singleton(2) -> "2"), mark("1")]
L3:
mark("1")
r("1") -> <v4>
jmp(L2) NEXT:[merge(when (a) { 1 -> "1" in Collections.singleton(2) -> "2" is Int -> "Int" !in Collections.singleton(3) -> "!3" !is Number -> "!Number" else -> null }|<v4>, <v8>, <v10>, <v14>, <v16>, <v17>) -> <v18>]
L4:
mark(in Collections.singleton(2) -> "2") PREV:[jmp?(L4|<v3>)]
mark(Collections.singleton(2))
r(2) -> <v5>
mark(singleton(2))
call(singleton(2), singleton|<v5>) -> <v6>
mark(in Collections.singleton(2))
call(in Collections.singleton(2), contains|<v6>, <v1>) -> <v7>
jmp?(L6|<v7>) NEXT:[mark(is Int -> "Int"), mark("2")]
L5:
mark("2")
r("2") -> <v8>
jmp(L2) NEXT:[merge(when (a) { 1 -> "1" in Collections.singleton(2) -> "2" is Int -> "Int" !in Collections.singleton(3) -> "!3" !is Number -> "!Number" else -> null }|<v4>, <v8>, <v10>, <v14>, <v16>, <v17>) -> <v18>]
L6:
mark(is Int -> "Int") PREV:[jmp?(L6|<v7>)]
mark(is Int)
magic(is Int|<v1>) -> <v9>
jmp?(L8|<v9>) NEXT:[mark(!in Collections.singleton(3) -> "!3"), mark("Int")]
L7:
mark("Int")
r("Int") -> <v10>
jmp(L2) NEXT:[merge(when (a) { 1 -> "1" in Collections.singleton(2) -> "2" is Int -> "Int" !in Collections.singleton(3) -> "!3" !is Number -> "!Number" else -> null }|<v4>, <v8>, <v10>, <v14>, <v16>, <v17>) -> <v18>]
L8:
mark(!in Collections.singleton(3) -> "!3") PREV:[jmp?(L8|<v9>)]
mark(Collections.singleton(3))
r(3) -> <v11>
mark(singleton(3))
call(singleton(3), singleton|<v11>) -> <v12>
mark(!in Collections.singleton(3))
call(!in Collections.singleton(3), contains|<v12>, <v1>) -> <v13>
jmp?(L10|<v13>) NEXT:[mark(!is Number -> "!Number"), mark("!3")]
L9:
mark("!3")
r("!3") -> <v14>
jmp(L2) NEXT:[merge(when (a) { 1 -> "1" in Collections.singleton(2) -> "2" is Int -> "Int" !in Collections.singleton(3) -> "!3" !is Number -> "!Number" else -> null }|<v4>, <v8>, <v10>, <v14>, <v16>, <v17>) -> <v18>]
L10:
mark(!is Number -> "!Number") PREV:[jmp?(L10|<v13>)]
mark(!is Number)
magic(!is Number|<v1>) -> <v15>
jmp?(L12|<v15>) NEXT:[mark(else -> null), mark("!Number")]
L11:
mark("!Number")
r("!Number") -> <v16>
jmp(L2) NEXT:[merge(when (a) { 1 -> "1" in Collections.singleton(2) -> "2" is Int -> "Int" !in Collections.singleton(3) -> "!3" !is Number -> "!Number" else -> null }|<v4>, <v8>, <v10>, <v14>, <v16>, <v17>) -> <v18>]
L12:
mark(else -> null) PREV:[jmp?(L12|<v15>)]
L13:
r(null) -> <v17>
jmp(L2)
L2:
merge(when (a) { 1 -> "1" in Collections.singleton(2) -> "2" is Int -> "Int" !in Collections.singleton(3) -> "!3" !is Number -> "!Number" else -> null }|<v4>, <v8>, <v10>, <v14>, <v16>, <v17>) -> <v18> PREV:[jmp(L2), jmp(L2), jmp(L2), jmp(L2), jmp(L2), jmp(L2)]
w(t|<v18>)
L1:
1 <END> NEXT:[<SINK>]
error:
<ERROR> PREV:[]
sink:
<SINK> PREV:[<ERROR>, <END>]
=====================
@@ -0,0 +1,12 @@
import java.util.Collections
fun foo(a: Number) {
val t = when (a) {
1 -> "1"
in Collections.singleton(2) -> "2"
is Int -> "Int"
!in Collections.singleton(3) -> "!3"
!is Number -> "!Number"
else -> null
}
}
@@ -0,0 +1,34 @@
== foo ==
fun foo(a: Number) {
val t = when (a) {
1 -> "1"
in Collections.singleton(2) -> "2"
is Int -> "Int"
!in Collections.singleton(3) -> "!3"
!is Number -> "!Number"
else -> null
}
}
---------------------
<v0>: {<: Number} NEW: magic(a: Number) -> <v0>
a <v1>: AND{{<: Any?}, *} NEW: r(a) -> <v1>
1 <v2>: * NEW: r(1) -> <v2>
1 <v3>: * NEW: magic(1|<v1>, <v2>) -> <v3>
"1" <v4>: {<: String?} NEW: r("1") -> <v4>
2 <v5>: {<: Int?} NEW: r(2) -> <v5>
singleton(2) <v6>: OR{{<: Collection<Int>}, {<: Collection<Int>}} NEW: call(singleton(2), singleton|<v5>) -> <v6>
Collections.singleton(2) <v6>: OR{{<: Collection<Int>}, {<: Collection<Int>}} COPY
in Collections.singleton(2) <v7>: * NEW: call(in Collections.singleton(2), contains|<v6>, <v1>) -> <v7>
"2" <v8>: {<: String?} NEW: r("2") -> <v8>
is Int <v9>: * NEW: magic(is Int|<v1>) -> <v9>
"Int" <v10>: {<: String?} NEW: r("Int") -> <v10>
3 <v11>: {<: Int?} NEW: r(3) -> <v11>
singleton(3) <v12>: OR{{<: Collection<Int>}, {<: Collection<Int>}} NEW: call(singleton(3), singleton|<v11>) -> <v12>
Collections.singleton(3) <v12>: OR{{<: Collection<Int>}, {<: Collection<Int>}} COPY
!in Collections.singleton(3) <v13>: * NEW: call(!in Collections.singleton(3), contains|<v12>, <v1>) -> <v13>
"!3" <v14>: {<: String?} NEW: r("!3") -> <v14>
!is Number <v15>: * NEW: magic(!is Number|<v1>) -> <v15>
"!Number" <v16>: {<: String?} NEW: r("!Number") -> <v16>
null <v17>: {<: String?} NEW: r(null) -> <v17>
when (a) { 1 -> "1" in Collections.singleton(2) -> "2" is Int -> "Int" !in Collections.singleton(3) -> "!3" !is Number -> "!Number" else -> null } <v18>: {<: String?} NEW: merge(when (a) { 1 -> "1" in Collections.singleton(2) -> "2" is Int -> "Int" !in Collections.singleton(3) -> "!3" !is Number -> "!Number" else -> null }|<v4>, <v8>, <v10>, <v14>, <v16>, <v17>) -> <v18>
=====================