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,
|
codegen: ExpressionCodegen,
|
||||||
forExpression: KtForExpression,
|
forExpression: KtForExpression,
|
||||||
loopRangeCall: ResolvedCall<*>
|
loopRangeCall: ResolvedCall<*>
|
||||||
) : AbstractForInRangeLoopGenerator(codegen, forExpression) {
|
) : AbstractForInExclusiveRangeLoopGenerator(codegen, forExpression) {
|
||||||
protected val receiverValue: ReceiverValue = loopRangeCall.extensionReceiver!!
|
protected val receiverValue: ReceiverValue = loopRangeCall.extensionReceiver!!
|
||||||
protected val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(loopRangeCall)
|
protected val expectedReceiverType: KotlinType = ExpressionCodegen.getExpectedReceiverType(loopRangeCall)
|
||||||
|
|
||||||
override fun storeRangeStartAndEnd() {
|
override fun generateFrom(): StackValue =
|
||||||
loopParameter().store(StackValue.constant(0, asmElementType), codegen.v)
|
StackValue.constant(0, asmElementType)
|
||||||
|
|
||||||
val receiver = codegen.generateReceiverValue(receiverValue, false)
|
override fun generateTo(): StackValue =
|
||||||
val receiverType = codegen.asmType(expectedReceiverType)
|
StackValue.operation(Type.INT_TYPE) { v ->
|
||||||
receiver.put(receiverType, codegen.v)
|
codegen.generateReceiverValue(receiverValue, false).put(codegen.asmType(expectedReceiverType), v)
|
||||||
getReceiverSizeAsInt()
|
getReceiverSizeAsInt()
|
||||||
codegen.v.iconst(1)
|
}
|
||||||
codegen.v.sub(Type.INT_TYPE)
|
|
||||||
StackValue.local(endVar, asmElementType).store(StackValue.onStack(Type.INT_TYPE), codegen.v)
|
|
||||||
}
|
|
||||||
|
|
||||||
/**
|
/**
|
||||||
* `(receiver -> size:I)`
|
* `(receiver -> size:I)`
|
||||||
|
|||||||
+5
-1
@@ -12,4 +12,8 @@ fun test(s: CharSequence): Int {
|
|||||||
// 0 getStart
|
// 0 getStart
|
||||||
// 0 getEnd
|
// 0 getEnd
|
||||||
// 0 getFirst
|
// 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 getStart
|
||||||
// 0 getEnd
|
// 0 getEnd
|
||||||
// 0 getFirst
|
// 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 getStart
|
||||||
// 0 getEnd
|
// 0 getEnd
|
||||||
// 0 getFirst
|
// 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 getStart
|
||||||
// 0 getEnd
|
// 0 getEnd
|
||||||
// 0 getFirst
|
// 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 getStart
|
||||||
// 0 getEnd
|
// 0 getEnd
|
||||||
// 0 getFirst
|
// 0 getFirst
|
||||||
// 0 getLast
|
// 0 getLast
|
||||||
|
|
||||||
|
// 0 IF_ICMPGT
|
||||||
|
// 0 IF_ICMPEQ
|
||||||
|
// 1 IF_ICMPGE
|
||||||
Reference in New Issue
Block a user