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:
Rafael Cordones
2012-10-29 22:06:42 +01:00
committed by Alexander Udalov
parent d28c9e0eef
commit cb99f26807
2 changed files with 45 additions and 0 deletions
@@ -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");