KT-2707 Optimize for loops for range literals
#KT-2707
This commit is contained in:
@@ -463,11 +463,8 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
assert resolvedCall != null;
|
assert resolvedCall != null;
|
||||||
|
|
||||||
CallableDescriptor rangeTo = resolvedCall.getResultingDescriptor();
|
CallableDescriptor rangeTo = resolvedCall.getResultingDescriptor();
|
||||||
if (RangeCodegenUtil.isOptimizableRangeTo(rangeTo)
|
if (RangeCodegenUtil.isOptimizableRangeTo(rangeTo)) {
|
||||||
// todo: currently, only Int ranges are supported, but all primitives must be optimized
|
generateForLoop(new ForInRangeLiteralLoopGenerator(forExpression, binaryCall, resolvedCall));
|
||||||
&& RangeCodegenUtil.isIntRange(rangeTo.getReturnType())
|
|
||||||
) {
|
|
||||||
generateForLoop(new ForInIntRangeLiteralLoopGenerator(forExpression, binaryCall, resolvedCall));
|
|
||||||
return StackValue.none();
|
return StackValue.none();
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
@@ -783,14 +780,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
private class ForInIntRangeLiteralLoopGenerator extends AbstractForLoopGenerator {
|
private class ForInRangeLiteralLoopGenerator extends AbstractForLoopGenerator {
|
||||||
private final RangeCodegenUtil.BinaryCall rangeCall;
|
private final RangeCodegenUtil.BinaryCall rangeCall;
|
||||||
private final ResolvedCall<? extends CallableDescriptor> resolvedCall;
|
private final ResolvedCall<? extends CallableDescriptor> resolvedCall;
|
||||||
private Type asmElementType;
|
private Type asmElementType;
|
||||||
private int indexVar;
|
private int indexVar;
|
||||||
private int lastVar;
|
private int lastVar;
|
||||||
|
|
||||||
private ForInIntRangeLiteralLoopGenerator(
|
private ForInRangeLiteralLoopGenerator(
|
||||||
@NotNull JetForExpression forExpression,
|
@NotNull JetForExpression forExpression,
|
||||||
@NotNull RangeCodegenUtil.BinaryCall rangeCall,
|
@NotNull RangeCodegenUtil.BinaryCall rangeCall,
|
||||||
ResolvedCall<? extends CallableDescriptor> resolvedCall
|
ResolvedCall<? extends CallableDescriptor> resolvedCall
|
||||||
@@ -819,7 +816,30 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
public void conditionAndJump(@NotNull Label loopExit) {
|
public void conditionAndJump(@NotNull Label loopExit) {
|
||||||
v.load(indexVar, asmElementType);
|
v.load(indexVar, asmElementType);
|
||||||
v.load(lastVar, asmElementType);
|
v.load(lastVar, asmElementType);
|
||||||
v.ificmpgt(loopExit);
|
|
||||||
|
int sort = asmElementType.getSort();
|
||||||
|
switch (sort) {
|
||||||
|
case Type.INT:
|
||||||
|
case Type.CHAR:
|
||||||
|
case Type.BYTE:
|
||||||
|
case Type.SHORT:
|
||||||
|
v.ificmpgt(loopExit);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Type.LONG:
|
||||||
|
v.lcmp();
|
||||||
|
v.ifgt(loopExit);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Type.FLOAT:
|
||||||
|
case Type.DOUBLE:
|
||||||
|
v.cmpg(asmElementType);
|
||||||
|
v.ifgt(loopExit);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unexpected range element type: " + asmElementType);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
@Override
|
@Override
|
||||||
@@ -831,7 +851,43 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
|||||||
|
|
||||||
@Override
|
@Override
|
||||||
public void afterBody() {
|
public void afterBody() {
|
||||||
v.iinc(indexVar, 1);
|
int sort = asmElementType.getSort();
|
||||||
|
switch (sort) {
|
||||||
|
case Type.INT:
|
||||||
|
case Type.CHAR:
|
||||||
|
case Type.BYTE:
|
||||||
|
case Type.SHORT:
|
||||||
|
v.iinc(indexVar, 1);
|
||||||
|
if (sort != Type.INT) {
|
||||||
|
v.load(indexVar, Type.INT_TYPE);
|
||||||
|
StackValue.coerce(Type.INT_TYPE, asmElementType, v);
|
||||||
|
v.store(indexVar, asmElementType);
|
||||||
|
}
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Type.LONG:
|
||||||
|
v.load(indexVar, asmElementType);
|
||||||
|
v.lconst(1);
|
||||||
|
v.add(asmElementType);
|
||||||
|
v.store(indexVar, asmElementType);
|
||||||
|
break;
|
||||||
|
|
||||||
|
case Type.FLOAT:
|
||||||
|
case Type.DOUBLE:
|
||||||
|
v.load(indexVar, asmElementType);
|
||||||
|
if (sort == Type.DOUBLE) {
|
||||||
|
v.dconst(1.0);
|
||||||
|
}
|
||||||
|
else {
|
||||||
|
v.fconst(1.0f);
|
||||||
|
}
|
||||||
|
v.add(asmElementType);
|
||||||
|
v.store(indexVar, asmElementType);
|
||||||
|
break;
|
||||||
|
|
||||||
|
default:
|
||||||
|
throw new IllegalStateException("Unexpected range element type: " + asmElementType);
|
||||||
|
}
|
||||||
super.afterBody();
|
super.afterBody();
|
||||||
}
|
}
|
||||||
|
|
||||||
|
|||||||
Reference in New Issue
Block a user