summaryrefslogtreecommitdiff
path: root/test
diff options
context:
space:
mode:
authorJames Iry <jamesiry@gmail.com>2013-03-15 08:28:35 -0700
committerJames Iry <jamesiry@gmail.com>2013-03-15 08:28:35 -0700
commit25aabc80c9f07bc75ad5b24d48b14f0911544eca (patch)
tree732f708f4438fea75079c11bece36a38ec0198f0 /test
parent482bef8079e2a2fecc2b8f77eb7c6da648125e3c (diff)
parent3a17ff00067f8f11288b1ddc778e193bed3ea017 (diff)
downloadscala-25aabc80c9f07bc75ad5b24d48b14f0911544eca.tar.gz
scala-25aabc80c9f07bc75ad5b24d48b14f0911544eca.tar.bz2
scala-25aabc80c9f07bc75ad5b24d48b14f0911544eca.zip
Merge pull request #2214 from JamesIry/master_constant_optimization
Analyze constants to remove unnecessary branches
Diffstat (limited to 'test')
-rw-r--r--test/files/jvm/constant-optimization/Foo_1.flags1
-rw-r--r--test/files/jvm/constant-optimization/Foo_1.scala9
-rw-r--r--test/files/jvm/constant-optimization/Test.scala27
-rwxr-xr-xtest/files/neg/t6446-additional.check9
-rwxr-xr-xtest/files/neg/t6446-missing.check7
-rw-r--r--test/files/neg/t6446-show-phases.check7
-rw-r--r--test/files/run/blame_eye_triple_eee.check9
-rw-r--r--test/files/run/blame_eye_triple_eee.flags1
-rw-r--r--test/files/run/blame_eye_triple_eee.scala61
-rw-r--r--test/files/run/constant-optimization.check5
-rw-r--r--test/files/run/constant-optimization.flags1
-rw-r--r--test/files/run/constant-optimization.scala61
-rw-r--r--test/files/run/programmatic-main.check7
13 files changed, 192 insertions, 13 deletions
diff --git a/test/files/jvm/constant-optimization/Foo_1.flags b/test/files/jvm/constant-optimization/Foo_1.flags
new file mode 100644
index 0000000000..86f52af447
--- /dev/null
+++ b/test/files/jvm/constant-optimization/Foo_1.flags
@@ -0,0 +1 @@
+-Ynooptimise -Yconst-opt \ No newline at end of file
diff --git a/test/files/jvm/constant-optimization/Foo_1.scala b/test/files/jvm/constant-optimization/Foo_1.scala
new file mode 100644
index 0000000000..cb67ad4e90
--- /dev/null
+++ b/test/files/jvm/constant-optimization/Foo_1.scala
@@ -0,0 +1,9 @@
+class Foo_1 {
+ def foo() {
+ // constant optimization should eliminate all branches
+ val i = 1
+ val x = if (i != 1) null else "good"
+ val y = if (x == null) "good" else x + ""
+ println(y)
+ }
+} \ No newline at end of file
diff --git a/test/files/jvm/constant-optimization/Test.scala b/test/files/jvm/constant-optimization/Test.scala
new file mode 100644
index 0000000000..283aa6f47a
--- /dev/null
+++ b/test/files/jvm/constant-optimization/Test.scala
@@ -0,0 +1,27 @@
+
+import scala.tools.partest.BytecodeTest
+import scala.tools.asm
+import asm.tree.InsnList
+import scala.collection.JavaConverters._
+
+object Test extends BytecodeTest {
+ val comparisons = Set(asm.Opcodes.IF_ACMPEQ, asm.Opcodes.IF_ACMPNE, asm.Opcodes.IF_ICMPEQ, asm.Opcodes.IF_ICMPGE, asm.Opcodes.IF_ICMPGT, asm.Opcodes.IF_ICMPLE,
+ asm.Opcodes.IF_ICMPLT, asm.Opcodes.IF_ICMPNE, asm.Opcodes.IFEQ, asm.Opcodes.IFGE, asm.Opcodes.IFGT, asm.Opcodes.IFLE, asm.Opcodes.IFLT,
+ asm.Opcodes.IFNE, asm.Opcodes.IFNONNULL, asm.Opcodes.IFNULL)
+
+ def show: Unit = {
+ val classNode = loadClassNode("Foo_1")
+ val methodNode = getMethod(classNode, "foo")
+ // after optimization there should be no comparisons left
+ val expected = 0
+
+ val got = countComparisons(methodNode.instructions)
+ assert(got == expected, s"expected $expected but got $got comparisons")
+ }
+
+ def countComparisons(insnList: InsnList): Int = {
+ def isComparison(node: asm.tree.AbstractInsnNode): Boolean =
+ (comparisons contains node.getOpcode)
+ insnList.iterator.asScala count isComparison
+ }
+} \ No newline at end of file
diff --git a/test/files/neg/t6446-additional.check b/test/files/neg/t6446-additional.check
index 53dd383941..24201c07c2 100755
--- a/test/files/neg/t6446-additional.check
+++ b/test/files/neg/t6446-additional.check
@@ -25,7 +25,8 @@ superaccessors 6 add super accessors in traits and nested classes
inliner 23 optimization: do inlining
inlinehandlers 24 optimization: inline exception handlers
closelim 25 optimization: eliminate uncalled closures
- dce 26 optimization: eliminate dead code
- jvm 27 generate JVM bytecode
- ploogin 28 A sample phase that does so many things it's kind of hard...
- terminal 29 The last phase in the compiler chain
+ constopt 26 optimization: optimize null and other constants
+ dce 27 optimization: eliminate dead code
+ jvm 28 generate JVM bytecode
+ ploogin 29 A sample phase that does so many things it's kind of hard...
+ terminal 30 The last phase in the compiler chain
diff --git a/test/files/neg/t6446-missing.check b/test/files/neg/t6446-missing.check
index f976bf480e..6e5bdcf07c 100755
--- a/test/files/neg/t6446-missing.check
+++ b/test/files/neg/t6446-missing.check
@@ -26,6 +26,7 @@ superaccessors 6 add super accessors in traits and nested classes
inliner 23 optimization: do inlining
inlinehandlers 24 optimization: inline exception handlers
closelim 25 optimization: eliminate uncalled closures
- dce 26 optimization: eliminate dead code
- jvm 27 generate JVM bytecode
- terminal 28 The last phase in the compiler chain
+ constopt 26 optimization: optimize null and other constants
+ dce 27 optimization: eliminate dead code
+ jvm 28 generate JVM bytecode
+ terminal 29 The last phase in the compiler chain
diff --git a/test/files/neg/t6446-show-phases.check b/test/files/neg/t6446-show-phases.check
index 5bbe43990c..a1bf408506 100644
--- a/test/files/neg/t6446-show-phases.check
+++ b/test/files/neg/t6446-show-phases.check
@@ -25,6 +25,7 @@ superaccessors 6 add super accessors in traits and nested classes
inliner 23 optimization: do inlining
inlinehandlers 24 optimization: inline exception handlers
closelim 25 optimization: eliminate uncalled closures
- dce 26 optimization: eliminate dead code
- jvm 27 generate JVM bytecode
- terminal 28 The last phase in the compiler chain
+ constopt 26 optimization: optimize null and other constants
+ dce 27 optimization: eliminate dead code
+ jvm 28 generate JVM bytecode
+ terminal 29 The last phase in the compiler chain
diff --git a/test/files/run/blame_eye_triple_eee.check b/test/files/run/blame_eye_triple_eee.check
new file mode 100644
index 0000000000..5e46d91a8f
--- /dev/null
+++ b/test/files/run/blame_eye_triple_eee.check
@@ -0,0 +1,9 @@
+if (NaN == NaN) is good
+if (x == x) is good
+if (x == NaN) is good
+if (NaN != NaN) is good
+if (x != x) is good
+if (NaN != x) is good
+x matching was good
+NaN matching was good
+loop with NaN was goood
diff --git a/test/files/run/blame_eye_triple_eee.flags b/test/files/run/blame_eye_triple_eee.flags
new file mode 100644
index 0000000000..c9b68d70dc
--- /dev/null
+++ b/test/files/run/blame_eye_triple_eee.flags
@@ -0,0 +1 @@
+-optimise
diff --git a/test/files/run/blame_eye_triple_eee.scala b/test/files/run/blame_eye_triple_eee.scala
new file mode 100644
index 0000000000..1640aead40
--- /dev/null
+++ b/test/files/run/blame_eye_triple_eee.scala
@@ -0,0 +1,61 @@
+object Test extends App {
+ import Double.NaN
+
+ // NaN must not equal NaN no matter what optimizations are applied
+ // All the following will seem redundant, but to an optimizer
+ // they can appear different
+
+ val x = NaN
+
+ if (NaN == NaN)
+ println("if (NaN == NaN) is broken")
+ else
+ println("if (NaN == NaN) is good")
+
+ if (x == x)
+ println("if (x == x) is broken")
+ else
+ println("if (x == x) is good")
+
+ if (x == NaN)
+ println("if (x == NaN) is broken")
+ else
+ println("if (x == NaN) is good")
+
+ if (NaN != NaN)
+ println("if (NaN != NaN) is good")
+ else
+ println("if (NaN != NaN) broken")
+
+ if (x != x)
+ println("if (x != x) is good")
+ else
+ println("if (x != x) broken")
+
+ if (NaN != x)
+ println("if (NaN != x) is good")
+ else
+ println("if (NaN != x) is broken")
+
+ x match {
+ case 0.0d => println("x matched 0!")
+ case NaN => println("x matched NaN!")
+ case _ => println("x matching was good")
+ }
+
+ NaN match {
+ case 0.0d => println("NaN matched 0!")
+ case NaN => println("NaN matched NaN!")
+ case _ => println("NaN matching was good")
+ }
+
+ var z = 0.0d
+ var i = 0
+ while (i < 10) {
+ if (i % 2 == 0) z = NaN
+ else z = NaN
+ i += 1
+ }
+ if (z.isNaN && i == 10) println("loop with NaN was goood")
+ else println("loop with NaN was broken")
+}
diff --git a/test/files/run/constant-optimization.check b/test/files/run/constant-optimization.check
new file mode 100644
index 0000000000..957ffc5a87
--- /dev/null
+++ b/test/files/run/constant-optimization.check
@@ -0,0 +1,5 @@
+testBothReachable: good
+testOneReachable: good
+testAllReachable: good
+testOneUnreachable: good
+testDefaultUnreachable: good
diff --git a/test/files/run/constant-optimization.flags b/test/files/run/constant-optimization.flags
new file mode 100644
index 0000000000..c9b68d70dc
--- /dev/null
+++ b/test/files/run/constant-optimization.flags
@@ -0,0 +1 @@
+-optimise
diff --git a/test/files/run/constant-optimization.scala b/test/files/run/constant-optimization.scala
new file mode 100644
index 0000000000..5d13272f3b
--- /dev/null
+++ b/test/files/run/constant-optimization.scala
@@ -0,0 +1,61 @@
+object Test extends App {
+ def testBothReachable() {
+ val i = util.Random.nextInt
+ val x = if (i % 2 == 0) null else "good"
+ val y = if (x == null) "good" else x + ""
+ println(s"testBothReachable: $y")
+ }
+
+ def testOneReachable() {
+ val i = 1
+ val x = if (i != 1) null else "good"
+ val y = if (x == null) "good" else x + ""
+ println(s"testOneReachable: $y")
+ }
+
+ def testAllReachable() {
+ val i = util.Random.nextInt
+ val y = (i % 2) match {
+ case 0 => "good"
+ case 1 => "good"
+ case _ => "good"
+ }
+ println(s"testAllReachable: $y")
+ }
+
+ def testOneUnreachable() {
+ val i = util.Random.nextInt
+ val x = if (i % 2 == 0) {
+ 1
+ } else {
+ 2
+ }
+ val y = x match {
+ case 0 => "good"
+ case 1 => "good"
+ case _ => "good"
+ }
+ println(s"testOneUnreachable: $y")
+ }
+
+ def testDefaultUnreachable() {
+ val i = util.Random.nextInt
+ val x = if (i % 2 == 0) {
+ 1
+ } else {
+ 2
+ }
+ val y = x match {
+ case 1 => "good"
+ case 2 => "good"
+ case _ => "good"
+ }
+ println(s"testDefaultUnreachable: $y")
+ }
+
+ testBothReachable()
+ testOneReachable()
+ testAllReachable()
+ testOneUnreachable()
+ testDefaultUnreachable()
+}
diff --git a/test/files/run/programmatic-main.check b/test/files/run/programmatic-main.check
index d472c569d2..61b947214c 100644
--- a/test/files/run/programmatic-main.check
+++ b/test/files/run/programmatic-main.check
@@ -25,7 +25,8 @@ superaccessors 6 add super accessors in traits and nested classes
inliner 23 optimization: do inlining
inlinehandlers 24 optimization: inline exception handlers
closelim 25 optimization: eliminate uncalled closures
- dce 26 optimization: eliminate dead code
- jvm 27 generate JVM bytecode
- terminal 28 The last phase in the compiler chain
+ constopt 26 optimization: optimize null and other constants
+ dce 27 optimization: eliminate dead code
+ jvm 28 generate JVM bytecode
+ terminal 29 The last phase in the compiler chain