ForLoopsLowering: Eliminate construction/boxing/unboxing of UInt/ULong.
This needs further cleanup to encapsulate more logic into ProgressionType.
This commit is contained in:
committed by
Alexander Udalov
parent
e1120f49d8
commit
177967258b
@@ -289,6 +289,8 @@ abstract class Symbols<out T : CommonBackendContext>(val context: T, irBuiltIns:
|
||||
|
||||
abstract val returnIfSuspended: IrSimpleFunctionSymbol
|
||||
|
||||
open val unsafeCoerceIntrinsic: IrSimpleFunctionSymbol? = null
|
||||
|
||||
companion object {
|
||||
fun isLateinitIsInitializedPropertyGetter(symbol: IrFunctionSymbol): Boolean =
|
||||
symbol is IrSimpleFunctionSymbol && symbol.owner.let { function ->
|
||||
|
||||
+80
-3
@@ -18,6 +18,7 @@ import org.jetbrains.kotlin.ir.expressions.impl.IrCallImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.functions
|
||||
import org.jetbrains.kotlin.ir.util.isUnsigned
|
||||
import org.jetbrains.kotlin.ir.visitors.IrElementVisitor
|
||||
import org.jetbrains.kotlin.name.Name
|
||||
import org.jetbrains.kotlin.utils.addToStdlib.firstNotNullResult
|
||||
@@ -32,11 +33,15 @@ internal enum class ProgressionType(
|
||||
INT_PROGRESSION(Name.identifier("toInt"), Name.identifier("toInt")),
|
||||
LONG_PROGRESSION(Name.identifier("toLong"), Name.identifier("toLong"), isLong = true),
|
||||
CHAR_PROGRESSION(Name.identifier("toChar"), Name.identifier("toInt")),
|
||||
UINT_PROGRESSION(Name.identifier("toUInt"), Name.identifier("toInt"), isUnsigned = true),
|
||||
ULONG_PROGRESSION(Name.identifier("toULong"), Name.identifier("toLong"), isLong = true, isUnsigned = true);
|
||||
UINT_PROGRESSION(Name.identifier("toInt"), Name.identifier("toInt"), isUnsigned = true),
|
||||
ULONG_PROGRESSION(Name.identifier("toLong"), Name.identifier("toLong"), isLong = true, isUnsigned = true);
|
||||
|
||||
/** Returns the [IrType] of the `first`/`last` properties and elements in the progression. */
|
||||
fun elementType(symbols: Symbols<CommonBackendContext>): IrType = elementClassifier(symbols).defaultType
|
||||
fun elementType(symbols: Symbols<CommonBackendContext>): IrType = when (this) {
|
||||
INT_PROGRESSION, UINT_PROGRESSION -> symbols.int
|
||||
LONG_PROGRESSION, ULONG_PROGRESSION -> symbols.long
|
||||
CHAR_PROGRESSION -> symbols.char
|
||||
}.defaultType
|
||||
|
||||
/** Returns the [IrClassSymbol] of the `first`/`last` properties and elements in the progression. */
|
||||
fun elementClassifier(symbols: Symbols<CommonBackendContext>): IrClassSymbol = when (this) {
|
||||
@@ -59,6 +64,15 @@ internal enum class ProgressionType(
|
||||
LONG_PROGRESSION, ULONG_PROGRESSION -> builtIns.longClass
|
||||
}
|
||||
|
||||
/** Returns the [IrType] used in loop conditions (`buildLoopCondition()`) and when calling `getProgressionLastElement()`. */
|
||||
fun compareType(symbols: Symbols<CommonBackendContext>): IrType = when (this) {
|
||||
INT_PROGRESSION -> symbols.int
|
||||
LONG_PROGRESSION -> symbols.long
|
||||
CHAR_PROGRESSION -> symbols.char
|
||||
UINT_PROGRESSION -> symbols.uInt!!
|
||||
ULONG_PROGRESSION -> symbols.uLong!!
|
||||
}.defaultType
|
||||
|
||||
fun castElementIfNecessary(element: IrExpression, context: CommonBackendContext) =
|
||||
element.castIfNecessary(elementType(context.ir.symbols), elementCastFunctionName)
|
||||
|
||||
@@ -78,6 +92,69 @@ internal enum class ProgressionType(
|
||||
.apply { dispatchReceiver = this@castIfNecessary }
|
||||
}
|
||||
|
||||
fun coerceToUnsigned(value: IrExpression, symbols: Symbols<CommonBackendContext>): IrExpression {
|
||||
if (!isUnsigned || value.type.isUnsigned()) return value
|
||||
|
||||
val unsafeCoerceIntrinsic = symbols.unsafeCoerceIntrinsic
|
||||
return if (unsafeCoerceIntrinsic != null) {
|
||||
val from = when (this) {
|
||||
UINT_PROGRESSION -> symbols.int.defaultType
|
||||
ULONG_PROGRESSION -> symbols.long.defaultType
|
||||
else -> error("Unexpected progression type")
|
||||
}
|
||||
val to = when (this) {
|
||||
UINT_PROGRESSION -> symbols.uInt!!.defaultType
|
||||
ULONG_PROGRESSION -> symbols.uLong!!.defaultType
|
||||
else -> error("Unexpected progression type")
|
||||
}
|
||||
IrCallImpl(value.startOffset, value.endOffset, to, unsafeCoerceIntrinsic).apply {
|
||||
putTypeArgument(0, from)
|
||||
putTypeArgument(1, to)
|
||||
putValueArgument(0, value)
|
||||
}
|
||||
} else {
|
||||
val conversionFunctionMap = when (this) {
|
||||
UINT_PROGRESSION -> symbols.toUIntByExtensionReceiver
|
||||
ULONG_PROGRESSION -> symbols.toULongByExtensionReceiver
|
||||
else -> error("Unexpected progression type")
|
||||
}
|
||||
val from = when (this) {
|
||||
UINT_PROGRESSION -> symbols.int.defaultType
|
||||
ULONG_PROGRESSION -> symbols.long.defaultType
|
||||
else -> error("Unexpected progression type")
|
||||
}.toKotlinType()
|
||||
val castFun = conversionFunctionMap.getValue(from)
|
||||
IrCallImpl(value.startOffset, value.endOffset, castFun.owner.returnType, castFun).apply {
|
||||
extensionReceiver = value
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
fun coerceToSigned(value: IrExpression, symbols: Symbols<CommonBackendContext>): IrExpression {
|
||||
if (!isUnsigned || !value.type.isUnsigned()) return value
|
||||
|
||||
val unsafeCoerceIntrinsic = symbols.unsafeCoerceIntrinsic
|
||||
return if (unsafeCoerceIntrinsic != null) {
|
||||
val from = when (this) {
|
||||
UINT_PROGRESSION -> symbols.uInt!!.defaultType
|
||||
ULONG_PROGRESSION -> symbols.uLong!!.defaultType
|
||||
else -> error("Unexpected progression type")
|
||||
}
|
||||
val to = when (this) {
|
||||
UINT_PROGRESSION -> symbols.int.defaultType
|
||||
ULONG_PROGRESSION -> symbols.long.defaultType
|
||||
else -> error("Unexpected progression type")
|
||||
}
|
||||
IrCallImpl(value.startOffset, value.endOffset, to, unsafeCoerceIntrinsic).apply {
|
||||
putTypeArgument(0, from)
|
||||
putTypeArgument(1, to)
|
||||
putValueArgument(0, value)
|
||||
}
|
||||
} else {
|
||||
castElementIfNecessary(value, symbols.context)
|
||||
}
|
||||
}
|
||||
|
||||
companion object {
|
||||
fun fromIrType(irType: IrType, symbols: Symbols<CommonBackendContext>): ProgressionType? = when {
|
||||
irType.isSubtypeOfClass(symbols.charProgression) -> CHAR_PROGRESSION
|
||||
|
||||
+18
-38
@@ -68,7 +68,6 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
|
||||
val inductionVariable: IrVariable
|
||||
|
||||
protected val stepVariable: IrVariable?
|
||||
protected val stepVariableForIncrement: IrVariable?
|
||||
val stepExpression: IrExpression
|
||||
// Always copy `stepExpression` is it may be used multiple times.
|
||||
get() = field.deepCopyWithSymbols()
|
||||
@@ -78,7 +77,7 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
|
||||
// Always copy `lastExpression` is it may be used in multiple conditions.
|
||||
get() = field.deepCopyWithSymbols()
|
||||
|
||||
private val symbols = context.ir.symbols
|
||||
protected val symbols = context.ir.symbols
|
||||
private val elementType: IrType
|
||||
|
||||
init {
|
||||
@@ -124,24 +123,6 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
|
||||
)
|
||||
stepVariable = tmpStepVar
|
||||
stepExpression = tmpStepExpression
|
||||
|
||||
stepVariableForIncrement = when (headerInfo.progressionType) {
|
||||
ProgressionType.UINT_PROGRESSION -> {
|
||||
val castFun = context.ir.symbols.toUIntByExtensionReceiver.getValue(stepType.toKotlinType())
|
||||
scope.createTmpVariable(
|
||||
irCall(castFun).apply { extensionReceiver = stepExpression },
|
||||
nameHint = "stepForIncrement"
|
||||
)
|
||||
}
|
||||
ProgressionType.ULONG_PROGRESSION -> {
|
||||
val castFun = context.ir.symbols.toULongByExtensionReceiver.getValue(stepType.toKotlinType())
|
||||
scope.createTmpVariable(
|
||||
irCall(castFun).apply { extensionReceiver = stepExpression },
|
||||
nameHint = "stepForIncrement"
|
||||
)
|
||||
}
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -155,10 +136,9 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
|
||||
/** Statement used to increment the induction variable. */
|
||||
protected fun incrementInductionVariable(builder: DeclarationIrBuilder): IrStatement = with(builder) {
|
||||
// inductionVariable = inductionVariable + step
|
||||
val stepExpressionToUse = stepVariableForIncrement?.let { irGet(stepVariableForIncrement) } ?: stepExpression
|
||||
// NOTE: We cannot use `stepExpression.type` below because it may be of type `Nothing`. This happens in the case of an illegal step
|
||||
// where the "step" is actually a `throw IllegalArgumentException(...)`.
|
||||
val stepType = stepVariableForIncrement?.type ?: headerInfo.progressionType.stepType(context.irBuiltIns)
|
||||
// NOTE: We cannot use `stepExpression.type` to match the value parameter type because it may be of type `Nothing`.
|
||||
// This happens in the case of an illegal step where the "step" is actually a `throw IllegalArgumentException(...)`.
|
||||
val stepType = headerInfo.progressionType.stepType(context.irBuiltIns)
|
||||
val plusFun = elementType.getClass()!!.functions.single {
|
||||
it.name == OperatorNameConventions.PLUS &&
|
||||
it.valueParameters.size == 1 &&
|
||||
@@ -168,7 +148,7 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
|
||||
inductionVariable.symbol, irCallOp(
|
||||
plusFun.symbol, plusFun.returnType,
|
||||
irGet(inductionVariable),
|
||||
stepExpressionToUse
|
||||
stepExpression
|
||||
)
|
||||
)
|
||||
}
|
||||
@@ -177,7 +157,7 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
|
||||
with(builder) {
|
||||
val builtIns = context.irBuiltIns
|
||||
val progressionType = headerInfo.progressionType
|
||||
val progressionElementType = progressionType.elementType(symbols)
|
||||
val progressionCompareType = progressionType.compareType(symbols)
|
||||
|
||||
// `compareTo` must be used for UInt/ULong; they don't have intrinsic comparison operators.
|
||||
val intCompFun = if (isLastInclusive) {
|
||||
@@ -185,17 +165,17 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
|
||||
} else {
|
||||
builtIns.lessFunByOperandType.getValue(builtIns.intClass)
|
||||
}
|
||||
val elementCompareToFun = progressionElementType.getClass()!!.functions.single {
|
||||
val elementCompareToFun = progressionCompareType.getClass()!!.functions.single {
|
||||
it.name == OperatorNameConventions.COMPARE_TO &&
|
||||
it.dispatchReceiverParameter != null && it.extensionReceiverParameter == null &&
|
||||
it.valueParameters.size == 1 && it.valueParameters[0].type == progressionElementType
|
||||
it.valueParameters.size == 1 && it.valueParameters[0].type == progressionCompareType
|
||||
}
|
||||
|
||||
val elementCompFun =
|
||||
if (isLastInclusive) {
|
||||
builtIns.lessOrEqualFunByOperandType[progressionElementType.classifierOrFail]
|
||||
builtIns.lessOrEqualFunByOperandType[progressionCompareType.classifierOrFail]
|
||||
} else {
|
||||
builtIns.lessFunByOperandType[progressionElementType.classifierOrFail]
|
||||
builtIns.lessFunByOperandType[progressionCompareType.classifierOrFail]
|
||||
}
|
||||
|
||||
fun conditionForDecreasing(): IrExpression =
|
||||
@@ -203,8 +183,8 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
|
||||
if (progressionType.isUnsigned) {
|
||||
irCall(intCompFun).apply {
|
||||
putValueArgument(0, irCall(elementCompareToFun).apply {
|
||||
dispatchReceiver = lastExpression
|
||||
putValueArgument(0, irGet(inductionVariable))
|
||||
dispatchReceiver = progressionType.coerceToUnsigned(lastExpression, symbols)
|
||||
putValueArgument(0, progressionType.coerceToUnsigned(irGet(inductionVariable), symbols))
|
||||
})
|
||||
putValueArgument(1, irInt(0))
|
||||
}
|
||||
@@ -220,8 +200,8 @@ internal abstract class NumericForLoopHeader<T : NumericHeaderInfo>(
|
||||
if (progressionType.isUnsigned) {
|
||||
irCall(intCompFun).apply {
|
||||
putValueArgument(0, irCall(elementCompareToFun).apply {
|
||||
dispatchReceiver = irGet(inductionVariable)
|
||||
putValueArgument(0, lastExpression)
|
||||
dispatchReceiver = progressionType.coerceToUnsigned(irGet(inductionVariable), symbols)
|
||||
putValueArgument(0, progressionType.coerceToUnsigned(lastExpression, symbols))
|
||||
})
|
||||
putValueArgument(1, irInt(0))
|
||||
}
|
||||
@@ -284,7 +264,7 @@ internal class ProgressionLoopHeader(
|
||||
else
|
||||
listOfNotNull(inductionVariable, lastVariableIfCanCacheLast)
|
||||
) +
|
||||
listOfNotNull(stepVariable, stepVariableForIncrement)
|
||||
listOfNotNull(stepVariable)
|
||||
|
||||
private var loopVariable: IrVariable? = null
|
||||
|
||||
@@ -303,7 +283,7 @@ internal class ProgressionLoopHeader(
|
||||
isMutable = true
|
||||
)
|
||||
} else {
|
||||
loopVariable?.initializer = irGet(inductionVariable)
|
||||
loopVariable?.initializer = headerInfo.progressionType.coerceToUnsigned(irGet(inductionVariable), symbols)
|
||||
loopVariable
|
||||
}
|
||||
|
||||
@@ -328,7 +308,7 @@ internal class ProgressionLoopHeader(
|
||||
// }
|
||||
IrDoWhileLoopImpl(oldLoop.startOffset, oldLoop.endOffset, oldLoop.type, oldLoop.origin).apply {
|
||||
label = oldLoop.label
|
||||
condition = irNotEquals(irGet(loopVariable!!), lastExpression)
|
||||
condition = irNotEquals(headerInfo.progressionType.coerceToSigned(irGet(loopVariable!!), symbols), lastExpression)
|
||||
body = newBody
|
||||
}
|
||||
} else {
|
||||
@@ -382,7 +362,7 @@ internal class IndexedGetLoopHeader(
|
||||
) : NumericForLoopHeader<IndexedGetHeaderInfo>(headerInfo, builder, context, isLastInclusive = false) {
|
||||
|
||||
override val loopInitStatements =
|
||||
listOfNotNull(headerInfo.objectVariable, inductionVariable, lastVariableIfCanCacheLast, stepVariable, stepVariableForIncrement)
|
||||
listOfNotNull(headerInfo.objectVariable, inductionVariable, lastVariableIfCanCacheLast, stepVariable)
|
||||
|
||||
override fun initializeIteration(
|
||||
loopVariable: IrVariable?,
|
||||
|
||||
+38
-34
@@ -17,12 +17,10 @@ import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
|
||||
import org.jetbrains.kotlin.ir.declarations.IrVariable
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.types.*
|
||||
import org.jetbrains.kotlin.ir.util.*
|
||||
import org.jetbrains.kotlin.name.FqName
|
||||
import org.jetbrains.kotlin.types.asSimpleType
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
import kotlin.math.absoluteValue
|
||||
|
||||
@@ -148,29 +146,14 @@ internal class UntilHandler(private val context: CommonBackendContext, private v
|
||||
val untilArgExpression = if (untilArgVar == null) untilArgCasted else irGet(untilArgVar)
|
||||
val last = untilArgExpression.decrement()
|
||||
|
||||
// Type of MIN_VALUE constant is signed even for unsigned progressions since the bounds are signed.
|
||||
val (minValueAsLong, minValueIrConst) =
|
||||
when (data) {
|
||||
ProgressionType.INT_PROGRESSION -> Pair(Int.MIN_VALUE.toLong(), irInt(Int.MIN_VALUE))
|
||||
ProgressionType.CHAR_PROGRESSION -> Pair(Char.MIN_VALUE.toLong(), irChar(Char.MIN_VALUE))
|
||||
ProgressionType.LONG_PROGRESSION -> Pair(Long.MIN_VALUE, irLong(Long.MIN_VALUE))
|
||||
ProgressionType.UINT_PROGRESSION -> Pair(
|
||||
UInt.MIN_VALUE.toLong(),
|
||||
IrConstImpl.int(
|
||||
startOffset,
|
||||
endOffset,
|
||||
symbols.uInt!!.defaultType,
|
||||
UInt.MIN_VALUE.toInt()
|
||||
)
|
||||
)
|
||||
ProgressionType.ULONG_PROGRESSION -> Pair(
|
||||
ULong.MIN_VALUE.toLong(),
|
||||
IrConstImpl.long(
|
||||
startOffset,
|
||||
endOffset,
|
||||
symbols.uLong!!.defaultType,
|
||||
ULong.MIN_VALUE.toLong()
|
||||
)
|
||||
)
|
||||
ProgressionType.UINT_PROGRESSION -> Pair(UInt.MIN_VALUE.toLong(), irInt(UInt.MIN_VALUE.toInt()))
|
||||
ProgressionType.ULONG_PROGRESSION -> Pair(ULong.MIN_VALUE.toLong(), irLong(ULong.MIN_VALUE.toLong()))
|
||||
}
|
||||
val additionalNotEmptyCondition = untilArg.constLongValue.let {
|
||||
when {
|
||||
@@ -496,22 +479,43 @@ internal class StepHandler(
|
||||
// - getProgressionLastElement(ULong, ULong, Long): ULong // Used by ULongProgression (uses Long step)
|
||||
//
|
||||
// We make sure to retrieve the correct symbol and use the correct argument types.
|
||||
val returnTypeClassifier = if (progressionType.isUnsigned) {
|
||||
progressionType.elementClassifier(symbols)
|
||||
} else {
|
||||
progressionType.stepClassifier(context.irBuiltIns)
|
||||
}
|
||||
val getProgressionLastElementFun = symbols.getProgressionLastElementByReturnType[returnTypeClassifier]
|
||||
?: throw IllegalArgumentException("No `getProgressionLastElement` for return type ${returnTypeClassifier.defaultType}")
|
||||
return irCall(getProgressionLastElementFun).apply {
|
||||
if (progressionType.isUnsigned) {
|
||||
putValueArgument(0, progressionType.castElementIfNecessary(first.deepCopyWithSymbols(), this@StepHandler.context))
|
||||
putValueArgument(1, progressionType.castElementIfNecessary(last.deepCopyWithSymbols(), this@StepHandler.context))
|
||||
return with(progressionType) {
|
||||
val returnTypeClassifier = if (progressionType.isUnsigned) {
|
||||
progressionType.elementClassifier(symbols)
|
||||
} else {
|
||||
putValueArgument(0, progressionType.castStepIfNecessary(first.deepCopyWithSymbols(), this@StepHandler.context))
|
||||
putValueArgument(1, progressionType.castStepIfNecessary(last.deepCopyWithSymbols(), this@StepHandler.context))
|
||||
progressionType.stepClassifier(context.irBuiltIns)
|
||||
}
|
||||
val getProgressionLastElementFun = symbols.getProgressionLastElementByReturnType[returnTypeClassifier]
|
||||
?: throw IllegalArgumentException("No `getProgressionLastElement` for return type ${returnTypeClassifier.defaultType}")
|
||||
val call = irCall(getProgressionLastElementFun).apply {
|
||||
if (isUnsigned) {
|
||||
putValueArgument(
|
||||
0,
|
||||
coerceToUnsigned(
|
||||
castElementIfNecessary(first.deepCopyWithSymbols(), this@StepHandler.context),
|
||||
symbols
|
||||
)
|
||||
)
|
||||
putValueArgument(
|
||||
1,
|
||||
coerceToUnsigned(
|
||||
castElementIfNecessary(last.deepCopyWithSymbols(), this@StepHandler.context),
|
||||
symbols
|
||||
)
|
||||
)
|
||||
} else {
|
||||
putValueArgument(0, castStepIfNecessary(first.deepCopyWithSymbols(), this@StepHandler.context))
|
||||
putValueArgument(1, castStepIfNecessary(last.deepCopyWithSymbols(), this@StepHandler.context))
|
||||
}
|
||||
putValueArgument(2, castStepIfNecessary(step.deepCopyWithSymbols(), this@StepHandler.context))
|
||||
}
|
||||
|
||||
if (isUnsigned) {
|
||||
// Bounds are signed for unsigned progressions.
|
||||
coerceToSigned(call, symbols)
|
||||
} else {
|
||||
call
|
||||
}
|
||||
putValueArgument(2, progressionType.castStepIfNecessary(step.deepCopyWithSymbols(), this@StepHandler.context))
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
@@ -507,7 +507,7 @@ class JvmSymbols(
|
||||
javaLangClass.functionByName("desiredAssertionStatus")
|
||||
}
|
||||
|
||||
val unsafeCoerceIntrinsic: IrSimpleFunctionSymbol =
|
||||
override val unsafeCoerceIntrinsic: IrSimpleFunctionSymbol =
|
||||
buildFun {
|
||||
name = Name.special("<unsafe-coerce>")
|
||||
origin = IrDeclarationOrigin.IR_BUILTINS_STUB
|
||||
|
||||
+3
-1
@@ -35,4 +35,6 @@ fun box(): String {
|
||||
// 1 INVOKESTATIC kotlin/internal/UProgressionUtilKt.getProgressionLastElement
|
||||
// 0 NEW java/lang/IllegalArgumentException
|
||||
// 0 ATHROW
|
||||
// 0 IF
|
||||
// 0 IF
|
||||
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
|
||||
|
||||
+3
-1
@@ -16,4 +16,6 @@ fun f(a: UInt): Int {
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 INVOKESTATIC kotlin/UnsignedKt.uintCompare
|
||||
// 2 IF
|
||||
// 2 IF
|
||||
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
|
||||
|
||||
+3
-1
@@ -16,4 +16,6 @@ fun f(a: ULong): Int {
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 INVOKESTATIC kotlin/UnsignedKt.ulongCompare
|
||||
// 2 IF
|
||||
// 2 IF
|
||||
// 0 INVOKESTATIC kotlin/ULong.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/ULong.(un)?box-impl
|
||||
|
||||
+2
@@ -56,3 +56,5 @@ fun testULongDownTo(a: ULong, b: ULong): Int {
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 0 INVOKESTATIC kotlin/U(Int|Long).constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/U(Int|Long).(un)?box-impl
|
||||
|
||||
+4
-1
@@ -1,3 +1,4 @@
|
||||
// WITH_RUNTIME
|
||||
const val M = UInt.MAX_VALUE
|
||||
|
||||
fun f(a: UInt): Int {
|
||||
@@ -15,4 +16,6 @@ fun f(a: UInt): Int {
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 INVOKESTATIC kotlin/UnsignedKt.uintCompare
|
||||
// 2 IF
|
||||
// 2 IF
|
||||
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
|
||||
|
||||
+3
-1
@@ -16,4 +16,6 @@ fun f(a: ULong): Int {
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 1 INVOKESTATIC kotlin/UnsignedKt.ulongCompare
|
||||
// 2 IF
|
||||
// 2 IF
|
||||
// 0 INVOKESTATIC kotlin/ULong.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/ULong.(un)?box-impl
|
||||
|
||||
+2
@@ -18,6 +18,8 @@ fun f(a: UInt): Int {
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
|
||||
|
||||
// JVM_TEMPLATES
|
||||
// 1 INVOKESTATIC kotlin/UnsignedKt.uintCompare
|
||||
|
||||
+2
@@ -18,6 +18,8 @@ fun f(a: UInt): Int {
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
|
||||
|
||||
// JVM_TEMPLATES
|
||||
// 1 IF
|
||||
|
||||
+2
@@ -18,6 +18,8 @@ fun f(a: ULong): Int {
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 0 INVOKESTATIC kotlin/ULong.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/ULong.(un)?box-impl
|
||||
|
||||
// JVM_TEMPLATES
|
||||
// 1 INVOKESTATIC kotlin/UnsignedKt.ulongCompare
|
||||
|
||||
+2
@@ -18,6 +18,8 @@ fun f(a: ULong): Int {
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getStep
|
||||
// 0 INVOKESTATIC kotlin/ULong.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/ULong.(un)?box-impl
|
||||
|
||||
// JVM_TEMPLATES
|
||||
// 1 IF
|
||||
|
||||
+9
-7
@@ -1,17 +1,17 @@
|
||||
// TARGET_BACKEND: JVM_IR
|
||||
// WITH_RUNTIME
|
||||
fun testUByteUntilUByte(a: UByte, b: UByte): UInt {
|
||||
var sum = 0u
|
||||
fun testUByteUntilUByte(a: UByte, b: UByte): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
sum = sum * 10u + i
|
||||
sum += i.toInt()
|
||||
}
|
||||
return sum
|
||||
}
|
||||
|
||||
fun testUShortUntilUShort(a: UShort, b: UShort): UInt {
|
||||
var sum = 0u
|
||||
fun testUShortUntilUShort(a: UShort, b: UShort): Int {
|
||||
var sum = 0
|
||||
for (i in a until b) {
|
||||
sum = sum * 10u + i
|
||||
sum += i.toInt()
|
||||
}
|
||||
return sum
|
||||
}
|
||||
@@ -31,4 +31,6 @@ fun testUShortUntilUShort(a: UShort, b: UShort): UInt {
|
||||
// 0 getStep
|
||||
// 2 IFGT
|
||||
// 2 IFLE
|
||||
// 4 IF
|
||||
// 4 IF
|
||||
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
|
||||
|
||||
+3
-1
@@ -38,4 +38,6 @@ fun box(): String {
|
||||
// 1 NEW java/lang/IllegalArgumentException
|
||||
// 1 ATHROW
|
||||
// 0 IF
|
||||
// 0 ARETURN
|
||||
// 0 ARETURN
|
||||
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
|
||||
|
||||
+3
-1
@@ -40,4 +40,6 @@ fun box(): String {
|
||||
// 0 ATHROW
|
||||
// 1 IFGT
|
||||
// 1 IF_ICMPNE
|
||||
// 2 IF
|
||||
// 2 IF
|
||||
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
|
||||
|
||||
Vendored
+3
-1
@@ -50,4 +50,6 @@ fun box(): String {
|
||||
// 3 IFLE
|
||||
// 1 IFGE
|
||||
// 6 IF
|
||||
// 0 INEG
|
||||
// 0 INEG
|
||||
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
|
||||
|
||||
Vendored
+3
-1
@@ -54,4 +54,6 @@ fun box(): String {
|
||||
// 4 IFLE
|
||||
// 1 IFGE
|
||||
// 7 IF
|
||||
// 1 INEG
|
||||
// 1 INEG
|
||||
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
|
||||
|
||||
+3
-1
@@ -42,4 +42,6 @@ fun box(): String {
|
||||
// 1 INVOKESTATIC kotlin/UnsignedKt.uintCompare
|
||||
// 1 IFGT
|
||||
// 1 IF_ICMPNE
|
||||
// 2 IF
|
||||
// 2 IF
|
||||
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
|
||||
|
||||
+3
-1
@@ -42,4 +42,6 @@ fun box(): String {
|
||||
// 1 IFEQ
|
||||
// 1 IFGT
|
||||
// 1 IF_ICMPNE
|
||||
// 3 IF
|
||||
// 3 IF
|
||||
// 0 INVOKESTATIC kotlin/UInt.constructor-impl
|
||||
// 0 INVOKE\w+ kotlin/UInt.(un)?box-impl
|
||||
|
||||
Reference in New Issue
Block a user