JVM: be more careful when removing unused constants

1. if an argument of a `pop` cannot be removed, then all other potential
   arguments of that `pop` can't be removed either, and the same applies
   to other `pop`s that touch them;
2. the same is true for primitive conversions, but this is even trickier
   to implement correctly, so I simply did the same thing as with
   boxing operators: replace the conversion itself with a `pop` and keep
   the argument as-is.

Somehow this actually removes *more* redundant primitive type conversions
than the old code in a couple bytecode text tests, so I've patched them
to kind of use the value, forcing the instructions to stay.

 #KT-46921 Fixed
This commit is contained in:
pyos
2021-05-26 15:10:45 +02:00
committed by Alexander Udalov
parent 2f60ce21a0
commit 34878d17eb
8 changed files with 113 additions and 118 deletions
@@ -1,34 +1,34 @@
fun test(p: Int?) {
if (p != null) {
p.toByte() //intValue & I2B
p.toShort() //intValue & I2S
p.toInt() //intValue
p.toLong() //intValue & I2L
p.toFloat() //intValue & I2F
p.toDouble() //intValue & I2D
val a = p.toByte() //intValue & I2B
val b = p.toShort() //intValue & I2S
val c = p.toInt() //intValue
val d = p.toLong() //intValue & I2L
val e = p.toFloat() //intValue & I2F
val f = p.toDouble() //intValue & I2D
}
}
fun test(p: Byte?) {
if (p != null) {
p.toByte() //byteValue
p.toShort() //byteValue & I2S
p.toInt() //byteValue
p.toLong() //byteValue & I2L
p.toFloat() //byteValue & I2F
p.toDouble() //byteValue & I2D
val a = p.toByte() //byteValue
val b = p.toShort() //byteValue & I2S
val c = p.toInt() //byteValue
val d = p.toLong() //byteValue & I2L
val e = p.toFloat() //byteValue & I2F
val f = p.toDouble() //byteValue & I2D
}
}
fun test(p: Char?) {
if (p != null) {
p.toByte() //charValue & I2B
p.toShort() //charValue & I2S
p.toInt() //charValue
p.toLong() //charValue & I2L
p.toFloat() //charValue & I2F
p.toDouble() //charValue & I2D
val a = p.toByte() //charValue & I2B
val b = p.toShort() //charValue & I2S
val c = p.toInt() //charValue
val d = p.toLong() //charValue & I2L
val e = p.toFloat() //charValue & I2F
val f = p.toDouble() //charValue & I2D
}
}
@@ -4,12 +4,12 @@ inline fun <R, T> foo(x : R?, block : (R?) -> T) : T {
}
fun bar() {
foo(1) { x -> x!!.toLong() }
foo(1) { x -> x!!.toShort() }
foo(1L) { x -> x!!.toByte() }
foo(1L) { x -> x!!.toShort() }
foo('a') { x -> x!!.toDouble() }
foo(1.0) { x -> x!!.toInt() }
val a = foo(1) { x -> x!!.toLong() }
val b = foo(1) { x -> x!!.toShort() }
val c = foo(1L) { x -> x!!.toByte() }
val d = foo(1L) { x -> x!!.toShort() }
val e = foo('a') { x -> x!!.toDouble() }
val f = foo(1.0) { x -> x!!.toInt() }
}
// 0 valueOf