From cb99f268072a334a5fbc47e6e872dd3365f060ed Mon Sep 17 00:00:00 2001 From: Rafael Cordones Date: Mon, 29 Oct 2012 22:06:42 +0100 Subject: [PATCH] KT-3002 optimized ==/!=0 Optimize byte-code generation for integer comparisons != and ==. Work done in Hackergarten Vienna. Co-authored-by: Kilian Matt --- .../jet/codegen/ExpressionCodegen.java | 29 +++++++++++++++++++ .../jet/codegen/ControlStructuresTest.java | 16 ++++++++++ 2 files changed, 45 insertions(+) diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 2292949c7a3..b90bf818022 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -2362,6 +2362,14 @@ public class ExpressionCodegen extends JetVisitor 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 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)); diff --git a/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java b/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java index b09cbc37acc..378ea834324 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java @@ -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");