ForLoopsLowering: Handle Sequence<*>.withIndex().
This commit is contained in:
committed by
Alexander Udalov
parent
132960a695
commit
174576af61
@@ -95,8 +95,8 @@ open class BuiltinSymbolsBase(protected val irBuiltIns: IrBuiltIns, protected va
|
|||||||
private fun progression(name: String) = getClass(Name.identifier(name), "kotlin", "ranges")
|
private fun progression(name: String) = getClass(Name.identifier(name), "kotlin", "ranges")
|
||||||
private fun progressionOrNull(name: String) = getClassOrNull(Name.identifier(name), "kotlin", "ranges")
|
private fun progressionOrNull(name: String) = getClassOrNull(Name.identifier(name), "kotlin", "ranges")
|
||||||
|
|
||||||
// The "...OrNull" variants are used for unsigned (and progressions) because the minimal stdlib used in tests do not include those
|
// The "...OrNull" variants are used for the classes below because the minimal stdlib used in tests do not include those classes.
|
||||||
// those classes. It was not feasible to add them to the JS reduced runtime because all its transitive dependencies also need to be
|
// It was not feasible to add them to the JS reduced runtime because all its transitive dependencies also need to be
|
||||||
// added, which would include a lot of the full stdlib.
|
// added, which would include a lot of the full stdlib.
|
||||||
open val uByte = getClassOrNull(Name.identifier("UByte"), "kotlin")
|
open val uByte = getClassOrNull(Name.identifier("UByte"), "kotlin")
|
||||||
open val uShort = getClassOrNull(Name.identifier("UShort"), "kotlin")
|
open val uShort = getClassOrNull(Name.identifier("UShort"), "kotlin")
|
||||||
@@ -104,6 +104,7 @@ open class BuiltinSymbolsBase(protected val irBuiltIns: IrBuiltIns, protected va
|
|||||||
open val uLong = getClassOrNull(Name.identifier("ULong"), "kotlin")
|
open val uLong = getClassOrNull(Name.identifier("ULong"), "kotlin")
|
||||||
val uIntProgression = progressionOrNull("UIntProgression")
|
val uIntProgression = progressionOrNull("UIntProgression")
|
||||||
val uLongProgression = progressionOrNull("ULongProgression")
|
val uLongProgression = progressionOrNull("ULongProgression")
|
||||||
|
val sequence = getClassOrNull(Name.identifier("Sequence"), "kotlin", "sequences")
|
||||||
|
|
||||||
val charProgression = progression("CharProgression")
|
val charProgression = progression("CharProgression")
|
||||||
val intProgression = progression("IntProgression")
|
val intProgression = progression("IntProgression")
|
||||||
|
|||||||
+4
-3
@@ -320,7 +320,7 @@ internal class DefaultHeaderInfoBuilder(context: CommonBackendContext, scopeOwne
|
|||||||
// DefaultHeaderInfoBuilder. The differences between the two are that NestedHeaderInfoBuilderForWithIndex:
|
// DefaultHeaderInfoBuilder. The differences between the two are that NestedHeaderInfoBuilderForWithIndex:
|
||||||
//
|
//
|
||||||
// - Has NO WithIndexHandler. We do not attempt to optimize `*.withIndex().withIndex()`.
|
// - Has NO WithIndexHandler. We do not attempt to optimize `*.withIndex().withIndex()`.
|
||||||
// - Has DefaultIterableHandler. This allows us to optimize `Iterable<*>.withIndex()` and `Sequence<*>.withIndex()`.
|
// - Has Default(Iterable|Sequence)Handler. This allows us to optimize `Iterable<*>.withIndex()` and `Sequence<*>.withIndex()`.
|
||||||
internal class NestedHeaderInfoBuilderForWithIndex(context: CommonBackendContext, scopeOwnerSymbol: () -> IrSymbol) :
|
internal class NestedHeaderInfoBuilderForWithIndex(context: CommonBackendContext, scopeOwnerSymbol: () -> IrSymbol) :
|
||||||
HeaderInfoBuilder(context, scopeOwnerSymbol) {
|
HeaderInfoBuilder(context, scopeOwnerSymbol) {
|
||||||
// NOTE: No WithIndexHandler; we cannot lower `iterable.withIndex().withIndex()`.
|
// NOTE: No WithIndexHandler; we cannot lower `iterable.withIndex().withIndex()`.
|
||||||
@@ -330,12 +330,13 @@ internal class NestedHeaderInfoBuilderForWithIndex(context: CommonBackendContext
|
|||||||
|
|
||||||
// NOTE: StringIterationHandler MUST come before CharSequenceIterationHandler.
|
// NOTE: StringIterationHandler MUST come before CharSequenceIterationHandler.
|
||||||
// String is subtype of CharSequence and therefore its handler is more specialized.
|
// String is subtype of CharSequence and therefore its handler is more specialized.
|
||||||
// DefaultIterableHandler must come last as it is handles iterables not handled by more specialized handlers.
|
// Default(Iterable|Sequence)Handler must come last as they handle iterables not handled by more specialized handlers.
|
||||||
override val expressionHandlers = listOf(
|
override val expressionHandlers = listOf(
|
||||||
ArrayIterationHandler(context),
|
ArrayIterationHandler(context),
|
||||||
DefaultProgressionHandler(context),
|
DefaultProgressionHandler(context),
|
||||||
StringIterationHandler(context),
|
StringIterationHandler(context),
|
||||||
CharSequenceIterationHandler(context),
|
CharSequenceIterationHandler(context),
|
||||||
DefaultIterableHandler(context)
|
DefaultIterableHandler(context),
|
||||||
|
DefaultSequenceHandler(context),
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
+3
-6
@@ -19,10 +19,9 @@ import org.jetbrains.kotlin.ir.util.getSimpleFunction
|
|||||||
import org.jetbrains.kotlin.util.OperatorNameConventions
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
/** Builds a [HeaderInfo] for Iterables not handled by more specialized handlers. */
|
/** Builds a [HeaderInfo] for Iterables not handled by more specialized handlers. */
|
||||||
internal open class DefaultIterableHandler(private val context: CommonBackendContext) :
|
internal class DefaultIterableHandler(private val context: CommonBackendContext) : ExpressionHandler {
|
||||||
ExpressionHandler {
|
|
||||||
|
|
||||||
protected open val iterableClassSymbol = context.ir.symbols.iterable
|
private val iterableClassSymbol = context.ir.symbols.iterable
|
||||||
|
|
||||||
override fun matchIterable(expression: IrExpression) = expression.type.isSubtypeOfClass(iterableClassSymbol)
|
override fun matchIterable(expression: IrExpression) = expression.type.isSubtypeOfClass(iterableClassSymbol)
|
||||||
|
|
||||||
@@ -34,6 +33,4 @@ internal open class DefaultIterableHandler(private val context: CommonBackendCon
|
|||||||
scope.createTmpVariable(irCall(iteratorFun).apply { dispatchReceiver = expression }, nameHint = "iterator")
|
scope.createTmpVariable(irCall(iteratorFun).apply { dispatchReceiver = expression }, nameHint = "iterator")
|
||||||
)
|
)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
// TODO: Handle Sequences by extending DefaultIterableHandler.
|
|
||||||
+37
@@ -0,0 +1,37 @@
|
|||||||
|
/*
|
||||||
|
* Copyright 2010-2020 JetBrains s.r.o. and Kotlin Programming Language contributors.
|
||||||
|
* Use of this source code is governed by the Apache 2.0 license that can be found in the license/LICENSE.txt file.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package org.jetbrains.kotlin.backend.common.lower.loops.handlers
|
||||||
|
|
||||||
|
import org.jetbrains.kotlin.backend.common.CommonBackendContext
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.createIrBuilder
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.loops.ExpressionHandler
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.loops.HeaderInfo
|
||||||
|
import org.jetbrains.kotlin.backend.common.lower.loops.IterableHeaderInfo
|
||||||
|
import org.jetbrains.kotlin.ir.builders.createTmpVariable
|
||||||
|
import org.jetbrains.kotlin.ir.builders.irCall
|
||||||
|
import org.jetbrains.kotlin.ir.expressions.IrExpression
|
||||||
|
import org.jetbrains.kotlin.ir.symbols.IrSymbol
|
||||||
|
import org.jetbrains.kotlin.ir.types.isSubtypeOfClass
|
||||||
|
import org.jetbrains.kotlin.ir.util.getSimpleFunction
|
||||||
|
import org.jetbrains.kotlin.util.OperatorNameConventions
|
||||||
|
|
||||||
|
/** Builds a [HeaderInfo] for Sequences not handled by more specialized handlers. */
|
||||||
|
internal class DefaultSequenceHandler(private val context: CommonBackendContext) : ExpressionHandler {
|
||||||
|
|
||||||
|
private val sequenceClassSymbol = context.ir.symbols.sequence
|
||||||
|
|
||||||
|
override fun matchIterable(expression: IrExpression) =
|
||||||
|
sequenceClassSymbol != null && expression.type.isSubtypeOfClass(sequenceClassSymbol)
|
||||||
|
|
||||||
|
override fun build(expression: IrExpression, scopeOwner: IrSymbol): HeaderInfo? =
|
||||||
|
with(context.createIrBuilder(scopeOwner, expression.startOffset, expression.endOffset)) {
|
||||||
|
val iteratorFun =
|
||||||
|
sequenceClassSymbol!!.getSimpleFunction(OperatorNameConventions.ITERATOR.asString())!!.owner
|
||||||
|
IterableHeaderInfo(
|
||||||
|
scope.createTmpVariable(irCall(iteratorFun).apply { dispatchReceiver = expression }, nameHint = "iterator")
|
||||||
|
)
|
||||||
|
}
|
||||||
|
}
|
||||||
compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInEmptySequenceWithIndex.kt
Vendored
-3
@@ -1,6 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TODO KT-36774 Generate optimized loops over 'xs.withIndex()' in JVM_IR
|
|
||||||
// TODO: Handle Sequences by extending DefaultIterableHandler.
|
|
||||||
val xs = listOf<Any>().asSequence()
|
val xs = listOf<Any>().asSequence()
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
-3
@@ -1,6 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TODO KT-36774 Generate optimized loops over 'xs.withIndex()' in JVM_IR
|
|
||||||
// TODO: Handle Sequences by extending DefaultIterableHandler.
|
|
||||||
fun <T : Sequence<*>> test(sequence: T): String {
|
fun <T : Sequence<*>> test(sequence: T): String {
|
||||||
val s = StringBuilder()
|
val s = StringBuilder()
|
||||||
|
|
||||||
|
|||||||
Vendored
-3
@@ -1,6 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TODO KT-36774 Generate optimized loops over 'xs.withIndex()' in JVM_IR
|
|
||||||
// TODO: Handle Sequences by extending DefaultIterableHandler.
|
|
||||||
val xs = listOf("a", "b", "c", "d").asSequence()
|
val xs = listOf("a", "b", "c", "d").asSequence()
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
-3
@@ -1,6 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TODO KT-36774 Generate optimized loops over 'xs.withIndex()' in JVM_IR
|
|
||||||
// TODO: Handle Sequences by extending DefaultIterableHandler.
|
|
||||||
val xs = listOf("a", "b", "c", "d").asSequence()
|
val xs = listOf("a", "b", "c", "d").asSequence()
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
-3
@@ -1,6 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TODO KT-36774 Generate optimized loops over 'xs.withIndex()' in JVM_IR
|
|
||||||
// TODO: Handle Sequences by extending DefaultIterableHandler.
|
|
||||||
val xs = listOf("a", "b", "c", "d").asSequence()
|
val xs = listOf("a", "b", "c", "d").asSequence()
|
||||||
|
|
||||||
fun box(): String {
|
fun box(): String {
|
||||||
|
|||||||
-3
@@ -1,6 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TODO KT-36774 Generate optimized loops over 'xs.withIndex()' in JVM_IR
|
|
||||||
// TODO: Handle Sequences by extending DefaultIterableHandler.
|
|
||||||
// FULL_JDK
|
// FULL_JDK
|
||||||
|
|
||||||
val xsl = arrayListOf("a", "b", "c", "d")
|
val xsl = arrayListOf("a", "b", "c", "d")
|
||||||
|
|||||||
-3
@@ -1,6 +1,3 @@
|
|||||||
// IGNORE_BACKEND: JVM_IR
|
|
||||||
// TODO KT-36774 Generate optimized loops over 'xs.withIndex()' in JVM_IR
|
|
||||||
// TODO: Handle Sequences by extending DefaultIterableHandler.
|
|
||||||
val xs = listOf("a", "b", "c", "d").asSequence()
|
val xs = listOf("a", "b", "c", "d").asSequence()
|
||||||
|
|
||||||
fun useAny(x: Any) {}
|
fun useAny(x: Any) {}
|
||||||
|
|||||||
Reference in New Issue
Block a user