diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java index 3ab8cc82519..44ad1093d19 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/ExpressionCodegen.java @@ -1905,8 +1905,16 @@ public class ExpressionCodegen extends JetVisitor { DeclarationDescriptor cls = op.getContainingDeclaration(); if (isNumberPrimitive(cls) && (op.getName().equals("inc") || op.getName().equals("dec"))) { receiver.put(receiver.type, v); - gen(expression.getBaseExpression(), asmType); // old value - generateIncrement(op, asmType, expression.getBaseExpression(), receiver); // increment in-place + JetExpression operand = expression.getBaseExpression(); + if (operand instanceof JetReferenceExpression) { + final int index = indexOfLocal((JetReferenceExpression) operand); + if (index >= 0 && JetTypeMapper.isIntPrimitive(asmType)) { + int increment = op.getName().equals("inc") ? 1 : -1; + return StackValue.postIncrement(index, increment); + } + } + gen(operand, asmType); // old value + generateIncrement(op, asmType, operand, receiver); // increment in-place return StackValue.onStack(asmType); // old value } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java index 189ee230b7f..c969955151f 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/StackValue.java @@ -256,6 +256,14 @@ public abstract class StackValue { return new ThisOuter(codegen, descriptor); } + public static StackValue postIncrement(int index, int increment) { + return new PostIncrement(index, increment); + } + + public static StackValue preIncrement(int index, int increment) { + return new PreIncrement(index, increment); + } + private static class None extends StackValue { public static None INSTANCE = new None(); private None() { @@ -963,4 +971,44 @@ public abstract class StackValue { codegen.generateThisOrOuter(descriptor); } } + + private static class PostIncrement extends StackValue { + private int index; + private int increment; + + public PostIncrement(int index, int increment) { + super(Type.INT_TYPE); + this.index = index; + this.increment = increment; + } + + @Override + public void put(Type type, InstructionAdapter v) { + if(!type.equals(Type.VOID_TYPE)) { + v.load(index, Type.INT_TYPE); + coerce(type, v); + } + v.iinc(index, increment); + } + } + + private static class PreIncrement extends StackValue { + private int index; + private int increment; + + public PreIncrement(int index, int increment) { + super(Type.INT_TYPE); + this.index = index; + this.increment = increment; + } + + @Override + public void put(Type type, InstructionAdapter v) { + v.iinc(index, increment); + if(!type.equals(Type.VOID_TYPE)) { + v.load(index, Type.INT_TYPE); + coerce(type, v); + } + } + } } diff --git a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java index fc1292cf899..a53c8791f80 100644 --- a/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java +++ b/compiler/backend/src/org/jetbrains/jet/codegen/intrinsics/Increment.java @@ -31,8 +31,7 @@ public class Increment implements IntrinsicMethod { if (operand instanceof JetReferenceExpression) { final int index = codegen.indexOfLocal((JetReferenceExpression) operand); if (index >= 0 && JetTypeMapper.isIntPrimitive(expectedType)) { - v.iinc(index, myDelta); - return StackValue.local(index, expectedType); + return StackValue.preIncrement(index, myDelta); } } StackValue value = codegen.genQualified(receiver, operand); diff --git a/examples/src/benchmarks/BinaryTrees.java b/examples/src/benchmarks/BinaryTrees.java new file mode 100644 index 00000000000..635ab88b8d4 --- /dev/null +++ b/examples/src/benchmarks/BinaryTrees.java @@ -0,0 +1,74 @@ +public class BinaryTrees { + + private final static int minDepth = 4; + + public static void main(String[] args){ + final long millis = System.currentTimeMillis(); + + int n = 20; + if (args.length > 0) n = Integer.parseInt(args[0]); + + int maxDepth = (minDepth + 2 > n) ? minDepth + 2 : n; + int stretchDepth = maxDepth + 1; + + int check = (TreeNode.bottomUpTree(0,stretchDepth)).itemCheck(); + System.out.println("stretch tree of depth "+stretchDepth+"\t check: " + check); + + TreeNode longLivedTree = TreeNode.bottomUpTree(0,maxDepth); + + for (int depth=minDepth; depth<=maxDepth; depth+=2){ + int iterations = 1 << (maxDepth - depth + minDepth); + check = 0; + + for (int i=1; i<=iterations; i++){ + check += (TreeNode.bottomUpTree(i,depth)).itemCheck(); + check += (TreeNode.bottomUpTree(-i,depth)).itemCheck(); + } + System.out.println((iterations*2) + "\t trees of depth " + depth + "\t check: " + check); + } + System.out.println("long lived tree of depth " + maxDepth + "\t check: "+ longLivedTree.itemCheck()); + + long total = System.currentTimeMillis() - millis; + System.out.println("[Binary Trees-" + System.getProperty("project.name")+ " Benchmark Result: " + total + "]"); + } + + + private static class TreeNode + { + private TreeNode left, right; + private int item; + + TreeNode(int item){ + this.item = item; + } + + private static TreeNode bottomUpTree(int item, int depth){ + if (depth>0){ + return new TreeNode( + bottomUpTree(2*item-1, depth-1) + , bottomUpTree(2*item, depth-1) + , item + ); + } + else { + return new TreeNode(item); + } + } + + TreeNode(TreeNode left, TreeNode right, int item){ + this.left = left; + this.right = right; + this.item = item; + } + + private int itemCheck(){ + // if necessary deallocate here + if (left==null) + return item; + else { + return item + left.itemCheck() - right.itemCheck(); + } + } + } +} + diff --git a/examples/src/benchmarks/BinaryTrees.kt b/examples/src/benchmarks/BinaryTrees.kt new file mode 100644 index 00000000000..89ab735995b --- /dev/null +++ b/examples/src/benchmarks/BinaryTrees.kt @@ -0,0 +1,52 @@ +val minDepth = 4 + +fun main(args: Array) { + val millis = System.currentTimeMillis() + + val n = if (args.size > 0) Integer.parseInt(args[0]) else 20; + + val maxDepth = if (minDepth + 2 > n) minDepth + 2 else n + val stretchDepth = maxDepth + 1 + + var check = bottomUpTree(0,stretchDepth).itemCheck() + System.out?.println("stretch tree of depth "+stretchDepth+"\t check: " + check); + + val longLivedTree = bottomUpTree(0,maxDepth); + + var depth = minDepth + while(depth<=maxDepth){ + val iterations = 1 shl (maxDepth - depth + minDepth) + check = 0 + + for (i in 1..iterations){ + check += bottomUpTree(i,depth).itemCheck() + check += bottomUpTree(-i,depth).itemCheck() + } + System.out?.println("${iterations*2}\t trees of depth $depth\t check: $check") + depth+=2 + } + System.out?.println("long lived tree of depth " + maxDepth + "\t check: "+ longLivedTree.itemCheck()); + + val total = System.currentTimeMillis() - millis + System.out?.println("[Binary Trees-" + System.getProperty("project.name") + " Benchmark Result: " + total + "]"); +} + +fun bottomUpTree(item: Int, depth: Int) : TreeNode = + if (depth>0){ + TreeNode(item, bottomUpTree(2*item-1, depth-1), bottomUpTree(2*item, depth-1)) + } + else { + TreeNode(item, null, null) + } + +class TreeNode(val item: Int, val left: TreeNode?, val right: TreeNode?) { + + fun itemCheck() : Int { + var res = item + if(left != null) + res += left.itemCheck() + if(right != null) + res -= right.itemCheck() + return res + } +} diff --git a/examples/src/benchmarks/Quicksort.java b/examples/src/benchmarks/Quicksort.java new file mode 100644 index 00000000000..32d9e9689da --- /dev/null +++ b/examples/src/benchmarks/Quicksort.java @@ -0,0 +1,48 @@ +public class Quicksort { + + public static void swap(int[] a, int i, int j) { + int temp = a[i]; + a[i] = a[j]; + a[j] = temp; + } + + public static void quicksort(int[] a, int L, int R) { + int m = a[(L + R) / 2]; + int i = L; + int j = R; + while (i <= j) { + while (a[i] < m) + i++; + while (a[j] > m) + j--; + if (i <= j) { + swap(a, i++, j--); + } + } + if (L < j) + quicksort(a, L, j); + if (R > i) + quicksort(a, i, R); + } + + public static void quicksort(int[] a) { + quicksort(a, 0, a.length - 1); + } + + public static void main(String[] args) { + // Sample data + int[] a = new int[100000000]; + for (int i = 0; i < a.length; i++) { + a[i] = i * 3 / 2 + 1; + if (i % 3 == 0) + a[i] = -a[i]; + } + + long start = System.currentTimeMillis(); + + quicksort(a); + + long total = System.currentTimeMillis() - start; + System.out.println("[Quicksort-" + System.getProperty("project.name")+ " Benchmark Result: " + total + "]"); + } +} \ No newline at end of file diff --git a/examples/src/benchmarks/Quicksort.kt b/examples/src/benchmarks/Quicksort.kt new file mode 100644 index 00000000000..31119549fa9 --- /dev/null +++ b/examples/src/benchmarks/Quicksort.kt @@ -0,0 +1,47 @@ +namespace quicksort + +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) { KT-5 + swap(i++, j--) + } + } + if (L < j) + quicksort(L, j) + if (R > i) + quicksort(i, R) +} + +fun main(array: Array) { + val a = IntArray(100000000) + var i = 0 + val len = a.size + while (i < len) { + a[i] = i * 3 / 2 + 1 + if (i % 3 == 0) + a[i] = -a[i] + i++ + } + + val start = System.currentTimeMillis() + + a.quicksort() + + val total = System.currentTimeMillis() - start + System.out?.println("[Quicksort-" + System.getProperty("project.name")+ " Benchmark Result: " + total + "]"); +}