summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2006-08-02 14:12:34 +0000
committerIulian Dragos <jaguarul@gmail.com>2006-08-02 14:12:34 +0000
commite87657e617b1418163dfd4fc49999f13cf154765 (patch)
treee31f51d5aa9c30c022672c4bc7b2f59c66a93ddc
parente40c9ebc9696448e04769bf9603e0011bd7fe8fc (diff)
downloadscala-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.
-rw-r--r--src/compiler/scala/tools/nsc/Settings.scala1
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/CopyPropagation.scala21
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala5
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/ClosureElimination.scala22
-rw-r--r--src/compiler/scala/tools/nsc/backend/opt/Inliners.scala24
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
}