From b669de16631748f7d3ba9f397655c1665c348ff5 Mon Sep 17 00:00:00 2001 From: Dmitry Petrov Date: Wed, 1 Sep 2021 15:31:19 +0300 Subject: [PATCH] JVM_IR generate range-based loop closer to Java counter loop KT-48435 KT-48507 --- .../FirBlackBoxCodegenTestGenerated.java | 6 - .../backend/common/CommonBackendContext.kt | 11 ++ .../kotlin/backend/common/lower/LowerUtils.kt | 2 +- .../common/lower/loops/ForLoopsLowering.kt | 149 +++++++++++++++--- .../common/lower/loops/HeaderProcessor.kt | 145 +++++++++++------ .../kotlin/backend/jvm/JvmBackendContext.kt | 7 + .../kotlin/backend/jvm/StatementOrigins.kt | 1 + .../box/coroutines/debug/debuggerMetadata.kt | 1 - .../coroutines/debug/debuggerMetadata_ir.kt | 113 ------------- .../forInArrayWithIndexNoElementVar.kt | 10 ++ .../forInArrayWithIndexNoIndexVar.kt | 10 ++ .../forInEmptyArrayWithIndex.kt | 10 ++ .../forInIntArrayWithIndex.kt | 10 ++ .../forInObjectArrayWithIndex.kt | 10 ++ .../bytecodeText/forLoop/forInCharSequence.kt | 9 ++ .../forLoop/forInCharSequenceTypeParameter.kt | 9 ++ .../forInCharSequenceWithIndex.kt | 10 ++ .../forInEmptyStringWithIndex.kt | 10 ++ .../forInStringWithIndex.kt | 10 ++ .../forInStringWithIndexNoElementVar.kt | 10 ++ .../forInStringWithIndexNoIndexVar.kt | 10 ++ ...thIndexWithExplicitlyTypedIndexVariable.kt | 10 ++ .../forLoop/forInDownToCharMinValue.kt | 9 ++ .../forLoop/forInDownToIntMinValue.kt | 9 ++ .../forLoop/forInDownToLongMinValue.kt | 9 ++ .../forInIndices/forInArrayListIndices.kt | 9 ++ .../forInIndices/forInCharSequenceIndices.kt | 9 ++ .../forInCharSequenceTypeParameterIndices.kt | 9 ++ .../forInCollectionImplicitReceiverIndices.kt | 9 ++ .../forInIndices/forInCollectionIndices.kt | 9 ++ .../forInCollectionTypeParameterIndices.kt | 9 ++ .../forInIndices/forInNonOptimizedIndices.kt | 9 ++ .../forInIndices/forInObjectArrayIndices.kt | 9 ++ .../forInPrimitiveArrayIndices.kt | 9 ++ .../forInEmptyListWithIndex.kt | 10 ++ .../forInIterableTypeParameterWithIndex.kt | 10 ++ .../forInListWithIndex.kt | 10 ++ .../forInListWithIndexNoElementVar.kt | 10 ++ .../forInListWithIndexNoIndexVar.kt | 10 ++ ...thIndexWithExplicitlyTypedIndexVariable.kt | 10 ++ .../bytecodeText/forLoop/forInObjectArray.kt | 9 ++ .../forLoop/forInPrimitiveArray.kt | 9 ++ .../forInDownToWithIndex.kt | 10 ++ .../forInIndicesWithIndex.kt | 10 ++ .../forInRangeToWithIndex.kt | 10 ++ .../forInReversedStepWithIndex.kt | 10 ++ .../forInReversedWithIndex.kt | 10 ++ .../forInStepReversedWithIndex.kt | 10 ++ .../forInStepWithIndex.kt | 10 ++ .../forInUntilWithIndex.kt | 10 ++ .../forInWithIndexNoIndexOrElementVar.kt | 10 ++ .../forInWithIndexNotDestructured.kt | 9 ++ .../forInWithIndexReversed.kt | 9 ++ .../forInWithIndexWithIndex.kt | 10 ++ .../forLoop/forInRangeSpecializedToUntil.kt | 7 +- .../forLoop/forInRangeToCharConst.kt | 9 ++ .../forLoop/forInRangeToCharMaxValue.kt | 9 ++ .../bytecodeText/forLoop/forInRangeToConst.kt | 8 +- .../forLoop/forInRangeToIntMaxValue.kt | 9 ++ .../forLoop/forInRangeToLongConst.kt | 9 ++ .../forLoop/forInRangeToLongMaxValue.kt | 9 ++ .../forLoop/forInRangeToQualifiedConst.kt | 9 ++ .../forLoop/forInRangeWithImplicitReceiver.kt | 9 ++ .../ForInReversedReversedRange.kt | 9 ++ .../forInReversedArrayIndices.kt | 9 ++ .../forInReversedCharSequenceIndices.kt | 9 ++ .../forInReversedCollectionIndices.kt | 9 ++ .../forInReversed/forInReversedDownTo.kt | 9 ++ .../forInReversedEmptyRangeLiteral.kt | 9 ++ .../forInReversed/forInReversedRange.kt | 9 ++ .../forInReversedRangeLiteral.kt | 9 ++ .../forInReversedReversedArrayIndices.kt | 9 ++ .../forInReversedReversedDownTo.kt | 9 ++ .../forInReversedReversedReversedRange.kt | 9 ++ .../forInReversedReversedUntil.kt | 9 ++ .../forInReversed/forInReversedUntil.kt | 9 ++ .../forInEmptySequenceWithIndex.kt | 10 ++ .../forInSequenceTypeParameterWithIndex.kt | 10 ++ .../forInSequenceWithIndex.kt | 10 ++ .../forInSequenceWithIndexNoElementVar.kt | 10 ++ .../forInSequenceWithIndexNoIndexVar.kt | 10 ++ .../forInSequenceWithIndexThrowsCME.kt | 9 ++ ...thIndexWithExplicitlyTypedIndexVariable.kt | 10 ++ .../forLoop/forInStringSpecialized.kt | 9 ++ .../forLoop/forInUntil/forInUntilChar.kt | 9 ++ .../forInUntil/forInUntilCharMaxValue.kt | 9 ++ .../forInUntil/forInUntilCharMinValue.kt | 9 ++ .../forLoop/forInUntil/forInUntilInt.kt | 9 ++ .../forInUntil/forInUntilIntMaxValue.kt | 9 ++ .../forInUntil/forInUntilIntMinValue.kt | 9 ++ .../forLoop/forInUntil/forInUntilLong.kt | 9 ++ .../forInUntil/forInUntilLongMaxValue.kt | 9 ++ .../forInUntil/forInUntilLongMinValue.kt | 9 ++ .../bytecodeText/forLoop/forIntInDownTo.kt | 9 ++ .../bytecodeText/forLoop/iincGeneration.kt | 9 ++ ...ntrinsicArrayConstructorsUseCounterLoop.kt | 9 ++ .../bytecodeText/forLoop/loopVarInterval.kt | 9 ++ .../forLoop/primitiveLiteralRange1.kt | 9 ++ .../forLoop/primitiveLiteralRange2.kt | 9 ++ .../forLoop/primitiveProgression.kt | 48 ++---- .../bytecodeText/forLoop/primitiveRange.kt | 21 ++- .../forLoop/stepped/illegalStepConst.kt | 27 ++-- .../forLoop/stepped/reversedThenStep.kt | 36 ++--- .../bytecodeText/forLoop/stepped/stepConst.kt | 33 ++-- .../stepConstOnNonLiteralProgression.kt | 39 +++-- .../forLoop/stepped/stepNonConst.kt | 36 ++--- .../stepNonConstOnNonLiteralProgression.kt | 41 +++-- .../forLoop/stepped/stepOnNonLiteralRange.kt | 36 ++--- .../bytecodeText/forLoop/stepped/stepOne.kt | 10 ++ .../forLoop/stepped/stepOneThenStepOne.kt | 10 ++ .../forLoop/stepped/stepThenDifferentStep.kt | 35 ++-- .../forLoop/stepped/stepThenReversed.kt | 10 ++ .../forLoop/stepped/stepThenSameStep.kt | 32 ++-- .../forLoop/stepped/stepThenStepNonConst.kt | 39 ++--- .../forLoop/stepped/stepThenStepOne.kt | 35 ++-- .../unsigned/forInDownToUIntMinValue.kt | 10 ++ .../unsigned/forInDownToULongMinValue.kt | 10 ++ .../unsigned/forInOptimizableUnsignedRange.kt | 9 ++ .../unsigned/forInRangeToUIntMaxValue.kt | 10 ++ .../unsigned/forInRangeToULongMaxValue.kt | 10 ++ .../unsigned/forInUntilUIntMaxValue.kt | 10 ++ .../unsigned/forInUntilUIntMinValue.kt | 10 ++ .../unsigned/forInUntilULongMaxValue.kt | 10 ++ .../unsigned/forInUntilULongMinValue.kt | 10 ++ .../forLoop/unsigned/illegalStepConst.kt | 27 ++-- .../forLoop/unsigned/reversedThenStep.kt | 33 ++-- .../stepConstOnNonLiteralProgression.kt | 26 +-- .../stepNonConstOnNonLiteralProgression.kt | 39 ++--- .../forLoop/unsigned/stepOnNonLiteralRange.kt | 34 ++-- .../forLoop/unsigned/stepThenDifferentStep.kt | 34 ++-- .../storeStackBeforeInline/differentTypes.kt | 9 +- .../storeStackBeforeInline/primitiveMerge.kt | 10 +- .../storeStackBeforeInline/withLambda.kt | 2 +- .../suspend/localsStateMachineTransform.kt | 8 +- .../codegen/BlackBoxCodegenTestGenerated.java | 6 - .../IrBlackBoxCodegenTestGenerated.java | 6 - .../LightAnalysisModeTestGenerated.java | 5 - 137 files changed, 1518 insertions(+), 573 deletions(-) delete mode 100644 compiler/testData/codegen/box/coroutines/debug/debuggerMetadata_ir.kt diff --git a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java index 444835415ac..e332d7ea65d 100644 --- a/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java +++ b/compiler/fir/fir2ir/tests-gen/org/jetbrains/kotlin/test/runners/codegen/FirBlackBoxCodegenTestGenerated.java @@ -10093,12 +10093,6 @@ public class FirBlackBoxCodegenTestGenerated extends AbstractFirBlackBoxCodegenT runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt"); } - @Test - @TestMetadata("debuggerMetadata_ir.kt") - public void testDebuggerMetadata_ir() throws Exception { - runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata_ir.kt"); - } - @Test @TestMetadata("elvisLineNumber.kt") public void testElvisLineNumber() throws Exception { diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CommonBackendContext.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CommonBackendContext.kt index 99fa29c9898..ae05330c6fb 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CommonBackendContext.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/CommonBackendContext.kt @@ -11,9 +11,11 @@ import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.builders.IrBuilderWithScope import org.jetbrains.kotlin.ir.builders.irCall import org.jetbrains.kotlin.ir.builders.irString +import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin import org.jetbrains.kotlin.ir.declarations.IrFile import org.jetbrains.kotlin.ir.expressions.IrCall import org.jetbrains.kotlin.ir.expressions.IrExpression +import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.symbols.IrClassSymbol import org.jetbrains.kotlin.ir.symbols.IrFileSymbol import org.jetbrains.kotlin.ir.symbols.IrSimpleFunctionSymbol @@ -53,4 +55,13 @@ interface CommonBackendContext : BackendContext, LoggingContext { val preferJavaLikeCounterLoop: Boolean get() = false + + val reuseLoopVariableAsInductionVariable: Boolean + get() = false + + val doWhileCounterLoopOrigin: IrStatementOrigin? + get() = null + + val inductionVariableOrigin: IrDeclarationOrigin + get() = IrDeclarationOrigin.IR_TEMPORARY_VARIABLE } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt index 972845a4afe..37792ee7888 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/LowerUtils.kt @@ -47,7 +47,7 @@ abstract class AbstractVariableRemapper : IrElementTransformerVoid() { override fun visitSetValue(expression: IrSetValue): IrExpression { expression.transformChildrenVoid() return remapVariable(expression.symbol.owner)?.let { - IrSetValueImpl(expression.startOffset, expression.endOffset, it.type, it.symbol, expression.value, expression.origin) + IrSetValueImpl(expression.startOffset, expression.endOffset, expression.type, it.symbol, expression.value, expression.origin) } ?: expression } } diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ForLoopsLowering.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ForLoopsLowering.kt index d110be0045c..98cee8dd39b 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ForLoopsLowering.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/ForLoopsLowering.kt @@ -8,16 +8,18 @@ package org.jetbrains.kotlin.backend.common.lower.loops import org.jetbrains.kotlin.backend.common.BodyLoweringPass import org.jetbrains.kotlin.backend.common.CommonBackendContext import org.jetbrains.kotlin.backend.common.IrElementTransformerVoidWithContext +import org.jetbrains.kotlin.backend.common.lower.AbstractVariableRemapper import org.jetbrains.kotlin.backend.common.lower.createIrBuilder import org.jetbrains.kotlin.backend.common.phaser.makeIrFilePhase import org.jetbrains.kotlin.ir.IrElement import org.jetbrains.kotlin.ir.IrStatement -import org.jetbrains.kotlin.ir.declarations.IrDeclaration -import org.jetbrains.kotlin.ir.declarations.IrDeclarationOrigin -import org.jetbrains.kotlin.ir.declarations.IrSymbolOwner -import org.jetbrains.kotlin.ir.declarations.IrVariable +import org.jetbrains.kotlin.ir.declarations.* +import org.jetbrains.kotlin.ir.declarations.impl.IrVariableImpl import org.jetbrains.kotlin.ir.expressions.* import org.jetbrains.kotlin.ir.expressions.impl.IrCompositeImpl +import org.jetbrains.kotlin.ir.symbols.impl.IrVariableSymbolImpl +import org.jetbrains.kotlin.ir.types.classifierOrNull +import org.jetbrains.kotlin.ir.types.isNullable import org.jetbrains.kotlin.ir.util.dump import org.jetbrains.kotlin.ir.util.render import org.jetbrains.kotlin.ir.visitors.* @@ -97,7 +99,10 @@ val forLoopsPhase = makeIrFilePhase( * } * ``` */ -class ForLoopsLowering(val context: CommonBackendContext, val loopBodyTransformer: ForLoopBodyTransformer? = null) : BodyLoweringPass { +class ForLoopsLowering( + val context: CommonBackendContext, + private val loopBodyTransformer: ForLoopBodyTransformer? = null +) : BodyLoweringPass { override fun lower(irBody: IrBody, container: IrDeclaration) { val oldLoopToNewLoop = mutableMapOf() @@ -160,30 +165,127 @@ private class RangeLoopTransformer( return super.visitBlock(expression) // Not a for-loop block. } - with(expression.statements) { - assert(size == 2) { "Expected 2 statements in for-loop block, was:\n${expression.dump()}" } - val iteratorVariable = get(0) as IrVariable - assert(iteratorVariable.origin == IrDeclarationOrigin.FOR_LOOP_ITERATOR) { "Expected FOR_LOOP_ITERATOR origin for iterator variable, was:\n${iteratorVariable.dump()}" } - val loopHeader = headerProcessor.extractHeader(iteratorVariable) - ?: return super.visitBlock(expression) // The iterable in the header is not supported. - val loweredHeader = lowerHeader(iteratorVariable, loopHeader) + val statements = expression.statements + assert(statements.size == 2) { "Expected 2 statements in for-loop block, was:\n${expression.dump()}" } + val iteratorVariable = statements[0] as IrVariable + assert(iteratorVariable.origin == IrDeclarationOrigin.FOR_LOOP_ITERATOR) { + "Expected FOR_LOOP_ITERATOR origin for iterator variable, was:\n${iteratorVariable.dump()}" + } + val oldLoop = statements[1] as IrWhileLoop + assert(oldLoop.origin == IrStatementOrigin.FOR_LOOP_INNER_WHILE) { + "Expected FOR_LOOP_INNER_WHILE origin for while loop, was:\n${oldLoop.dump()}" + } - val oldLoop = get(1) as IrWhileLoop - assert(oldLoop.origin == IrStatementOrigin.FOR_LOOP_INNER_WHILE) { "Expected FOR_LOOP_INNER_WHILE origin for while loop, was:\n${oldLoop.dump()}" } - val (newLoop, loopReplacementExpression) = lowerWhileLoop(oldLoop, loopHeader) - ?: return super.visitBlock(expression) // Cannot lower the loop. + val loopHeader = headerProcessor.extractHeader(iteratorVariable) + ?: return super.visitBlock(expression) // The iterable in the header is not supported. + val loweredHeader = lowerHeader(iteratorVariable, loopHeader) - // We can lower both the header and while loop. - // Update mapping from old to new loop so we can later update references in break/continue. - oldLoopToNewLoop[oldLoop] = newLoop + val (newLoop, loopReplacementExpression) = lowerWhileLoop(oldLoop, loopHeader) + ?: return super.visitBlock(expression) // Cannot lower the loop. - set(0, loweredHeader) - set(1, loopReplacementExpression) + // We can lower both the header and while loop. + // Update mapping from old to new loop so we can later update references in break/continue. + oldLoopToNewLoop[oldLoop] = newLoop + + statements[0] = loweredHeader + statements[1] = loopReplacementExpression + + if (context.reuseLoopVariableAsInductionVariable && loopHeader.canReuseLoopVariableAsInductionVariable) { + reuseLoopVariableAsInductionVariable(expression) } return super.visitBlock(expression) } + private fun reuseLoopVariableAsInductionVariable(irBlock: IrBlock) { + // Given a loop in the form: + // { + // var inductionVariable = + // } + // do { + // if (!()) break + // val loopVariable = inductionVariable + // + // } while ( { inductionVariable += ; true } ) + // replace it with: + // { + // var loopVariable' = + // } + // do { + // if (!()) break + // + // } while ( { loopVariable' += ; true } ) + // where whenLoopCondition' and originalLoopBody' are corresponding statements + // with inductionVariable and loopVariable remapped to loopVariable'. + // + // NB we can do so only with a do-while counter loop as described above, + // otherwise it changes semantics of 'continue' inside the loop. + + val header = irBlock.statements[0] as? IrStatementContainer ?: return + + val inductionVariableIndex = header.statements.indexOfFirst { it.isInductionVariable(context) } + if (inductionVariableIndex < 0) return + val inductionVariable = header.statements[inductionVariableIndex] as IrVariable + + val innerLoop = findInnerDoWhileLoop(irBlock.statements[1]) ?: return + if (innerLoop.origin != context.doWhileCounterLoopOrigin) return + val loopVariableContainerAndIndex = findLoopVariable(innerLoop) ?: return + val (loopVariableContainer, loopVariableIndex) = loopVariableContainerAndIndex + val loopVariable = loopVariableContainer.statements[loopVariableIndex] as IrVariable + + val inductionVariableType = inductionVariable.type + val loopVariableType = loopVariable.type + if (loopVariableType.isNullable()) return + if (loopVariableType.classifierOrNull != inductionVariableType.classifierOrNull) return + + val newLoopVariable = IrVariableImpl( + loopVariable.startOffset, loopVariable.endOffset, loopVariable.origin, + IrVariableSymbolImpl(), + loopVariable.name, loopVariableType, + isVar = true, // NB original loop variable is 'val' + isConst = false, isLateinit = false + ) + newLoopVariable.initializer = inductionVariable.initializer + + header.statements[inductionVariableIndex] = newLoopVariable + loopVariableContainer.statements.removeAt(loopVariableIndex) + + val remapper = object : AbstractVariableRemapper() { + override fun remapVariable(value: IrValueDeclaration): IrValueDeclaration? = + if (value == inductionVariable || value == loopVariable) newLoopVariable else null + } + irBlock.statements[1].transformChildren(remapper, null) + } + + private fun findInnerDoWhileLoop(statement: IrStatement): IrDoWhileLoop? { + if (statement is IrDoWhileLoop) { + return statement + } + if (statement is IrWhen) { + val branch0Result = statement.branches[0].result + if (branch0Result is IrDoWhileLoop) + return branch0Result + } + return null + } + + private fun findLoopVariable(doWhileLoop: IrDoWhileLoop): Pair? { + val loopBody = doWhileLoop.body as? IrContainerExpression ?: return null + for ((index, statement) in loopBody.statements.withIndex()) { + if (statement.isLoopVariable()) + return Pair(loopBody, index) + else if (statement is IrContainerExpression && statement.origin == IrStatementOrigin.FOR_LOOP_NEXT) { + val loopVarIndex = statement.statements.indexOfFirst { it.isLoopVariable() } + if (loopVarIndex < 0) return null + return Pair(statement, loopVarIndex) + } + } + return null + } + + private fun IrStatement.isLoopVariable() = + this is IrVariable && origin == IrDeclarationOrigin.FOR_LOOP_VARIABLE + /** * Lowers the "header" statement that stores the iterator into the loop variable * (e.g., `val it = someIterable.iterator()`) and gather information for building the for-loop @@ -204,9 +306,8 @@ private class RangeLoopTransformer( private fun lowerWhileLoop(loop: IrWhileLoop, loopHeader: ForLoopHeader): LoopReplacement? { val loopBodyStatements = (loop.body as? IrContainerExpression)?.statements ?: return null - val (mainLoopVariable, mainLoopVariableIndex, loopVariableComponents, loopVariableComponentIndices) = gatherLoopVariableInfo( - loopBodyStatements - ) + val (mainLoopVariable, mainLoopVariableIndex, loopVariableComponents, loopVariableComponentIndices) = + gatherLoopVariableInfo(loopBodyStatements) if (loopHeader.consumesLoopVariableComponents && mainLoopVariable.origin != IrDeclarationOrigin.IR_TEMPORARY_VARIABLE) { // We determine if there is a destructuring declaration by checking if the main loop variable is temporary. diff --git a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt index d44537477c1..fae8f109851 100644 --- a/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt +++ b/compiler/ir/backend.common/src/org/jetbrains/kotlin/backend/common/lower/loops/HeaderProcessor.kt @@ -44,6 +44,10 @@ interface ForLoopHeader { */ val consumesLoopVariableComponents: Boolean + /** `true` if it's possible to use loop variable as induction variable in this kind of loop */ + val canReuseLoopVariableAsInductionVariable: Boolean + get() = false + /** Statements used to initialize an iteration of the loop (e.g., assign loop variable). */ fun initializeIteration( loopVariable: IrVariable?, @@ -56,6 +60,13 @@ interface ForLoopHeader { fun buildLoop(builder: DeclarationIrBuilder, oldLoop: IrLoop, newBody: IrExpression?): LoopReplacement } +internal const val inductionVariableName = "inductionVariable" + +internal fun IrStatement.isInductionVariable(context: CommonBackendContext) = + this is IrVariable && + origin == context.inductionVariableOrigin && + name.asString() == inductionVariableName + abstract class NumericForLoopHeader( val headerInfo: T, builder: DeclarationIrBuilder, @@ -64,6 +75,8 @@ abstract class NumericForLoopHeader( override val consumesLoopVariableComponents = false + override val canReuseLoopVariableAsInductionVariable get() = true + val inductionVariable: IrVariable protected val stepVariable: IrVariable? @@ -92,8 +105,9 @@ abstract class NumericForLoopHeader( inductionVariable = scope.createTmpVariable( headerInfo.first.asElementType(), - nameHint = "inductionVariable", + nameHint = inductionVariableName, isMutable = true, + origin = this@NumericForLoopHeader.context.inductionVariableOrigin, irType = elementClass.defaultType ) @@ -317,7 +331,11 @@ class ProgressionLoopHeader( // // Loop body // } while (loopVar != last) // } - val newLoop = IrDoWhileLoopImpl(oldLoop.startOffset, oldLoop.endOffset, oldLoop.type, oldLoop.origin).apply { + val newLoopOrigin = if (preferJavaLikeCounterLoop) + this@ProgressionLoopHeader.context.doWhileCounterLoopOrigin + else + oldLoop.origin + val newLoop = IrDoWhileLoopImpl(oldLoop.startOffset, oldLoop.endOffset, oldLoop.type, newLoopOrigin).apply { val loopVariableExpression = irGet(loopVariable!!).let { headerInfo.progressionType.run { if (this is UnsignedProgressionType) { @@ -331,6 +349,10 @@ class ProgressionLoopHeader( body = newBody } + if (preferJavaLikeCounterLoop) { + moveInductionVariableUpdateToLoopCondition(newLoop) + } + val loopCondition = buildLoopCondition(this@with) LoopReplacement(newLoop, irIfThen(loopCondition, newLoop)) } else if (preferJavaLikeCounterLoop && !headerInfo.isLastInclusive) { @@ -338,25 +360,17 @@ class ProgressionLoopHeader( // (`for (int i = first; i < lastExclusive; ++i) { ... }`). // Otherwise loop-related optimizations will not kick in, resulting in significant performance degradation. // - // If possible, use a do-while loop: + // Use a do-while loop: // do { // if ( !( inductionVariable < last ) ) break // val loopVariable = inductionVariable // // } while ( { inductionVariable += step; true } ) // This loop form is equivalent to the Java counter loop shown above. - // - // Otherwise, use a simple while loop: - // while (inductionVar < last) { - // val loopVar = inductionVar - // inductionVar += step - // // Loop body - // } val newLoopCondition = buildLoopCondition(this@with) buildJavaLikeDoWhileCounterLoop(oldLoop, newLoopCondition, newBody) - ?: buildJavaLikeWhileCounterLoop(oldLoop, newLoopCondition, newBody) } else { // Use an if-guarded do-while loop (note the difference in loop condition): // @@ -383,11 +397,52 @@ class ProgressionLoopHeader( it.name == OperatorNameConventions.NOT } ?: error("No '${OperatorNameConventions.NOT}' in ${context.irBuiltIns.booleanClass.owner.render()}") + private fun moveInductionVariableUpdateToLoopCondition(doWhileLoop: IrDoWhileLoop) { + // On JVM, it's important that induction variable update happens in the end of the loop + // (otherwise HotSpot will not treat it as a counter loop). + // Moving induction variable update to loop condition (instead of just placing it in the end of loop body) + // also allows reusing loop variable as induction variable later. + // + // Transform a loop in the form: + // do { + // { } + // + // } while () + // to + // do { + // { } + // + // } while ( { if (!) break; ; true } ) + val doWhileBody = doWhileLoop.body as? IrContainerExpression ?: return + if (doWhileBody.origin != IrStatementOrigin.FOR_LOOP_INNER_WHILE) return + val doWhileLoopNext = doWhileBody.statements[0] as? IrContainerExpression ?: return + if (doWhileLoopNext.origin != IrStatementOrigin.FOR_LOOP_NEXT) return + + val updateInductionVarIndex = doWhileLoopNext.statements + .indexOfFirst { it is IrSetValue && it.symbol.owner.isInductionVariable(context) } + if (updateInductionVarIndex < 0) return + val updateInductionVar = doWhileLoopNext.statements[updateInductionVarIndex] + doWhileLoopNext.statements.removeAt(updateInductionVarIndex) + + val loopCondition = doWhileLoop.condition + val loopConditionStartOffset = loopCondition.startOffset + val loopConditionEndOffset = loopCondition.endOffset + doWhileLoop.condition = IrCompositeImpl( + loopConditionStartOffset, loopConditionEndOffset, loopCondition.type, + origin = null, + statements = listOf( + createNegatedConditionCheck(doWhileLoop.condition, doWhileLoop), + updateInductionVar, + IrConstImpl.boolean(loopConditionStartOffset, loopConditionEndOffset, context.irBuiltIns.booleanType, true) + ) + ) + } + private fun buildJavaLikeDoWhileCounterLoop( oldLoop: IrLoop, newLoopCondition: IrExpression, newBody: IrExpression? - ): LoopReplacement? { + ): LoopReplacement { // Transform loop: // while () { // { @@ -402,31 +457,19 @@ class ProgressionLoopHeader( // val forLoopVariable = inductionVariable // // } while ( { inductionVariable += step; true } ) - val bodyBlock = newBody as? IrContainerExpression ?: return null - val forLoopNextBlock = bodyBlock.statements[0] as? IrContainerExpression ?: return null - if (forLoopNextBlock.origin != IrStatementOrigin.FOR_LOOP_NEXT) return null - val loopStep = forLoopNextBlock.statements.last() as? IrSetValue ?: return null + val bodyBlock = newBody as? IrContainerExpression + ?: throw AssertionError("newBody: ${newBody?.dump()}") + val forLoopNextBlock = bodyBlock.statements[0] as? IrContainerExpression + ?: throw AssertionError("bodyBlock[0]: ${bodyBlock.statements[0].dump()}") + if (forLoopNextBlock.origin != IrStatementOrigin.FOR_LOOP_NEXT) + throw AssertionError("FOR_LOOP_NEXT expected: ${forLoopNextBlock.dump()}") + val loopStep = forLoopNextBlock.statements.last() as? IrSetValue + ?: throw AssertionError("forLoopNextBlock.last: ${forLoopNextBlock.statements.last().dump()}") - val doWhileLoop = IrDoWhileLoopImpl(oldLoop.startOffset, oldLoop.endOffset, oldLoop.type, oldLoop.origin) + val doWhileLoop = IrDoWhileLoopImpl(oldLoop.startOffset, oldLoop.endOffset, oldLoop.type, context.doWhileCounterLoopOrigin) doWhileLoop.label = oldLoop.label - val conditionStartOffset = newLoopCondition.startOffset - val conditionEndOffset = newLoopCondition.endOffset - val negatedCondition = - IrCallImpl.fromSymbolOwner(conditionStartOffset, conditionEndOffset, booleanNot.symbol).apply { - dispatchReceiver = newLoopCondition - } - - val negatedConditionCheck = - IrWhenImpl( - conditionStartOffset, conditionEndOffset, context.irBuiltIns.unitType, null, - listOf( - IrBranchImpl( - negatedCondition, - IrBreakImpl(conditionStartOffset, conditionEndOffset, context.irBuiltIns.nothingType, doWhileLoop) - ) - ) - ) + val negatedConditionCheck = createNegatedConditionCheck(newLoopCondition, doWhileLoop) bodyBlock.statements[0] = negatedConditionCheck val loopVarAssignments = @@ -455,23 +498,25 @@ class ProgressionLoopHeader( return LoopReplacement(doWhileLoop, doWhileLoop) } - private fun buildJavaLikeWhileCounterLoop( - oldLoop: IrLoop, - newLoopCondition: IrExpression, - newBody: IrExpression? - ): LoopReplacement { - // while (inductionVar < last) { - // val loopVar = inductionVar - // inductionVar += step - // // Loop body - // } - val newLoop = IrWhileLoopImpl(oldLoop.startOffset, oldLoop.endOffset, oldLoop.type, oldLoop.origin).apply { - label = oldLoop.label - condition = newLoopCondition - body = newBody - } - return LoopReplacement(newLoop, newLoop) + private fun createNegatedConditionCheck(newLoopCondition: IrExpression, doWhileLoop: IrDoWhileLoop): IrWhenImpl { + val conditionStartOffset = newLoopCondition.startOffset + val conditionEndOffset = newLoopCondition.endOffset + val negatedCondition = + IrCallImpl.fromSymbolOwner(conditionStartOffset, conditionEndOffset, booleanNot.symbol).apply { + dispatchReceiver = newLoopCondition + } + + return IrWhenImpl( + conditionStartOffset, conditionEndOffset, context.irBuiltIns.unitType, null, + listOf( + IrBranchImpl( + negatedCondition, + IrBreakImpl(conditionStartOffset, conditionEndOffset, context.irBuiltIns.nothingType, doWhileLoop) + ) + ) + ) } + } private class InitializerCallReplacer(val replacementCall: IrCall) : IrElementTransformerVoid() { diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt index 92036164571..1a577acacf1 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/JvmBackendContext.kt @@ -30,6 +30,7 @@ import org.jetbrains.kotlin.ir.declarations.* import org.jetbrains.kotlin.ir.declarations.impl.IrFactoryImpl import org.jetbrains.kotlin.ir.expressions.IrExpression import org.jetbrains.kotlin.ir.expressions.IrFunctionReference +import org.jetbrains.kotlin.ir.expressions.IrStatementOrigin import org.jetbrains.kotlin.ir.symbols.* import org.jetbrains.kotlin.ir.types.IrType import org.jetbrains.kotlin.ir.types.IrTypeSystemContext @@ -217,6 +218,12 @@ class JvmBackendContext( override val preferJavaLikeCounterLoop: Boolean get() = true + override val reuseLoopVariableAsInductionVariable: Boolean + get() = true + + override val doWhileCounterLoopOrigin: IrStatementOrigin + get() = JvmLoweredStatementOrigin.DO_WHILE_COUNTER_LOOP + inner class JvmIr( irModuleFragment: IrModuleFragment, symbolTable: SymbolTable diff --git a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/StatementOrigins.kt b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/StatementOrigins.kt index 1bc14a1b40f..b9701a9d8c8 100644 --- a/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/StatementOrigins.kt +++ b/compiler/ir/backend.jvm/src/org/jetbrains/kotlin/backend/jvm/StatementOrigins.kt @@ -9,4 +9,5 @@ import org.jetbrains.kotlin.ir.expressions.IrStatementOriginImpl interface JvmLoweredStatementOrigin { object DEFAULT_STUB_CALL_TO_IMPLEMENTATION : IrStatementOriginImpl("DEFAULT_STUB_CALL_TO_IMPLEMENTATION") + object DO_WHILE_COUNTER_LOOP: IrStatementOriginImpl("DO_WHILE_COUNTER_LOOP") } diff --git a/compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt b/compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt index 3c473c13fe2..2d3776d58f9 100644 --- a/compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt +++ b/compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt @@ -1,5 +1,4 @@ // IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM_IR // TARGET_BACKEND: JVM // WITH_RUNTIME // WITH_COROUTINES diff --git a/compiler/testData/codegen/box/coroutines/debug/debuggerMetadata_ir.kt b/compiler/testData/codegen/box/coroutines/debug/debuggerMetadata_ir.kt deleted file mode 100644 index 5be19b5a276..00000000000 --- a/compiler/testData/codegen/box/coroutines/debug/debuggerMetadata_ir.kt +++ /dev/null @@ -1,113 +0,0 @@ -// IGNORE_BACKEND_FIR: JVM_IR -// IGNORE_BACKEND: JVM -// TARGET_BACKEND: JVM -// WITH_RUNTIME -// WITH_COROUTINES - -@file:Suppress("INVISIBLE_REFERENCE", "INVISIBLE_MEMBER", "CANNOT_OVERRIDE_INVISIBLE_MEMBER") - -import helpers.* -import kotlin.coroutines.* -import kotlin.coroutines.intrinsics.* -import kotlin.coroutines.jvm.internal.* - -suspend fun getSpilledToVariable() = suspendCoroutineUninterceptedOrReturn> { - (it as BaseContinuationImpl).getSpilledVariableFieldMapping() -} - -fun Array.toMap(): Map { - val res = hashMapOf() - for (i in 0..(size - 1) step 2) { - res[get(i)] = get(i + 1) - } - return res -} - -var continuation: Continuation? = null - -suspend fun suspendHere() = suspendCoroutineUninterceptedOrReturn { - continuation = it - COROUTINE_SUSPENDED -} - -suspend fun dummy() {} - -suspend fun named(): String { - dummy() - val s1 = "" - val s2 = "" - val s3 = "" - val s4 = "" - val s5 = "" - val s6 = "" - val s7 = "" - val s8 = "" - val s9 = "" - val map = getSpilledToVariable().toMap() - println(s1 + s2 + s3 + s4 + s5 + s6 + s7 + s8 + s9) - return map["L$0"] + map["L$1"] + map["L$2"] + map["L$3"] + map["L$4"] + map["L$5"] + map["L$6"] + map["L$7"] + map["L$8"] -} - -suspend fun suspended() { - dummy() - val ss = "" - suspendHere() - println(ss) -} - -suspend fun multipleLocalsInOneSlot() { - for (first in 0 until 1) { - suspendHere() - println(first) - } - for (second in 0 until 1) { - suspendHere() - println(second) - } -} - -fun builder(c: suspend () -> Unit) { - c.startCoroutine(EmptyContinuation) -} - -fun box(): String { - var res: String = "" - builder { - res = named() - } - if (res != "s1s2s3s4s5s6s7s8s9") { - return "" + res - } - builder { - dummy() - val a = "" - res = getSpilledToVariable().toMap()["L$0"] ?: "lambda fail" - println(a) - } - if (res != "a") { - return "" + res - } - - builder { - suspended() - } - res = (continuation!! as BaseContinuationImpl).getSpilledVariableFieldMapping()!!.toMap()["L$0"] ?: "suspended fail" - if (res != "ss") { - return "" + res - } - - builder { - multipleLocalsInOneSlot() - } - res = (continuation!! as BaseContinuationImpl).getSpilledVariableFieldMapping()!!.toMap()["I$1"] ?: "multipleLocalsInOneSlot fail 1" - if (res != "first") { - return "" + res - } - continuation!!.resumeWith(Result.success(Unit)) - res = (continuation!! as BaseContinuationImpl).getSpilledVariableFieldMapping()!!.toMap()["I$1"] ?: "multipleLocalsInOneSlot fail 2" - if (res != "second") { - return "" + res - } - - return "OK" -} \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrayWithIndexNoElementVar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrayWithIndexNoElementVar.kt index b3c58f0171a..6915d62941d 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrayWithIndexNoElementVar.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrayWithIndexNoElementVar.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val arr = arrayOf("a", "b", "c", "d") fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrayWithIndexNoIndexVar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrayWithIndexNoIndexVar.kt index ba943b2a4c6..ba8b3301f30 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrayWithIndexNoIndexVar.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInArrayWithIndexNoIndexVar.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val arr = arrayOf("a", "b", "c", "d") fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInEmptyArrayWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInEmptyArrayWithIndex.kt index e48e94248b3..b48eb1195c6 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInEmptyArrayWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInEmptyArrayWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val arr = intArrayOf() fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInIntArrayWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInIntArrayWithIndex.kt index dfded9a2882..db34cd1e8db 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInIntArrayWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInIntArrayWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val arr = intArrayOf(10, 20, 30, 40) fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInObjectArrayWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInObjectArrayWithIndex.kt index 3d6edb26cee..9b9e6881d94 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInObjectArrayWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInArrayWithIndex/forInObjectArrayWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val arr = arrayOf("a", "b", "c", "d") fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequence.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequence.kt index 75de096871b..bf9e9aaa749 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequence.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequence.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun test() { var s = "" for (c in "testString") { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceTypeParameter.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceTypeParameter.kt index 861ba9e185d..151d23cbcd4 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceTypeParameter.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceTypeParameter.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun test(sequence: T) { var s = "" for (c in sequence) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt index a26bed1e833..2cd523c7e6b 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInCharSequenceWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val cs: CharSequence = "abcd" fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt index e530e73dee1..557eab3e205 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInEmptyStringWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for ((index, x) in "".withIndex()) { return "Loop over empty String should not be executed" diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndex.kt index 68d3d6b21d3..f8e5621b2b0 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { val s = StringBuilder() diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt index fdaabd22322..16514945753 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoElementVar.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xs = "abcd" fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt index 294b590bf09..65543114bc3 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexNoIndexVar.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xs = "abcd" fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt index a0ca4050be1..4638e67914f 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInCharSequenceWithIndex/forInStringWithIndexWithExplicitlyTypedIndexVariable.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xs = "abcd" fun useAny(x: Any) {} diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInDownToCharMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInDownToCharMinValue.kt index 39f778edae0..2f95dabe369 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInDownToCharMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInDownToCharMinValue.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = Char.MIN_VALUE fun f(a: Char): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInDownToIntMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInDownToIntMinValue.kt index 6b13bb6895d..f549d731ed4 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInDownToIntMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInDownToIntMinValue.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = Int.MIN_VALUE fun f(a: Int): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInDownToLongMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInDownToLongMinValue.kt index 9ae281a3d6d..b04e9ac4c88 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInDownToLongMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInDownToLongMinValue.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = Long.MIN_VALUE fun f(a: Long): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInArrayListIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInArrayListIndices.kt index 36b0c576857..6d6b64f2e71 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInArrayListIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInArrayListIndices.kt @@ -1,5 +1,14 @@ // WITH_RUNTIME +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { val a = ArrayList() a.add("OK") diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCharSequenceIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCharSequenceIndices.kt index 264ac79e0e4..2274a5ed8c6 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCharSequenceIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCharSequenceIndices.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun test(s: CharSequence): Int { var result = 0 for (i in s.indices) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCharSequenceTypeParameterIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCharSequenceTypeParameterIndices.kt index 21ee58e2a4c..b9d1a176241 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCharSequenceTypeParameterIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCharSequenceTypeParameterIndices.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun test(s: T): Int { var result = 0 for (i in s.indices) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCollectionImplicitReceiverIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCollectionImplicitReceiverIndices.kt index 6392e9c0fcb..bddfdc09067 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCollectionImplicitReceiverIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCollectionImplicitReceiverIndices.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun Collection.sumIndices(): Int { var sum = 0 for (i in indices) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCollectionIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCollectionIndices.kt index 1fb322be881..ab06d2ffd19 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCollectionIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCollectionIndices.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun test() { var sum = 0 for (i in listOf(0, 0, 0, 0).indices) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCollectionTypeParameterIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCollectionTypeParameterIndices.kt index 4dff26c0560..66ffeac241b 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCollectionTypeParameterIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInCollectionTypeParameterIndices.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun > test(c: T) { var sum = 0 for (i in c.indices) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInNonOptimizedIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInNonOptimizedIndices.kt index 94b39a240c4..41b0f16cd41 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInNonOptimizedIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInNonOptimizedIndices.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + import kotlin.test.assertEquals fun test(coll: Collection<*>?): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndices.kt index 12c30077122..26d71855207 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInObjectArrayIndices.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun test() { var sum = 0 for (i in arrayOf("", "", "", "").indices) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndices.kt index d8bbd3900c0..0e18ea8dcea 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIndices/forInPrimitiveArrayIndices.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun test() { var sum = 0 for (i in intArrayOf(0, 0, 0, 0).indices) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInEmptyListWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInEmptyListWithIndex.kt index 6bc751a35df..cae16a1dc14 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInEmptyListWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInEmptyListWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xs = listOf() fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInIterableTypeParameterWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInIterableTypeParameterWithIndex.kt index af7cb1e1615..e92ec007a0d 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInIterableTypeParameterWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInIterableTypeParameterWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun > test(iterable: T): String { val s = StringBuilder() diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndex.kt index 328f0ea8239..b098bf6aa42 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xs = listOf("a", "b", "c", "d") fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndexNoElementVar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndexNoElementVar.kt index a88a377cc3f..63cc5f31492 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndexNoElementVar.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndexNoElementVar.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xs = listOf("a", "b", "c", "d") fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndexNoIndexVar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndexNoIndexVar.kt index 4567a36a553..3dbed3ecf4a 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndexNoIndexVar.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndexNoIndexVar.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xs = listOf("a", "b", "c", "d") fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndexWithExplicitlyTypedIndexVariable.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndexWithExplicitlyTypedIndexVariable.kt index 0b48a4b7f81..398cc02bf82 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndexWithExplicitlyTypedIndexVariable.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInIterableWithIndex/forInListWithIndexWithExplicitlyTypedIndexVariable.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xs = listOf("a", "b", "c", "d") fun useAny(x: Any) {} diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInObjectArray.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInObjectArray.kt index c282b88f7bd..2cddbdd7328 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInObjectArray.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInObjectArray.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun array() = arrayOfNulls(4) fun f(): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInPrimitiveArray.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInPrimitiveArray.kt index e9377f5d052..3e759dab3de 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInPrimitiveArray.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInPrimitiveArray.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun intArray() = intArrayOf(0, 0, 0, 0) fun longArray() = longArrayOf(0, 0, 0, 0) diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInDownToWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInDownToWithIndex.kt index 7597514554f..d3362e0cf17 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInDownToWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInDownToWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for ((i, v) in (7 downTo 4).withIndex()) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInIndicesWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInIndicesWithIndex.kt index 756f08d8274..784610c55ba 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInIndicesWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInIndicesWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for ((i, v) in listOf(4, 5, 6, 7).indices.withIndex()) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInRangeToWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInRangeToWithIndex.kt index f1b1c7ab7a7..084c5c21b88 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInRangeToWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInRangeToWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for ((i, v) in (4..7).withIndex()) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInReversedStepWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInReversedStepWithIndex.kt index 1171484e609..ae85d27c110 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInReversedStepWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInReversedStepWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for ((i, v) in ((4..11).reversed() step 2).withIndex()) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInReversedWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInReversedWithIndex.kt index 8320282ea5f..79f63663e2f 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInReversedWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInReversedWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for ((i, v) in (4..7).reversed().withIndex()) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInStepReversedWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInStepReversedWithIndex.kt index 775fc4c5c44..e7e9f33f866 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInStepReversedWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInStepReversedWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for ((i, v) in (4..11 step 2).reversed().withIndex()) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInStepWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInStepWithIndex.kt index 35de3c85581..c2e421998f4 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInStepWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInStepWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for ((i, v) in (4..11 step 2).withIndex()) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInUntilWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInUntilWithIndex.kt index 0ad4307772c..db11336839a 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInUntilWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInUntilWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for ((i, v) in (4 until 8).withIndex()) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexNoIndexOrElementVar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexNoIndexOrElementVar.kt index 7df9fe839d5..327a27bbbbb 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexNoIndexOrElementVar.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexNoIndexOrElementVar.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for ((_, _) in (4..7).withIndex()) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexNotDestructured.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexNotDestructured.kt index 155aa7c1c76..545400b6fde 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexNotDestructured.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexNotDestructured.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (iv in (4..7).withIndex()) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexReversed.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexReversed.kt index 745022b3872..1fe083d3d22 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexReversed.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexReversed.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for ((i, v) in (4..7).withIndex().reversed()) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexWithIndex.kt index 46023a2b34a..4ef721301b8 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInProgressionWithIndex/forInWithIndexWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for ((outer, iv) in (4..7).withIndex().withIndex()) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeSpecializedToUntil.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeSpecializedToUntil.kt index f6873b98fc3..d53813ffa00 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeSpecializedToUntil.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeSpecializedToUntil.kt @@ -23,5 +23,10 @@ fun test(): Int { // JVM_IR_TEMPLATES // 1 IF_ICMPGT -// 1 IF_ICMPNE +// 1 IF_ICMPEQ // 2 IF +// 7 ILOAD +// 4 ISTORE +// 1 IINC +// 1 IADD +// 1 ISUB diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConst.kt index afcc0512fcf..8854d8b7f01 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharConst.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val N = 'Z' fun test(): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharMaxValue.kt index e061937e0e6..243dbf90e77 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToCharMaxValue.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = Char.MAX_VALUE fun f(a: Char): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConst.kt index 68e9b7e8e3c..0e3fb0a2977 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToConst.kt @@ -18,7 +18,13 @@ fun test(): Int { // JVM_TEMPLATES // 1 IF_ICMPGT // 1 IF +// 5 ILOAD +// 4 ISTORE +// 1 IINC // JVM_IR_TEMPLATES // 1 IF_ICMPGE -// 1 IF \ No newline at end of file +// 1 IF +// 4 ILOAD +// 3 ISTORE +// 1 IINC \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToIntMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToIntMaxValue.kt index b8fc928ed6d..e74ea96da14 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToIntMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToIntMaxValue.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = Int.MAX_VALUE fun f(a: Int): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt index 8af84c78865..3c594de8274 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongConst.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val N = 42L fun test(): Long { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongMaxValue.kt index 24e1601fb51..886fc86c5e1 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToLongMaxValue.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = Long.MAX_VALUE fun f(a: Long): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConst.kt index 3c74ad7fc7e..cb9c0b81903 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeToQualifiedConst.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + object Host { const val M = 1 const val N = 4 diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithImplicitReceiver.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithImplicitReceiver.kt index bf4425bb49f..cbd8d3f6801 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithImplicitReceiver.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInRangeWithImplicitReceiver.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun Int.digitsUpto(end: Int): Int { var sum = 0 for (i in rangeTo(end)) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/ForInReversedReversedRange.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/ForInReversedReversedRange.kt index f9d548e31ef..494304afbfb 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/ForInReversedReversedRange.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/ForInReversedReversedRange.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + import kotlin.test.* fun intRange() = 1 .. 4 diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndices.kt index f9c80bf8a83..080a8e7bc03 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedArrayIndices.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + import kotlin.test.* fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedCharSequenceIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedCharSequenceIndices.kt index 8d621117a5a..830098e512d 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedCharSequenceIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedCharSequenceIndices.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + import kotlin.test.* fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedCollectionIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedCollectionIndices.kt index 000ec3c97df..5a4e53a74c3 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedCollectionIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedCollectionIndices.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + import kotlin.test.* fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownTo.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownTo.kt index 3fecfcb40e0..34f72e6ef2e 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownTo.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedDownTo.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + import kotlin.test.* fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedEmptyRangeLiteral.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedEmptyRangeLiteral.kt index 6067efd7841..dcf79ec981f 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedEmptyRangeLiteral.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedEmptyRangeLiteral.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (i in (4 .. 1).reversed()) { throw AssertionError("Loop should not be executed") diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRange.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRange.kt index da203dbaaba..1baf3ee07c5 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRange.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRange.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + import kotlin.test.* fun intRange() = 1 .. 4 diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteral.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteral.kt index 701a6a520c2..b684b60295a 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteral.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedRangeLiteral.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + import kotlin.test.* fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedArrayIndices.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedArrayIndices.kt index 4fc487e27d1..b3f65f5e0c9 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedArrayIndices.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedArrayIndices.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + import kotlin.test.* fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownTo.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownTo.kt index f157d325b33..5b75846317d 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownTo.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedDownTo.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + import kotlin.test.* fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedReversedRange.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedReversedRange.kt index 0225f709aee..dd520bd1752 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedReversedRange.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedReversedRange.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + import kotlin.test.* fun intRange() = 1 .. 4 diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntil.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntil.kt index 56c670e9302..250c982c418 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntil.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedReversedUntil.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + import kotlin.test.* fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntil.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntil.kt index 0ed66000e78..259ff412dea 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntil.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInReversed/forInReversedUntil.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + import kotlin.test.* fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInEmptySequenceWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInEmptySequenceWithIndex.kt index 8e33d90a42c..3c3b027a558 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInEmptySequenceWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInEmptySequenceWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xs = listOf().asSequence() fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceTypeParameterWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceTypeParameterWithIndex.kt index bdf37408f68..5fe54f65a8a 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceTypeParameterWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceTypeParameterWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun > test(sequence: T): String { val s = StringBuilder() diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndex.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndex.kt index 0b46e2e2398..60421e655c5 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndex.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndex.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xs = listOf("a", "b", "c", "d").asSequence() fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexNoElementVar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexNoElementVar.kt index 27ce8e49cd1..c884418cd4d 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexNoElementVar.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexNoElementVar.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xs = listOf("a", "b", "c", "d").asSequence() fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexNoIndexVar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexNoIndexVar.kt index 21dd1d9d7bc..86ba7f25b0f 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexNoIndexVar.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexNoIndexVar.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xs = listOf("a", "b", "c", "d").asSequence() fun box(): String { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexThrowsCME.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexThrowsCME.kt index c398a6ddb3e..5347ddcfce0 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexThrowsCME.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexThrowsCME.kt @@ -1,6 +1,15 @@ // IGNORE_BACKEND_FIR: JVM_IR // FULL_JDK +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xsl = arrayListOf("a", "b", "c", "d") val xs = xsl.asSequence() diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexWithExplicitlyTypedIndexVariable.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexWithExplicitlyTypedIndexVariable.kt index 82f6f5eaf16..389e89fd4de 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexWithExplicitlyTypedIndexVariable.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInSequenceWithIndex/forInSequenceWithIndexWithExplicitlyTypedIndexVariable.kt @@ -1,4 +1,14 @@ // IGNORE_BACKEND_FIR: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + val xs = listOf("a", "b", "c", "d").asSequence() fun useAny(x: Any) {} diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInStringSpecialized.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInStringSpecialized.kt index d3eb41c5ee5..488e3d59356 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInStringSpecialized.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInStringSpecialized.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun test() { var s = "" for (c in "testString") { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilChar.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilChar.kt index 2732ea00cdd..b36d158f526 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilChar.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilChar.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun test(a: Char, b: Char): String { var s = "" for (i in a until b) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValue.kt index 9d390ce5456..ea803f6b522 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMaxValue.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = Char.MAX_VALUE fun f(a: Char): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMinValue.kt index 9a6cb0d349f..dc0d268c53f 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilCharMinValue.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = Char.MIN_VALUE fun f(a: Char): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilInt.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilInt.kt index 8200ae4370a..28c0a8a8c53 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilInt.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilInt.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun test(a: Int, b: Int): Int { var sum = 0 for (i in a until b) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValue.kt index 35f7ce14c48..1ec658f8381 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMaxValue.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = Int.MAX_VALUE fun f(a: Int): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMinValue.kt index 3aa1c31f878..ed369f80ae7 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilIntMinValue.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = Int.MIN_VALUE fun f(a: Int): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLong.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLong.kt index 4ae4e21711f..1b6265e7193 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLong.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLong.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun test(a: Long, b: Long): Long { var sum = 0L for (i in a until b) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValue.kt index 22b7cdeb29b..e2d012a73b7 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMaxValue.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = Long.MAX_VALUE fun f(a: Long): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMinValue.kt index aa7c2b18258..9f4a80964ff 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forInUntil/forInUntilLongMinValue.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = Long.MIN_VALUE fun f(a: Long): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/forIntInDownTo.kt b/compiler/testData/codegen/bytecodeText/forLoop/forIntInDownTo.kt index 3c12c664cf4..f348020210b 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/forIntInDownTo.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/forIntInDownTo.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun test(): Int { var sum = 0 for (i in 4 downTo 1) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/iincGeneration.kt b/compiler/testData/codegen/bytecodeText/forLoop/iincGeneration.kt index 4a6c0e74ded..bb704b078d5 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/iincGeneration.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/iincGeneration.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + // WITH_RUNTIME fun intRangeTo(a: Int, b: Int) { for (i in a .. b) {} } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/intrinsicArrayConstructorsUseCounterLoop.kt b/compiler/testData/codegen/bytecodeText/forLoop/intrinsicArrayConstructorsUseCounterLoop.kt index 6d456264668..8d25daf6edf 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/intrinsicArrayConstructorsUseCounterLoop.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/intrinsicArrayConstructorsUseCounterLoop.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun Int.toTrue() = true fun testBooleanArray(n: Int) = diff --git a/compiler/testData/codegen/bytecodeText/forLoop/loopVarInterval.kt b/compiler/testData/codegen/bytecodeText/forLoop/loopVarInterval.kt index eef5cc4de93..971070a51cb 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/loopVarInterval.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/loopVarInterval.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun f() { for (c in "123") { print(c) diff --git a/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt b/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt index 93fa091f308..d24916cc6d5 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange1.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun f() { for (i in 1..2) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange2.kt b/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange2.kt index b00ccd0835b..084fedc7e3e 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange2.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/primitiveLiteralRange2.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun f(a: Int, b: Int) { for (i in a..b) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/primitiveProgression.kt b/compiler/testData/codegen/bytecodeText/forLoop/primitiveProgression.kt index 7dc3a511038..c8fd6edacb3 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/primitiveProgression.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/primitiveProgression.kt @@ -1,3 +1,12 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun f() { for (i in 0..5 step 2) { } @@ -11,36 +20,6 @@ fun f() { // JVM non-IR does NOT specifically handle "step" progressions. The stepped progressions in the above code are constructed and their // first/last/step properties are retrieved. // JVM IR has an optimized handler for "step" progressions and elides the construction of the stepped progressions. -// -// Expected lowered form of `for (i in 0..5 step 2)`: -// -// // Standard form of loop over progression -// var inductionVar = 0 -// val last = getProgressionLastElement(0, 5, 2) -// val step = 2 -// if (inductionVar <= last) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += step -// // Loop body -// } while (i != last) -// } -// -// Expected lowered form of `for (i in 5 downTo 1 step 1)`: -// -// // Standard form of loop over progression -// var inductionVar = 5 -// val last = 1 -// val step = -1 -// if (last <= inductionVar) { // Optimized out in bytecode -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += step -// // Loop body -// } while (last <= inductionVar) -// } // 0 iterator @@ -56,7 +35,12 @@ fun f() { // 0 getLast // 0 getStep // 1 IF_ICMPGT -// 1 IF_ICMPNE +// 1 IF_ICMPEQ // 1 IF_ICMPLE // 3 IF -// 1 INVOKESTATIC kotlin/internal/ProgressionUtilKt.getProgressionLastElement \(III\)I \ No newline at end of file +// 1 INVOKESTATIC kotlin/internal/ProgressionUtilKt.getProgressionLastElement \(III\)I +// 6 ILOAD +// 4 ISTORE +// 2 IINC +// 0 IADD +// 0 ISUB \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/primitiveRange.kt b/compiler/testData/codegen/bytecodeText/forLoop/primitiveRange.kt index 25a678239cc..0af84698502 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/primitiveRange.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/primitiveRange.kt @@ -1,5 +1,17 @@ +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + +fun consume(i: Int) {} + fun f(r: IntRange) { for (i in r) { + consume(i) } } @@ -8,4 +20,11 @@ fun f(r: IntRange) { // 0 getEnd // 1 getFirst // 1 getLast -// 0 getStep \ No newline at end of file +// 0 getStep + +// 2 ISTORE +// 5 ILOAD +// 1 IINC +// 1 IF_ICMPGT +// 1 IF_ICMPEQ +// 2 IF \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/illegalStepConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/illegalStepConst.kt index 196e206947e..8297e69152f 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/illegalStepConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/illegalStepConst.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (i in 1..6 step 0) { } @@ -8,23 +18,6 @@ fun box(): String { // For "step" progressions in JVM IR, if the step is constant and <= 0, the expression for step is replaced with an // IllegalArgumentException. The backend can then eliminate the entire loop and the rest of the function as dead code. -// -// Expected lowered form of loop (before bytecode optimization): -// -// // Additional statements: -// throw IllegalArgumentException("Step must be positive, was: 0.") -// -// // Standard form of loop over progression -// var inductionVar = 1 -// val last = getProgressionLastElement(1, 6, 0) -// if (inductionVar <= last) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += 0 -// // Loop body -// } while (i != last) -// } // 0 iterator // 0 getStart diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/reversedThenStep.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/reversedThenStep.kt index 1c723bcc8ea..cfd3145070c 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/reversedThenStep.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/reversedThenStep.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (i in (1..8).reversed() step 2) { } @@ -9,22 +19,6 @@ fun box(): String { // For "step" progressions in JVM IR, a call to getProgressionLastElement() is made to compute the "last" value. // If the step is non-constant, there is a check that it is > 0, and if not, an IllegalArgumentException is thrown. However, when the // step is constant and > 0, this check does not need to be added. -// -// Expected lowered form of loop: -// -// // Standard form of loop over progression -// val last = getProgressionLastElement(8, 1, -2) -// var inductionVar = 8 -// if (last <= inductionVar) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += -2 -// // Loop body -// } while (i != last) -// } -// -// We can't use "0 reversed" in the regex below because "reversed" is in the test filename. // 0 INVOKE.*reversed // 0 iterator @@ -37,5 +31,11 @@ fun box(): String { // 0 NEW java/lang/IllegalArgumentException // 0 ATHROW // 1 IF_ICMPGT -// 1 IF_ICMPNE -// 2 IF \ No newline at end of file +// 1 IF_ICMPEQ +// 2 IF +// 4 ILOAD +// 2 ISTORE +// 0 IADD +// 0 ISUB +// 1 IINC +// 1 IINC \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepConst.kt index 2a20594985c..dd098b72cf0 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepConst.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (i in 1..7 step 2) { } @@ -9,20 +19,6 @@ fun box(): String { // For "step" progressions in JVM IR, a call to getProgressionLastElement() is made to compute the "last" value. // If the step is non-constant, there is a check that it is > 0, and if not, an IllegalArgumentException is thrown. However, when the // step is constant and > 0, this check does not need to be added. -// -// Expected lowered form of loop: -// -// // Standard form of loop over progression -// var inductionVar = 1 -// val last = getProgressionLastElement(1, 7, 2) -// if (inductionVar <= last) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += 2 -// // Loop body -// } while (i != last) -// } // 0 iterator // 0 getStart @@ -34,5 +30,10 @@ fun box(): String { // 0 NEW java/lang/IllegalArgumentException // 0 ATHROW // 1 IF_ICMPGT -// 1 IF_ICMPNE -// 2 IF \ No newline at end of file +// 1 IF_ICMPEQ +// 2 IF +// 4 ILOAD +// 2 ISTORE +// 0 IADD +// 0 ISUB +// 1 IINC \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepConstOnNonLiteralProgression.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepConstOnNonLiteralProgression.kt index 3f4e61ef32c..e148bb272f5 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepConstOnNonLiteralProgression.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepConstOnNonLiteralProgression.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { val intProgression = 1..7 step 3 // `step` ensures type is IntProgression, NOT IntRange for (i in intProgression step 2) { @@ -12,25 +22,7 @@ fun box(): String { // If the step is non-constant, there is a check that it is > 0, and if not, an IllegalArgumentException is thrown. However, when the // step is constant and > 0, this check does not need to be added. // -// Expected lowered form of loop: -// -// // Additional statements: -// val nestedFirst = intProgression.first -// val nestedLast = intProgression.last -// val nestedStep = intProgression.step -// val maybeNegatedStep = if (nestedStep <= 0) -2 else 2 -// -// // Standard form of loop over progression -// var inductionVar = nestedFirst -// val last = getProgressionLastElement(nestedFirst, nestedLast, maybeNegatedStep) -// if ((maybeNegatedStep > 0 && inductionVar <= last) || (maybeNegatedStep < 0 && last <= inductionVar)) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += maybeNegatedStep -// // Loop body -// } while (i != last) -// } + // 0 iterator // 0 getStart @@ -43,9 +35,14 @@ fun box(): String { // 0 ATHROW // 1 IF_ICMPGT // 1 IF_ICMPLE -// 1 IF_ICMPNE +// 1 IF_ICMPEQ // 1 IFLE // 1 IFGT // 1 IFGE // 6 IF -// 0 INEG \ No newline at end of file +// 0 INEG +// 14 ILOAD +// 6 ISTORE +// 1 IADD +// 0 ISUB +// 0 IINC \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepNonConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepNonConst.kt index f51481ef067..f6476ca0510 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepNonConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepNonConst.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun one() = 1 fun box(): String { @@ -11,23 +21,6 @@ fun box(): String { // For "step" progressions in JVM IR, a call to getProgressionLastElement() is made to compute the "last" value. // If the step is non-constant, there is a check that it is > 0, and if not, an IllegalArgumentException is thrown. // -// Expected lowered form of loop: -// -// // Additional statements: -// var stepArg = one() -// if (stepArg <= 0) throw IllegalArgumentException("Step must be positive, was: $stepArg.") -// -// // Standard form of loop over progression -// var inductionVar = 1 -// val last = getProgressionLastElement(1, 7, stepArg) -// if (inductionVar <= last) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += stepArg -// // Loop body -// } while (i != last) -// } // 0 iterator // 0 getStart @@ -39,6 +32,11 @@ fun box(): String { // 1 NEW java/lang/IllegalArgumentException // 1 ATHROW // 1 IF_ICMPGT -// 1 IF_ICMPNE +// 1 IF_ICMPEQ // 1 IFGT -// 3 IF \ No newline at end of file +// 3 IF +// 9 ILOAD +// 4 ISTORE +// 1 IADD +// 0 ISUB +// 0 IINC \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepNonConstOnNonLiteralProgression.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepNonConstOnNonLiteralProgression.kt index c83f788eb42..a06da1137e6 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepNonConstOnNonLiteralProgression.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepNonConstOnNonLiteralProgression.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun one() = 1 fun box(): String { @@ -13,27 +23,7 @@ fun box(): String { // If "step" is called on a non-literal progression, there is a check to see if that progression's step value is < 0. // If the step is non-constant, there is a check that it is > 0, and if not, an IllegalArgumentException is thrown. // -// Expected lowered form of loop: -// -// // Additional statements: -// val nestedFirst = intProgression.first -// val nestedLast = intProgression.last -// val nestedStep = intProgression.step -// var stepArg = one() -// if (stepArg <= 0) throw IllegalArgumentException("Step must be positive, was: $stepArg.") -// if (nestedStep <= 0) stepArg = -stepArg -// -// // Standard form of loop over progression -// var inductionVar = nestedFirst -// val last = getProgressionLastElement(nestedFirst, nestedLast, stepArg) -// if ((stepArg > 0 && inductionVar <= last) || (stepArg < 0 && last <= inductionVar)) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += stepArg -// // Loop body -// } while (i != last) -// } + // 0 iterator // 0 getStart @@ -46,9 +36,14 @@ fun box(): String { // 1 ATHROW // 1 IF_ICMPGT // 1 IF_ICMPLE -// 1 IF_ICMPNE +// 1 IF_ICMPEQ // 1 IFLE // 2 IFGT // 1 IFGE // 7 IF -// 1 INEG \ No newline at end of file +// 1 INEG +// 18 ILOAD +// 8 ISTORE +// 1 IADD +// 0 ISUB +// 0 IINC \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepOnNonLiteralRange.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepOnNonLiteralRange.kt index 675a441ca5f..c1a54054739 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepOnNonLiteralRange.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepOnNonLiteralRange.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { val intRange = 1..7 for (i in intRange step 2) { @@ -12,23 +22,6 @@ fun box(): String { // However, if the progression is of type *Range (e.g., IntRange) instead of *Progression (e.g., IntProgression), this // check is not needed since *Range always has step == 1. // -// Expected lowered form of loop: -// -// // Additional statements: -// val nestedFirst = intRange.first -// val nestedLast = intRange.last -// -// // Standard form of loop over progression -// var inductionVar = nestedFirst -// val last = getProgressionLastElement(nestedFirst, nestedLast, 2) -// if (inductionVar <= last) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += 2 -// // Loop body -// } while (i != last) -// } // 0 iterator // 0 getStart @@ -40,6 +33,11 @@ fun box(): String { // 0 NEW java/lang/IllegalArgumentException // 0 ATHROW // 1 IF_ICMPGT -// 1 IF_ICMPNE +// 1 IF_ICMPEQ // 2 IF -// 0 INEG \ No newline at end of file +// 0 INEG +// 7 ILOAD +// 4 ISTORE +// 0 IADD +// 0 ISUB +// 1 IINC \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepOne.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepOne.kt index 7851e4878e9..e468f03715b 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepOne.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepOne.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (i in 1..4 step 1) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepOneThenStepOne.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepOneThenStepOne.kt index 5d29051ecf6..03f7ee8aa95 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepOneThenStepOne.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepOneThenStepOne.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (i in 1..4 step 1 step 1) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenDifferentStep.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenDifferentStep.kt index 20cd8c37512..7b9687c7ea0 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenDifferentStep.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenDifferentStep.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (i in 1..7 step 3 step 2) { } @@ -11,22 +21,6 @@ fun box(): String { // If the step is non-constant, there is a check that it is > 0, and if not, an IllegalArgumentException is thrown. However, when the // step is constant and > 0, this check does not need to be added. // -// Expected lowered form of loop: -// -// // Additional variables: -// val outerNestedLast = getProgressionLastElement(1, 7, 3) -// -// // Standard form of loop over progression -// var inductionVar = 1 -// val last = getProgressionLastElement(1, outerNestedLast, 2) -// if (inductionVar <= last) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += 2 -// // Loop body -// } while (i != last) -// } // 0 iterator // 0 getStart @@ -38,5 +32,10 @@ fun box(): String { // 0 NEW java/lang/IllegalArgumentException // 0 ATHROW // 1 IF_ICMPGT -// 1 IF_ICMPNE -// 2 IF \ No newline at end of file +// 1 IF_ICMPEQ +// 2 IF +// 5 ILOAD +// 3 ISTORE +// 0 IADD +// 0 ISUB +// 1 IINC \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenReversed.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenReversed.kt index 8f8eccd84fe..a45cd974a17 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenReversed.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenReversed.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (i in (1..8 step 2).reversed()) { } diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenSameStep.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenSameStep.kt index 699aa7362ef..055cff2a50f 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenSameStep.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenSameStep.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (i in 1..8 step 2 step 2) { } @@ -11,19 +21,6 @@ fun box(): String { // If the step is non-constant, there is a check that it is > 0, and if not, an IllegalArgumentException is thrown. However, when the // step is constant and > 0, this check does not need to be added. // -// Expected lowered form of loop: -// -// // Standard form of loop over progression -// var inductionVar = 1 -// val last = getProgressionLastElement(1, 8, 2) -// if (inductionVar <= last) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += 2 -// // Loop body -// } while (i != last) -// } // 0 iterator // 0 getStart @@ -35,5 +32,10 @@ fun box(): String { // 0 NEW java/lang/IllegalArgumentException // 0 ATHROW // 1 IF_ICMPGT -// 1 IF_ICMPNE -// 2 IF \ No newline at end of file +// 1 IF_ICMPEQ +// 2 IF +// 4 ILOAD +// 2 ISTORE +// 0 IADD +// 0 ISUB +// 1 IINC \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenStepNonConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenStepNonConst.kt index 320e2963414..dbf6a0a8dd8 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenStepNonConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenStepNonConst.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun one() = 1 fun box(): String { @@ -11,26 +21,6 @@ fun box(): String { // For "step" progressions in JVM IR, if the step is non-constant, there is a check that it is > 0, and if not, an IllegalArgumentException // is thrown. // -// Expected lowered form of loop: -// -// // Additional statments: -// var innerStepArg = one() -// if (innerStepArg <= 0) throw IllegalArgumentException("Step must be positive, was: $innerStepArg.") -// val outerNestedLast = getProgressionLastElement(1, 6, innerStepArg) -// var outerStepArg = one() -// if (outerStepArg <= 0) throw IllegalArgumentException("Step must be positive, was: $outerStepArg.") -// -// // Standard form of loop over progression -// var inductionVar = 1 -// val last = getProgressionLastElement(1, outerNestedLast, outerStepArg) -// if (inductionVar <= last) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += outerStepArg -// // Loop body -// } while (i != last) -// } // 0 iterator // 0 getStart @@ -42,6 +32,11 @@ fun box(): String { // 2 NEW java/lang/IllegalArgumentException // 2 ATHROW // 1 IF_ICMPGT -// 1 IF_ICMPNE +// 1 IF_ICMPEQ // 2 IFGT -// 4 IF \ No newline at end of file +// 4 IF +// 13 ILOAD +// 6 ISTORE +// 1 IADD +// 0 ISUB +// 0 IINC diff --git a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenStepOne.kt b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenStepOne.kt index b8eb8bf3352..32e0c6c7901 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenStepOne.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/stepped/stepThenStepOne.kt @@ -1,4 +1,14 @@ // TARGET_BACKEND: JVM_IR + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (i in 1..5 step 2 step 1) { } @@ -11,22 +21,6 @@ fun box(): String { // If the step is non-constant, there is a check that it is > 0, and if not, an IllegalArgumentException is thrown. However, when the // step is constant and > 0, this check does not need to be added. // -// Expected lowered form of loop: -// -// // Additional variables: -// val innerNestedLast = getProgressionLastElement(1, 5, 2) -// -// // Standard form of loop over progression -// var inductionVar = 1 -// val last = innerNestedLast -// if (inductionVar <= last) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += 1 -// // Loop body -// } while (i != last) -// } // 0 iterator // 0 getStart @@ -38,5 +32,10 @@ fun box(): String { // 0 NEW java/lang/IllegalArgumentException // 0 ATHROW // 1 IF_ICMPGT -// 1 IF_ICMPNE -// 2 IF \ No newline at end of file +// 1 IF_ICMPEQ +// 2 IF +// 4 ILOAD +// 2 ISTORE +// 0 IADD +// 0 ISUB +// 1 IINC diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToUIntMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToUIntMinValue.kt index d1b585d22b2..01ab7c32414 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToUIntMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToUIntMinValue.kt @@ -1,4 +1,14 @@ // WITH_RUNTIME + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = UInt.MIN_VALUE fun f(a: UInt): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToULongMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToULongMinValue.kt index 1e43d708dd9..3682f7b80c5 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToULongMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInDownToULongMinValue.kt @@ -1,4 +1,14 @@ // WITH_RUNTIME + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = ULong.MIN_VALUE fun f(a: ULong): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInOptimizableUnsignedRange.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInOptimizableUnsignedRange.kt index d9443ec785b..d45d23280af 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInOptimizableUnsignedRange.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInOptimizableUnsignedRange.kt @@ -1,5 +1,14 @@ // WITH_RUNTIME +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun testUIntRangeLiteral(a: UInt, b: UInt): Int { var s = 0 for (x in a .. b) { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToUIntMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToUIntMaxValue.kt index 69843ba0f7f..32d19b7f367 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToUIntMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToUIntMaxValue.kt @@ -1,4 +1,14 @@ // WITH_RUNTIME + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = UInt.MAX_VALUE fun f(a: UInt): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToULongMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToULongMaxValue.kt index 3c82e5295a6..eb984c85fa1 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToULongMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInRangeToULongMaxValue.kt @@ -1,4 +1,14 @@ // WITH_RUNTIME + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = ULong.MAX_VALUE fun f(a: ULong): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMaxValue.kt index 4458f4d04a9..68214dfd782 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMaxValue.kt @@ -1,4 +1,14 @@ // WITH_RUNTIME + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = UInt.MAX_VALUE fun f(a: UInt): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMinValue.kt index 24798f9ffad..77808f3d312 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilUIntMinValue.kt @@ -1,4 +1,14 @@ // WITH_RUNTIME + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = UInt.MIN_VALUE fun f(a: UInt): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMaxValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMaxValue.kt index f18bb198ef0..a33f293b145 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMaxValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMaxValue.kt @@ -1,4 +1,14 @@ // WITH_RUNTIME + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = ULong.MAX_VALUE fun f(a: ULong): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMinValue.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMinValue.kt index fda559fa914..82e8312ce28 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMinValue.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/forInUntilULongMinValue.kt @@ -1,4 +1,14 @@ // WITH_RUNTIME + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + const val M = ULong.MIN_VALUE fun f(a: ULong): Int { diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/illegalStepConst.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/illegalStepConst.kt index 781e8977aa5..366c5cab316 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/illegalStepConst.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/illegalStepConst.kt @@ -1,5 +1,15 @@ // TARGET_BACKEND: JVM_IR // WITH_RUNTIME + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (i in 1u..6u step 0) { } @@ -9,23 +19,6 @@ fun box(): String { // For "step" progressions in JVM IR, if the step is constant and <= 0, the expression for step is replaced with an // IllegalArgumentException. The backend can then eliminate the entire loop and the rest of the function as dead code. -// -// Expected lowered form of loop (before bytecode optimization): -// -// // Additional statements: -// throw IllegalArgumentException("Step must be positive, was: 0.") -// -// // Standard form of loop over progression -// var inductionVar = 1u -// val last = getProgressionLastElement(1u, 6u, 0) -// if (inductionVar <= last) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += 0 -// // Loop body -// } while (i != last) -// } // 0 iterator // 0 getStart diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/reversedThenStep.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/reversedThenStep.kt index be11ac3899c..796ab6bf0d0 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/reversedThenStep.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/reversedThenStep.kt @@ -1,5 +1,15 @@ // TARGET_BACKEND: JVM_IR // WITH_RUNTIME + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (i in (1u..8u).reversed() step 2) { } @@ -10,22 +20,6 @@ fun box(): String { // For "step" progressions in JVM IR, a call to getProgressionLastElement() is made to compute the "last" value. // If the step is non-constant, there is a check that it is > 0, and if not, an IllegalArgumentException is thrown. However, when the // step is constant and > 0, this check does not need to be added. -// -// Expected lowered form of loop: -// -// // Standard form of loop over progression -// val last = getProgressionLastElement(8u, 1u, -2) -// var inductionVar = 8u -// if (last <= inductionVar) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += -2 -// // Loop body -// } while (i != last) -// } -// -// We can't use "0 reversed" in the regex below because "reversed" is in the test filename. // 0 INVOKE.*reversed // 0 iterator @@ -38,7 +32,12 @@ fun box(): String { // 0 NEW java/lang/IllegalArgumentException // 0 ATHROW // 1 IFGT -// 1 IF_ICMPNE +// 1 IF_ICMPEQ // 2 IF // 0 INVOKESTATIC kotlin/UInt.constructor-impl // 0 INVOKE\w+ kotlin/UInt.(un)?box-impl +// 5 ILOAD +// 3 ISTORE +// 0 IADD +// 0 ISUB +// 1 IINC diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepConstOnNonLiteralProgression.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepConstOnNonLiteralProgression.kt index 48c316d7d23..ae877a7b5b9 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepConstOnNonLiteralProgression.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepConstOnNonLiteralProgression.kt @@ -13,25 +13,6 @@ fun box(): String { // If the step is non-constant, there is a check that it is > 0, and if not, an IllegalArgumentException is thrown. However, when the // step is constant and > 0, this check does not need to be added. // -// Expected lowered form of loop: -// -// // Additional statements: -// val nestedFirst = uintProgression.first -// val nestedLast = uintProgression.last -// val nestedStep = uintProgression.step -// val maybeNegatedStep = if (nestedStep <= 0) -2 else 2 -// -// // Standard form of loop over progression -// var inductionVar = nestedFirst -// val last = getProgressionLastElement(nestedFirst, nestedLast, maybeNegatedStep) -// if ((maybeNegatedStep > 0 && inductionVar <= last) || (maybeNegatedStep < 0 && last <= inductionVar)) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += maybeNegatedStep -// // Loop body -// } while (i != last) -// } // 0 iterator // 0 getStart @@ -44,10 +25,15 @@ fun box(): String { // 0 ATHROW // 2 INVOKESTATIC kotlin/UnsignedKt.uintCompare // 2 IFGT -// 1 IF_ICMPNE +// 1 IF_ICMPEQ // 2 IFLE // 1 IFGE // 6 IF // 0 INEG // 0 INVOKESTATIC kotlin/UInt.constructor-impl // 0 INVOKE\w+ kotlin/UInt.(un)?box-impl +// 21 ILOAD +// 13 ISTORE +// 1 IADD +// 0 ISUB +// 0 IINC diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepNonConstOnNonLiteralProgression.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepNonConstOnNonLiteralProgression.kt index f7e9a93ad0f..9d15f53cffc 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepNonConstOnNonLiteralProgression.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepNonConstOnNonLiteralProgression.kt @@ -1,5 +1,15 @@ // TARGET_BACKEND: JVM_IR // WITH_RUNTIME + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun one() = 1 fun box(): String { @@ -13,28 +23,6 @@ fun box(): String { // For "step" progressions in JVM IR, a call to getProgressionLastElement() is made to compute the "last" value. // If "step" is called on a non-literal progression, there is a check to see if that progression's step value is < 0. // If the step is non-constant, there is a check that it is > 0, and if not, an IllegalArgumentException is thrown. -// -// Expected lowered form of loop: -// -// // Additional statements: -// val nestedFirst = uintProgression.first -// val nestedLast = uintProgression.last -// val nestedStep = uintProgression.step -// var stepArg = one() -// if (stepArg <= 0) throw IllegalArgumentException("Step must be positive, was: $stepArg.") -// if (nestedStep <= 0) stepArg = -stepArg -// -// // Standard form of loop over progression -// var inductionVar = nestedFirst -// val last = getProgressionLastElement(nestedFirst, nestedLast, stepArg) -// if ((stepArg > 0 && inductionVar <= last) || (stepArg < 0 && last <= inductionVar)) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += stepArg -// // Loop body -// } while (i != last) -// } // 0 iterator // 0 getStart @@ -47,10 +35,15 @@ fun box(): String { // 1 ATHROW // 2 INVOKESTATIC kotlin/UnsignedKt.uintCompare // 3 IFGT -// 1 IF_ICMPNE +// 1 IF_ICMPEQ // 2 IFLE // 1 IFGE // 7 IF // 1 INEG // 0 INVOKESTATIC kotlin/UInt.constructor-impl // 0 INVOKE\w+ kotlin/UInt.(un)?box-impl +// 25 ILOAD +// 15 ISTORE +// 1 IADD +// 0 ISUB +// 0 IINC \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepOnNonLiteralRange.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepOnNonLiteralRange.kt index 4da2218b0d7..b17e587dd76 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepOnNonLiteralRange.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepOnNonLiteralRange.kt @@ -1,5 +1,15 @@ // TARGET_BACKEND: JVM_IR // WITH_RUNTIME + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { val uintRange = 1u..7u for (i in uintRange step 2) { @@ -13,23 +23,6 @@ fun box(): String { // However, if the progression is of type *Range (e.g., IntRange) instead of *Progression (e.g., IntProgression), this // check is not needed since *Range always has step == 1. // -// Expected lowered form of loop: -// -// // Additional statements: -// val nestedFirst = uintRange.first -// val nestedLast = uintRange.last -// -// // Standard form of loop over progression -// var inductionVar = nestedFirst -// val last = getProgressionLastElement(nestedFirst, nestedLast, 2) -// if (inductionVar <= last) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += 2 -// // Loop body -// } while (i != last) -// } // 0 iterator // 0 getStart @@ -42,8 +35,13 @@ fun box(): String { // 0 ATHROW // 1 INVOKESTATIC kotlin/UnsignedKt.uintCompare // 1 IFGT -// 1 IF_ICMPNE +// 1 IF_ICMPEQ // 2 IF // 0 INEG // 0 INVOKESTATIC kotlin/UInt.constructor-impl // 0 INVOKE\w+ kotlin/UInt.(un)?box-impl +// 12 ILOAD +// 9 ISTORE +// 0 IADD +// 0 ISUB +// 1 IINC \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepThenDifferentStep.kt b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepThenDifferentStep.kt index 7b6d60153e2..4a72d821308 100644 --- a/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepThenDifferentStep.kt +++ b/compiler/testData/codegen/bytecodeText/forLoop/unsigned/stepThenDifferentStep.kt @@ -1,5 +1,15 @@ // TARGET_BACKEND: JVM_IR // WITH_RUNTIME + +// IMPORTANT! +// Please, when your changes cause failures in bytecodeText tests for 'for' loops, +// examine the resulting bytecode shape carefully. +// Range and progression-based loops generated with Kotlin compiler should be +// as close as possible to Java counter loops ('for (int i = a; i < b; ++i) { ... }'). +// Otherwise it may result in performance regression due to missing HotSpot optimizations. +// Run Kotlin compiler benchmarks (https://github.com/Kotlin/kotlin-benchmarks) +// with compiler built from your changes if you are not sure. + fun box(): String { for (i in 1u..7u step 3 step 2) { } @@ -11,23 +21,6 @@ fun box(): String { // nested call to "step". // If the step is non-constant, there is a check that it is > 0, and if not, an IllegalArgumentException is thrown. However, when the // step is constant and > 0, this check does not need to be added. -// -// Expected lowered form of loop: -// -// // Additional statements: -// val outerNestedLast = getProgressionLastElement(1u, 7u, 3) -// -// // Standard form of loop over progression -// var inductionVar = 1u -// val last = getProgressionLastElement(1u, outerNestedLast, 2) -// if (inductionVar <= last) { -// // Loop is not empty -// do { -// val i = inductionVar -// inductionVar += 2 -// // Loop body -// } while (i != last) -// } // 0 iterator // 0 getStart @@ -40,7 +33,12 @@ fun box(): String { // 0 ATHROW // 1 INVOKESTATIC kotlin/UnsignedKt.uintCompare // 1 IFGT -// 1 IF_ICMPNE +// 1 IF_ICMPEQ // 2 IF // 0 INVOKESTATIC kotlin/UInt.constructor-impl // 0 INVOKE\w+ kotlin/UInt.(un)?box-impl +// 6 ILOAD +// 4 ISTORE +// 0 IADD +// 0 ISUB +// 1 IINC diff --git a/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/differentTypes.kt b/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/differentTypes.kt index 58773c2cae0..84650a31b8e 100644 --- a/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/differentTypes.kt +++ b/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/differentTypes.kt @@ -15,7 +15,14 @@ fun foo() { // 7 ALOAD // 2 LSTORE // 3 LLOAD -// 1 MAXLOCALS = 10 // 0 InlineMarker + +// JVM_TEMPLATES +// 1 MAXLOCALS = 10 // 16 ISTORE // 11 ILOAD + +// JVM_IR_TEMPLATES +// 1 MAXLOCALS = 9 +// 13 ISTORE +// 8 ILOAD diff --git a/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/primitiveMerge.kt b/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/primitiveMerge.kt index c050e0eb37b..237b957f594 100644 --- a/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/primitiveMerge.kt +++ b/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/primitiveMerge.kt @@ -15,8 +15,16 @@ fun test() { // 2 ASTORE // 5 ALOAD +// 0 InlineMarker + +// JVM_TEMPLATES // 1 MAXLOCALS = 3 // 1 MAXLOCALS = 4 -// 0 InlineMarker // 14 ISTORE // 7 ILOAD + +// JVM_IR_TEMPLATES +// 2 MAXLOCALS = 3 +// 1 MAXLOCALS = 4 +// 11 ISTORE +// 4 ILOAD \ No newline at end of file diff --git a/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/withLambda.kt b/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/withLambda.kt index 0b3f37c4786..f50476e226e 100644 --- a/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/withLambda.kt +++ b/compiler/testData/codegen/bytecodeText/storeStackBeforeInline/withLambda.kt @@ -20,5 +20,5 @@ fun foo() : String { // JVM_IR_TEMPLATES // 4 ASTORE // 16 ALOAD -// 1 MAXLOCALS = 7 +// 1 MAXLOCALS = 6 // 0 InlineMarker diff --git a/compiler/testData/debug/localVariables/suspend/localsStateMachineTransform.kt b/compiler/testData/debug/localVariables/suspend/localsStateMachineTransform.kt index a68f0adf6a5..c29155d9f0a 100644 --- a/compiler/testData/debug/localVariables/suspend/localsStateMachineTransform.kt +++ b/compiler/testData/debug/localVariables/suspend/localsStateMachineTransform.kt @@ -31,19 +31,19 @@ suspend fun box() { // test.kt:11 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=0:int // test.kt:5 f: x:int=0:int // test.kt:11 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=0:int -// test.kt:10 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null +// test.kt:10 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=0:int // test.kt:11 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=1:int // test.kt:5 f: x:int=1:int // test.kt:11 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=1:int -// test.kt:10 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null +// test.kt:10 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=1:int // test.kt:14 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null // test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null // test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=0:int // test.kt:5 f: x:int=0:int // test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=0:int -// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null +// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=0:int // test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=1:int // test.kt:5 f: x:int=1:int // test.kt:16 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=1:int -// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null +// test.kt:15 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null, x:int=1:int // test.kt:18 box: $continuation:kotlin.coroutines.Continuation=TestKt$box$1, $result:java.lang.Object=null diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java index a8900dc3315..24d4f840d93 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/BlackBoxCodegenTestGenerated.java @@ -10021,12 +10021,6 @@ public class BlackBoxCodegenTestGenerated extends AbstractBlackBoxCodegenTest { runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt"); } - @Test - @TestMetadata("debuggerMetadata_ir.kt") - public void testDebuggerMetadata_ir() throws Exception { - runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata_ir.kt"); - } - @Test @TestMetadata("elvisLineNumber.kt") public void testElvisLineNumber() throws Exception { diff --git a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java index 7fd374d80f7..4897e92e245 100644 --- a/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java +++ b/compiler/tests-common-new/tests-gen/org/jetbrains/kotlin/test/runners/codegen/IrBlackBoxCodegenTestGenerated.java @@ -10093,12 +10093,6 @@ public class IrBlackBoxCodegenTestGenerated extends AbstractIrBlackBoxCodegenTes runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata.kt"); } - @Test - @TestMetadata("debuggerMetadata_ir.kt") - public void testDebuggerMetadata_ir() throws Exception { - runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata_ir.kt"); - } - @Test @TestMetadata("elvisLineNumber.kt") public void testElvisLineNumber() throws Exception { diff --git a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java index 389a505138c..02f0e8fee15 100644 --- a/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java +++ b/compiler/tests-gen/org/jetbrains/kotlin/codegen/LightAnalysisModeTestGenerated.java @@ -7860,11 +7860,6 @@ public class LightAnalysisModeTestGenerated extends AbstractLightAnalysisModeTes @TestDataPath("$PROJECT_ROOT") @RunWith(JUnit3RunnerWithInners.class) public static class Debug extends AbstractLightAnalysisModeTest { - @TestMetadata("debuggerMetadata_ir.kt") - public void ignoreDebuggerMetadata_ir() throws Exception { - runTest("compiler/testData/codegen/box/coroutines/debug/debuggerMetadata_ir.kt"); - } - private void runTest(String testDataFilePath) throws Exception { KotlinTestUtils.runTest(this::doTest, TargetBackend.JVM, testDataFilePath); }