summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorPaul Phillips <paulp@improving.org>2011-08-21 16:05:06 +0000
committerPaul Phillips <paulp@improving.org>2011-08-21 16:05:06 +0000
commita707ec6fef216334e2cde4437664f28a3983d1eb (patch)
treef3c1522042b55386caed29f6d89c0c976f652471
parent553bea21fbe38c23060be74b5acefefe49c5abbf (diff)
downloadscala-a707ec6fef216334e2cde4437664f28a3983d1eb.tar.gz
scala-a707ec6fef216334e2cde4437664f28a3983d1eb.tar.bz2
scala-a707ec6fef216334e2cde4437664f28a3983d1eb.zip
Bug in optimizer eliminated potentially excepti...
Bug in optimizer eliminated potentially exceptional not-dead code. Streamlined isSideEffecting logic. Review by ureche.
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala18
-rw-r--r--test/files/run/optimizer-array-load.check6
-rw-r--r--test/files/run/optimizer-array-load.flags1
-rw-r--r--test/files/run/optimizer-array-load.scala16
4 files changed, 31 insertions, 10 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
index c7939e09c7..9522f4b3ea 100644
--- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
+++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala
@@ -16,6 +16,7 @@ abstract class DeadCodeElimination extends SubComponent {
import global._
import icodes._
import icodes.opcodes._
+ import definitions.RuntimePackage
val phaseName = "dce"
@@ -103,7 +104,7 @@ abstract class DeadCodeElimination extends SubComponent {
defs = defs + Pair(((bb, idx)), rd.vars)
// Console.println(i + ": " + (bb, idx) + " rd: " + rd + " and having: " + defs)
case RETURN(_) | JUMP(_) | CJUMP(_, _, _, _) | CZJUMP(_, _, _, _) | STORE_FIELD(_, _) |
- THROW(_) | STORE_ARRAY_ITEM(_) | SCOPE_ENTER(_) | SCOPE_EXIT(_) | STORE_THIS(_) |
+ THROW(_) | LOAD_ARRAY_ITEM(_) | STORE_ARRAY_ITEM(_) | SCOPE_ENTER(_) | SCOPE_EXIT(_) | STORE_THIS(_) |
LOAD_EXCEPTION(_) | SWITCH(_, _) | MONITOR_ENTER() | MONITOR_EXIT() => worklist += ((bb, idx))
case CALL_METHOD(m1, _) if isSideEffecting(m1) => worklist += ((bb, idx)); log("marking " + m1)
case CALL_METHOD(m1, SuperCall(_)) =>
@@ -268,15 +269,12 @@ abstract class DeadCodeElimination extends SubComponent {
abort("could not find init in: " + method)
}
+ private def isPure(sym: Symbol) = (
+ (sym.isGetter && sym.isFinal && !sym.isLazy)
+ || (sym.isPrimaryConstructor && (sym.enclosingPackage == RuntimePackage || inliner.isClosureClass(sym.owner)))
+ )
/** Is 'sym' a side-effecting method? TODO: proper analysis. */
- private def isSideEffecting(sym: Symbol): Boolean = {
- !((sym.isGetter && sym.isFinal && !sym.isLazy)
- || (sym.isConstructor
- && !(sym.owner == method.symbol.owner && method.symbol.isConstructor) // a call to another constructor
- && sym.owner.owner == definitions.RuntimePackage.moduleClass)
- || (sym.isConstructor && inliner.isClosureClass(sym.owner))
-/* || definitions.isBox(sym)
- || definitions.isUnbox(sym)*/)
- }
+ private def isSideEffecting(sym: Symbol) = !isPure(sym)
+
} /* DeadCode */
}
diff --git a/test/files/run/optimizer-array-load.check b/test/files/run/optimizer-array-load.check
new file mode 100644
index 0000000000..e8371f0060
--- /dev/null
+++ b/test/files/run/optimizer-array-load.check
@@ -0,0 +1,6 @@
+0
+1
+2
+3
+4
+5
diff --git a/test/files/run/optimizer-array-load.flags b/test/files/run/optimizer-array-load.flags
new file mode 100644
index 0000000000..eb4d19bcb9
--- /dev/null
+++ b/test/files/run/optimizer-array-load.flags
@@ -0,0 +1 @@
+-optimise \ No newline at end of file
diff --git a/test/files/run/optimizer-array-load.scala b/test/files/run/optimizer-array-load.scala
new file mode 100644
index 0000000000..a4d76f7385
--- /dev/null
+++ b/test/files/run/optimizer-array-load.scala
@@ -0,0 +1,16 @@
+object Test {
+ def f() = {
+ val ar = Array.ofDim[Int](5)
+ var x = 0
+
+ while (x<=5) {
+ println(x)
+ val a = ar(x)
+ x+=1
+ }
+ }
+ def main(args: Array[String]): Unit = {
+ try { f() ; assert(false, "should have thrown exception") }
+ catch { case _: ArrayIndexOutOfBoundsException => () }
+ }
+}