diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2010-08-23 08:52:16 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2010-08-23 08:52:16 +0000 |
commit | c5650b9f7dd378c02918a5df879b74fbf22e4cb7 (patch) | |
tree | 7a0b1fa6aa2fccc1afd0e9ce3e1e6bccc4c8fdb0 | |
parent | 6c2c125d1bf407b450c242f8dcf7d640367ef18f (diff) | |
download | scala-c5650b9f7dd378c02918a5df879b74fbf22e4cb7.tar.gz scala-c5650b9f7dd378c02918a5df879b74fbf22e4cb7.tar.bz2 scala-c5650b9f7dd378c02918a5df879b74fbf22e4cb7.zip |
Improved the peephole optimizer to use liveness.
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala | 40 | ||||
-rw-r--r-- | src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala | 1 |
2 files changed, 33 insertions, 8 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala index 70bea2d44a..0897b94a15 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala @@ -25,8 +25,9 @@ abstract class ClosureElimination extends SubComponent { override def newPhase(p: Phase) = new ClosureEliminationPhase(p) /** A simple peephole optimizer. */ - val peephole = new PeepholeOpt( (i1, i2) => - (i1, i2) match { + val peephole = new PeepholeOpt { + + def peep(bb: BasicBlock, i1: Instruction, i2: Instruction) = (i1, i2) match { case (CONSTANT(c), DROP(_)) => if (c.tag == UnitTag) Some(List(i2)) @@ -37,7 +38,21 @@ abstract class ClosureElimination extends SubComponent { if (x eq y) Some(Nil) else None case (STORE_LOCAL(x), LOAD_LOCAL(y)) if (x == y) => - Some(List(DUP(x.kind), STORE_LOCAL(x))) + var liveOut = liveness.out(bb) + if (!liveOut(x)) { + log("store/load to a dead local? " + x) + val instrs = bb.getArray + var idx = instrs.length - 1 + while (idx > 0 && (instrs(idx) ne i2)) { + liveOut = liveness.interpret(liveOut, instrs(idx)) + idx -= 1 + } + if (!liveOut(x)) { + println("removing dead store/load " + x) + Some(Nil) + } else None + } else + Some(List(DUP(x.kind), STORE_LOCAL(x))) case (LOAD_LOCAL(_), DROP(_)) | (DUP(_), DROP(_)) => Some(Nil) @@ -52,7 +67,8 @@ abstract class ClosureElimination extends SubComponent { Some(DROP(REFERENCE(definitions.ObjectClass)) :: Nil); case _ => None - }); + } + } /** The closure elimination phase. */ @@ -85,7 +101,7 @@ abstract class ClosureElimination extends SubComponent { def analyzeClass(cls: IClass): Unit = if (settings.Xcloselim.value) { cls.methods.foreach { m => analyzeMethod(m) - peephole.transformMethod(m); + peephole(m); }} @@ -202,12 +218,20 @@ abstract class ClosureElimination extends SubComponent { /** Peephole optimization. */ - class PeepholeOpt(peep: (Instruction, Instruction) => Option[List[Instruction]]) { + abstract class PeepholeOpt { private var method: IMethod = null - def transformMethod(m: IMethod): Unit = if (m.code ne null) { + /** Concrete implementations will perform their optimizations here */ + def peep(bb: BasicBlock, i1: Instruction, i2: Instruction): Option[List[Instruction]] + + var liveness: global.icodes.liveness.LivenessAnalysis = null + + def apply(m: IMethod): Unit = if (m.code ne null) { method = m + liveness = new global.icodes.liveness.LivenessAnalysis + liveness.init(m) + liveness.run for (b <- m.code.blocks) transformBlock(b) } @@ -225,7 +249,7 @@ abstract class ClosureElimination extends SubComponent { redo = false; while (t != Nil) { - peep(h, t.head) match { + peep(b, h, t.head) match { case Some(newInstrs) => newInstructions = seen.reverse ::: newInstrs ::: t.tail; redo = true; diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala index e365b3bc08..589425298f 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -47,6 +47,7 @@ abstract class DeadCodeElimination extends SubComponent { cls.methods.foreach { m => this.method = m dieCodeDie(m) + global.closureElimination.peephole(m) } } |