summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2010-08-23 08:52:16 +0000
committerIulian Dragos <jaguarul@gmail.com>2010-08-23 08:52:16 +0000
commitc5650b9f7dd378c02918a5df879b74fbf22e4cb7 (patch)
tree7a0b1fa6aa2fccc1afd0e9ce3e1e6bccc4c8fdb0 /src
parent6c2c125d1bf407b450c242f8dcf7d640367ef18f (diff)
downloadscala-c5650b9f7dd378c02918a5df879b74fbf22e4cb7.tar.gz
scala-c5650b9f7dd378c02918a5df879b74fbf22e4cb7.tar.bz2
scala-c5650b9f7dd378c02918a5df879b74fbf22e4cb7.zip
Improved the peephole optimizer to use liveness.
Diffstat (limited to 'src')
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala40
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala1
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)
}
}