diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2006-02-14 12:50:40 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2006-02-14 12:50:40 +0000 |
commit | 2197e9485a681f72068c5768263bcd1757664775 (patch) | |
tree | 3bc2b962af4209f182925724ec7f089ca91a3bb9 /src/compiler/scala/tools/nsc/backend/icode | |
parent | 9392e582986c3d54cde992c3141b52c97f7d6e16 (diff) | |
download | scala-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')
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; } |