diff options
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala | 18 | ||||
-rw-r--r-- | test/files/run/optimizer-array-load.check | 6 | ||||
-rw-r--r-- | test/files/run/optimizer-array-load.flags | 1 | ||||
-rw-r--r-- | test/files/run/optimizer-array-load.scala | 16 |
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 => () } + } +} |