diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2007-10-08 14:34:59 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2007-10-08 14:34:59 +0000 |
commit | c4181f656d306a986549ef990a1f531313bee420 (patch) | |
tree | b2d4e4cd6ca20ed36e359bfaab4d25f0aa9e2d3c /src/compiler/scala/tools/nsc/backend | |
parent | 9ce1dd8d50095a64a68bc86d5f5a856209eaf1f2 (diff) | |
download | scala-c4181f656d306a986549ef990a1f531313bee420.tar.gz scala-c4181f656d306a986549ef990a1f531313bee420.tar.bz2 scala-c4181f656d306a986549ef990a1f531313bee420.zip |
Improved/refactored parts of the optimization p...
Improved/refactored parts of the optimization phases, removed option
Ybytecode-read (enabled now by -optimise).
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend')
5 files changed, 65 insertions, 53 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala index dc4afa22c0..46d0c9ab0a 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala @@ -12,6 +12,7 @@ import java.io.PrintWriter import scala.collection.mutable.HashMap import scala.tools.nsc.symtab._ import analysis.{Liveness, ReachingDefinitions} +import scala.tools.nsc.symtab.classfile.ICodeReader /** Glue together ICode parts. * @@ -27,6 +28,7 @@ abstract class ICodes extends AnyRef with Primitives with Linearizers with Printers + with Repository { val global: Global @@ -74,6 +76,10 @@ abstract class ICodes extends AnyRef settings.Xdce.value = true } + object icodeReader extends ICodeReader { + lazy val global: ICodes.this.global.type = ICodes.this.global + } + /** A phase which works on icode. */ abstract class ICodePhase(prev: Phase) extends global.GlobalPhase(prev) { override def erasedTypes = true diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala index 27342deb85..79e1764a31 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala @@ -192,6 +192,52 @@ abstract class ReachingDefinitions { IState(locals, stack) } + /** Return the instructions that produced the 'm' elements on the stack, below given 'depth'. + * for instance, findefs(bb, idx, 1, 1) returns the instructions that might have produced the + * value found below the topmost element of the stack. + */ + def findDefs(bb: BasicBlock, idx: Int, m: Int, depth: Int): List[(BasicBlock, Int)] = if (idx > 0) { + assert(bb.isClosed) + var instrs = bb.getArray + var res: List[(BasicBlock, Int)] = Nil + var i = idx + var n = m + var d = depth + // "I look for who produced the 'n' elements below the 'd' topmost slots of the stack" + while (n > 0 && i > 0) { + i -= 1 + val prod = instrs(i).produced + if (prod > d) { + res = (bb, i) :: res + n = n - (prod - d) + if (bb(i) != LOAD_EXCEPTION) + d = instrs(i).consumed + } else { + d -= prod + d += instrs(i).consumed + } + } + + if (n > 0) { + val stack = this.in(bb).stack + assert(stack.length >= n, "entry stack is too small, expected: " + n + " found: " + stack) + stack.drop(d).take(n) foreach { defs => + res = defs.toList ::: res + } + } + res + } else { + val stack = this.in(bb).stack + assert(stack.length >= m, "entry stack is too small, expected: " + m + " found: " + stack) + stack.take(m) flatMap (_.toList) + } + + /** Return the definitions that produced the topmost 'm' elements on the stack, + * and that reach the instruction at index 'idx' in basic block 'bb'. + */ + def findDefs(bb: BasicBlock, idx: Int, m: Int): List[(BasicBlock, Int)] = + findDefs(bb, idx, m, 0) + override def toString: String = { val sb = new compat.StringBuilder sb.append("rdef: \n") diff --git a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala index da9a38eef7..f793346d66 100644 --- a/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala +++ b/src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala @@ -1348,7 +1348,7 @@ abstract class GenJVM extends SubComponent { && !sym.enclClass.hasFlag(Flags.INTERFACE) && !sym.isClassConstructor) ACC_FINAL else 0) jf = jf | (if (isStaticSymbol(sym)) ACC_STATIC else 0) - jf = jf | (if (sym hasFlag Flags.SYNTHETIC) ACC_SYNTHETIC else 0) + jf = jf | (if (sym hasFlag Flags.ACCESSOR) ACC_SYNTHETIC else 0) jf } diff --git a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala index de00968145..3bcb9e98bf 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala @@ -105,7 +105,7 @@ abstract class DeadCodeElimination extends SubComponent { case CALL_METHOD(m1, SuperCall(_)) => worklist += ((bb, idx)) // super calls to constructor case DROP(_) => - val necessary = findDefs(bb, idx, 1) exists { p => + val necessary = rdef.findDefs(bb, idx, 1) exists { p => val (bb1, idx1) = p bb1(idx1) match { case CALL_METHOD(m1, _) if isSideEffecting(m1) => true @@ -152,7 +152,7 @@ abstract class DeadCodeElimination extends SubComponent { () case _ => - for ((bb1, idx1) <- findDefs(bb, idx, instr.consumed) if !useful(bb1)(idx1)) { + for ((bb1, idx1) <- rdef.findDefs(bb, idx, instr.consumed) if !useful(bb1)(idx1)) { log("\tAdding " + bb1(idx1)) worklist += ((bb1, idx1)) } @@ -210,7 +210,8 @@ abstract class DeadCodeElimination extends SubComponent { for ((i, idx) <- bb.toList.zipWithIndex) { if (!useful(bb)(idx)) { for ((consumedType, depth) <- i.consumedTypes.reverse.zipWithIndex) { - val defs = findDefs(bb, idx, i.consumed, depth) + log("Finding definitions of: " + i + "\n\t" + consumedType + " at depth: " + depth) + val defs = rdef.findDefs(bb, idx, 1, depth) for (d <- defs) { if (!compensations.isDefinedAt(d)) compensations(d) = List(DROP(consumedType)) @@ -246,52 +247,6 @@ abstract class DeadCodeElimination extends SubComponent { abort("could not find init in: " + method) } - /** Return the instructions that produced the 'm' elements on the stack, below given 'depth'. - * for instance, findefs(bb, idx, 1, 1) returns the instructions that might have produced the - * value found below the topmost element of the stack. - */ - def findDefs(bb: BasicBlock, idx: Int, m: Int, depth: Int): List[(BasicBlock, Int)] = if (idx > 0) { - assert(bb.isClosed) - var instrs = bb.getArray - var res: List[(BasicBlock, Int)] = Nil - var i = idx - var n = m - var d = 0 - // "I look for who produced the 'n' elements below the 'd' topmost slots of the stack" - while (n > 0 && i > 0) { - i -= 1 - val prod = instrs(i).produced - if (prod > d) { - res = (bb, i) :: res - n = n - (prod - d) - if (bb(i) != LOAD_EXCEPTION) - d = instrs(i).consumed - } else { - d -= prod - d += instrs(i).consumed - } - } - - if (n > 0) { - val stack = rdef.in(bb).stack - assert(stack.length >= n, "entry stack is too small, expected: " + n + " found: " + stack) - stack.drop(d).take(n) foreach { defs => - res = defs.toList ::: res - } - } - res - } else { - val stack = rdef.in(bb).stack - assert(stack.length >= m, "entry stack is too small, expected: " + m + " found: " + stack) - stack.take(m) flatMap (_.toList) - } - - /** Return the definitions that produced the topmost 'm' elements on the stack, - * and that reach the instruction at index 'idx' in basic block 'bb'. - */ - def findDefs(bb: BasicBlock, idx: Int, m: Int): List[(BasicBlock, Int)] = - findDefs(bb, idx, m, 0) - /** Is 'sym' a side-effecting method? TODO: proper analysis. */ private def isSideEffecting(sym: Symbol): Boolean = { !(sym.isGetter // for testing only diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index c7d33a7693..8dabbd3173 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -309,16 +309,21 @@ abstract class Inliners extends SubComponent { log("\tlooked up method: " + concreteMethod.fullNameString) } + if (receiver == definitions.PredefModule.moduleClass) { + log("loading predef") + icodes.icode(receiver, true) + } if (settings.debug.value) log("Treating " + i - + "\n\tclasses.contains: " + classes.contains(receiver) + + "\n\treceiver: " + receiver + + "\n\ticodes.available: " + icodes.available(receiver) + "\n\tconcreteMethod.isFinal: " + concreteMethod.isFinal); - if ( classes.contains(receiver) + if ( icodes.available(receiver) && (isClosureClass(receiver) || concreteMethod.isFinal || receiver.isFinal)) { - classes(receiver).lookupMethod(concreteMethod) match { + icodes.icode(receiver).get.lookupMethod(concreteMethod) match { case Some(inc) => if (inc.symbol != m.symbol && (inlinedMethods(inc.symbol) < 2) |