diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2006-08-02 14:12:34 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2006-08-02 14:12:34 +0000 |
commit | e87657e617b1418163dfd4fc49999f13cf154765 (patch) | |
tree | e31f51d5aa9c30c022672c4bc7b2f59c66a93ddc | |
parent | e40c9ebc9696448e04769bf9603e0011bd7fe8fc (diff) | |
download | scala-e87657e617b1418163dfd4fc49999f13cf154765.tar.gz scala-e87657e617b1418163dfd4fc49999f13cf154765.tar.bz2 scala-e87657e617b1418163dfd4fc49999f13cf154765.zip |
Removed -Xshowicode which is now taken over by ...
Removed -Xshowicode which is now taken over by '-print:icode' and can
prind icode after any phase (inline, closure elimination, etc.) Various
bug fixes in closure elimination.
5 files changed, 54 insertions, 19 deletions
diff --git a/src/compiler/scala/tools/nsc/Settings.scala b/src/compiler/scala/tools/nsc/Settings.scala index 1239216e91..7f6c5f1a51 100644 --- a/src/compiler/scala/tools/nsc/Settings.scala +++ b/src/compiler/scala/tools/nsc/Settings.scala @@ -116,7 +116,6 @@ class Settings(error: String => unit) { val Xdce = BooleanSetting("-Xdce", "Perform dead code elimination") val Xshowcls = StringSetting ("-Xshowcls", "class", "Show class info", "") val Xshowobj = StringSetting ("-Xshowobj", "object", "Show object info", "") - val Xshowicode = BooleanSetting("-Xshowicode", "Print the generated ICode") val Xgadt = BooleanSetting("-Xgadt", "enable gadt for classes") val Xlinearizer = ChoiceSetting ("-Xlinearizer", "Linearizer to use", List("normal", "dfs", "rpo", "dump"), "rpo") val Xgenerics = BooleanSetting("-Xgenerics", "Use generic Java types"); diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala index 2c9daba6d3..740b25fd20 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala @@ -25,9 +25,13 @@ abstract class CopyPropagation { case class Field(r: Record, sym: Symbol) extends Location; /** Values that can be on the stack. */ - abstract class Value; + abstract class Value { + def isRecord = false; + } case class This extends Value; - case class Record(cls: Symbol, bindings: Map[Symbol, Value]) extends Value; + case class Record(cls: Symbol, bindings: Map[Symbol, Value]) extends Value { + override def isRecord = true; + } case class Deref(l: Location) extends Value; case object Unknown extends Value; object AllRecords extends Record(NoSymbol, new HashMap[Symbol, Value]); @@ -98,6 +102,19 @@ abstract class CopyPropagation { } } + /** Return a local which contains the same value as this field, if any. */ + def getLocalForField(r: Record, f: Symbol): Option[Value] = { + assert(r.bindings.isDefinedAt(f), + "Record " + r + " does not contain a field " + f); + + var target: Value = r.bindings(f); + target match { + case Deref(LocalVar(l)) => Some(Deref(LocalVar(getAlias(l)))) + case This() => Some(target) + case _ => None + } + } + override def toString(): String = { "\nBindings: " + bindings + "\nStack: " + stack; } diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala index 1dfe643afd..ac6cf70093 100644 --- a/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala +++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala @@ -13,10 +13,11 @@ trait DataFlowAnalysis[L <: CompleteLattice] { val in: Map[P, lattice.Elem] = new HashMap; val out: Map[P, lattice.Elem] = new HashMap; + val visited: HashSet[P] = new HashSet; /* Implement this function to initialize the worklist. */ def init(f: => Unit): Unit = { - in.clear; out.clear; worklist.clear; + in.clear; out.clear; worklist.clear; visited.clear; f; } @@ -28,7 +29,7 @@ trait DataFlowAnalysis[L <: CompleteLattice] { */ def forwardAnalysis(f: (P, lattice.Elem) => lattice.Elem): Unit = { while (!worklist.isEmpty) { - val point = worklist.elements.next; worklist -= point; + val point = worklist.elements.next; worklist -= point; visited += point; val output = f(point, in(point)); if (out(point) == (lattice.bottom) || output != out(point)) { diff --git a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala index 27bb116a3f..f4d7640816 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala @@ -124,18 +124,24 @@ abstract class ClosureElimination extends SubComponent { case LOAD_FIELD(f, false) => info.stack(0) match { case r @ Record(cls, bindings) if bindings.isDefinedAt(f) => - bb.replaceInstruction(i, - DROP(REFERENCE(cls)) :: - valueToInstruction(info.getBinding(r, f)) :: Nil); - log("Replaced " + i + " with " + info.getBinding(r, f)); + info.getLocalForField(r, f) match { + case Some(local) => + bb.replaceInstruction(i, + DROP(REFERENCE(cls)) :: valueToInstruction(local) :: Nil); + log("Replaced " + i + " with " + info.getBinding(r, f)); + case None => (); + } case Deref(LocalVar(l)) => info.getBinding(l) match { case r @ Record(cls, bindings) if bindings.isDefinedAt(f) => - bb.replaceInstruction(i, - DROP(REFERENCE(cls)) :: - valueToInstruction(info.getBinding(r, f)) :: Nil); - log("Replaced " + i + " with " + info.getBinding(r, f)); + info.getLocalForField(r, f) match { + case Some(local) => + bb.replaceInstruction(i, + DROP(REFERENCE(cls)) :: valueToInstruction(local) :: Nil); + log("Replaced " + i + " with " + info.getBinding(r, f)); + case None => (); + } case _ => (); } diff --git a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala index 004969c3c5..b9f4295929 100644 --- a/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala +++ b/src/compiler/scala/tools/nsc/backend/opt/Inliners.scala @@ -61,8 +61,8 @@ abstract class Inliners extends SubComponent { block: BasicBlock, instr: Instruction, callee: IMethod): Unit = { -// log("Inlining " + callee + " in " + caller + " at pos: " + -// classes(caller.symbol.owner).cunit.position(instr.pos)); + log("Inlining " + callee + " in " + caller + " at pos: " + + classes(caller.symbol.owner).cunit.position(instr.pos)); val targetPos = instr.pos; val a = new analysis.MethodTFA(callee); @@ -105,11 +105,19 @@ abstract class Inliners extends SubComponent { handler } + /** alfa-rename `l' in caller's context. */ + def dupLocal(l: Local): Local = { + val sym = caller.symbol.newVariable(l.sym.pos, freshName(l.sym.name.toString())); + sym.setInfo(l.sym.tpe); + new Local(sym, l.kind, false) + } + /** Adds parameters from another method as locals */ def addParamsAsLocals(m: IMethod, ls: List[Local]): Unit = { m.locals = m.locals ::: (ls map { a => if (a.arg) { - val l = new Local(a.sym, a.kind, false); + //val l = new Local(a.sym, a.kind, false); + val l = dupLocal(a); argsToLocal += a -> l; l } else @@ -253,6 +261,8 @@ abstract class Inliners extends SubComponent { if (settings.debug.value) log("" + i + " has actual receiver: " + receiver); } + if (settings.debug.value) + log("Treating " + i); if ( classes.contains(receiver) && (isClosureClass(receiver) @@ -263,7 +273,8 @@ abstract class Inliners extends SubComponent { if (inc != m && (inc.code ne null) && isSafeToInline(m, inc, info._2)) { retry = true; - count = count + 1; + if (!isClosureClass(receiver)) // only count non-closures + count = count + 1; inline(m, bb, i, inc); /* Remove this method from the cache, as the calls-private relation @@ -279,7 +290,7 @@ abstract class Inliners extends SubComponent { } info = tfa.interpret(info, i); }}}} - } while (retry && count < 5); + } while (retry && count < 15); normalize(m); } catch { case e => @@ -354,7 +365,8 @@ abstract class Inliners extends SubComponent { if (stack.length > (1 + callee.symbol.info.paramTypes.length) && (callee.exh exists (.covered.contains(callee.code.startBlock)))) { - false; + if (settings.debug.value) log("method " + callee.symbol + " is used on a non-empty stack with finalizer."); + false } else true } |