[JVM_IR] Use ifne and ifeq for integer zero comparisons.
This commit is contained in:
@@ -32,6 +32,7 @@ import org.jetbrains.kotlin.resolve.jvm.JvmPrimitiveType
|
||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||
import org.jetbrains.kotlin.types.KotlinType
|
||||
import org.jetbrains.org.objectweb.asm.Label
|
||||
import org.jetbrains.org.objectweb.asm.Opcodes
|
||||
import org.jetbrains.org.objectweb.asm.Type
|
||||
import org.jetbrains.org.objectweb.asm.commons.InstructionAdapter
|
||||
|
||||
@@ -67,6 +68,20 @@ object CompareTo : IntrinsicMethod() {
|
||||
}
|
||||
}
|
||||
|
||||
class IntegerZeroComparison(val op: IElementType, val a: MaterialValue): BooleanValue(a.codegen) {
|
||||
override fun jumpIfFalse(target: Label) {
|
||||
mv.visitJumpInsn(Opcodes.IFNE, target)
|
||||
}
|
||||
|
||||
override fun jumpIfTrue(target: Label) {
|
||||
mv.visitJumpInsn(Opcodes.IFEQ, target)
|
||||
}
|
||||
|
||||
override fun discard() {
|
||||
a.discard()
|
||||
}
|
||||
}
|
||||
|
||||
class BooleanComparison(val op: IElementType, val a: MaterialValue, val b: MaterialValue) : BooleanValue(a.codegen) {
|
||||
override fun jumpIfFalse(target: Label) {
|
||||
// TODO 1. get rid of the dependency; 2. take `b.type` into account.
|
||||
|
||||
@@ -14,17 +14,15 @@ import org.jetbrains.kotlin.codegen.AsmUtil.genAreEqualCall
|
||||
import org.jetbrains.kotlin.codegen.AsmUtil.isPrimitive
|
||||
import org.jetbrains.kotlin.codegen.StackValue
|
||||
import org.jetbrains.kotlin.codegen.intrinsics.IntrinsicMethods
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysFalseIfeq
|
||||
import org.jetbrains.kotlin.codegen.pseudoInsns.fakeAlwaysTrueIfeq
|
||||
import org.jetbrains.kotlin.config.LanguageFeature
|
||||
import org.jetbrains.kotlin.ir.expressions.IrFunctionAccessExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin
|
||||
import org.jetbrains.kotlin.ir.types.IrType
|
||||
import org.jetbrains.kotlin.ir.types.classOrNull
|
||||
import org.jetbrains.kotlin.ir.types.isNullable
|
||||
import org.jetbrains.kotlin.ir.types.toKotlinType
|
||||
import org.jetbrains.kotlin.ir.util.isEnumClass
|
||||
import org.jetbrains.kotlin.ir.util.isEnumEntry
|
||||
import org.jetbrains.kotlin.ir.util.isIntegerConst
|
||||
import org.jetbrains.kotlin.ir.util.isNullConst
|
||||
import org.jetbrains.kotlin.lexer.KtTokens
|
||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||
@@ -97,9 +95,14 @@ class Equals(val operator: IElementType) : IntrinsicMethod() {
|
||||
MaterialValue(codegen, Type.BOOLEAN_TYPE, codegen.context.irBuiltIns.booleanType)
|
||||
} else {
|
||||
val operandType = if (!isPrimitive(leftType)) AsmTypes.OBJECT_TYPE else leftType
|
||||
val aValue = a.accept(codegen, data).materializedAt(operandType, a.type)
|
||||
val bValue = b.accept(codegen, data).materializedAt(operandType, b.type)
|
||||
BooleanComparison(operator, aValue, bValue)
|
||||
if (operandType == Type.INT_TYPE && (a.isIntegerConst(0) || b.isIntegerConst(0))) {
|
||||
val nonZero = if (a.isIntegerConst(0)) b else a
|
||||
IntegerZeroComparison(operator, nonZero.accept(codegen, data).materializedAt(operandType, nonZero.type))
|
||||
} else {
|
||||
val aValue = a.accept(codegen, data).materializedAt(operandType, a.type)
|
||||
val bValue = b.accept(codegen, data).materializedAt(operandType, b.type)
|
||||
BooleanComparison(operator, aValue, bValue)
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -154,6 +154,8 @@ fun IrExpression.isTrueConst() = this is IrConst<*> && this.kind == IrConstKind.
|
||||
|
||||
fun IrExpression.isFalseConst() = this is IrConst<*> && this.kind == IrConstKind.Boolean && this.value == false
|
||||
|
||||
fun IrExpression.isIntegerConst(value: Int) = this is IrConst<*> && this.kind == IrConstKind.Int && this.value == value
|
||||
|
||||
fun IrExpression.coerceToUnit(builtins: IrBuiltIns): IrExpression {
|
||||
val valueType = getKotlinType(this)
|
||||
return coerceToUnitIfNeeded(valueType, builtins)
|
||||
|
||||
@@ -1,6 +1,3 @@
|
||||
// IGNORE_BACKEND: JVM_IR
|
||||
// TODO KT-36841 Generate integer comparison with 0 instructions (IFNE, etc) when comparing integers with 0 in JVM_IR
|
||||
|
||||
fun test(a: Int, b: Int, c: Int) {
|
||||
when (0) {
|
||||
a -> throw IllegalArgumentException("a is 0")
|
||||
|
||||
Reference in New Issue
Block a user