diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2007-04-19 08:34:19 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2007-04-19 08:34:19 +0000 |
commit | d934e21d461da5833d3ec0c1ea1ae1bb8ba78c6f (patch) | |
tree | e5adc5718a71d2307e3324dce077ecf0c7074901 /src | |
parent | 2ef5d4c6d81e5008fdb2ae1b4f2ecdd9d9901fd2 (diff) | |
download | scala-d934e21d461da5833d3ec0c1ea1ae1bb8ba78c6f.tar.gz scala-d934e21d461da5833d3ec0c1ea1ae1bb8ba78c6f.tar.bz2 scala-d934e21d461da5833d3ec0c1ea1ae1bb8ba78c6f.zip |
Unused local variables are eliminated by dead c...
Unused local variables are eliminated by dead code elimination.
Diffstat (limited to 'src')
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala | 2 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala | 29 |
2 files changed, 25 insertions, 6 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index 3d059f971b..5f2613e59d 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -1272,7 +1272,7 @@ abstract class GenJVM extends SubComponent { /** * Compute the indexes of each local variable of the given - * method. + * method. Assumes parameters come first in the list of locals. */ def computeLocalVarsIndex(m: IMethod): Unit = { var idx = 1 diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala index 28fcda23b2..b587fa06b8 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -39,12 +39,14 @@ abstract class DeadCodeElimination extends SubComponent { /** Remove dead code. */ class DeadCode { - def analyzeClass(cls: IClass): Unit = + + def analyzeClass(cls: IClass): Unit = { cls.methods.foreach { m => this.method = m // analyzeMethod(m); dieCodeDie(m) } + } val rdef = new reachingDefinitions.ReachingDefinitionsAnalysis; @@ -57,6 +59,9 @@ abstract class DeadCodeElimination extends SubComponent { /** what instructions have been marked as useful? */ val useful: mutable.Map[BasicBlock, mutable.BitSet] = new mutable.HashMap + /** what local variables have been accessed at least once? */ + var accessedLocals: List[Local] = Nil + /** the current method. */ var method: IMethod = _ @@ -64,10 +69,15 @@ abstract class DeadCodeElimination extends SubComponent { log("dead code elimination on " + m); // (new DepthFirstLinerizer).linearize(m) m.code.blocks.clear + accessedLocals = m.params.reverse m.code.blocks ++= linearizer.linearize(m) collectRDef(m) mark sweep(m) + if (m.locals.diff(accessedLocals).length > 0) { + log("Removed dead locals: " + m.locals.diff(accessedLocals)) + m.locals = accessedLocals.reverse + } } /** collect reaching definitions and initial useful instructions for this method. */ @@ -84,8 +94,8 @@ abstract class DeadCodeElimination extends SubComponent { case LOAD_LOCAL(l) => defs = defs + ((bb, idx)) -> rd._1 // Console.println(i + ": " + (bb, idx) + " rd: " + rd + " and having: " + defs) - case RETURN(_) | JUMP(_) | CJUMP(_, _, _, _) | CZJUMP(_, _, _, _) | - DROP(_) | THROW() | STORE_FIELD(_, _) | STORE_ARRAY_ITEM(_) | + case RETURN(_) | JUMP(_) | CJUMP(_, _, _, _) | CZJUMP(_, _, _, _) | STORE_FIELD(_, _) | + DROP(_) | THROW() | STORE_ARRAY_ITEM(_) | SCOPE_ENTER(_) | SCOPE_EXIT(_) | LOAD_EXCEPTION() | SWITCH(_, _) | MONITOR_ENTER() | MONITOR_EXIT() => worklist += ((bb, idx)) case CALL_METHOD(m1, _) if isSideEffecting(m1) => worklist += ((bb, idx)) case CALL_METHOD(m1, SuperCall(_)) => @@ -147,15 +157,24 @@ abstract class DeadCodeElimination extends SubComponent { case Some(is) => is foreach bb.emit case None => () } + // check for accessed locals + i match { + case LOAD_LOCAL(l) if !l.arg => + accessedLocals = l :: accessedLocals + case STORE_LOCAL(l) if !l.arg => + accessedLocals = l :: accessedLocals + case _ => () + } } else { i match { case NEW(REFERENCE(sym)) => log("skipped object creation: " + sym) //Console.println("skipping class file altogether: " + sym.fullNameString) - icodes.classes -= sym + if (inliner.isClosureClass(sym)) + icodes.classes -= sym case _ => () } - log("Skipped: bb_" + bb + ": " + idx + "( " + i + ")") + if (settings.debug.value) log("Skipped: bb_" + bb + ": " + idx + "( " + i + ")") } } |