Skip to content

Commit

Permalink
SOMETHING COMPILES!!!!!
Browse files Browse the repository at this point in the history
  • Loading branch information
soelgary committed Apr 25, 2016
1 parent 8a666d7 commit 440a38b
Show file tree
Hide file tree
Showing 6 changed files with 104 additions and 45 deletions.
16 changes: 11 additions & 5 deletions src/main.sml
Original file line number Diff line number Diff line change
Expand Up @@ -33,17 +33,20 @@ fun compile filename =
(*val { prolog, epilog, body=assem'} = Frame.procEntryExit3(frame, assem)*)
(*val (assem'', alloc) = RegAlloc.alloc(assem', frame)*)
val (assem'', alloc) = RegAlloc.alloc(assem, frame)
val replace = (fn(temp) => valOf(Temp.Table.look(alloc,temp)))
val replaceAll = map (fn(instr) => Assem.format replace instr) assem''
val replaced = foldr (fn(a,b) => a ^ b) "" replaceAll
in
(assem'', alloc)
(assem'', alloc, replaced)
end
| toAsm(Frame.STRING (label, value)) =
(* TODO: temporary hack *)
([], Temp.Table.empty)
([], Temp.Table.empty, "")

val exp = Parse.parse(filename)
val _ = FindEscape.findEscape(exp)
val ir = Semant.transProg(exp)
val asm = (List.map (#1 o toAsm) ir)
val asm = (List.map (#3 o toAsm) ir)
in
(* Print the IR fragments. *)
print "\nIR\n-----\n";
Expand All @@ -55,8 +58,11 @@ fun compile filename =
ir);

(* Print the Assem. *)
print "\nASM\n-----\n";
(*print "\nASM\n-----\n";
print (foldr (fn (a, s) =>
(foldr (fn (i, s) => Assem.format Temp.makestring i ^ s) s a)) "" asm)
(foldr (fn (i, s) => Assem.format Temp.makestring i ^ s) s a)) "" asm);*)

print "\nFinal\n-----\n";
print (foldr (fn(a,b) => a ^ b) "" asm)
end
end
14 changes: 7 additions & 7 deletions src/register/alloc.sml
Original file line number Diff line number Diff line change
@@ -1,28 +1,28 @@
signature REG_ALLOC =
sig
structure Frame : FRAME
type allocation = Frame.register Temp.Table.table
type allocation = Color.allocation
val alloc : Assem.instr list * Frame.frame -> Assem.instr list * allocation
end

structure RegAlloc : REG_ALLOC =
struct
structure Frame = MipsFrame
type allocation = Frame.register Temp.Table.table
type allocation = Color.allocation
exception CannotAllocateError

fun alloc (instrs, frame) =
let val cfg = MakeGraph.instrs2graph(instrs)
val (interference, liveOut) = Liveness.interferenceGraph(cfg)
val (interference as Liveness.IGRAPH{graph=g, tnode=t, gtemp=gt, moves=ms}, liveOut) = Liveness.interferenceGraph(cfg)
val _ = Liveness.show(interference)
(* TODO: What to do with the spills? *)
(*val (alloc', spills) =
Color.color { interference = interference,
val (alloc', spills) =
Color.color { interference = (Liveness.IGRAPH{graph=g, tnode=t, gtemp=gt, moves=ms}),
initial = Frame.tempMap,
spillCost = (fn node => 0),
registers = Frame.registers }*)
registers = Frame.registers }
in
(instrs, Frame.tempMap)
(instrs, alloc')
end
end

Expand Down
111 changes: 79 additions & 32 deletions src/register/color.sml
Original file line number Diff line number Diff line change
Expand Up @@ -9,47 +9,94 @@ sig
-> allocation * Temp.temp list
end

structure Color :> COLOR =
structure Color : COLOR =
struct
structure Frame : FRAME = MipsFrame
type allocation = Frame.register Temp.Table.table

(* TODO: Use these to implement Color.color. *)
(*fun findNodeToRemove(nodes) =
let fun findNodeToRemoveAcc([],empty) =
if empty then NONE else raise CannotAllocateError
| findNodeToRemoveAcc(n::rest,_) =
(print(Int.toString(List.length(Graph.adj n)) ^ "\n\n");
(if List.length(Graph.adj n) < Frame.sizeOfK
then SOME(n) else findNodeToRemoveAcc(rest,false)))
in
findNodeToRemoveAcc(nodes,true)
end
fun removeNode([],n) = []
| removeNode(node::nodes,n) =
if Graph.eq(node,n) then nodes else node::removeNode(nodes,n)
fun buildStack([],s) = s
| buildStack(node::nodes,s) =
case findNodeToRemove(node::nodes) of
NONE => raise CannotAllocateError
| SOME(n) =>
let val reducedNodes = removeNode(node::nodes,n)
in
Stack.push(s,n);
buildStack(reducedNodes,s)
end
exception CannotAllocateError
exception NotEnoughRegisters

val nodeStack = case igraph of
Liveness.IGRAPH{graph=g, tnode=t, gtemp=gt, moves=ms} =>
buildStack(Graph.nodes(g),Stack.empty())*)
structure RegisterSet = BinarySetFn(struct type ord_key = Frame.register
val compare = String.compare
end)

(* TODO: Write this. *)
fun color { interference,
initial,
spillCost,
registers } =
(initial, [])
let fun findNodeToRemove(nodes) =
let fun findNodeToRemoveAcc([],empty) =
if empty then NONE else raise CannotAllocateError
| findNodeToRemoveAcc(n::rest,_) =
(print(Int.toString(List.length(Graph.adj n)) ^ "\n\n");
(if List.length(Graph.adj n) < Frame.sizeOfK
then SOME(n) else findNodeToRemoveAcc(rest,false)))
in
findNodeToRemoveAcc(nodes,true)
end

fun removeNode([],n) = []
| removeNode(node::nodes,n) =
if Graph.eq(node,n) then nodes else node::removeNode(nodes,n)

fun buildStack([],s) = s
| buildStack(node::nodes,s) =
case findNodeToRemove(node::nodes) of
NONE => raise CannotAllocateError
| SOME(n) =>
let val reducedNodes = removeNode(node::nodes,n)
in
Stack.push(s,n);
buildStack(reducedNodes,s)
end

val nodeStack = case interference of
Liveness.IGRAPH{graph=g, tnode=t, gtemp=gt, moves=ms} =>
buildStack(Graph.nodes(g),Stack.empty())

fun enumerateAdjacentColors(adjacentNodes,alloc,gtemp) =
let fun buildSet([],accSet) = accSet
| buildSet(node::nodes,accSet) =
case Temp.Table.look(alloc,gtemp(node)) of
NONE => buildSet(nodes,accSet)
| SOME(r) => buildSet(nodes,RegisterSet.add(accSet,r))
in
buildSet(adjacentNodes,RegisterSet.empty)
end

(* return a set of colors*)

(* Get all adjacent nodes
Enumerate the assigned colors from each adjacent node
Take the difference of the available colors and the used colors
If there is an unused color, assign it, otherwise raise NotEnoughRegisters
*)
(* Check each adjacent node. Find the lowest available register *)
fun lowestAvailableRegister(node,alloc,gt) =
let val adj = Graph.adj(node)
val adjacentColors = enumerateAdjacentColors(adj,alloc,gt)
val allColors = RegisterSet.addList(RegisterSet.empty, Frame.availableRegisters)
val availableColors = RegisterSet.difference(allColors, adjacentColors)
in
if RegisterSet.numItems(availableColors) > 0 then hd(RegisterSet.listItems(availableColors))
else raise NotEnoughRegisters
end

fun apply (stack,alloc,gt) =
case Stack.pop(stack) of
NONE => alloc
| SOME(n) =>
let val register = lowestAvailableRegister(n,alloc,gt)
val updatedAllocation = Temp.Table.enter(alloc,gt(n),register)
in
apply(stack,updatedAllocation,gt)
end

in
case interference of
Liveness.IGRAPH{graph=g, tnode=t, gtemp=gt, moves=ms} =>
(apply(nodeStack,initial,gt), [])
end

end
1 change: 1 addition & 0 deletions src/semant/frame.sig
Original file line number Diff line number Diff line change
Expand Up @@ -16,6 +16,7 @@ sig
val wordSize: int
val sizeOfK: int
val registers: register list
val availableRegisters: register list

(* For tests *)
val registersAsTemps: int list
Expand Down
1 change: 1 addition & 0 deletions src/semant/mipsframe.sml
Original file line number Diff line number Diff line change
Expand Up @@ -23,6 +23,7 @@ struct
"$t8", "$t9"]

val registers = specialregs @ argregs @ calleesaves @ callersaves
val availableRegisters = callersaves

fun precolor() : register Temp.Table.table =
let
Expand Down
6 changes: 5 additions & 1 deletion stack.sml
Original file line number Diff line number Diff line change
Expand Up @@ -2,12 +2,16 @@
This will be useful in the register allocator *)
structure Stack =
struct
fun isEmpty(s) =
case !s of
[] => true
| _ => false
fun empty() = ref []
fun push(s,el) = s := el::(!s)
fun pop(s) =
case !s of
[] => NONE
| el::rest => (s := rest; el)
| el::rest => (s := rest; SOME(el))
fun printStack(s) =
let fun printH([]) = print("End Stack\n")
| printH((el: Graph.node)::rest) =
Expand Down

0 comments on commit 440a38b

Please sign in to comment.