summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2007-10-08 14:34:59 +0000
committerIulian Dragos <jaguarul@gmail.com>2007-10-08 14:34:59 +0000
commitc4181f656d306a986549ef990a1f531313bee420 (patch)
treeb2d4e4cd6ca20ed36e359bfaab4d25f0aa9e2d3c /src/compiler/scala/tools/nsc/backend
parent9ce1dd8d50095a64a68bc86d5f5a856209eaf1f2 (diff)
downloadscala-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')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/ICodes.scala6
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/ReachingDefinitions.scala46
-rw-r--r--src/compiler/scala/tools/nsc/backend/jvm/GenJVM.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/DeadCodeElimination.scala53
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala11
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)