Skip to content

Commit 736a768

Browse files
committed
doc frontend and refactor
1 parent f5bcd31 commit 736a768

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

48 files changed

+1153
-614
lines changed

src/main/scala/decaf/Main.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -3,5 +3,6 @@ package decaf
33
import decaf.driver.Launcher
44

55
object Main {
6+
67
def main(args: Array[String]): Unit = Launcher.withArgs(args)
78
}

src/main/scala/decaf/backend/asm/Asm.scala

Lines changed: 14 additions & 2 deletions
Original file line numberDiff line numberDiff line change
@@ -18,8 +18,15 @@ import decaf.util.Conversions._
1818
* @param emitter helper assembly code emitter
1919
* @param regAlloc register allocator
2020
*/
21-
class Asm(val emitter: AsmEmitter, val regAlloc: RegAlloc) extends Phase[TacProg, String]("asm: " + emitter) {
21+
class Asm(val emitter: AsmEmitter, val regAlloc: RegAlloc)(implicit config: Config)
22+
extends Phase[TacProg, String]("asm: " + emitter, config) {
2223

24+
/**
25+
* Transformer entry.
26+
*
27+
* @param prog a TAC program
28+
* @return a string representing the emitted assembly code
29+
*/
2330
override def transform(prog: TacProg): String = {
2431
Log.info("phase: asm")
2532
val analyzer = new LivenessAnalyzer[PseudoInstr]
@@ -42,7 +49,12 @@ class Asm(val emitter: AsmEmitter, val regAlloc: RegAlloc) extends Phase[TacProg
4249
emitter.emitEnd()
4350
}
4451

45-
override def onSucceed(code: String)(implicit config: Config): Unit = {
52+
/**
53+
* After emitting the assembly code, output it to file.
54+
*
55+
* @param code assembly code
56+
*/
57+
override def onSucceed(code: String): Unit = {
4658
if (config.target.equals(Config.Target.PA5)) {
4759
val path = config.dstDir / config.sourceBaseName + ".s"
4860
val printer = new PrintWriter(path)

src/main/scala/decaf/backend/asm/AsmEmitter.scala

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -4,7 +4,6 @@ import decaf.lowlevel.AsmCodePrinter
44
import decaf.lowlevel.instr.{PseudoInstr, Reg}
55
import decaf.lowlevel.tac.{TacFunc, VTable}
66

7-
87
/**
98
* Emit assembly code.
109
*
@@ -13,6 +12,7 @@ import decaf.lowlevel.tac.{TacFunc, VTable}
1312
* @param callerSaveRegs platform-specific registers that need be saved by caller.
1413
*/
1514
abstract class AsmEmitter(val platformName: String, val allocatableRegs: Array[Reg], val callerSaveRegs: Array[Reg]) {
15+
1616
/**
1717
* Emit assembly code for a virtual table.
1818
*

src/main/scala/decaf/backend/asm/Holes.scala

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,10 +11,12 @@ import decaf.lowlevel.instr.{PseudoInstr, Temp}
1111
object Holes {
1212

1313
object CallerSave extends PseudoInstr(new Array[Temp](0), new Array[Temp](0)) {
14+
1415
override def toString: String = "# TODO: caller save"
1516
}
1617

1718
object CallerRestore extends PseudoInstr(new Array[Temp](0), new Array[Temp](0)) {
19+
1820
override def toString: String = "# TODO: caller restore"
1921
}
2022

src/main/scala/decaf/backend/asm/SubroutineEmitter.scala

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -11,6 +11,7 @@ import decaf.lowlevel.label.Label
1111
* @param info basic info of this subroutine
1212
*/
1313
abstract class SubroutineEmitter protected(val emitter: AsmEmitter, var info: SubroutineInfo) {
14+
1415
/**
1516
* Append an assembly instruction that stores the value of a register to stack.
1617
*

src/main/scala/decaf/backend/asm/mips/MipsAsmEmitter.scala

Lines changed: 9 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -10,7 +10,6 @@ import decaf.util.Conversions._
1010

1111
import scala.collection.mutable
1212

13-
1413
/**
1514
* Emit MIPS assembly code.
1615
*/
@@ -24,7 +23,9 @@ final class MipsAsmEmitter extends AsmEmitter("mips", Mips.allocatableRegs, Mips
2423
val parent = vtbl.parent.get
2524
printer.println(".word %s # parent: %s", parent.label, parent.className)
2625
}
27-
else printer.println(".word 0 # parent: none")
26+
else {
27+
printer.println(".word 0 # parent: none")
28+
}
2829
val index = pool.add(vtbl.className)
2930
printer.println(".word %s%d # class name", STR_PREFIX, index)
3031
vtbl.getItems.forEach { entry =>
@@ -149,6 +150,7 @@ final class MipsAsmEmitter extends AsmEmitter("mips", Mips.allocatableRegs, Mips
149150
}
150151

151152
private class MipsInstrSelector private[mips](var entry: Label) extends TacInstr.Visitor {
153+
152154
private[mips] val seq = new mutable.ArrayBuffer[PseudoInstr]
153155
private[mips] var maxArgs = 0
154156
private var argCount = 0
@@ -216,8 +218,11 @@ final class MipsAsmEmitter extends AsmEmitter("mips", Mips.allocatableRegs, Mips
216218
}
217219

218220
override def visitParm(instr: TacInstr.Parm): Unit = {
219-
if (argCount < 4) seq += new Mips.Move(Mips.argRegs(argCount), instr.value)
220-
else seq += new Mips.StoreWord(instr.value, Mips.SP, argCount * 4)
221+
if (argCount < 4) {
222+
seq += new Mips.Move(Mips.argRegs(argCount), instr.value)
223+
} else {
224+
seq += new Mips.StoreWord(instr.value, Mips.SP, argCount * 4)
225+
}
221226
argCount += 1
222227
}
223228

src/main/scala/decaf/backend/asm/mips/MipsSubroutineEmitter.scala

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -33,12 +33,14 @@ class MipsSubroutineEmitter private[mips](emitter: MipsAsmEmitter, info: Subrout
3333
extends SubroutineEmitter(emitter, info) {
3434

3535
override def emitStoreToStack(src: Reg, temp: Temp): Unit = {
36-
if (!offsets.contains(temp)) if (temp.index < info.numArgs) { // Always map arg `i` to `SP + 4 * i`.
37-
offsets(temp) = 4 * temp.index
38-
}
39-
else {
40-
offsets(temp) = nextLocalOffset
41-
nextLocalOffset += 4
36+
if (!offsets.contains(temp)) {
37+
if (temp.index < info.numArgs) { // Always map arg `i` to `SP + 4 * i`.
38+
offsets(temp) = 4 * temp.index
39+
}
40+
else {
41+
offsets(temp) = nextLocalOffset
42+
nextLocalOffset += 4
43+
}
4244
}
4345
buf += new Mips.NativeStoreWord(src, Mips.SP, offsets(temp))
4446
}
@@ -77,7 +79,9 @@ class MipsSubroutineEmitter private[mips](emitter: MipsAsmEmitter, info: Subrout
7779
for {
7880
(reg, i) <- Mips.calleeSaved.zipWithIndex
7981
if used(reg)
80-
} printer.printInstr(new Mips.NativeStoreWord(reg, Mips.SP, info.argsSize + 4 * i), "save value of " + reg)
82+
} {
83+
printer.printInstr(new Mips.NativeStoreWord(reg, Mips.SP, info.argsSize + 4 * i), "save value of " + reg)
84+
}
8185
printer.printComment("end of prologue")
8286
printer.println()
8387

@@ -94,8 +98,10 @@ class MipsSubroutineEmitter private[mips](emitter: MipsAsmEmitter, info: Subrout
9498
for {
9599
(reg, i) <- Mips.calleeSaved.zipWithIndex
96100
if used(reg)
97-
} printer.printInstr(new Mips.NativeLoadWord(Mips.calleeSaved(i), Mips.SP, info.argsSize + 4 * i),
98-
"restore value of $S" + i)
101+
} {
102+
printer.printInstr(new Mips.NativeLoadWord(Mips.calleeSaved(i), Mips.SP, info.argsSize + 4 * i),
103+
"restore value of $S" + i)
104+
}
99105
if (info.hasCalls) {
100106
printer.printInstr(new Mips.NativeLoadWord(Mips.RA, Mips.SP, info.argsSize + 32), "restore the return address")
101107
}

src/main/scala/decaf/backend/dataflow/BasicBlock.scala

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -12,6 +12,7 @@ import scala.collection.mutable
1212
* @tparam I type of the instructions stored in the block
1313
*/
1414
trait BasicBlock[I <: PseudoInstr] extends Iterable[Loc[I]] {
15+
1516
/**
1617
* Id, MUST be unique in one control flow graph.
1718
*/
@@ -70,6 +71,7 @@ trait BasicBlock[I <: PseudoInstr] extends Iterable[Loc[I]] {
7071
*/
7172
case class ContinuousBasicBlock[I <: PseudoInstr](id: Int, label: Option[Label], instrSeq: List[Loc[I]])
7273
extends BasicBlock[I] {
74+
7375
override def iterator: Iterator[Loc[I]] = instrSeq.iterator
7476

7577
override def seqIterator: Iterator[Loc[I]] = instrSeq.iterator
@@ -87,6 +89,7 @@ case class ContinuousBasicBlock[I <: PseudoInstr](id: Int, label: Option[Label],
8789
*/
8890
case class EndByJumpBasicBlock[I <: PseudoInstr](id: Int, label: Option[Label], sequential: List[Loc[I]],
8991
jump: Loc[I]) extends BasicBlock[I] {
92+
9093
override def iterator: Iterator[Loc[I]] = (sequential :+ jump).iterator
9194

9295
override def seqIterator: Iterator[Loc[I]] = sequential.iterator
@@ -107,6 +110,7 @@ case class EndByJumpBasicBlock[I <: PseudoInstr](id: Int, label: Option[Label],
107110
*/
108111
case class EndByCondJumpBasicBlock[I <: PseudoInstr](id: Int, label: Option[Label], sequential: List[Loc[I]],
109112
jump: Loc[I]) extends BasicBlock[I] {
113+
110114
override def iterator: Iterator[Loc[I]] = (sequential :+ jump).iterator
111115

112116
override def seqIterator: Iterator[Loc[I]] = sequential.iterator
@@ -126,6 +130,7 @@ case class EndByCondJumpBasicBlock[I <: PseudoInstr](id: Int, label: Option[Labe
126130
*/
127131
case class EndByReturnBasicBlock[I <: PseudoInstr](id: Int, label: Option[Label], sequential: List[Loc[I]],
128132
ret: Loc[I]) extends BasicBlock[I] {
133+
129134
override def iterator: Iterator[Loc[I]] = (sequential :+ ret).iterator
130135

131136
override def seqIterator: Iterator[Loc[I]] = sequential.iterator

src/main/scala/decaf/backend/dataflow/CFG.scala

Lines changed: 4 additions & 3 deletions
Original file line numberDiff line numberDiff line change
@@ -20,7 +20,6 @@ import scala.collection.mutable
2020
class CFG[I <: PseudoInstr](nodes: List[BasicBlock[I]], edges: List[(Int, Int)])
2121
extends Iterable[BasicBlock[I]] {
2222

23-
2423
/**
2524
* Get basic block by id.
2625
*
@@ -92,6 +91,7 @@ class CFG[I <: PseudoInstr](nodes: List[BasicBlock[I]], edges: List[(Int, Int)])
9291
}
9392

9493
object CFG {
94+
9595
/**
9696
* Build a control flow graph from a sequence of instructions (in one function/subroutine).
9797
*
@@ -102,8 +102,9 @@ object CFG {
102102

103103
@scala.annotation.tailrec
104104
def build(seq: List[I], label: Option[Label], bbs: List[BasicBlock[I]]): List[BasicBlock[I]] = {
105-
if (seq.isEmpty) bbs
106-
else {
105+
if (seq.isEmpty) {
106+
bbs
107+
} else {
107108
val (sequential, remainder) = seq.span(_.isSequential)
108109
assert(remainder.nonEmpty)
109110
val end :: rest = remainder

src/main/scala/decaf/backend/dataflow/LivenessAnalyzer.scala

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -5,6 +5,7 @@ import decaf.lowlevel.instr.{PseudoInstr, Temp}
55
import scala.collection.mutable
66

77
class LivenessAnalyzer[I <: PseudoInstr] extends Function[CFG[I], Unit] {
8+
89
override def apply(graph: CFG[I]): Unit = {
910
for (bb <- graph) {
1011
computeDefAndLiveUseFor(bb)
@@ -54,7 +55,9 @@ class LivenessAnalyzer[I <: PseudoInstr] extends Function[CFG[I], Unit] {
5455
loc.instr.getWritten.forEach(bb.`def`.add)
5556
loc.instr.getRead.forEach { t =>
5657
if (!bb.`def`.contains(t)) // used before being assigned to a value
58+
{
5759
bb.liveUse.add(t)
60+
}
5861
}
5962
}
6063
}

0 commit comments

Comments
 (0)