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 val inductionVariableOrigin: IrDeclarationOrigin
get() = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE get() = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE
val optimizeLoopsOverUnsignedArrays: Boolean
get() = false
} }
@@ -72,7 +72,10 @@ abstract class IndexedGetIterationHandler(
/** Builds a [HeaderInfo] for arrays. */ /** Builds a [HeaderInfo] for arrays. */
internal class ArrayIterationHandler(context: CommonBackendContext) : IndexedGetIterationHandler(context, canCacheLast = true) { 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 override val IrType.sizePropertyGetter
get() = getClass()!!.getPropertyGetter("size")!!.owner get() = getClass()!!.getPropertyGetter("size")!!.owner
@@ -76,9 +76,14 @@ internal class CollectionIndicesHandler(context: CommonBackendContext) : Indices
} }
internal class ArrayIndicesHandler(context: CommonBackendContext) : IndicesHandler(context) { internal class ArrayIndicesHandler(context: CommonBackendContext) : IndicesHandler(context) {
private val supportsUnsignedArrays = context.optimizeLoopsOverUnsignedArrays
override val matcher = SimpleCalleeMatcher { 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>") } fqName { it == FqName("kotlin.collections.<get-indices>") }
parameterCount { it == 0 } parameterCount { it == 0 }
} }
@@ -26,12 +26,19 @@ import org.jetbrains.kotlin.name.FqName
internal class WithIndexHandler(context: CommonBackendContext, private val visitor: NestedHeaderInfoBuilderForWithIndex) : internal class WithIndexHandler(context: CommonBackendContext, private val visitor: NestedHeaderInfoBuilderForWithIndex) :
HeaderInfoFromCallHandler<Nothing?> { HeaderInfoFromCallHandler<Nothing?> {
private val supportsUnsignedArrays = context.optimizeLoopsOverUnsignedArrays
// Use Quantifier.ANY so we can handle all `withIndex()` calls in the same manner. // Use Quantifier.ANY so we can handle all `withIndex()` calls in the same manner.
override val matcher = override val matcher =
createIrCallMatcher(Quantifier.ANY) { createIrCallMatcher(Quantifier.ANY) {
callee { callee {
fqName { it == FqName("kotlin.collections.withIndex") } 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 } parameterCount { it == 0 }
} }
callee { callee {
@@ -215,6 +215,9 @@ class JvmBackendContext(
override val preferJavaLikeCounterLoop: Boolean override val preferJavaLikeCounterLoop: Boolean
get() = true get() = true
override val optimizeLoopsOverUnsignedArrays: Boolean
get() = true
override val doWhileCounterLoopOrigin: IrStatementOrigin override val doWhileCounterLoopOrigin: IrStatementOrigin
get() = JvmLoweredStatementOrigin.DO_WHILE_COUNTER_LOOP get() = JvmLoweredStatementOrigin.DO_WHILE_COUNTER_LOOP