JVM_IR generate less bytecode for for-loops if possible(KT-22334).
This commit is contained in:
+42
-7
@@ -10,12 +10,10 @@ import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||
import org.jetbrains.kotlin.backend.common.lower.loops.*
|
||||
import org.jetbrains.kotlin.backend.common.lower.matchers.SimpleCalleeMatcher
|
||||
import org.jetbrains.kotlin.ir.builders.irInt
|
||||
import org.jetbrains.kotlin.ir.expressions.IrCall
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConst
|
||||
import org.jetbrains.kotlin.ir.expressions.IrConstKind
|
||||
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||
import org.jetbrains.kotlin.ir.expressions.*
|
||||
import org.jetbrains.kotlin.ir.expressions.impl.IrConstImpl
|
||||
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||
import org.jetbrains.kotlin.ir.util.fqNameWhenAvailable
|
||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||
|
||||
/** Builds a [HeaderInfo] for progressions built using the `rangeTo` function. */
|
||||
@@ -67,7 +65,46 @@ internal class RangeToHandler(private val context: CommonBackendContext) :
|
||||
if (preferJavaLikeCounterLoop || this.constLongValue == -1L) return null
|
||||
}
|
||||
|
||||
val irConst = this as? IrConst<*> ?: return null
|
||||
return when (this) {
|
||||
is IrConst<*> -> convertIrConst(this)
|
||||
is IrCall -> convertIrCall(this)
|
||||
else -> null
|
||||
}
|
||||
}
|
||||
|
||||
private val allowedMethods = listOf(
|
||||
"kotlin.ByteArray.<get-size>",
|
||||
"kotlin.CharArray.<get-size>",
|
||||
"kotlin.String.<get-length>",
|
||||
"kotlin.ShortArray.<get-size>",
|
||||
"kotlin.IntArray.<get-size>",
|
||||
"kotlin.LongArray.<get-size>",
|
||||
"kotlin.FloatArray.<get-size>",
|
||||
"kotlin.DoubleArray.<get-size>",
|
||||
"kotlin.BooleanArray.<get-size>",
|
||||
"kotlin.collections.List.<get-size>",
|
||||
"kotlin.collections.MutableList.<get-size>",
|
||||
"kotlin.CharSequence.<get-length>",
|
||||
"kotlin.collections.Set.<get-size>",
|
||||
"kotlin.collections.MutableSet.<get-size>",
|
||||
"kotlin.collections.Map.<get-size>",
|
||||
"kotlin.collections.MutableMap.<get-size>",
|
||||
)
|
||||
|
||||
private fun convertIrCall(irCall: IrCall): IrExpression? {
|
||||
fun IrCall.dispatchReceiverName() = (dispatchReceiver as? IrCall)?.symbol?.owner?.fqNameWhenAvailable.toString()
|
||||
|
||||
return if (irCall.origin == IrStatementOrigin.MINUS
|
||||
&& (irCall.getValueArgument(0) as? IrConst<*>)?.value == 1
|
||||
&& irCall.dispatchReceiverName() in allowedMethods // to avoid possible underflow
|
||||
) irCall.dispatchReceiver
|
||||
else null
|
||||
}
|
||||
|
||||
private fun convertIrConst(irConst: IrConst<*>): IrExpression? {
|
||||
val startOffset = irConst.startOffset
|
||||
val endOffset = irConst.endOffset
|
||||
val type = irConst.type
|
||||
return when (irConst.kind) {
|
||||
IrConstKind.Char -> {
|
||||
val charValue = IrConstKind.Char.valueOf(irConst)
|
||||
@@ -108,6 +145,4 @@ internal class RangeToHandler(private val context: CommonBackendContext) :
|
||||
null
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
Reference in New Issue
Block a user