[JVM_IR] Avoid boxing when comparing primitive to object.
This commit is contained in:
+19
-7
@@ -21,8 +21,8 @@ import org.jetbrains.kotlin.backend.jvm.JvmBackendContext
|
|||||||
import org.jetbrains.kotlin.backend.jvm.codegen.*
|
import org.jetbrains.kotlin.backend.jvm.codegen.*
|
||||||
import org.jetbrains.kotlin.backend.jvm.ir.isSmartcastFromHigherThanNullable
|
import org.jetbrains.kotlin.backend.jvm.ir.isSmartcastFromHigherThanNullable
|
||||||
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
import org.jetbrains.kotlin.builtins.KotlinBuiltIns
|
||||||
|
import org.jetbrains.kotlin.codegen.AsmUtil
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil.comparisonOperandType
|
import org.jetbrains.kotlin.codegen.AsmUtil.comparisonOperandType
|
||||||
import org.jetbrains.kotlin.codegen.AsmUtil.unboxType
|
|
||||||
import org.jetbrains.kotlin.codegen.BranchedValue
|
import org.jetbrains.kotlin.codegen.BranchedValue
|
||||||
import org.jetbrains.kotlin.codegen.NumberCompare
|
import org.jetbrains.kotlin.codegen.NumberCompare
|
||||||
import org.jetbrains.kotlin.codegen.ObjectCompare
|
import org.jetbrains.kotlin.codegen.ObjectCompare
|
||||||
@@ -135,20 +135,27 @@ class NonIEEE754FloatComparison(val op: IElementType, val a: MaterialValue, val
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
class PrimitiveToBoxedComparison(
|
class PrimitiveToObjectComparison(
|
||||||
val op: IElementType,
|
val op: IElementType,
|
||||||
private val boxedValue: MaterialValue,
|
private val boxedValue: MaterialValue,
|
||||||
private val loadOther: () -> MaterialValue
|
private val useNullCheck: Boolean,
|
||||||
|
private val primitiveType: Type,
|
||||||
|
private val loadOther: () -> MaterialValue,
|
||||||
) : BooleanValue(boxedValue.codegen) {
|
) : BooleanValue(boxedValue.codegen) {
|
||||||
|
|
||||||
override fun jumpIfFalse(target: Label) {
|
override fun jumpIfFalse(target: Label) {
|
||||||
val compareLabel = Label()
|
val compareLabel = Label()
|
||||||
mv.dup()
|
mv.dup()
|
||||||
mv.ifnonnull(compareLabel)
|
if (useNullCheck) {
|
||||||
|
mv.ifnonnull(compareLabel)
|
||||||
|
} else {
|
||||||
|
mv.instanceOf(AsmUtil.boxType(primitiveType))
|
||||||
|
mv.ifne(compareLabel)
|
||||||
|
}
|
||||||
mv.pop()
|
mv.pop()
|
||||||
mv.goTo(target)
|
mv.goTo(target)
|
||||||
mv.mark(compareLabel)
|
mv.mark(compareLabel)
|
||||||
val unboxedValue = boxedValue.materializedAt(unboxType(boxedValue.type), boxedValue.irType)
|
val unboxedValue = boxedValue.materializedAt(primitiveType, boxedValue.irType)
|
||||||
BooleanComparison(op, unboxedValue, loadOther()).jumpIfFalse(target)
|
BooleanComparison(op, unboxedValue, loadOther()).jumpIfFalse(target)
|
||||||
}
|
}
|
||||||
|
|
||||||
@@ -156,11 +163,16 @@ class PrimitiveToBoxedComparison(
|
|||||||
val compareLabel = Label()
|
val compareLabel = Label()
|
||||||
val endLabel = Label()
|
val endLabel = Label()
|
||||||
mv.dup()
|
mv.dup()
|
||||||
mv.ifnonnull(compareLabel)
|
if (useNullCheck) {
|
||||||
|
mv.ifnonnull(compareLabel)
|
||||||
|
} else {
|
||||||
|
mv.instanceOf(AsmUtil.boxType(primitiveType))
|
||||||
|
mv.ifne(compareLabel)
|
||||||
|
}
|
||||||
mv.pop()
|
mv.pop()
|
||||||
mv.goTo(endLabel)
|
mv.goTo(endLabel)
|
||||||
mv.mark(compareLabel)
|
mv.mark(compareLabel)
|
||||||
val unboxedValue = boxedValue.materializedAt(unboxType(boxedValue.type), boxedValue.irType)
|
val unboxedValue = boxedValue.materializedAt(primitiveType, boxedValue.irType)
|
||||||
BooleanComparison(op, unboxedValue, loadOther()).jumpIfTrue(target)
|
BooleanComparison(op, unboxedValue, loadOther()).jumpIfTrue(target)
|
||||||
mv.mark(endLabel)
|
mv.mark(endLabel)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -28,6 +28,7 @@ import org.jetbrains.kotlin.ir.util.isNullConst
|
|||||||
import org.jetbrains.kotlin.lexer.KtTokens
|
import org.jetbrains.kotlin.lexer.KtTokens
|
||||||
import org.jetbrains.kotlin.psi2ir.generators.hasNoSideEffects
|
import org.jetbrains.kotlin.psi2ir.generators.hasNoSideEffects
|
||||||
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes
|
||||||
|
import org.jetbrains.kotlin.resolve.jvm.AsmTypes.OBJECT_TYPE
|
||||||
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
import org.jetbrains.kotlin.resolve.jvm.jvmSignature.JvmMethodSignature
|
||||||
import org.jetbrains.kotlin.types.isNullable
|
import org.jetbrains.kotlin.types.isNullable
|
||||||
import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberOrNullableType
|
import org.jetbrains.kotlin.types.typeUtil.isPrimitiveNumberOrNullableType
|
||||||
@@ -98,19 +99,25 @@ class Equals(val operator: IElementType) : IntrinsicMethod() {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
// Avoid boxing for `primitive == object` and `boxed primitive == primitive` where we know
|
||||||
|
// what comparison means. The optimization does not apply to `object == primitive` as equals
|
||||||
|
// could be overridden for the object.
|
||||||
if ((opToken == IrStatementOrigin.EQEQ || opToken == IrStatementOrigin.EXCLEQ) &&
|
if ((opToken == IrStatementOrigin.EQEQ || opToken == IrStatementOrigin.EXCLEQ) &&
|
||||||
(AsmUtil.isIntOrLongPrimitive(leftType) || AsmUtil.isIntOrLongPrimitive(rightType)) &&
|
((AsmUtil.isIntOrLongPrimitive(leftType) && !AsmUtil.isPrimitive(rightType)) ||
|
||||||
(AsmUtil.isBoxedTypeOf(leftType, rightType) || AsmUtil.isBoxedTypeOf(rightType, leftType))
|
(AsmUtil.isIntOrLongPrimitive(rightType) && AsmUtil.isBoxedTypeOf(leftType, rightType)))
|
||||||
) {
|
) {
|
||||||
val leftIsPrimitive = AsmUtil.isIntOrLongPrimitive(leftType)
|
val leftIsPrimitive = AsmUtil.isIntOrLongPrimitive(leftType)
|
||||||
|
val primitiveType = if (leftIsPrimitive) leftType else rightType
|
||||||
|
val nonPrimitiveType = if (leftIsPrimitive) rightType else leftType
|
||||||
|
val useNullCheck = AsmUtil.isBoxedTypeOf(nonPrimitiveType, primitiveType)
|
||||||
return if (leftIsPrimitive) {
|
return if (leftIsPrimitive) {
|
||||||
val loadOther = loadOther(a, leftType)
|
val loadOther = loadOther(a, leftType)
|
||||||
val boxedValue = b.accept(codegen, data).materializedAt(rightType, b.type)
|
val boxedValue = b.accept(codegen, data).materializedAt(rightType, b.type)
|
||||||
PrimitiveToBoxedComparison(operator, boxedValue, loadOther)
|
PrimitiveToObjectComparison(operator, boxedValue, useNullCheck, primitiveType, loadOther)
|
||||||
} else {
|
} else {
|
||||||
val boxedValue = a.accept(codegen, data).materializedAt(leftType, a.type)
|
val boxedValue = a.accept(codegen, data).materializedAt(leftType, a.type)
|
||||||
val loadOther = loadOther(b, rightType)
|
val loadOther = loadOther(b, rightType)
|
||||||
PrimitiveToBoxedComparison(operator, boxedValue, loadOther)
|
PrimitiveToObjectComparison(operator, boxedValue, useNullCheck, primitiveType, loadOther)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
-3
@@ -1,6 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TODO KT-36646 Don't box primitive values in equality comparison with nullable primitive values in JVM_IR
|
|
||||||
|
|
||||||
fun testBoolean1(a: Boolean, b: Any?) = a == b
|
fun testBoolean1(a: Boolean, b: Any?) = a == b
|
||||||
fun testBoolean2(a: Boolean, b: Any?) = a != b
|
fun testBoolean2(a: Boolean, b: Any?) = a != b
|
||||||
|
|
||||||
|
|||||||
@@ -5,80 +5,80 @@ FILE fqName:<root> fileName:/primitiveComparisons.kt
|
|||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun btest1 (a: kotlin.Byte, b: kotlin.Byte): kotlin.Boolean declared in <root>'
|
RETURN type=kotlin.Nothing from='public final fun btest1 (a: kotlin.Byte, b: kotlin.Byte): kotlin.Boolean declared in <root>'
|
||||||
CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT
|
CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT
|
||||||
arg0: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Byte' type=kotlin.Int origin=null
|
arg0: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'a: kotlin.Byte declared in <root>.btest1' type=kotlin.Byte origin=null
|
GET_VAR 'a: kotlin.Byte declared in <root>.btest1' type=kotlin.Byte origin=null
|
||||||
arg1: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Byte' type=kotlin.Int origin=null
|
arg1: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'b: kotlin.Byte declared in <root>.btest1' type=kotlin.Byte origin=null
|
GET_VAR 'b: kotlin.Byte declared in <root>.btest1' type=kotlin.Byte origin=null
|
||||||
FUN name:btest2 visibility:public modality:FINAL <> (a:kotlin.Byte, b:kotlin.Byte) returnType:kotlin.Boolean
|
FUN name:btest2 visibility:public modality:FINAL <> (a:kotlin.Byte, b:kotlin.Byte) returnType:kotlin.Boolean
|
||||||
VALUE_PARAMETER name:a index:0 type:kotlin.Byte
|
VALUE_PARAMETER name:a index:0 type:kotlin.Byte
|
||||||
VALUE_PARAMETER name:b index:1 type:kotlin.Byte
|
VALUE_PARAMETER name:b index:1 type:kotlin.Byte
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun btest2 (a: kotlin.Byte, b: kotlin.Byte): kotlin.Boolean declared in <root>'
|
RETURN type=kotlin.Nothing from='public final fun btest2 (a: kotlin.Byte, b: kotlin.Byte): kotlin.Boolean declared in <root>'
|
||||||
CALL 'public final fun less (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT
|
CALL 'public final fun less (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT
|
||||||
arg0: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Byte' type=kotlin.Int origin=null
|
arg0: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'a: kotlin.Byte declared in <root>.btest2' type=kotlin.Byte origin=null
|
GET_VAR 'a: kotlin.Byte declared in <root>.btest2' type=kotlin.Byte origin=null
|
||||||
arg1: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Byte' type=kotlin.Int origin=null
|
arg1: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'b: kotlin.Byte declared in <root>.btest2' type=kotlin.Byte origin=null
|
GET_VAR 'b: kotlin.Byte declared in <root>.btest2' type=kotlin.Byte origin=null
|
||||||
FUN name:btest3 visibility:public modality:FINAL <> (a:kotlin.Byte, b:kotlin.Byte) returnType:kotlin.Boolean
|
FUN name:btest3 visibility:public modality:FINAL <> (a:kotlin.Byte, b:kotlin.Byte) returnType:kotlin.Boolean
|
||||||
VALUE_PARAMETER name:a index:0 type:kotlin.Byte
|
VALUE_PARAMETER name:a index:0 type:kotlin.Byte
|
||||||
VALUE_PARAMETER name:b index:1 type:kotlin.Byte
|
VALUE_PARAMETER name:b index:1 type:kotlin.Byte
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun btest3 (a: kotlin.Byte, b: kotlin.Byte): kotlin.Boolean declared in <root>'
|
RETURN type=kotlin.Nothing from='public final fun btest3 (a: kotlin.Byte, b: kotlin.Byte): kotlin.Boolean declared in <root>'
|
||||||
CALL 'public final fun greaterOrEqual (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GTEQ
|
CALL 'public final fun greaterOrEqual (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GTEQ
|
||||||
arg0: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Byte' type=kotlin.Int origin=null
|
arg0: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'a: kotlin.Byte declared in <root>.btest3' type=kotlin.Byte origin=null
|
GET_VAR 'a: kotlin.Byte declared in <root>.btest3' type=kotlin.Byte origin=null
|
||||||
arg1: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Byte' type=kotlin.Int origin=null
|
arg1: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'b: kotlin.Byte declared in <root>.btest3' type=kotlin.Byte origin=null
|
GET_VAR 'b: kotlin.Byte declared in <root>.btest3' type=kotlin.Byte origin=null
|
||||||
FUN name:btest4 visibility:public modality:FINAL <> (a:kotlin.Byte, b:kotlin.Byte) returnType:kotlin.Boolean
|
FUN name:btest4 visibility:public modality:FINAL <> (a:kotlin.Byte, b:kotlin.Byte) returnType:kotlin.Boolean
|
||||||
VALUE_PARAMETER name:a index:0 type:kotlin.Byte
|
VALUE_PARAMETER name:a index:0 type:kotlin.Byte
|
||||||
VALUE_PARAMETER name:b index:1 type:kotlin.Byte
|
VALUE_PARAMETER name:b index:1 type:kotlin.Byte
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun btest4 (a: kotlin.Byte, b: kotlin.Byte): kotlin.Boolean declared in <root>'
|
RETURN type=kotlin.Nothing from='public final fun btest4 (a: kotlin.Byte, b: kotlin.Byte): kotlin.Boolean declared in <root>'
|
||||||
CALL 'public final fun lessOrEqual (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LTEQ
|
CALL 'public final fun lessOrEqual (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LTEQ
|
||||||
arg0: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Byte' type=kotlin.Int origin=null
|
arg0: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'a: kotlin.Byte declared in <root>.btest4' type=kotlin.Byte origin=null
|
GET_VAR 'a: kotlin.Byte declared in <root>.btest4' type=kotlin.Byte origin=null
|
||||||
arg1: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Byte' type=kotlin.Int origin=null
|
arg1: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'b: kotlin.Byte declared in <root>.btest4' type=kotlin.Byte origin=null
|
GET_VAR 'b: kotlin.Byte declared in <root>.btest4' type=kotlin.Byte origin=null
|
||||||
FUN name:stest1 visibility:public modality:FINAL <> (a:kotlin.Short, b:kotlin.Short) returnType:kotlin.Boolean
|
FUN name:stest1 visibility:public modality:FINAL <> (a:kotlin.Short, b:kotlin.Short) returnType:kotlin.Boolean
|
||||||
VALUE_PARAMETER name:a index:0 type:kotlin.Short
|
VALUE_PARAMETER name:a index:0 type:kotlin.Short
|
||||||
VALUE_PARAMETER name:b index:1 type:kotlin.Short
|
VALUE_PARAMETER name:b index:1 type:kotlin.Short
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun stest1 (a: kotlin.Short, b: kotlin.Short): kotlin.Boolean declared in <root>'
|
RETURN type=kotlin.Nothing from='public final fun stest1 (a: kotlin.Short, b: kotlin.Short): kotlin.Boolean declared in <root>'
|
||||||
CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT
|
CALL 'public final fun greater (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GT
|
||||||
arg0: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Short' type=kotlin.Int origin=null
|
arg0: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'a: kotlin.Short declared in <root>.stest1' type=kotlin.Short origin=null
|
GET_VAR 'a: kotlin.Short declared in <root>.stest1' type=kotlin.Short origin=null
|
||||||
arg1: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Short' type=kotlin.Int origin=null
|
arg1: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'b: kotlin.Short declared in <root>.stest1' type=kotlin.Short origin=null
|
GET_VAR 'b: kotlin.Short declared in <root>.stest1' type=kotlin.Short origin=null
|
||||||
FUN name:stest2 visibility:public modality:FINAL <> (a:kotlin.Short, b:kotlin.Short) returnType:kotlin.Boolean
|
FUN name:stest2 visibility:public modality:FINAL <> (a:kotlin.Short, b:kotlin.Short) returnType:kotlin.Boolean
|
||||||
VALUE_PARAMETER name:a index:0 type:kotlin.Short
|
VALUE_PARAMETER name:a index:0 type:kotlin.Short
|
||||||
VALUE_PARAMETER name:b index:1 type:kotlin.Short
|
VALUE_PARAMETER name:b index:1 type:kotlin.Short
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun stest2 (a: kotlin.Short, b: kotlin.Short): kotlin.Boolean declared in <root>'
|
RETURN type=kotlin.Nothing from='public final fun stest2 (a: kotlin.Short, b: kotlin.Short): kotlin.Boolean declared in <root>'
|
||||||
CALL 'public final fun less (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT
|
CALL 'public final fun less (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LT
|
||||||
arg0: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Short' type=kotlin.Int origin=null
|
arg0: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'a: kotlin.Short declared in <root>.stest2' type=kotlin.Short origin=null
|
GET_VAR 'a: kotlin.Short declared in <root>.stest2' type=kotlin.Short origin=null
|
||||||
arg1: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Short' type=kotlin.Int origin=null
|
arg1: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'b: kotlin.Short declared in <root>.stest2' type=kotlin.Short origin=null
|
GET_VAR 'b: kotlin.Short declared in <root>.stest2' type=kotlin.Short origin=null
|
||||||
FUN name:stest3 visibility:public modality:FINAL <> (a:kotlin.Short, b:kotlin.Short) returnType:kotlin.Boolean
|
FUN name:stest3 visibility:public modality:FINAL <> (a:kotlin.Short, b:kotlin.Short) returnType:kotlin.Boolean
|
||||||
VALUE_PARAMETER name:a index:0 type:kotlin.Short
|
VALUE_PARAMETER name:a index:0 type:kotlin.Short
|
||||||
VALUE_PARAMETER name:b index:1 type:kotlin.Short
|
VALUE_PARAMETER name:b index:1 type:kotlin.Short
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun stest3 (a: kotlin.Short, b: kotlin.Short): kotlin.Boolean declared in <root>'
|
RETURN type=kotlin.Nothing from='public final fun stest3 (a: kotlin.Short, b: kotlin.Short): kotlin.Boolean declared in <root>'
|
||||||
CALL 'public final fun greaterOrEqual (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GTEQ
|
CALL 'public final fun greaterOrEqual (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=GTEQ
|
||||||
arg0: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Short' type=kotlin.Int origin=null
|
arg0: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'a: kotlin.Short declared in <root>.stest3' type=kotlin.Short origin=null
|
GET_VAR 'a: kotlin.Short declared in <root>.stest3' type=kotlin.Short origin=null
|
||||||
arg1: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Short' type=kotlin.Int origin=null
|
arg1: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'b: kotlin.Short declared in <root>.stest3' type=kotlin.Short origin=null
|
GET_VAR 'b: kotlin.Short declared in <root>.stest3' type=kotlin.Short origin=null
|
||||||
FUN name:stest4 visibility:public modality:FINAL <> (a:kotlin.Short, b:kotlin.Short) returnType:kotlin.Boolean
|
FUN name:stest4 visibility:public modality:FINAL <> (a:kotlin.Short, b:kotlin.Short) returnType:kotlin.Boolean
|
||||||
VALUE_PARAMETER name:a index:0 type:kotlin.Short
|
VALUE_PARAMETER name:a index:0 type:kotlin.Short
|
||||||
VALUE_PARAMETER name:b index:1 type:kotlin.Short
|
VALUE_PARAMETER name:b index:1 type:kotlin.Short
|
||||||
BLOCK_BODY
|
BLOCK_BODY
|
||||||
RETURN type=kotlin.Nothing from='public final fun stest4 (a: kotlin.Short, b: kotlin.Short): kotlin.Boolean declared in <root>'
|
RETURN type=kotlin.Nothing from='public final fun stest4 (a: kotlin.Short, b: kotlin.Short): kotlin.Boolean declared in <root>'
|
||||||
CALL 'public final fun lessOrEqual (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LTEQ
|
CALL 'public final fun lessOrEqual (arg0: kotlin.Int, arg1: kotlin.Int): kotlin.Boolean declared in kotlin.internal.ir' type=kotlin.Boolean origin=LTEQ
|
||||||
arg0: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Short' type=kotlin.Int origin=null
|
arg0: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'a: kotlin.Short declared in <root>.stest4' type=kotlin.Short origin=null
|
GET_VAR 'a: kotlin.Short declared in <root>.stest4' type=kotlin.Short origin=null
|
||||||
arg1: CALL 'public open fun toInt (): kotlin.Int declared in kotlin.Short' type=kotlin.Int origin=null
|
arg1: TYPE_OP type=kotlin.Int origin=IMPLICIT_CAST typeOperand=kotlin.Int
|
||||||
$this: GET_VAR 'b: kotlin.Short declared in <root>.stest4' type=kotlin.Short origin=null
|
GET_VAR 'b: kotlin.Short declared in <root>.stest4' type=kotlin.Short origin=null
|
||||||
FUN name:itest1 visibility:public modality:FINAL <> (a:kotlin.Int, b:kotlin.Int) returnType:kotlin.Boolean
|
FUN name:itest1 visibility:public modality:FINAL <> (a:kotlin.Int, b:kotlin.Int) returnType:kotlin.Boolean
|
||||||
VALUE_PARAMETER name:a index:0 type:kotlin.Int
|
VALUE_PARAMETER name:a index:0 type:kotlin.Int
|
||||||
VALUE_PARAMETER name:b index:1 type:kotlin.Int
|
VALUE_PARAMETER name:b index:1 type:kotlin.Int
|
||||||
|
|||||||
Reference in New Issue
Block a user