diff options
author | Iulian Dragos <jaguarul@gmail.com> | 2005-09-23 16:04:36 +0000 |
---|---|---|
committer | Iulian Dragos <jaguarul@gmail.com> | 2005-09-23 16:04:36 +0000 |
commit | cb95310d8689cb78b783b13222996938f39cb8ee (patch) | |
tree | 3e6cf97fe7613c00afde91ca747bd428274a63ea /sources | |
parent | 4a72b68fe32818b2532308536a91a0e573590ab9 (diff) | |
download | scala-cb95310d8689cb78b783b13222996938f39cb8ee.tar.gz scala-cb95310d8689cb78b783b13222996938f39cb8ee.tar.bz2 scala-cb95310d8689cb78b783b13222996938f39cb8ee.zip |
Initial commit.
Diffstat (limited to 'sources')
-rw-r--r-- | sources/scala/tools/nsc/backend/icode/Linearizers.scala | 71 |
1 files changed, 71 insertions, 0 deletions
diff --git a/sources/scala/tools/nsc/backend/icode/Linearizers.scala b/sources/scala/tools/nsc/backend/icode/Linearizers.scala new file mode 100644 index 0000000000..be6e9548f2 --- /dev/null +++ b/sources/scala/tools/nsc/backend/icode/Linearizers.scala @@ -0,0 +1,71 @@ +/* NSC -- new scala compiler + * Copyright 2005 LAMP/EPFL + * @author Martin Odersky + */ + +// $Id$ + +package scala.tools.nsc.backend.icode; + +import scala.tools.nsc.ast._; +import scala.collection.mutable.Queue; + +trait Linearizers: ICodes { + import opcodes._; + + trait Linearizer { + def linearize(c: Code): List[BasicBlock]; + } + + /** + * A simple linearizer which predicts all branches to + * take the 'success' branch and tries to schedule those + * blocks immediately after the test. This is in sync with + * how 'while' statements are translated (if the test is + * 'true', the loop continues). + */ + class NormalLinearizer extends Linearizer with WorklistAlgorithm { + type Elem = BasicBlock; + val worklist: Queue[Elem] = new Queue(); + + var blocks: List[BasicBlock] = Nil; + + def linearize(c: Code): List[BasicBlock] = { + val b = c.startBlock; + blocks = b :: Nil; + + run( { worklist.enqueue(b); } ); + blocks.reverse; + } + + def processElement(b: BasicBlock) = + b.lastInstruction match { + case JUMP(where) => + add(where); + case CJUMP(success, failure, _, _) => + add(success); + add(failure); + case CZJUMP(success, failure, _, _) => + add(success); + add(failure); + case SWITCH(_, labels) => + add(labels); + case RETURN() => + () + } + + /** + * Prepend b to the list, if not already scheduled. + * TODO: use better test than linear search + */ + def add(b: BasicBlock) = + if (blocks.contains(b)) + () + else { + blocks = b :: blocks; + worklist enqueue b; + } + + def add(bs: List[BasicBlock]): Unit = bs foreach add; + } +} |