KT-3002 optimized ==/!=0
Optimize byte-code generation for integer comparisons != and ==. Work done in Hackergarten Vienna. Co-authored-by: Kilian Matt <kilian.matt@gmail.com>
This commit is contained in:
committed by
Alexander Udalov
parent
d28c9e0eef
commit
cb99f26807
@@ -2362,6 +2362,14 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
return genCmpWithNull(left, leftType, opToken);
|
||||
}
|
||||
|
||||
if (isIntZero(left, leftType)) {
|
||||
return genCmpWithZero(right, rightType, opToken);
|
||||
}
|
||||
|
||||
if (isIntZero(right, rightType)) {
|
||||
return genCmpWithZero(left, leftType, opToken);
|
||||
}
|
||||
|
||||
if (isPrimitive(leftType) != isPrimitive(rightType)) {
|
||||
gen(left, leftType);
|
||||
StackValue.valueOf(v, leftType);
|
||||
@@ -2384,6 +2392,27 @@ public class ExpressionCodegen extends JetVisitor<StackValue, StackValue> implem
|
||||
genEqualsForExpressionsOnStack(v, opToken, leftType, rightType, leftJetType.isNullable(), rightJetType.isNullable());
|
||||
}
|
||||
|
||||
private boolean isIntZero(JetExpression expr, Type exprType) {
|
||||
CompileTimeConstant<?> exprValue = bindingContext.get(BindingContext.COMPILE_TIME_VALUE, expr);
|
||||
return isIntPrimitive(exprType) && exprValue != null && exprValue.getValue().equals(0);
|
||||
}
|
||||
|
||||
private StackValue genCmpWithZero(JetExpression exp, Type expType, IElementType opToken) {
|
||||
v.iconst(1);
|
||||
gen(exp, expType);
|
||||
Label ok = new Label();
|
||||
if (JetTokens.EQEQ == opToken || JetTokens.EQEQEQ == opToken) {
|
||||
v.ifeq(ok);
|
||||
}
|
||||
else {
|
||||
v.ifne(ok);
|
||||
}
|
||||
v.pop();
|
||||
v.iconst(0);
|
||||
v.mark(ok);
|
||||
return StackValue.onStack(Type.BOOLEAN_TYPE);
|
||||
}
|
||||
|
||||
private StackValue genCmpWithNull(JetExpression exp, Type expType, IElementType opToken) {
|
||||
v.iconst(1);
|
||||
gen(exp, boxType(expType));
|
||||
|
||||
@@ -234,6 +234,22 @@ public class ControlStructuresTest extends CodegenTestCase {
|
||||
blackBoxFile("regressions/kt237.jet");
|
||||
}
|
||||
|
||||
public void testCompareToZero() throws Exception {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||
loadText("fun foo(a: Int, b: Int): Boolean = a == 0 && b != 0 && 0 == a && 0 != b");
|
||||
String text = generateToText();
|
||||
/*
|
||||
* Check that the we generate optimized byte-code!
|
||||
*/
|
||||
assertTrue(text.contains("IFEQ"));
|
||||
assertTrue(text.contains("IFNE"));
|
||||
assertFalse(text.contains("IF_ICMPEQ"));
|
||||
assertFalse(text.contains("IF_ICMPNE"));
|
||||
final Method main = generateFunction();
|
||||
assertEquals(true, main.invoke(null, 0, 1));
|
||||
assertEquals(false, main.invoke(null, 1, 0));
|
||||
}
|
||||
|
||||
public void testCompareToNull() throws Exception {
|
||||
createEnvironmentWithMockJdkAndIdeaAnnotations(ConfigurationKind.JDK_ONLY);
|
||||
loadText("fun foo(a: String?, b: String?): Boolean = a == null && b !== null && null == a && null !== b");
|
||||
|
||||
Reference in New Issue
Block a user