Skip to content

Commit 37c0e96

Browse files
committed
fix format of doc in backend
1 parent 736a768 commit 37c0e96

File tree

4 files changed

+34
-30
lines changed

4 files changed

+34
-30
lines changed

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

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -22,7 +22,7 @@ abstract class AsmEmitter(val platformName: String, val allocatableRegs: Array[R
2222

2323
/**
2424
* Instruction selection for a TAC function.
25-
* <p>
25+
*
2626
* Since no register allocation is done, the generated instructions may still contain pseudo registers (temps).
2727
*
2828
* @param func TAC function

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

Lines changed: 3 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -15,7 +15,7 @@ import scala.collection.mutable
1515
*/
1616
final class MipsAsmEmitter extends AsmEmitter("mips", Mips.allocatableRegs, Mips.callerSaved) {
1717

18-
override def emitVTable(vtbl: VTable): Unit = { // vtable begin
18+
override def emitVTable(vtbl: VTable): Unit = {
1919
printer.println(".data")
2020
printer.println(".align 2")
2121
printer.printLabel(vtbl.label, "virtual table for " + vtbl.className)
@@ -32,7 +32,6 @@ final class MipsAsmEmitter extends AsmEmitter("mips", Mips.allocatableRegs, Mips
3232
printer.println(".word %s # member method", entry.name)
3333
}
3434
printer.println()
35-
// vtable end
3635
}
3736

3837
override def selectInstr(func: TacFunc): (List[PseudoInstr], SubroutineInfo) = {
@@ -49,13 +48,13 @@ final class MipsAsmEmitter extends AsmEmitter("mips", Mips.allocatableRegs, Mips
4948
override def emitSubroutine(info: SubroutineInfo) = new MipsSubroutineEmitter(this, info)
5049

5150
override def emitEnd(): String = {
52-
if (!usedIntrinsics.isEmpty) {
51+
if (usedIntrinsics.nonEmpty) {
5352
printer.println("# start of intrinsics")
5453
if (usedIntrinsics.contains(Intrinsic.READ_LINE.entry)) loadReadLine()
5554
if (usedIntrinsics.contains(Intrinsic.STRING_EQUAL.entry)) loadStringEqual()
5655
if (usedIntrinsics.contains(Intrinsic.PRINT_BOOL.entry)) loadPrintBool()
5756
printer.println("# end of intrinsics")
58-
printer.println
57+
printer.println()
5958
}
6059
printer.println("# start of constant strings")
6160
printer.println(".data")

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

Lines changed: 16 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -4,6 +4,11 @@ import decaf.lowlevel.instr.{PseudoInstr, Temp}
44

55
import scala.collection.mutable
66

7+
/**
8+
* Perform liveness analysis.
9+
*
10+
* @tparam I type of instructions
11+
*/
712
class LivenessAnalyzer[I <: PseudoInstr] extends Function[CFG[I], Unit] {
813

914
override def apply(graph: CFG[I]): Unit = {
@@ -37,17 +42,18 @@ class LivenessAnalyzer[I <: PseudoInstr] extends Function[CFG[I], Unit] {
3742
}
3843

3944
/**
40-
* Compute the {@code def} and {@code liveUse} set for basic block {@code bb}.
41-
* <p>
45+
* Compute the `def and `liveUse` set for basic block `bb`.
46+
*
4247
* Recall the definition:
43-
* - {@code def}: set of all variables (i.e. temps) that are assigned to a value. Thus, we simply union all the
48+
*
49+
* - `def`: set of all variables (i.e. temps) that are assigned to a value. Thus, we simply union all the
4450
* written temps of every instruction.
45-
* - {@code liveUse}: set of all variables (i.e. temps) that are used before they are assigned to a value in this
51+
* - `liveUse`: set of all variables (i.e. temps) that are used before they are assigned to a value in this
4652
* basic block. Note this is NOT simply equal to the union set all read temps, but only those are not yet
4753
* assigned/reassigned.
4854
*
4955
* @param bb basic block
50-
*/
56+
**/
5157
private def computeDefAndLiveUseFor(bb: BasicBlock[I]): Unit = {
5258
bb.`def` = new mutable.TreeSet[Temp]
5359
bb.liveUse = new mutable.TreeSet[Temp]
@@ -65,12 +71,13 @@ class LivenessAnalyzer[I <: PseudoInstr] extends Function[CFG[I], Unit] {
6571
/**
6672
* Perform liveness analysis for every single location in a basic block, so that we know at each program location,
6773
* which variables stay alive.
68-
* <p>
74+
*
6975
* Idea: realizing that every location loc can be regarded as a "mini" basic block -- a block containing that
7076
* instruction solely, then the data flow equations also hold, and the situation becomes much simpler:
71-
* - loc.liveOut = loc.next.liveIn
72-
* - loc.def is simply the set of written temps
73-
* - loc.liveUse is simply the set of read temps, since it is impossible to read and write a same temp
77+
*
78+
* - `loc.liveOut = loc.next.liveIn`
79+
* - `loc.def` is simply the set of written temps
80+
* - `loc.liveUse` is simply the set of read temps, since it is impossible to read and write a same temp
7481
* simultaneously
7582
* So you see, to back propagate every location solves the problem.
7683
*

src/main/scala/decaf/backend/reg/BruteRegAlloc.scala

Lines changed: 14 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -9,7 +9,6 @@ import scala.util.Random
99

1010
/**
1111
* Brute force greedy register allocation algorithm.
12-
* <p>
1312
* To make our life easier, don't consider any special registers that may be used during call.
1413
*/
1514
final class BruteRegAlloc(emitter: AsmEmitter) extends RegAlloc(emitter) {
@@ -32,6 +31,7 @@ final class BruteRegAlloc(emitter: AsmEmitter) extends RegAlloc(emitter) {
3231
val used = new mutable.TreeSet[Reg]
3332
}
3433

34+
/** Bind a temp with a register. */
3535
private def bind(temp: Temp, reg: Reg)(implicit ctx: Context): Unit = {
3636
ctx.used += reg
3737
ctx.occupied += reg
@@ -40,6 +40,7 @@ final class BruteRegAlloc(emitter: AsmEmitter) extends RegAlloc(emitter) {
4040
ctx.tempOf(reg) = temp
4141
}
4242

43+
/** Unbind a temp with its register. */
4344
private def unbind(temp: Temp)(implicit ctx: Context): Unit = {
4445
if (ctx.regOf.contains(temp)) {
4546
ctx.occupied.remove(ctx.regOf(temp))
@@ -49,24 +50,21 @@ final class BruteRegAlloc(emitter: AsmEmitter) extends RegAlloc(emitter) {
4950

5051
/**
5152
* Main algorithm of local register allocation à la brute-force. Basic idea:
52-
* <ul>
53-
* <li>Allocation is preformed block-by-block.</li>
54-
* <li>Assume that every allocatable register is unoccupied before entering every basic block.</li>
55-
* <li>For every read (src) and written (dst) temp {@code t} in every pseudo instruction, attempt the following
56-
* in order:</li>
57-
* <li><ol>
58-
* <li>{@code t} is already bound to a register: keep on using it.</li>
59-
* <li>If there exists an available (unoccupied, or the occupied temp is no longer alive) register,
60-
* then bind to it.</li>
61-
* <li>Arbitrarily pick a general register, spill its value to stack, and then bind to it.</li>
62-
* </ol></li>
63-
* </ul>
64-
* <p>
65-
* The output assembly code is maintained by {@code emitter}.
53+
*
54+
* - Allocation is preformed block-by-block.
55+
* - Assume that every allocatable register is unoccupied before entering every basic block.
56+
* - For every read (src) and written (dst) temp `t` in every pseudo instruction, attempt the following in order:
57+
*
58+
* 1. `t` is already bound to a register: keep on using it.
59+
* 1. If there exists an available (unoccupied, or the occupied temp is no longer alive) register,
60+
* then bind to it.
61+
* 1. Arbitrarily pick a general register, spill its value to stack, and then bind to it.</li>
62+
*
63+
* The output assembly code is maintained by `ctx.emitter`.
6664
*
6765
* @param bb the basic block which the algorithm performs on
6866
* @param ctx context
69-
* @see #allocRegFor
67+
* @see [[allocRegFor]]
7068
*/
7169
private def localAlloc(bb: BasicBlock[PseudoInstr])(implicit ctx: Context): Unit = {
7270
ctx.regOf.clear()

0 commit comments

Comments
 (0)