Generate for-in-indices as a precondition loop
Precondition loops are better optimized by HotSpot (and, quite likely, by ART). Also, we generate more compact bytecode that way. KT-17903 Generate 'for-in-indices' as a precondition loop
This commit is contained in:
+8
-11
@@ -28,21 +28,18 @@ abstract class ForInOptimizedIndicesLoopGenerator(
|
||||
codegen: ExpressionCodegen,
|
||||
forExpression: KtForExpression,
|
||||
loopRangeCall: ResolvedCall<*>
|
||||
) : AbstractForInRangeLoopGenerator(codegen, forExpression) {
|
||||
) : AbstractForInExclusiveRangeLoopGenerator(codegen, forExpression) {
|
||||
protected val receiverValue: ReceiverValue = loopRangeCall.extensionReceiver!!
|
||||
protected val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(loopRangeCall)
|
||||
|
||||
override fun storeRangeStartAndEnd() {
|
||||
loopParameter().store(StackValue.constant(0, asmElementType), codegen.v)
|
||||
override fun generateFrom(): StackValue =
|
||||
StackValue.constant(0, asmElementType)
|
||||
|
||||
val receiver = codegen.generateReceiverValue(receiverValue, false)
|
||||
val receiverType = codegen.asmType(expectedReceiverType)
|
||||
receiver.put(receiverType, codegen.v)
|
||||
getReceiverSizeAsInt()
|
||||
codegen.v.iconst(1)
|
||||
codegen.v.sub(Type.INT_TYPE)
|
||||
StackValue.local(endVar, asmElementType).store(StackValue.onStack(Type.INT_TYPE), codegen.v)
|
||||
}
|
||||
override fun generateTo(): StackValue =
|
||||
StackValue.operation(Type.INT_TYPE) { v ->
|
||||
codegen.generateReceiverValue(receiverValue, false).put(codegen.asmType(expectedReceiverType), v)
|
||||
getReceiverSizeAsInt()
|
||||
}
|
||||
|
||||
/**
|
||||
* `(receiver -> size:I)`
|
||||
|
||||
+5
-1
@@ -12,4 +12,8 @@ fun test(s: CharSequence): Int {
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getLast
|
||||
|
||||
// 0 IF_ICMPGT
|
||||
// 0 IF_ICMPEQ
|
||||
// 1 IF_ICMPGE
|
||||
+5
-1
@@ -12,4 +12,8 @@ fun Collection<Int>.sumIndices(): Int {
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getLast
|
||||
|
||||
// 0 IF_ICMPGT
|
||||
// 0 IF_ICMPEQ
|
||||
// 1 IF_ICMPGE
|
||||
+5
-1
@@ -11,4 +11,8 @@ fun test() {
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getLast
|
||||
|
||||
// 0 IF_ICMPGT
|
||||
// 0 IF_ICMPEQ
|
||||
// 1 IF_ICMPGE
|
||||
+5
-1
@@ -11,4 +11,8 @@ fun test() {
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getLast
|
||||
|
||||
// 0 IF_ICMPGT
|
||||
// 0 IF_ICMPEQ
|
||||
// 1 IF_ICMPGE
|
||||
+5
-1
@@ -11,4 +11,8 @@ fun test() {
|
||||
// 0 getStart
|
||||
// 0 getEnd
|
||||
// 0 getFirst
|
||||
// 0 getLast
|
||||
// 0 getLast
|
||||
|
||||
// 0 IF_ICMPGT
|
||||
// 0 IF_ICMPEQ
|
||||
// 1 IF_ICMPGE
|
||||
Reference in New Issue
Block a user