JVM_IR: Generate counter loop for reversed array (KT-22429)

This commit is contained in:
Xin Wang
2022-01-07 16:55:26 +08:00
committed by teamcity
parent cd957ae774
commit 60657022e0
4 changed files with 63 additions and 1 deletions
@@ -1234,6 +1234,12 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/arrays/forInReversed"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("reversedArray.kt")
public void testReversedArray() throws Exception {
runTest("compiler/testData/codegen/box/arrays/forInReversed/reversedArray.kt");
}
@Test
@TestMetadata("reversedArrayOriginalUpdatedInLoopBody.kt")
public void testReversedArrayOriginalUpdatedInLoopBody() throws Exception {
@@ -10,12 +10,15 @@ 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.IndexedGetHeaderInfo
import org.jetbrains.kotlin.backend.common.lower.matchers.Quantifier
import org.jetbrains.kotlin.backend.common.lower.matchers.SimpleCalleeMatcher
import org.jetbrains.kotlin.backend.common.lower.matchers.createIrCallMatcher
import org.jetbrains.kotlin.ir.builders.createTmpVariable
import org.jetbrains.kotlin.ir.builders.irCall
import org.jetbrains.kotlin.ir.builders.irGet
import org.jetbrains.kotlin.ir.builders.irInt
import org.jetbrains.kotlin.ir.declarations.IrSimpleFunction
import org.jetbrains.kotlin.ir.expressions.IrCall
import org.jetbrains.kotlin.ir.expressions.IrExpression
import org.jetbrains.kotlin.ir.symbols.IrSymbol
import org.jetbrains.kotlin.ir.types.*
@@ -75,7 +78,21 @@ internal class ArrayIterationHandler(context: CommonBackendContext) : IndexedGet
private val supportsUnsignedArrays = context.optimizeLoopsOverUnsignedArrays
override fun matchIterable(expression: IrExpression) =
expression.type.run { isArray() || isPrimitiveArray() || (supportsUnsignedArrays && isUnsignedArray()) }
expression.type.run { isArray() || isPrimitiveArray() || (supportsUnsignedArrays && isUnsignedArray()) } ||
expression.run {
this is IrCall && reversedArrayMatcher(this)
}
private val reversedArrayMatcher =
createIrCallMatcher(Quantifier.ANY) {
callee {
fqName { it == FqName("kotlin.collections.reversed") }
extensionReceiver {
it != null && it.type.run { isArray() || isPrimitiveArray() }
}
parameterCount { it == 0 }
}
}
override val IrType.sizePropertyGetter
get() = getClass()!!.getPropertyGetter("size")!!.owner
@@ -0,0 +1,33 @@
// TARGET_BACKEND: JVM_IR
// WITH_STDLIB
import kotlin.test.*
fun box(): String {
testReversed()
testReversedArray()
return "OK"
}
fun testReversed() {
val arr = intArrayOf(6, 7, 8, 9)
var result = ""
for (i in arr.reversed()) {
arr[0] = 0
result += i
}
assertEquals("9876", result)
}
fun testReversedArray() {
val arr = intArrayOf(6, 7, 8, 9)
var result = ""
for (i in arr.reversedArray()) {
arr[0] = 0
result += i
}
assertEquals("9876", result)
}
// CHECK_BYTECODE_TEXT
// 0 java/util/List.iterator
// 2 IINC
@@ -1234,6 +1234,12 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes
KtTestUtil.assertAllTestsPresentByMetadataWithExcluded(this.getClass(), new File("compiler/testData/codegen/box/arrays/forInReversed"), Pattern.compile("^(.+)\\.kt$"), null, TargetBackend.JVM_IR, true);
}
@Test
@TestMetadata("reversedArray.kt")
public void testReversedArray() throws Exception {
runTest("compiler/testData/codegen/box/arrays/forInReversed/reversedArray.kt");
}
@Test
@TestMetadata("reversedArrayOriginalUpdatedInLoopBody.kt")
public void testReversedArrayOriginalUpdatedInLoopBody() throws Exception {