Devirtualization fails to eliminate boxing in function reference context
^KT-49847 Fixed Merge-request: KT-MR-6460 Merged-by: Vladimir Sukharev <Vladimir.Sukharev@jetbrains.com>
This commit is contained in:
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
class C {
|
||||
fun foo(x: Int) = x
|
||||
}
|
||||
|
||||
// CHECK: define void @"kfun:#main(){}"()
|
||||
// CHECK-NOT: Int-box
|
||||
// TODO Remove next check after fix of https://youtrack.jetbrains.com/issue/KT-53100/Optimization-needed-T-unboxCONSTANTPRIMITIVEx-T-x
|
||||
// CHECK: Int-unbox
|
||||
// CHECK-NOT: Int-unbox
|
||||
// CHECK: ret void
|
||||
fun main() {
|
||||
val c = C()
|
||||
val fooref = c::foo
|
||||
if( fooref(42) == 42)
|
||||
println("ok")
|
||||
}
|
||||
@@ -0,0 +1,21 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
class C<T> {
|
||||
fun foo(x: T) = x
|
||||
}
|
||||
|
||||
// CHECK: define void @"kfun:#main(){}"()
|
||||
// CHECK-NOT: Int-box
|
||||
// TODO Remove next check after fix of https://youtrack.jetbrains.com/issue/KT-53100/Optimization-needed-T-unboxCONSTANTPRIMITIVEx-T-x
|
||||
// CHECK: Int-unbox
|
||||
// CHECK-NOT: Int-unbox
|
||||
// CHECK: ret void
|
||||
fun main() {
|
||||
val c = C<Int>()
|
||||
val fooref = c::foo
|
||||
if( fooref(42) == 42)
|
||||
println("ok")
|
||||
}
|
||||
@@ -0,0 +1,13 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
// CHECK: define internal void @"kfun:$foo$FUNCTION_REFERENCE$0.<init>#internal"
|
||||
// CHECK-SAME: i32
|
||||
|
||||
fun <T> T.foo() { println(this) }
|
||||
|
||||
fun main() {
|
||||
println(5::foo)
|
||||
}
|
||||
@@ -0,0 +1,34 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
fun interface Foo {
|
||||
fun bar(x: Int): Any
|
||||
}
|
||||
|
||||
fun baz(x: Any): Int = x.hashCode()
|
||||
|
||||
// CHECK: define void @"kfun:#main(){}"()
|
||||
// Boxing/unboxing need to be used now due to non-devirtualized call
|
||||
// CHECK: Int-box
|
||||
|
||||
// TODO Remove two next checks, when advanced optimization of Int-unbox(Int-box(x)) would be done for snippet like:
|
||||
// TODO VAR IR_TEMPORARY_VARIABLE name:arg0 type:kotlin.Any [val]
|
||||
// TODO BLOCK type=kotlin.Any origin=null
|
||||
// TODO CALL <Int-box>
|
||||
// TODO GET_VAR 'val arg1: kotlin.Int [val]'
|
||||
// TODO CALL <Int-unbox>
|
||||
// TODO GET_VAR 'val arg0: kotlin.Any [val]'
|
||||
// CHECK: Int-box
|
||||
// CHECK: Int-unbox
|
||||
|
||||
// CHECK-NOT: Int-box
|
||||
// CHECK-NOT: Int-unbox
|
||||
// CHECK: ret void
|
||||
|
||||
fun main() {
|
||||
val foo: Foo = Foo(::baz)
|
||||
if( foo.bar(42) == 42 )
|
||||
println("passed")
|
||||
}
|
||||
@@ -0,0 +1,24 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
fun interface Foo<T> {
|
||||
fun bar(x: T): Any
|
||||
}
|
||||
|
||||
fun baz(x: Any): Int = x.hashCode()
|
||||
|
||||
// CHECK: define void @"kfun:#main(){}"()
|
||||
// Boxing/unboxing need to be used now due to non-devirtualized call
|
||||
// CHECK: Int-box
|
||||
// CHECK-NOT: Int-box
|
||||
// CHECK: Int-unbox
|
||||
// CHECK-NOT: Int-unbox
|
||||
// CHECK-NOT: Int-box
|
||||
// CHECK: ret void
|
||||
fun main() {
|
||||
val foo: Foo<Int> = Foo(::baz)
|
||||
if( foo.bar(42) == 42 )
|
||||
println("passed")
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
fun interface Foo {
|
||||
fun bar(x: Int): Int
|
||||
}
|
||||
|
||||
fun baz(x: Int): Int = x.hashCode()
|
||||
|
||||
// CHECK: define void @"kfun:#main(){}"()
|
||||
// CHECK-NOT: Int-box
|
||||
// CHECK-NOT: Int-unbox
|
||||
// CHECK: ret void
|
||||
fun main() {
|
||||
val foo: Foo = Foo(::baz)
|
||||
if( foo.bar(42) == 42 )
|
||||
println("passed")
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
fun interface Foo<T> {
|
||||
fun bar(x: T): Int
|
||||
}
|
||||
|
||||
fun baz(x: Any): Int = x.hashCode()
|
||||
|
||||
// CHECK: define void @"kfun:#main(){}"()
|
||||
// CHECK-NOT: Int-box
|
||||
// CHECK-NOT: Int-unbox
|
||||
// CHECK: ret void
|
||||
fun main() {
|
||||
val foo: Foo<Int> = Foo(::baz)
|
||||
if( foo.bar(42) == 42 )
|
||||
println("passed")
|
||||
}
|
||||
@@ -0,0 +1,20 @@
|
||||
/*
|
||||
* Copyright 2010-2022 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||
*/
|
||||
|
||||
fun plus1(x: Int) = x + 1
|
||||
|
||||
// CHECK: define void @"kfun:#main(){}"()
|
||||
// CHECK-NOT: Int-box
|
||||
// CHECK-NOT: Int-unbox
|
||||
// CHECK: ret void
|
||||
fun main() {
|
||||
val ref = ::plus1
|
||||
var y = 0
|
||||
repeat(100000) {
|
||||
y += ref(it) // Should be devirtualized and invoked without boxing/unboxing (`Int-box`/`Int-unbox`)
|
||||
}
|
||||
if (y > 999999)
|
||||
println("y > 999999")
|
||||
}
|
||||
Reference in New Issue
Block a user