Make optimized loop over unsigned array, indices, withIndex JVM-specific

This commit is contained in:
Dmitry Petrov
2021-09-22 18:55:29 +03:00
committed by TeamCityServer
parent be28b3c74d
commit 9799ad7bd8
5 changed files with 24 additions and 3 deletions
@@ -61,4 +61,7 @@ interface CommonBackendContext : BackendContext, LoggingContext {
val inductionVariableOrigin: IrDeclarationOrigin
get() = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE
val optimizeLoopsOverUnsignedArrays: Boolean
get() = false
}
@@ -72,7 +72,10 @@ abstract class IndexedGetIterationHandler(
/** Builds a [HeaderInfo] for arrays. */
internal class ArrayIterationHandler(context: CommonBackendContext) : IndexedGetIterationHandler(context, canCacheLast = true) {
override fun matchIterable(expression: IrExpression) = expression.type.run { isArray() || isPrimitiveArray() || isUnsignedArray() }
private val supportsUnsignedArrays = context.optimizeLoopsOverUnsignedArrays
override fun matchIterable(expression: IrExpression) =
expression.type.run { isArray() || isPrimitiveArray() || (supportsUnsignedArrays && isUnsignedArray()) }
override val IrType.sizePropertyGetter
get() = getClass()!!.getPropertyGetter("size")!!.owner
@@ -76,9 +76,14 @@ internal class CollectionIndicesHandler(context: CommonBackendContext) : Indices
}
internal class ArrayIndicesHandler(context: CommonBackendContext) : IndicesHandler(context) {
private val supportsUnsignedArrays = context.optimizeLoopsOverUnsignedArrays
override val matcher = SimpleCalleeMatcher {
extensionReceiver { it != null && it.type.run { isArray() || isPrimitiveArray() || isUnsignedArray() } }
extensionReceiver {
it != null && it.type.run {
isArray() || isPrimitiveArray() || (supportsUnsignedArrays && isUnsignedArray())
}
}
fqName { it == FqName("kotlin.collections.<get-indices>") }
parameterCount { it == 0 }
}
@@ -26,12 +26,19 @@ import org.jetbrains.kotlin.name.FqName
internal class WithIndexHandler(context: CommonBackendContext, private val visitor: NestedHeaderInfoBuilderForWithIndex) :
HeaderInfoFromCallHandler<Nothing?> {
private val supportsUnsignedArrays = context.optimizeLoopsOverUnsignedArrays
// Use Quantifier.ANY so we can handle all `withIndex()` calls in the same manner.
override val matcher =
createIrCallMatcher(Quantifier.ANY) {
callee {
fqName { it == FqName("kotlin.collections.withIndex") }
extensionReceiver { it != null && it.type.run { isArray() || isPrimitiveArray() || isUnsignedArray() || isIterable() } }
extensionReceiver {
it != null && it.type.run {
isArray() || isPrimitiveArray() || isIterable() ||
(supportsUnsignedArrays && isUnsignedArray())
}
}
parameterCount { it == 0 }
}
callee {
@@ -215,6 +215,9 @@ class JvmBackendContext(
override val preferJavaLikeCounterLoop: Boolean
get() = true
override val optimizeLoopsOverUnsignedArrays: Boolean
get() = true
override val doWhileCounterLoopOrigin: IrStatementOrigin
get() = JvmLoweredStatementOrigin.DO_WHILE_COUNTER_LOOP