summaryrefslogtreecommitdiff
path: root/src/compiler
diff options
context:
space:
mode:
authormichelou <michelou@epfl.ch>2006-12-04 14:40:02 +0000
committermichelou <michelou@epfl.ch>2006-12-04 14:40:02 +0000
commit525018c3cab1aaeb6644e9dacae2ab36ffa28d13 (patch)
tree34307dcf8857e5383a379f5a1a0e6ca9e23c5935 /src/compiler
parent98f71af784e981f170d69fdbb416fc23b0ca72dd (diff)
downloadscala-525018c3cab1aaeb6644e9dacae2ab36ffa28d13.tar.gz
scala-525018c3cab1aaeb6644e9dacae2ab36ffa28d13.tar.bz2
scala-525018c3cab1aaeb6644e9dacae2ab36ffa28d13.zip
removed leading/trailing tabs/blanks in backend...
removed leading/trailing tabs/blanks in backend/icode/*.scala
Diffstat (limited to 'src/compiler')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala265
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/CheckerError.scala8
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/CompleteLattice.scala21
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala60
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala73
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/LubError.scala11
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala237
-rw-r--r--src/compiler/scala/tools/nsc/doc/DocGenerator.scala2
8 files changed, 363 insertions, 314 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
index 4946ed13d8..1e1fe8f629 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
@@ -1,20 +1,20 @@
-/* NSC -- new scala compiler
- * Copyright 2005 LAMP/EPFL
+/* NSC -- new Scala compiler
+ * Copyright 2005-2007 LAMP/EPFL
* @author Martin Odersky
*/
// $Id$
-package scala.tools.nsc.backend.icode;
+package scala.tools.nsc.backend.icode
-import compat.StringBuilder;
-import scala.tools.nsc.ast._;
-import scala.collection.mutable.Map;
-import scala.tools.nsc.util.Position;
-import scala.tools.nsc.backend.icode.analysis.ProgramPoint;
+import compat.StringBuilder
+import scala.tools.nsc.ast._
+import scala.collection.mutable.Map
+import scala.tools.nsc.util.Position
+import scala.tools.nsc.backend.icode.analysis.ProgramPoint
trait BasicBlocks requires ICodes {
- import opcodes._;
+ import opcodes._
/** This class represents a basic block. Each
* basic block contains a list of instructions that are
@@ -26,37 +26,37 @@ trait BasicBlocks requires ICodes {
with ProgramPoint[BasicBlock] {
/** The label of the block */
- val label = theLabel;
+ val label = theLabel
- /** When set, the 'emit' methods will be ignored. */
- var ignore: Boolean = false;
+ /** When set, the <code>emit</code> methods will be ignored. */
+ var ignore: Boolean = false
- var preds: List[BasicBlock] = null;
+ var preds: List[BasicBlock] = null
/** Is this block the head of a while? */
- var loopHeader = false;
+ var loopHeader = false
/** ICode instructions, used as temporary storage while emitting code.
* Once closed is called, only the `instrs' array should be used.
*/
- private var instructionList: List[Instruction] = Nil;
+ private var instructionList: List[Instruction] = Nil
- private var _lastInstruction: Instruction = null;
+ private var _lastInstruction: Instruction = null
- private var closed: boolean = false;
+ private var closed: boolean = false
- private var instrs: Array[Instruction] = _;
- private var touched = false;
+ private var instrs: Array[Instruction] = _
+ private var touched = false
def toList: List[Instruction] = {
if (closed && touched)
- instructionList = List.fromArray(instrs);
+ instructionList = List.fromArray(instrs)
instructionList
}
def fromList(is: List[Instruction]): Unit = {
- instrs = toInstructionArray(is);
- closed = true;
+ instrs = toInstructionArray(is)
+ closed = true
}
// public:
@@ -66,7 +66,7 @@ trait BasicBlocks requires ICodes {
*/
def indexOf(inst: Instruction): Int = {
assert(closed)
- var i = 0;
+ var i = 0
while (i < instrs.length) {
if (instrs(i) eq inst) return i
i = i + 1
@@ -80,14 +80,14 @@ trait BasicBlocks requires ICodes {
/** Apply a function to all the instructions of the block. */
def traverse(f: Instruction => unit) = {
if (!closed) {
- dump;
- global.abort("Traversing an open block!: " + label);
+ dump
+ global.abort("Traversing an open block!: " + label)
}
- instrs foreach f;
+ instrs foreach f
}
def traverseBackwards(f: Instruction => Unit) = {
- var i = instrs.length - 1;
+ var i = instrs.length - 1
while (i >= 0) {
f(instrs(i));
i = i - 1
@@ -97,19 +97,19 @@ trait BasicBlocks requires ICodes {
/** The number of instructions in this basic block so far. */
def size: Int =
if (isClosed)
- instrs.length;
+ instrs.length
else
- instructionList.length;
+ instructionList.length
/** Return the index of the instruction which produced the value
* consumed by the given instruction.
*/
def findDef(pos: Int): Option[Int] = {
- assert(closed);
- var i = pos;
- var d = 0;
+ assert(closed)
+ var i = pos
+ var d = 0
while (i > 0) {
- i = i - 1;
+ i = i - 1
val prod = instrs(i).produced
if (prod > 0 && d == 0)
return Some(i)
@@ -119,12 +119,11 @@ trait BasicBlocks requires ICodes {
}
/** Return the n-th instruction. */
- def apply(n: Int): Instruction = {
+ def apply(n: Int): Instruction =
if (closed)
instrs(n)
else
instructionList.reverse(n)
- }
///////////////////// Substitutions ///////////////////////
@@ -133,10 +132,10 @@ trait BasicBlocks requires ICodes {
* they are anchored. It retains the position of the previous instruction.
*/
def replaceInstruction(pos: Int, instr: Instruction): Boolean = {
- assert(closed, "Instructions can be replaced only after the basic block is closed");
+ assert(closed, "Instructions can be replaced only after the basic block is closed")
- instr.pos = instrs(pos).pos;
- instrs(pos) = instr;
+ instr.pos = instrs(pos).pos
+ instrs(pos) = instr
true
}
@@ -146,42 +145,46 @@ trait BasicBlocks requires ICodes {
* It retains the position of the previous instruction.
*/
def replaceInstruction(oldInstr: Instruction, newInstr: Instruction): Boolean = {
- assert(closed, "Instructions can be replaced only after the basic block is closed");
+ assert(closed, "Instructions can be replaced only after the basic block is closed")
- var i = 0;
- var changed = false;
+ var i = 0
+ var changed = false
while (i < instrs.length && !changed) {
if (instrs(i) == oldInstr) {
- newInstr.pos = oldInstr.pos;
- instrs(i) = newInstr;
- changed = true;
+ newInstr.pos = oldInstr.pos
+ instrs(i) = newInstr
+ changed = true
}
- i = i + 1;
+ i = i + 1
}
changed
}
- /** Replaces iold with 'is'. It does not update the position field in the newly
- * inserted instrucitons, so it behaves differently than the one-instruction
- * versions of this function.
+ /** Replaces <code>iold</code> with <code>is</code>. It does not update
+ * the position field in the newly inserted instrucitons, so it behaves
+ * differently than the one-instruction versions of this function.
+ *
+ * @param iold ..
+ * @param is ..
+ * @return ..
*/
def replaceInstruction(iold: Instruction, is: List[Instruction]): Boolean = {
- assert(closed, "Instructions can be replaced only after the basic block is closed");
+ assert(closed, "Instructions can be replaced only after the basic block is closed")
- var i = 0;
- var changed = false;
+ var i = 0
+ var changed = false
while (i < instrs.length && (instrs(i) ne iold))
i = i + 1;
if (i < instrs.length) {
val newInstrs = new Array[Instruction](instrs.length + is.length - 1);
- changed = true;
- Array.copy(instrs, 0, newInstrs, 0, i);
- var j = i;
+ changed = true
+ Array.copy(instrs, 0, newInstrs, 0, i)
+ var j = i
for (val x <- is) {
- newInstrs(j) = x;
- j = j + 1;
+ newInstrs(j) = x
+ j = j + 1
}
if (i + 1 < instrs.length)
Array.copy(instrs, i + 1, newInstrs, j, instrs.length - i - 1)
@@ -191,33 +194,39 @@ trait BasicBlocks requires ICodes {
changed
}
- /** Remove instructions found at the given positions. */
+ /** Removes instructions found at the given positions.
+ *
+ * @param positions ...
+ */
def removeInstructionsAt(positions: Int*): Unit = {
- assert(closed);
- val removed = positions.toList;
- val newInstrs = new Array[Instruction](instrs.length - positions.length);
- var i = 0;
- var j = 0;
+ assert(closed)
+ val removed = positions.toList
+ val newInstrs = new Array[Instruction](instrs.length - positions.length)
+ var i = 0
+ var j = 0
while (i < instrs.length) {
if (!removed.contains(i)) {
- newInstrs(j) = instrs(i);
- j = j + 1;
+ newInstrs(j) = instrs(i)
+ j = j + 1
}
- i = i + 1;
+ i = i + 1
}
- instrs = newInstrs;
+ instrs = newInstrs
}
- /** Replace all instructions found in the map. */
- def subst(map: Map[Instruction, Instruction]) =
+ /** Replaces all instructions found in the map.
+ *
+ * @param map ...
+ */
+ def subst(map: Map[Instruction, Instruction]): Unit =
if (!closed) substOnList(map) else {
- var i = 0;
+ var i = 0
while (i < instrs.length) {
map get instrs(i) match {
- case Some(instr) => touched = replaceInstruction(i, instr);
- case None => ();
+ case Some(instr) => touched = replaceInstruction(i, instr)
+ case None => ()
}
- i = i + 1;
+ i = i + 1
}
}
@@ -226,12 +235,12 @@ trait BasicBlocks requires ICodes {
case Nil => Nil
case x :: xs =>
map.get(x) match {
- case Some(newInstr) => newInstr :: subst(xs);
- case None => x :: subst(xs);
+ case Some(newInstr) => newInstr :: subst(xs)
+ case None => x :: subst(xs)
}
}
- instructionList = subst(instructionList);
+ instructionList = subst(instructionList)
}
////////////////////// Emit //////////////////////
@@ -240,59 +249,58 @@ trait BasicBlocks requires ICodes {
/** Add a new instruction at the end of the block,
* using the same source position as the last emitted instruction
*/
- def emit(instr: Instruction): Unit = {
+ def emit(instr: Instruction): Unit =
if (!instructionList.isEmpty)
- emit(instr, instructionList.head.pos);
+ emit(instr, instructionList.head.pos)
else
- emit(instr, Position.NOPOS);
- }
+ emit(instr, Position.NOPOS)
def emit(instr: Instruction, pos: Int) = {
if (closed) {
- print();
+ print()
Console.println("trying to emit: " + instr)
}
- assert (!closed || ignore, "BasicBlock closed");
+ assert (!closed || ignore, "BasicBlock closed")
if (!ignore) {
- touched = true;
- instr.pos = pos;
- instructionList = instr :: instructionList;
- _lastInstruction = instr;
+ touched = true
+ instr.pos = pos
+ instructionList = instr :: instructionList
+ _lastInstruction = instr
}
}
/** Close the block */
def close = {
assert(instructionList.length > 0,
- "Empty block.");
- closed = true;
- instructionList = instructionList.reverse;
- instrs = toInstructionArray(instructionList);
+ "Empty block.")
+ closed = true
+ instructionList = instructionList.reverse
+ instrs = toInstructionArray(instructionList)
}
def open = {
- closed = false;
- ignore = false;
+ closed = false
+ ignore = false
}
def clear: Unit = {
- instructionList = Nil;
- instrs = null;
- preds = null;
+ instructionList = Nil
+ instrs = null
+ preds = null
}
- def isEmpty: Boolean = instructionList.isEmpty;
+ def isEmpty: Boolean = instructionList.isEmpty
/** Enter ignore mode: new 'emit'ted instructions will not be
- * added to this basic block. It makes the generation of THROW
- * and RETURNs easier.
+ * added to this basic block. It makes the generation of THROW
+ * and RETURNs easier.
*/
- def enterIgnoreMode = ignore = true;
+ def enterIgnoreMode = ignore = true
def exitIgnoreMode = {
- assert(ignore, "Exit ignore mode when not in ignore mode.");
- ignore = false;
+ assert(ignore, "Exit ignore mode when not in ignore mode.")
+ ignore = false
}
/** Return the last instruction of this basic block. */
@@ -300,40 +308,40 @@ trait BasicBlocks requires ICodes {
if (closed)
instrs(instrs.length - 1)
else
- instructionList.head;
+ instructionList.head
def firstInstruction =
if (closed)
instrs(0)
else
- instructionList.last;
+ instructionList.last
/** Convert the list to an array */
def toInstructionArray(l: List[Instruction]): Array[Instruction] = {
- var array = new Array[Instruction](l.length);
- var i: Int = 0;
+ var array = new Array[Instruction](l.length)
+ var i: Int = 0
- l foreach (x => { array(i) = x; i = i + 1 });
+ l foreach (x => { array(i) = x; i = i + 1 })
array
}
- def isClosed = closed;
+ def isClosed = closed
// TODO: Take care of exception handlers!
def successors : List[BasicBlock] = if (isEmpty) Nil else
lastInstruction match {
- case JUMP (where) => List(where);
- case CJUMP(success, failure, _, _) => success :: failure :: Nil;
- case CZJUMP(success, failure, _, _) => success :: failure :: Nil;
- case SWITCH(_,labels) => labels;
- case RETURN(_) => Nil;
- case THROW() => Nil;
+ case JUMP (where) => List(where)
+ case CJUMP(success, failure, _, _) => success :: failure :: Nil
+ case CZJUMP(success, failure, _, _) => success :: failure :: Nil
+ case SWITCH(_,labels) => labels
+ case RETURN(_) => Nil
+ case THROW() => Nil
case _ =>
if (isClosed) {
- dump;
- global.abort("The last instruction is not a control flow instruction: " + lastInstruction);
+ dump
+ global.abort("The last instruction is not a control flow instruction: " + lastInstruction)
}
- else Nil;
+ else Nil
}
/** Returns the precessors of this block, in the current 'code' chunk.
@@ -341,36 +349,35 @@ trait BasicBlocks requires ICodes {
* in different code 'chunks' than the rest of the method.
*/
def predecessors: List[BasicBlock] = {
- preds = code.blocks.elements.filter (.successors.contains(this)).toList;
+ preds = code.blocks.elements.filter (.successors.contains(this)).toList
preds
}
- override def equals(other: Any): Boolean = (
+ override def equals(other: Any): Boolean =
other.isInstanceOf[BasicBlock] &&
other.asInstanceOf[BasicBlock].label == label &&
other.asInstanceOf[BasicBlock].code == code
- );
// Instead of it, rather use a printer
- def print() : unit = print(java.lang.System.out);
+ def print() : unit = print(java.lang.System.out)
def print(out: java.io.PrintStream) : unit = {
- out.println("block #"+label+" :");
- toList.foreach(i => out.println(" " + i));
- out.print("Successors: ");
- successors.foreach((x: BasicBlock) => out.print(" "+x.label.toString()));
- out.println();
+ out.println("block #"+label+" :")
+ toList.foreach(i => out.println(" " + i))
+ out.print("Successors: ")
+ successors.foreach((x: BasicBlock) => out.print(" "+x.label.toString()))
+ out.println()
}
def fullString: String = {
- val buf = new StringBuilder();
- buf.append("Block ").append(label.toString());
- buf.append("\nSuccessors: ").append(successors);
- buf.append("\nPredecessors: ").append(predecessors);
+ val buf = new StringBuilder()
+ buf.append("Block ").append(label.toString())
+ buf.append("\nSuccessors: ").append(successors)
+ buf.append("\nPredecessors: ").append(predecessors)
buf.toString()
}
- override def toString(): String = "" + label;
+ override def toString(): String = "" + label
}
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/CheckerError.scala b/src/compiler/scala/tools/nsc/backend/icode/CheckerError.scala
index da1232b6e9..cf3b764dd3 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/CheckerError.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/CheckerError.scala
@@ -1,11 +1,11 @@
-/* NSC -- new scala compiler
- * Copyright 2005 LAMP/EPFL
+/* NSC -- new Scala compiler
+ * Copyright 2005-2007 LAMP/EPFL
* @author Martin Odersky
*/
// $Id$
-package scala.tools.nsc.backend.icode;
+package scala.tools.nsc.backend.icode
-class CheckerError(s: String) extends Exception(s);
+class CheckerError(s: String) extends Exception(s)
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/CompleteLattice.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/CompleteLattice.scala
index 36e10d6366..3e0aa892d8 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/CompleteLattice.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/CompleteLattice.scala
@@ -1,19 +1,26 @@
-package scala.tools.nsc.backend.icode.analysis;
+/* NSC -- new Scala compiler
+ * Copyright 2005-2007 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+// $Id$
+
+package scala.tools.nsc.backend.icode.analysis
/** A complete lattice.
*/
trait CompleteLattice {
- type Elem;
+ type Elem
- /** Return the least upper bound of `a' and `b' */
- def lub2(a: Elem, b: Elem): Elem;
+ /** Return the least upper bound of <code>a</code> and <code>b</code> */
+ def lub2(a: Elem, b: Elem): Elem
/** Return the top element. */
- def top: Elem;
+ def top: Elem
/** Return the bottom element. */
- def bottom: Elem;
+ def bottom: Elem
/** Compute the least upper bound of a list of elements. */
- def lub(xs: List[Elem]): Elem = if (xs == Nil) bottom else xs reduceLeft lub2;
+ def lub(xs: List[Elem]): Elem = if (xs == Nil) bottom else xs reduceLeft lub2
}
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 b8d4a1e92c..8ab7007967 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/DataFlowAnalysis.scala
@@ -1,40 +1,49 @@
-package scala.tools.nsc.backend.icode.analysis;
+/* NSC -- new Scala compiler
+ * Copyright 2005-2007 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+// $Id$
-import scala.collection.mutable.{Map, HashMap, Set, HashSet};
+package scala.tools.nsc.backend.icode.analysis
+
+import scala.collection.mutable.{Map, HashMap, Set, HashSet}
/** A generic framework for data flow analysis.
*/
trait DataFlowAnalysis[L <: CompleteLattice] {
/** A type for program points. */
- type P <: ProgramPoint[P];
- val lattice: L;
+ type P <: ProgramPoint[P]
+ val lattice: L
- val worklist: Set[P] = new HashSet;
+ val worklist: Set[P] = new HashSet
- val in: Map[P, lattice.Elem] = new HashMap;
- val out: Map[P, lattice.Elem] = new HashMap;
- val visited: HashSet[P] = new HashSet;
+ 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; visited.clear;
- f;
+ f
}
- def run: Unit;
+ def run: Unit
- /** Implement forward dataflow analysis: the transfer function is
- * applied when inputs to a Program point change, to obtain the new
- * output value.
+ /** Implements forward dataflow analysis: the transfer function is
+ * applied when inputs to a Program point change, to obtain the new
+ * output value.
+ *
+ * @param f ...
*/
- def forwardAnalysis(f: (P, lattice.Elem) => lattice.Elem): Unit = {
+ def forwardAnalysis(f: (P, lattice.Elem) => lattice.Elem): Unit =
while (!worklist.isEmpty) {
val point = worklist.elements.next; worklist -= point; visited += point;
- val output = f(point, in(point));
+ val output = f(point, in(point))
if ((lattice.bottom == out(point)) || output != out(point)) {
- out(point) = output;
- val succs = point.successors;
+ out(point) = output
+ val succs = point.successors
succs foreach { p =>
if (!worklist.contains(p))
worklist += p;
@@ -42,22 +51,25 @@ trait DataFlowAnalysis[L <: CompleteLattice] {
}
}
}
- }
- def backwardAnalysis(f: (P, lattice.Elem) => lattice.Elem): Unit = {
+ /** ...
+ *
+ * @param f ...
+ */
+ def backwardAnalysis(f: (P, lattice.Elem) => lattice.Elem): Unit =
while (!worklist.isEmpty) {
- val point = worklist.elements.next; worklist -= point;
+ val point = worklist.elements.next; worklist -= point
- out(point) = lattice.lub(point.successors map in.apply);
- val input = f(point, out(point));
+ out(point) = lattice.lub(point.successors map in.apply)
+ val input = f(point, out(point))
if ((lattice.bottom == in(point)) || input != in(point)) {
- in(point) = input;
+ in(point) = input
point.predecessors foreach { p =>
if (!worklist.contains(p))
worklist += p;
}
}
}
- }
+
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala
index a2b3d94736..abb79ef3e5 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/Liveness.scala
@@ -1,4 +1,11 @@
-package scala.tools.nsc.backend.icode.analysis;
+/* NSC -- new Scala compiler
+ * Copyright 2005-2007 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+// $Id$
+
+package scala.tools.nsc.backend.icode.analysis
import compat.StringBuilder
import scala.collection.mutable.{HashMap, Map}
@@ -8,68 +15,68 @@ import scala.collection.immutable.{Set, ListSet}
* Compute liveness information for local variables.
*/
abstract class Liveness {
- val global: Global;
- import global._;
- import icodes._;
+ val global: Global
+ import global._
+ import icodes._
/** The lattice for this analysis. */
object livenessLattice extends CompleteLattice {
- type Elem = Set[Local];
+ type Elem = Set[Local]
val top: Elem = new ListSet[Local]() {
- override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef];
+ override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
}
val bottom: Elem = new ListSet[Local]() {
- override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef];
+ override def equals(that: Any): Boolean = this eq that.asInstanceOf[AnyRef]
}
- def lub2(a: Elem, b: Elem): Elem = a incl b;
+ def lub2(a: Elem, b: Elem): Elem = a incl b
}
final class LivenessAnalysis extends DataFlowAnalysis[livenessLattice.type] {
- type P = BasicBlock;
- val lattice = livenessLattice;
+ type P = BasicBlock
+ val lattice = livenessLattice
- var method: IMethod = _;
+ var method: IMethod = _
- val gen: Map[BasicBlock, Set[Local]] = new HashMap();
- val kill:Map[BasicBlock, Set[Local]] = new HashMap();
+ val gen: Map[BasicBlock, Set[Local]] = new HashMap()
+ val kill:Map[BasicBlock, Set[Local]] = new HashMap()
def init(m: IMethod): Unit = {
- this.method = m;
+ this.method = m
for (val b <- m.code.blocks.toList;
val Pair(g, k) = genAndKill(b)) {
- gen += b -> g;
- kill += b -> k;
+ gen += b -> g
+ kill += b -> k
}
init {
- worklist ++= m.code.blocks.toList;
+ worklist ++= m.code.blocks.toList
m.code.blocks.foreach { b =>
- in(b) = lattice.bottom;
- out(b) = lattice.bottom;
+ in(b) = lattice.bottom
+ out(b) = lattice.bottom
}
}
}
- import opcodes._;
+ import opcodes._
/** Return the gen and kill sets for this block. */
def genAndKill(b: BasicBlock): Pair[Set[Local], Set[Local]] = {
- var genSet = new ListSet[Local];
- var killSet = new ListSet[Local];
+ var genSet = new ListSet[Local]
+ var killSet = new ListSet[Local]
for (val i <- b.toList) i match {
- case LOAD_LOCAL(local) if (!killSet(local)) => genSet = genSet + local;
- case STORE_LOCAL(local) => killSet = killSet + local;
- case _ => ();
+ case LOAD_LOCAL(local) if (!killSet(local)) => genSet = genSet + local
+ case STORE_LOCAL(local) => killSet = killSet + local
+ case _ => ()
}
Pair(genSet, killSet)
}
override def run: Unit = {
- backwardAnalysis(blockTransfer);
+ backwardAnalysis(blockTransfer)
if (settings.debug.value) {
linearizer.linearize(method).foreach(b => if (b != method.code.startBlock)
assert(in(b) != lattice.bottom,
@@ -82,17 +89,17 @@ abstract class Liveness {
/** Abstract interpretation for one instruction. */
def interpret(out: lattice.Elem, i: Instruction): lattice.Elem = {
- var in = out;
+ var in = out
if (settings.debug.value) {
- log("- " + i);
- log("out: " + out);
- log("\n");
+ log("- " + i)
+ log("out: " + out)
+ log("\n")
}
i match {
- case LOAD_LOCAL(l) => in = in + l;
- case STORE_LOCAL(l) => in = in - l;
+ case LOAD_LOCAL(l) => in = in + l
+ case STORE_LOCAL(l) => in = in - l
case _ =>
()
}
@@ -100,7 +107,7 @@ abstract class Liveness {
} /* def interpret */
override def toString(): String = {
- val buf = new StringBuilder();
+ val buf = new StringBuilder()
for (val b <- method.code.blocks.toList) {
buf.append("\nlive-in(" + b + ")=" + in(b) + "\nlive-out(" + b + ")=" + out(b));
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/LubError.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/LubError.scala
index 0271f8ebea..40d8be1b8a 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/LubError.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/LubError.scala
@@ -1,5 +1,12 @@
-package scala.tools.nsc.backend.icode.analysis;
+/* NSC -- new Scala compiler
+ * Copyright 2005-2007 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+// $Id$
+
+package scala.tools.nsc.backend.icode.analysis
class LubError(a: Any, b: Any, msg: String) extends Exception {
- override def toString() = "Lub error: " + msg + a + b;
+ override def toString() = "Lub error: " + msg + a + b
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
index f873ae44d7..fcb369615e 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/analysis/TypeFlowAnalysis.scala
@@ -1,39 +1,48 @@
-package scala.tools.nsc.backend.icode.analysis;
+/* NSC -- new Scala compiler
+ * Copyright 2005-2007 LAMP/EPFL
+ * @author Martin Odersky
+ */
+
+// $Id$
+
+package scala.tools.nsc.backend.icode.analysis
-import scala.collection.mutable.{Map, HashMap};
+import scala.collection.mutable.{Map, HashMap}
/** A data-flow analysis on types, that works on ICode.
+ *
+ * @author Iulian Dragos
*/
abstract class TypeFlowAnalysis {
- val global: Global;
- import global._;
+ val global: Global
+ import global._
/** The lattice of ICode types.
*/
object typeLattice extends CompleteLattice {
- type Elem = icodes.TypeKind;
+ type Elem = icodes.TypeKind
- val Object = icodes.REFERENCE(global.definitions.ObjectClass);
- val All = icodes.REFERENCE(global.definitions.AllClass);
+ val Object = icodes.REFERENCE(global.definitions.ObjectClass)
+ val All = icodes.REFERENCE(global.definitions.AllClass)
- def top = Object;
- def bottom = All;
+ def top = Object
+ def bottom = All
def lub2(a: Elem, b: Elem) =
if (a eq bottom) b
else if (b eq bottom) a
- else icodes.lub(a, b);
+ else icodes.lub(a, b)
}
/** The lattice of type stacks. It is a straight forward extension of
* the type lattice (lub is pairwise lub of the list elements).
*/
object typeStackLattice extends CompleteLattice {
- import icodes._;
- type Elem = TypeStack;
+ import icodes._
+ type Elem = TypeStack
- override val top = new TypeStack;
- override val bottom = new TypeStack;
+ override val top = new TypeStack
+ override val bottom = new TypeStack
def lub2(s1: TypeStack, s2: TypeStack) = {
if (s1 eq bottom) s2
@@ -54,7 +63,7 @@ abstract class TypeFlowAnalysis {
}
def this(o: VarBinding) = {
- this();
+ this()
this ++= o
}
}
@@ -63,30 +72,30 @@ abstract class TypeFlowAnalysis {
* names to types and a type stack.
*/
object typeFlowLattice extends CompleteLattice {
- import icodes._;
+ import icodes._
type Elem = Pair[VarBinding, icodes.TypeStack]
override val top = new Pair(new VarBinding, typeStackLattice.top) {
- override def equals(that: Any) = (this eq that.asInstanceOf[AnyRef]);
+ override def equals(that: Any) = (this eq that.asInstanceOf[AnyRef])
}
override val bottom = new Pair(new VarBinding, typeStackLattice.bottom) {
- override def equals(that: Any) = (this eq that.asInstanceOf[AnyRef]);
+ override def equals(that: Any) = (this eq that.asInstanceOf[AnyRef])
}
def lub2(a: Elem, b: Elem) = {
- val Pair(env1, s1) = a;
- val Pair(env2, s2) = b;
+ val Pair(env1, s1) = a
+ val Pair(env2, s2) = b
- val resultingLocals = new VarBinding;
+ val resultingLocals = new VarBinding
for (val binding1 <- env1.elements) {
- val tp2 = env2(binding1._1);
- resultingLocals += binding1._1 -> typeLattice.lub2(binding1._2, tp2);
+ val tp2 = env2(binding1._1)
+ resultingLocals += binding1._1 -> typeLattice.lub2(binding1._2, tp2)
}
for (val binding2 <- env2.elements; resultingLocals(binding2._1) eq typeLattice.bottom) {
- val tp1 = env1(binding2._1);
- resultingLocals += binding2._1 -> typeLattice.lub2(binding2._2, tp1);
+ val tp1 = env1(binding2._1)
+ resultingLocals += binding2._1 -> typeLattice.lub2(binding2._2, tp1)
}
Pair(resultingLocals, typeStackLattice.lub2(a._2, b._2))
@@ -94,42 +103,42 @@ abstract class TypeFlowAnalysis {
}
class MethodTFA extends DataFlowAnalysis[typeFlowLattice.type] {
- import icodes._;
- import icodes.opcodes._;
+ import icodes._
+ import icodes.opcodes._
- type P = BasicBlock;
- val lattice = typeFlowLattice;
+ type P = BasicBlock
+ val lattice = typeFlowLattice
- val STRING = icodes.REFERENCE(TypeFlowAnalysis.this.global.definitions.StringClass);
- var method: IMethod = _;
+ val STRING = icodes.REFERENCE(TypeFlowAnalysis.this.global.definitions.StringClass)
+ var method: IMethod = _
/** Initialize the in/out maps for the analysis of the given method. */
def init(m: icodes.IMethod): Unit = {
- this.method = m;
+ this.method = m
init {
- worklist += m.code.startBlock;
- worklist ++= (m.exh map (.startBlock));
+ worklist += m.code.startBlock
+ worklist ++= (m.exh map (.startBlock))
m.code.blocks.foreach { b =>
- in(b) = typeFlowLattice.bottom;
- out(b) = typeFlowLattice.bottom;
+ in(b) = typeFlowLattice.bottom
+ out(b) = typeFlowLattice.bottom
}
m.exh foreach { e =>
- val stack = new TypeStack;
+ val stack = new TypeStack
stack.push(
- REFERENCE(if (e.cls eq NoSymbol) definitions.ObjectClass else e.cls));
- in(e.startBlock) = Pair(in(e.startBlock)._1, stack);
+ REFERENCE(if (e.cls eq NoSymbol) definitions.ObjectClass else e.cls))
+ in(e.startBlock) = Pair(in(e.startBlock)._1, stack)
}
}
}
def this(m: icodes.IMethod) = {
- this();
+ this()
init(m)
}
def run = {
- forwardAnalysis(blockTransfer);
+ forwardAnalysis(blockTransfer)
if (settings.debug.value) {
linearizer.linearize(method).foreach(b => if (b != method.code.startBlock)
assert(visited.contains(b),
@@ -137,15 +146,14 @@ abstract class TypeFlowAnalysis {
}
}
- def blockTransfer(b: BasicBlock, in: lattice.Elem): lattice.Elem = {
+ def blockTransfer(b: BasicBlock, in: lattice.Elem): lattice.Elem =
b.toList.foldLeft(in)(interpret)
- }
/** Abstract interpretation for one instruction. */
def interpret(in: typeFlowLattice.Elem, i: Instruction): typeFlowLattice.Elem = {
- val out = Pair(new VarBinding(in._1), new TypeStack(in._2));
- val bindings = out._1;
- val stack = out._2;
+ val out = Pair(new VarBinding(in._1), new TypeStack(in._2))
+ val bindings = out._1
+ val stack = out._2
/* if (settings.debug.value) {
Console.println("Stack: " + stack);
@@ -154,103 +162,104 @@ abstract class TypeFlowAnalysis {
i match {
case THIS(clasz) =>
- stack push toTypeKind(clasz.tpe);
+ stack push toTypeKind(clasz.tpe)
case CONSTANT(const) =>
- stack push toTypeKind(const.tpe);
+ stack push toTypeKind(const.tpe)
case LOAD_ARRAY_ITEM(kind) =>
- val Pair(INT, ARRAY(elem)) = stack.pop2;
- stack.push(elem);
+ val Pair(INT, ARRAY(elem)) = stack.pop2
+ stack.push(elem)
case LOAD_LOCAL(local) =>
- val t = bindings(local);
- stack push (if (t == typeLattice.bottom) local.kind else t);
+ val t = bindings(local)
+ stack push (if (t == typeLattice.bottom) local.kind else t)
case LOAD_FIELD(field, isStatic) =>
if (!isStatic)
- stack.pop;
- stack push toTypeKind(field.tpe);
+ stack.pop
+ stack push toTypeKind(field.tpe)
case LOAD_MODULE(module) =>
- stack push toTypeKind(module.tpe);
+ stack push toTypeKind(module.tpe)
case STORE_ARRAY_ITEM(kind) =>
- stack.pop3;
+ stack.pop3
case STORE_LOCAL(local) =>
- val t = stack.pop;
- bindings += local -> t;
+ val t = stack.pop
+ bindings += local -> t
case STORE_FIELD(field, isStatic) =>
if (isStatic)
stack.pop
else
- stack.pop2;
+ stack.pop2
case CALL_PRIMITIVE(primitive) =>
- primitive match {
- case Negation(kind) => stack.pop; stack.push(kind);
+ primitive match {
+ case Negation(kind) =>
+ stack.pop; stack.push(kind)
case Test(_, kind, zero) =>
- stack.pop;
- if (!zero) stack.pop;
+ stack.pop
+ if (!zero) stack.pop
stack push BOOL;
case Comparison(_, _) =>
- stack.pop2;
- stack push INT;
+ stack.pop2
+ stack push INT
case Arithmetic(op, kind) =>
- stack.pop;
+ stack.pop
if (op != NOT)
- stack.pop;
- stack push kind;
+ stack.pop
+ stack push kind
- case Logical(op, kind) =>
- stack.pop2;
- stack push kind;
+ case Logical(op, kind) =>
+ stack.pop2
+ stack push kind
- case Shift(op, kind) =>
- stack.pop2;
- stack push kind;
+ case Shift(op, kind) =>
+ stack.pop2
+ stack push kind
- case Conversion(src, dst) =>
- stack.pop;
- stack push dst;
+ case Conversion(src, dst) =>
+ stack.pop
+ stack push dst
- case ArrayLength(kind) =>
- stack.pop;
- stack push INT;
+ case ArrayLength(kind) =>
+ stack.pop
+ stack push INT
- case StartConcat =>
- stack.push(ConcatClass);
+ case StartConcat =>
+ stack.push(ConcatClass)
- case EndConcat =>
- stack.pop;
- stack.push(STRING);
+ case EndConcat =>
+ stack.pop
+ stack.push(STRING)
- case StringConcat(el) =>
- stack.pop2;
- stack push ConcatClass;
+ case StringConcat(el) =>
+ stack.pop2
+ stack push ConcatClass
}
case CALL_METHOD(method, style) => style match {
case Dynamic =>
- stack.pop(1 + method.info.paramTypes.length);
- stack.push(toTypeKind(method.info.resultType));
+ stack.pop(1 + method.info.paramTypes.length)
+ stack.push(toTypeKind(method.info.resultType))
case Static(onInstance) =>
if (onInstance) {
- stack.pop(1 + method.info.paramTypes.length);
+ stack.pop(1 + method.info.paramTypes.length)
if (!method.isConstructor)
stack.push(toTypeKind(method.info.resultType));
} else {
- stack.pop(method.info.paramTypes.length);
- stack.push(toTypeKind(method.info.resultType));
+ stack.pop(method.info.paramTypes.length)
+ stack.push(toTypeKind(method.info.resultType))
}
case SuperCall(mix) =>
- stack.pop(1 + method.info.paramTypes.length);
- stack.push(toTypeKind(method.info.resultType));
+ stack.pop(1 + method.info.paramTypes.length)
+ stack.push(toTypeKind(method.info.resultType))
}
case BOX(kind) =>
@@ -262,57 +271,57 @@ abstract class TypeFlowAnalysis {
stack.push(kind)
case NEW(kind) =>
- stack.push(kind);
+ stack.push(kind)
case CREATE_ARRAY(elem) =>
- stack.pop;
- stack.push(ARRAY(elem));
+ stack.pop
+ stack.push(ARRAY(elem))
case IS_INSTANCE(tpe) =>
- stack.pop
- stack.push(BOOL);
+ stack.pop
+ stack.push(BOOL)
case CHECK_CAST(tpe) =>
- stack.pop;
- stack.push(tpe);
+ stack.pop
+ stack.push(tpe)
case SWITCH(tags, labels) =>
- stack.pop;
+ stack.pop
case JUMP(where) =>
- ()
+ ()
case CJUMP(success, failure, cond, kind) =>
- stack.pop2;
+ stack.pop2
case CZJUMP(success, failure, cond, kind) =>
- stack.pop;
+ stack.pop
case RETURN(kind) =>
if (kind != UNIT)
stack.pop;
case THROW() =>
- stack.pop;
+ stack.pop
case DROP(kind) =>
- stack.pop;
+ stack.pop
case DUP(kind) =>
- stack.push(stack.head);
+ stack.push(stack.head)
case MONITOR_ENTER() =>
- stack.pop;
+ stack.pop
case MONITOR_EXIT() =>
- stack.pop;
+ stack.pop
case _ =>
- dump;
- abort("Unknown instruction: " + i);
+ dump
+ abort("Unknown instruction: " + i)
}
out
- }
+ } // interpret
}
}
diff --git a/src/compiler/scala/tools/nsc/doc/DocGenerator.scala b/src/compiler/scala/tools/nsc/doc/DocGenerator.scala
index b591b499bb..7b2f4f059f 100644
--- a/src/compiler/scala/tools/nsc/doc/DocGenerator.scala
+++ b/src/compiler/scala/tools/nsc/doc/DocGenerator.scala
@@ -843,7 +843,7 @@ abstract class DocGenerator extends Models {
<option value="#Objects">Objects</option>
<option value="#Traits">Traits</option>
</select>
- <span style="word-spacing:-3px;">
+ <span style="font-family:Courier;word-spacing:-8px;">
<a href={Unparsed("javascript:gotoName('A')")}>A</a>
<a href={Unparsed("javascript:gotoName('B')")}>B</a>
<a href={Unparsed("javascript:gotoName('C')")}>C</a>