Get rid of redundant boxing of unsigned operands of infix 'compareTo'
^KT-48759: Fixed
This commit is contained in:
committed by
teamcity
parent
7423b35741
commit
cb93e9d408
+6
@@ -21437,6 +21437,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/implicitCastToNonValueClassType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("infixCompareToOptimization.kt")
|
||||
public void testInfixCompareToOptimization() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/infixCompareToOptimization.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("initBlock.kt")
|
||||
public void testInitBlock() throws Exception {
|
||||
|
||||
+20
-13
@@ -17,9 +17,7 @@ import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.isInt
|
||||
import org.jetbrains.kotlin.ir.types.isLong
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.dump
|
||||
import org.jetbrains.kotlin.ir.util.fqNameForIrSerialization
|
||||
import org.jetbrains.kotlin.ir.util.render
|
||||
@@ -42,6 +40,13 @@ class JvmBuiltInsLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||
if (context.state.target >= JvmTarget.JVM_1_8) {
|
||||
val parentClassName = callee.parent.fqNameForIrSerialization.asString()
|
||||
val functionName = callee.name.asString()
|
||||
if (parentClassName == "kotlin.CompareToKt" && functionName == "compareTo") {
|
||||
val operandType = expression.getValueArgument(0)!!.type
|
||||
when {
|
||||
operandType.isUInt() -> return expression.replaceWithCallTo(context.ir.symbols.compareUnsignedInt)
|
||||
operandType.isULong() -> return expression.replaceWithCallTo(context.ir.symbols.compareUnsignedLong)
|
||||
}
|
||||
}
|
||||
val jvm8Replacement = jvm8builtInReplacements[parentClassName to functionName]
|
||||
if (jvm8Replacement != null) {
|
||||
return expression.replaceWithCallTo(jvm8Replacement)
|
||||
@@ -76,8 +81,8 @@ class JvmBuiltInsLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||
("kotlin.ULong" to "toString") to context.ir.symbols.toUnsignedStringLong
|
||||
)
|
||||
|
||||
// Originals are so far only instance methods, and the replacements are
|
||||
// statics, so we copy dispatch receivers to a value argument if needed.
|
||||
// Originals are so far only instance methods and extensions, while the replacements are
|
||||
// statics, so we copy dispatch and extension receivers to a value argument if needed.
|
||||
// If we can't coerce arguments to required types, keep original expression (see below).
|
||||
private fun IrCall.replaceWithCallTo(replacement: IrSimpleFunctionSymbol): IrExpression {
|
||||
val expectedType = this.type
|
||||
@@ -90,16 +95,18 @@ class JvmBuiltInsLowering(val context: JvmBackendContext) : FileLoweringPass {
|
||||
replacement
|
||||
).also { newCall ->
|
||||
var valueArgumentOffset = 0
|
||||
this.dispatchReceiver?.let {
|
||||
val coercedDispatchReceiver = it.coerceIfPossible(replacement.owner.valueParameters[valueArgumentOffset].type)
|
||||
?: return this@replaceWithCallTo
|
||||
newCall.putValueArgument(valueArgumentOffset, coercedDispatchReceiver)
|
||||
valueArgumentOffset++
|
||||
|
||||
fun tryToAddCoercedArgument(expr: IrExpression): Boolean {
|
||||
val coercedExpr = expr.coerceIfPossible(replacement.owner.valueParameters[valueArgumentOffset].type)
|
||||
?: return false
|
||||
newCall.putValueArgument(valueArgumentOffset++, coercedExpr)
|
||||
return true
|
||||
}
|
||||
|
||||
this.extensionReceiver?.let { if (!tryToAddCoercedArgument(it)) return this@replaceWithCallTo }
|
||||
this.dispatchReceiver?.let { if (!tryToAddCoercedArgument(it)) return this@replaceWithCallTo }
|
||||
for (index in 0 until valueArgumentsCount) {
|
||||
val coercedValueArgument = getValueArgument(index)!!.coerceIfPossible(replacement.owner.valueParameters[index].type)
|
||||
?: return this@replaceWithCallTo
|
||||
newCall.putValueArgument(index + valueArgumentOffset, coercedValueArgument)
|
||||
if (!tryToAddCoercedArgument(getValueArgument(index)!!)) return this@replaceWithCallTo
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@@ -0,0 +1,16 @@
|
||||
// WITH_STDLIB
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
|
||||
fun compareUInts(a: UInt, b: UInt) = a compareTo b
|
||||
fun compareULongs(a: ULong, b: ULong) = a compareTo b
|
||||
|
||||
|
||||
fun box(): String {
|
||||
if (compareUInts(0u, 1u) != -1) return "Fail 1"
|
||||
if (compareULongs(0u, 1u) != -1) return "Fail 2"
|
||||
return "OK"
|
||||
}
|
||||
|
||||
// CHECK_BYTECODE_TEXT
|
||||
// 0 INVOKESTATIC kotlin/ULong.box-impl
|
||||
// 0 INVOKESTATIC kotlin/UInt.box-impl
|
||||
+6
@@ -21437,6 +21437,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/implicitCastToNonValueClassType.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("infixCompareToOptimization.kt")
|
||||
public void testInfixCompareToOptimization() throws Exception {
|
||||
runTest("compiler/testData/codegen/box/inlineClasses/infixCompareToOptimization.kt");
|
||||
}
|
||||
|
||||
@Test
|
||||
@TestMetadata("initBlock.kt")
|
||||
public void testInitBlock() throws Exception {
|
||||
|
||||
Reference in New Issue
Block a user