summaryrefslogtreecommitdiff
path: root/src/compiler/scala/tools/nsc/backend/icode
diff options
context:
space:
mode:
authorIulian Dragos <jaguarul@gmail.com>2006-02-14 12:50:40 +0000
committerIulian Dragos <jaguarul@gmail.com>2006-02-14 12:50:40 +0000
commit2197e9485a681f72068c5768263bcd1757664775 (patch)
tree3bc2b962af4209f182925724ec7f089ca91a3bb9 /src/compiler/scala/tools/nsc/backend/icode
parent9392e582986c3d54cde992c3141b52c97f7d6e16 (diff)
downloadscala-2197e9485a681f72068c5768263bcd1757664775.tar.gz
scala-2197e9485a681f72068c5768263bcd1757664775.tar.bz2
scala-2197e9485a681f72068c5768263bcd1757664775.zip
Refactored ICode and added basic inlining capab...
Refactored ICode and added basic inlining capabilities.
Diffstat (limited to 'src/compiler/scala/tools/nsc/backend/icode')
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala24
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Checkers.scala2
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/GenICode.scala24
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/ICodes.scala17
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala9
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Members.scala23
-rw-r--r--src/compiler/scala/tools/nsc/backend/icode/Printers.scala6
7 files changed, 61 insertions, 44 deletions
diff --git a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
index 83128a8274..aa42da4273 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/BasicBlocks.scala
@@ -57,7 +57,10 @@ mixin class BasicBlocks requires ICodes {
/** Apply a function to all the instructions of the block. */
def traverse(f: Instruction => unit) = {
- assert(closed, "Traversing an open block!: ");
+ if (!closed) {
+ dump;
+ global.abort("Traversing an open block!: " + label);
+ }
instrs foreach f;
}
@@ -160,7 +163,6 @@ mixin class BasicBlocks requires ICodes {
assert (!closed || ignore, "BasicBlock closed");
if (!ignore) {
-// Console.println("block " + label + ": " + instr);
instr.pos = pos;
instructionList = instr :: instructionList;
_lastInstruction = instr;
@@ -172,7 +174,19 @@ mixin class BasicBlocks requires ICodes {
assert(instructionList.length > 0,
"Empty block.");
closed = true;
- instrs = toInstructionArray(instructionList.reverse);
+ instructionList = instructionList.reverse;
+ instrs = toInstructionArray(instructionList);
+ }
+
+ def open = {
+ closed = false;
+ }
+
+ def instructions: List[Instruction] = instructionList;
+
+ def clear: Unit = {
+ instructionList = Nil;
+ instrs = null;
}
def isEmpty: Boolean = instructionList.isEmpty;
@@ -222,8 +236,10 @@ mixin class BasicBlocks requires ICodes {
case RETURN(_) => Nil;
case THROW() => Nil;
case _ =>
- if (isClosed)
+ if (isClosed) {
+ dump;
global.abort("The last instruction is not a control flow instruction: " + lastInstruction);
+ }
else Nil;
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala b/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala
index 00741a1e0e..0963a89bc9 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Checkers.scala
@@ -59,7 +59,7 @@ abstract class Checkers {
def checkICodes: Unit = {
Console.println("[[consistency check at beginning of phase " + globalPhase.name + "]]");
- classes foreach check;
+ classes.values foreach check;
}
def check(cls: IClass): Unit = {
diff --git a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
index 553a797f93..23b1584c82 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/GenICode.scala
@@ -75,7 +75,7 @@ abstract class GenICode extends SubComponent {
log("Generating class: " + tree.symbol.fullNameString);
ctx setClass (new IClass(tree.symbol) setCompilationUnit unit);
addClassFields(ctx, tree.symbol);
- classes = ctx.clazz :: classes;
+ classes += tree.symbol -> ctx.clazz;
gen(impl, ctx);
ctx setClass null;
@@ -83,13 +83,6 @@ abstract class GenICode extends SubComponent {
case ModuleDef(mods, name, impl) =>
abort("Modules should not reach backend!");
- log("Generating module: " + tree.symbol.fullNameString);
- ctx setClass (new IClass(tree.symbol) setCompilationUnit unit);
- addClassFields(ctx, tree.symbol);
- classes = ctx.clazz :: classes;
- gen(impl, ctx);
- ctx setClass null;
-
case ValDef(mods, name, tpt, rhs) => ctx; // we use the symbol to add fields
case DefDef(mods, name, tparams, vparamss, tpt, rhs) =>
@@ -646,7 +639,7 @@ abstract class GenICode extends SubComponent {
log("synchronized block start");
ctx1 = ctx1.Try(
bodyCtx => {
- val ctx1 = genLoad(args.head, bodyCtx, toTypeKind(tree.tpe.resultType));
+ val ctx1 = genLoad(args.head, bodyCtx, expectedType /* toTypeKind(tree.tpe.resultType) */);
ctx1.bb.emit(LOAD_LOCAL(monitor, false));
ctx1.bb.emit(MONITOR_EXIT(), tree.pos);
ctx1
@@ -655,6 +648,7 @@ abstract class GenICode extends SubComponent {
exhCtx.bb.emit(LOAD_LOCAL(monitor, false));
exhCtx.bb.emit(MONITOR_EXIT(), tree.pos);
exhCtx.bb.emit(THROW());
+ exhCtx.bb.enterIgnoreMode;
exhCtx
})));
if (settings.debug.value)
@@ -1303,20 +1297,21 @@ abstract class GenICode extends SubComponent {
if (block.size == 1 && optCont != None) {
val Some(cont) = optCont;
val pred = block.predecessors;
- log("Preds: " + pred + " of " + block);
+ log("Preds: " + pred + " of " + block + " (" + optCont + ")");
pred foreach { p =>
p.lastInstruction match {
case CJUMP(succ, fail, cond, kind) =>
if (settings.debug.value)
log("Pruning empty if branch.");
changed = true;
- p.replaceInstruction(p.lastInstruction,
+ assert(p.replaceInstruction(p.lastInstruction,
if (block == succ)
CJUMP(cont, fail, cond, kind)
else if (block == fail)
CJUMP(succ, cont, cond, kind)
else
- abort("Could not find block in preds"));
+ abort("Could not find block in preds")),
+ "Didn't find p.lastInstruction");
case CZJUMP(succ, fail, cond, kind) =>
if (settings.debug.value)
@@ -1334,7 +1329,8 @@ abstract class GenICode extends SubComponent {
if (settings.debug.value)
log("Pruning empty if branch.");
changed = true;
- p.replaceInstruction(p.lastInstruction, JUMP(cont));
+ assert(p.replaceInstruction(p.lastInstruction, JUMP(cont)),
+ "Didn't find p.lastInstruction");
case SWITCH(tags, labels) =>
if (settings.debug.value)
@@ -1632,6 +1628,8 @@ abstract class GenICode extends SubComponent {
case _ => instr;
}
}
+
+ override def toString() = symbol.toString();
}
///////////////// Fake instructions //////////////////////////
diff --git a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
index 99ecc1b1c2..03c9976437 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/ICodes.scala
@@ -7,7 +7,10 @@
package scala.tools.nsc.backend.icode;
+import java.io.PrintWriter;
+
import scala.tools.nsc.symtab._;
+import scala.collection.mutable.HashMap;
/** Glue together ICode parts.
*/
@@ -24,7 +27,7 @@ abstract class ICodes extends AnyRef
val global: Global;
/** The ICode representation of classes */
- var classes: List[IClass] = _;
+ var classes: HashMap[global.Symbol, IClass] = new HashMap();
/** The ICode linearizer. */
val linearizer: Linearizer =
@@ -37,6 +40,16 @@ abstract class ICodes extends AnyRef
else
global.abort("Unknown linearizer: " + global.settings.Xlinearizer.value);
- def init = { classes = Nil }
+
+ /** Print all classes and basic blocks. Used for debugging. */
+ def dump: Unit = {
+ val printer = new global.icodePrinter.TextPrinter(new PrintWriter(System.out, true),
+ new global.icodes.DumpLinearizer());
+
+ global.icodes.classes.values foreach { c => printer.printClass(c); }
+ }
+
+
+ def init = { }
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
index 52611fd4d5..ae326c0714 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Linearizers.scala
@@ -155,4 +155,13 @@ mixin class Linearizers requires ICodes {
if (!blocks.contains(b))
blocks = b :: blocks;
}
+
+ /** A 'dump' of the blocks in this method, which does not
+ * require any well-formedness of the basic blocks (like
+ * the last instruction being a jump).
+ */
+ class DumpLinearizer extends Linearizer {
+ def linearize(m: IMethod): List[BasicBlock] =
+ m.code.blocks.toList;
+ }
}
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Members.scala b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
index 28826a5439..02af695f37 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Members.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Members.scala
@@ -99,27 +99,6 @@ mixin class Members requires ICodes {
/** This methods returns a string representation of the ICode */
override def toString() : String = "ICode '" + label + "'";
- /** This method print the code */
-// def print() : unit = print(System.out);
-
-// def print(out: java.io.PrintStream) : unit = {
-// traverse((bb: BasicBlock) => {
-// out.println("Block #" + bb.label);
-// out.println("Substituable variables : ");
-// if (bb.substituteVars != null)
-// bb.substituteVars.foreach(out.print);
-// else
-// out.println(" {Empty} ");
-// out.println("Instructions:");
-// bb.traverse((ici: Instruction) =>
-// out.println(" "+ici.toString()));
-// out.print ("Successors: ");
-// bb.successors.foreach((bb: BasicBlock) => out.print(bb.label+", "));
-// out.println (""); // ?? Del
-// out.println ();
-// });
-// }
-
/* Compute a unique new label */
def nextLabel = {
currentLabel = currentLabel + 1;
@@ -159,6 +138,8 @@ mixin class Members requires ICodes {
override def toString() = symbol.fullNameString;
def lookupField(s: Symbol) = fields find ((f) => f.symbol == s);
+ def lookupMethod(s: Symbol) = methods find ((m) => m.symbol == s);
+ def lookupMethod(s: Name) = methods find ((m) => m.symbol.name == s);
}
/** Represent a field in ICode */
diff --git a/src/compiler/scala/tools/nsc/backend/icode/Printers.scala b/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
index 68ead723d7..7dbb3e1313 100644
--- a/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
+++ b/src/compiler/scala/tools/nsc/backend/icode/Printers.scala
@@ -18,7 +18,7 @@ abstract class Printers {
import global.icodes.opcodes._;
import global.icodes._;
- class TextPrinter(writer: PrintWriter) {
+ class TextPrinter(writer: PrintWriter, lin: Linearizer) {
var margin = 0;
var out = writer;
@@ -88,7 +88,7 @@ abstract class Printers {
println(" {");
println("locals: " + m.locals.mkString("", ", ", ""));
println;
- linearizer.linearize(m) foreach printBlock;
+ lin.linearize(m) foreach printBlock;
println("}");
indent;println("Exception handlers: ");
@@ -114,7 +114,7 @@ abstract class Printers {
def printBlock(bb: BasicBlock): Unit = {
print(bb.label); print(": "); indent; println;
- bb traverse printInstruction;
+ bb.instructions foreach printInstruction;
undent; println;
}