From ce1718e5182a34efadda24e37cae7e61ac1ea0b6 Mon Sep 17 00:00:00 2001 From: Alex Tkachman Date: Tue, 29 Nov 2011 11:56:30 +0200 Subject: [PATCH] better handling of empty if/else blocks --- .../jet/codegen/ExpressionCodegen.java | 57 +++++++++++++++---- .../codegen/controlStructures/quicksort.jet | 42 ++++++++++++++ .../testData/codegen/regressions/kt239.jet | 4 +- .../jet/codegen/ControlStructuresTest.java | 5 ++ .../jet/codegen/PrimitiveTypesTest.java | 2 +- examples/src/benchmarks/Quicksort.java | 4 +- examples/src/benchmarks/Quicksort.kt | 6 +- 7 files changed, 101 insertions(+), 19 deletions(-) create mode 100644 compiler/testData/codegen/controlStructures/quicksort.jet diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 44ad1093d19..9edbcab7a40 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -155,6 +155,19 @@ public class ExpressionCodegen extends JetVisitor { return genQualified(receiver, expression.getBaseExpression()); } + private static boolean isEmptyExpression(JetElement expr) { + if(expr == null) + return true; + if(expr instanceof JetBlockExpression) { + JetBlockExpression blockExpression = (JetBlockExpression) expr; + List statements = blockExpression.getStatements(); + if(statements.size() == 0 || statements.size() == 1 && isEmptyExpression(statements.get(0))) { + return true; + } + } + return false; + } + @Override public StackValue visitIfExpression(JetIfExpression expression, StackValue receiver) { Type asmType = expressionType(expression); @@ -167,27 +180,36 @@ public class ExpressionCodegen extends JetVisitor { throw new CompilationException(); } - if (thenExpression == null) { + if (isEmptyExpression(thenExpression)) { + if (isEmptyExpression(elseExpression)) { + condition.put(asmType, v); + return StackValue.onStack(asmType); + } return generateSingleBranchIf(condition, elseExpression, false); } - - if (elseExpression == null) { - return generateSingleBranchIf(condition, thenExpression, true); + else { + if (isEmptyExpression(elseExpression)) { + return generateSingleBranchIf(condition, thenExpression, true); + } } Label elseLabel = new Label(); condition.condJump(elseLabel, true, v); // == 0, i.e. false + Label end = continueLabel == null ? new Label() : continueLabel; + gen(thenExpression, asmType); - Label endLabel = new Label(); - v.goTo(endLabel); + v.goTo(end); v.mark(elseLabel); gen(elseExpression, asmType); - v.mark(endLabel); + if(end != continueLabel) + v.mark(end); + else + v.goTo(end); return StackValue.onStack(asmType); } @@ -198,16 +220,21 @@ public class ExpressionCodegen extends JetVisitor { myContinueTargets.push(condition); v.mark(condition); - Label end = new Label(); + Label end = continueLabel != null ? continueLabel : new Label(); myBreakTargets.push(end); + Label savedContinueLabel = continueLabel; + continueLabel = condition; + final StackValue conditionValue = gen(expression.getCondition()); conditionValue.condJump(end, true, v); gen(expression.getBody(), Type.VOID_TYPE); v.goTo(condition); - v.mark(end); + continueLabel = savedContinueLabel; + if(end != continueLabel) + v.mark(end); myBreakTargets.pop(); myContinueTargets.pop(); @@ -519,13 +546,14 @@ public class ExpressionCodegen extends JetVisitor { } private StackValue generateSingleBranchIf(StackValue condition, JetExpression expression, boolean inverse) { - Label endLabel = new Label(); + Label end = continueLabel != null ? continueLabel : new Label(); - condition.condJump(endLabel, inverse, v); + condition.condJump(end, inverse, v); gen(expression, Type.VOID_TYPE); - v.mark(endLabel); + if(continueLabel != end) + v.mark(end); return StackValue.none(); } @@ -655,6 +683,8 @@ public class ExpressionCodegen extends JetVisitor { return StackValue.onStack(Type.getObjectType(closure.getClassname())); } + private Label continueLabel; + private StackValue generateBlock(List statements) { Label blockStart = new Label(); v.mark(blockStart); @@ -671,9 +701,12 @@ public class ExpressionCodegen extends JetVisitor { } StackValue answer = StackValue.none(); + Label savedContinueLabel = continueLabel; + continueLabel = null; for (int i = 0, statementsSize = statements.size(); i < statementsSize; i++) { JetElement statement = statements.get(i); if (i == statements.size() - 1 /*&& statement instanceof JetExpression && !bindingContext.get(BindingContext.STATEMENT, statement)*/) { + continueLabel = savedContinueLabel; answer = gen(statement); } else { diff --git a/compiler/testData/codegen/controlStructures/quicksort.jet b/compiler/testData/codegen/controlStructures/quicksort.jet new file mode 100644 index 00000000000..96813b62c10 --- /dev/null +++ b/compiler/testData/codegen/controlStructures/quicksort.jet @@ -0,0 +1,42 @@ +fun IntArray.swap(i:Int, j:Int) { + val temp = this[i] + this[i] = this[j] + this[j] = temp +} + +fun IntArray.quicksort() = quicksort(0, size-1) + +fun IntArray.quicksort(L: Int, R:Int) { + val m = this[(L + R) / 2] + var i = L + var j = R + while (i <= j) { + while (this[i] < m) + i++ + while (this[j] > m) + j-- + if (i <= j) { + swap(i++, j--) + } + else { + } + } + if (L < j) + quicksort(L, j) + if (R > i) + quicksort(i, R) +} + +fun box() : String { + val a = IntArray(10) + for(i in 0..4) { + a[2*i] = 2*i + a[2*i+1] = -2*i-1 + } + a.quicksort() + for(i in 0..9) { + System.out?.print(a[i]) + System.out?.print(' ') + } + return "OK" +} \ No newline at end of file diff --git a/compiler/testData/codegen/regressions/kt239.jet b/compiler/testData/codegen/regressions/kt239.jet index ca9e1cc1d5e..f36b32743d8 100644 --- a/compiler/testData/codegen/regressions/kt239.jet +++ b/compiler/testData/codegen/regressions/kt239.jet @@ -1,3 +1,5 @@ -fun box(i: Int?) { +fun box() : String { + val i : Int? = 0 val j = i?.plus(3) //verify error + return "OK" } diff --git a/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java b/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java index 0c1d8f4aa41..a1bf84af9d6 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/ControlStructuresTest.java @@ -220,4 +220,9 @@ public class ControlStructuresTest extends CodegenTestCase { createEnvironmentWithFullJdk(); blackBoxFile("regressions/kt434.jet"); } + + public void testQuicksort() throws Exception { + blackBoxFile("controlStructures/quicksort.jet"); +// System.out.println(generateToText()); + } } diff --git a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java index e98e1b17a8b..d52a2e3c488 100644 --- a/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java +++ b/compiler/tests/org/jetbrains/jet/codegen/PrimitiveTypesTest.java @@ -266,7 +266,7 @@ public class PrimitiveTypesTest extends CodegenTestCase { } public void testKt239 () throws Exception { - blackBoxFile("regressions/kt242.jet"); + blackBoxFile("regressions/kt239.jet"); } public void testKt243 () throws Exception { diff --git a/examples/src/benchmarks/Quicksort.java b/examples/src/benchmarks/Quicksort.java index 32d9e9689da..20b53bec4fb 100644 --- a/examples/src/benchmarks/Quicksort.java +++ b/examples/src/benchmarks/Quicksort.java @@ -30,6 +30,8 @@ public class Quicksort { } public static void main(String[] args) { + long start = System.currentTimeMillis(); + // Sample data int[] a = new int[100000000]; for (int i = 0; i < a.length; i++) { @@ -38,8 +40,6 @@ public class Quicksort { a[i] = -a[i]; } - long start = System.currentTimeMillis(); - quicksort(a); long total = System.currentTimeMillis() - start; diff --git a/examples/src/benchmarks/Quicksort.kt b/examples/src/benchmarks/Quicksort.kt index 31119549fa9..2d98fe82335 100644 --- a/examples/src/benchmarks/Quicksort.kt +++ b/examples/src/benchmarks/Quicksort.kt @@ -17,7 +17,7 @@ fun IntArray.quicksort(L: Int, R:Int) { i++ while (this[j] > m) j-- - if (i <= j) { KT-5 + if (i <= j) { swap(i++, j--) } } @@ -28,6 +28,8 @@ fun IntArray.quicksort(L: Int, R:Int) { } fun main(array: Array) { + val start = System.currentTimeMillis() + val a = IntArray(100000000) var i = 0 val len = a.size @@ -38,8 +40,6 @@ fun main(array: Array) { i++ } - val start = System.currentTimeMillis() - a.quicksort() val total = System.currentTimeMillis() - start