From d934e21d461da5833d3ec0c1ea1ae1bb8ba78c6f Mon Sep 17 00:00:00 2001 From: Iulian Dragos Date: Thu, 19 Apr 2007 08:34:19 +0000 Subject: Unused local variables are eliminated by dead c... Unused local variables are eliminated by dead code elimination. --- .../scala/tools/nsc/backend/jvm/GenJVM.scala | 2 +- .../nsc/backend/opt/DeadCodeElimination.scala | 29 ++++++++++++++++++---- 2 files changed, 25 insertions(+), 6 deletions(-) (limited to 'src') 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 + ")") } } -- cgit v1.2.3