Skip to content

Commit

Permalink
Did liveness graph
Browse files Browse the repository at this point in the history
  • Loading branch information
jake-derry committed Apr 20, 2020
1 parent ac66811 commit 5dafc5f
Show file tree
Hide file tree
Showing 49 changed files with 349 additions and 193 deletions.
2 changes: 1 addition & 1 deletion .cm/SKEL/main.sml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Skeleton 5
d2f9d"Flow"d"List"d"Temp"d"Assem"Cd"Canon"d"Parse"d"TextIO"d"MIPSGen"d"MakeGraph"Nad"Main"h3aä¢F"gp1d"MIPSFrame"aä¢Tr"jgp1ÿgp1e"Translate"ad"S"jgp1ÿ1gp1e"Semant"
d2f7d"Flow"d"List"Cd"Temp"d"Assem"d"Canon"d"Parse"d"TextIO"Cd"MIPSGen"d"Liveness"d"MakeGraph"d"Printtree"d"PrintAbsyn"Nad"Main"h3aä¢F"gp1d"MIPSFrame"aä¢Tr"jgp1ÿgp1e"Translate"ad"S"jgp1ÿ‚gp1e"Semant"
Binary file modified .cm/amd64-unix/main.sml
Binary file not shown.
Binary file modified IR/.cm/amd64-unix/temp.sig
Binary file not shown.
Binary file modified IR/.cm/amd64-unix/temp.sml
Binary file not shown.
Binary file modified IR/.cm/amd64-unix/translate.sig
Binary file not shown.
Binary file modified IR/.cm/amd64-unix/translate.sml
Binary file not shown.
2 changes: 2 additions & 0 deletions IR/temp.sig
Original file line number Diff line number Diff line change
Expand Up @@ -10,5 +10,7 @@ sig
val namedlabel : string -> label
structure Set : ORD_SET sharing type Set.Key.ord_key = temp
structure Map : ORD_MAP sharing type Map.Key.ord_key = temp
type set = Set.set
val tempSetToString : set -> string
end

10 changes: 8 additions & 2 deletions IR/temp.sml
Original file line number Diff line number Diff line change
Expand Up @@ -3,10 +3,10 @@ struct
type temp = int

val labelCount = ref 0
val temps = ref 100
val temps = ref 0

fun reset () =
let val () = temps := 100
let val () = temps := 0
val () = labelCount := 0
in
()
Expand All @@ -32,6 +32,12 @@ struct

structure Set = SplaySetFn(TempOrd)
structure Map = SplayMapFn(TempOrd)

type 'a map = 'a Map.map
type set = Set.set

fun tempSetToString (ts) =
(Set.foldl (fn (item, s) => s ^ ", " ^ (makestring item)) "" ts)

fun newlabel() =
let
Expand Down
1 change: 1 addition & 0 deletions IR/translate.sml
Original file line number Diff line number Diff line change
Expand Up @@ -234,6 +234,7 @@ struct
val trBody = unNx body'
val trBody' = F.procEntryExit1(levelFrame, trBody)
in (* Append to frag list *)
print "procedureEntryExit just added to fragList\n";
fragList := F.PROC ({body = trBody', frame = levelFrame}) :: (!fragList)
end

Expand Down
Binary file modified assem/.cm/amd64-unix/assem.sml
Binary file not shown.
Binary file modified assem/.cm/amd64-unix/canon.sml
Binary file not shown.
Binary file modified assem/.cm/amd64-unix/codegen.sig
Binary file not shown.
Binary file modified assem/.cm/amd64-unix/frame.sig
Binary file not shown.
2 changes: 1 addition & 1 deletion liveness/.cm/SKEL/flow.sml
Original file line number Diff line number Diff line change
@@ -1,2 +1,2 @@
Skeleton 5
d2f2d"Int"d"Temp"ad"Flow"h2ad"G"jgp1d"NodeKey"gp1e"FuncGraph"ad"T"jh0gp1e"IntMapTable"
d2f4d"Int"d"Char"d"Temp"d"String"ad"Flow"h2ad"G"jgp1d"NodeKey"gp1e"FuncGraph"ad"T"jh0gp1e"IntMapTable"
3 changes: 2 additions & 1 deletion liveness/.cm/SKEL/liveness.sml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Skeleton 5
d3f2d"Flow"d"Temp"a�LIVENESS"h0ad"Liveness"jh1ad"G"jgp1d"NodeKey"gp1e"FuncGraph"gp1�
d2f4d"Int"ä˘Flow"d"List"ä˘Temp"ad"Liveness"h3ad"TempSet"gp2˙d"Set"ad"TempMap"gp2˙d"Map"aä˘G"gp2˙
˙
Binary file modified liveness/.cm/amd64-unix/flow.sml
Binary file not shown.
Binary file added liveness/.cm/amd64-unix/liveness.sml
Binary file not shown.
Binary file modified liveness/.cm/amd64-unix/makegraph.sml
Binary file not shown.
12 changes: 7 additions & 5 deletions liveness/flow.sml
Original file line number Diff line number Diff line change
Expand Up @@ -3,12 +3,14 @@ struct
structure G = FuncGraph (NodeKey)
structure T = IntMapTable (type key = int
fun getInt(n) = n)
type node = string * Temp.temp list * Temp.temp list * bool * Temp.label list option
type node = string * Temp.temp list * Temp.temp list * (Temp.temp * Temp.temp) option * Temp.label list option
type graph = node G.graph
datatype flowgraph = FGRAPH of {control: graph,
def: Temp.temp list T.table,
use: Temp.temp list T.table,
ismove: bool T.table}

fun printNode (nid, (assem, def, use, ismove, jump)) = Int.toString nid ^ ": " ^ assem
fun printNodeForVis (nid, (assem, def, use, ismove, jump)) =
Int.toString nid ^ ": " ^ String.translate (fn (c) => (case c of
#"\n" => "|"
| _ => Char.toString c)) (let val format0 = (* Assem.format(Temp.makestring) *) (fn x => x)
in (format0 assem)
end)
end
Binary file modified liveness/graph/.cm/amd64-unix/funcgraph.sig
Binary file not shown.
Binary file modified liveness/graph/.cm/amd64-unix/funcgraph.sml
Binary file not shown.
4 changes: 3 additions & 1 deletion liveness/graph/funcgraph.sig
Original file line number Diff line number Diff line change
Expand Up @@ -105,6 +105,8 @@ val isAdjacent: 'a node * 'a node -> bool
* that says how to convert any given node's data into a
* string, and it will print everything out
*)
val printGraph: ((nodeID * 'a) -> string) -> 'a graph -> unit
val printGraph: ((nodeID * 'a) -> string) -> 'a graph -> bool -> unit

val printGraphVis : ((nodeID * 'a) -> string) -> 'a graph -> unit

end
35 changes: 30 additions & 5 deletions liveness/graph/funcgraph.sml
Original file line number Diff line number Diff line change
Expand Up @@ -113,7 +113,7 @@ struct
NodeSet.member(NodeSet.union(s1,p1),n2) orelse
NodeSet.member(NodeSet.union(s2,p2),n1)

fun printGraph stringify g =
fun printGraph stringify g printSuccPred =
let fun println x = print(x ^"\n")
fun stringNid nid =
let val (_,data,_,_) = getNode(g,nid)
Expand All @@ -123,13 +123,38 @@ struct
fun prOneNode(nid,data,succs,preds) =
let val s = stringify(nid,data)
val () = println("Node: " ^ s)
val () = println(" -> Successors:")
val () = prSet succs
val () = println(" -> Predecessors:")
val () = prSet preds
val _ = (if printSuccPred then
(println(" -> Successors:");
prSet succs;
println(" -> Predecessors:");
prSet preds)
else ())
in ()
end
in NodeMap.app prOneNode g
end

fun printGraphVis stringify g =
let fun println x = print(x ^"\n")
fun stringNid nid =
let val (_,data,_,_) = getNode(g,nid)
in stringify(nid,data)
end
fun prSet s = NodeSet.app (println o stringNid) s

fun prNodeName (nid, data, succs, preds) =
let val s = stringify(nid, data)
val _ = println("\"" ^ s ^ "\"")
in ()
end

fun prOneAllSuccs(nid,data,succs,preds) =
let val thisName = stringify(nid,data)
val _ = NodeSet.app ((fn node => (print ("\"" ^ thisName ^ "\" \"" ^ node ^ "\"\n"))) o stringNid) succs
in ()
end
in NodeMap.app prNodeName g;
NodeMap.app prOneAllSuccs g
end

end
120 changes: 113 additions & 7 deletions liveness/liveness.sml
Original file line number Diff line number Diff line change
@@ -1,18 +1,124 @@
signature LIVENESS =
(* signature LIVENESS =
sig
type igraph
type node
type live
type livegraph
(* val interferenceGraph : Flow.flowgraph -> igraph * (node -> Temp.temp list)
val show : outstream * igraph -> unit *)
end
val flowToLiveGraph : Flow.graph -> livegraph
val showLiveGraph : livegraph -> unit
structure Liveness : LIVENESS =
end *)

structure Liveness (*: LIVENESS*) =
struct
structure G = FuncGraph (NodeKey)
type igraph = G.graph
type node = Flow.node
datatype igraph = IGRAPH of {graph: igraph,
structure TempSet = Temp.Set
structure TempMap = Temp.Map
structure G = Flow.G

type temp_set = TempSet.set

type node = Temp.temp G.node
datatype igraph = IGRAPH of {graph: Temp.temp G.graph,
tnode: Temp.temp -> node,
gtemp: node -> Temp.temp,
moves: (node * node) list}


type live = {def: Temp.set,
use: Temp.set,
move: (Temp.temp * Temp.temp) option,
liveIn: Temp.set,
liveOut: Temp.set}

type livegraph = live G.graph

(* Calculates liveness and adds that info to flow graph *)
fun flowToLiveGraph (flow : Flow.node G.graph) : livegraph =
let fun convertFlowToLive () =
(* Copy original graph (only nodes) *)
let fun init (flowNode : Flow.node Flow.G.node, liveGraph : livegraph) =
let val nid = G.getNodeID (flowNode)
val (assm, def, use, move, jump) = G.nodeInfo (flowNode)
val newInfo = {def=TempSet.addList (TempSet.empty, def),
use=TempSet.addList (TempSet.empty, use),
move=move,
liveIn=Temp.Set.empty,
liveOut=Temp.Set.empty}
in G.addNode (liveGraph, nid, newInfo)
end

(* Copy the edges *)
fun copyEdges (oldNode, newGraph) =
let val nid = G.getNodeID (oldNode)
val oldInfo = G.nodeInfo (oldNode)
val oldSuccs = G.succs (oldNode)
val newNode = G.getNode (newGraph, nid)
in List.foldl (fn (succ, graph) => G.addEdge (graph, {from=nid, to=succ})) newGraph oldSuccs
end

fun iterateLiveness (edgedGraph) =
let fun iterGraph (nid, graph) =
let val node = G.getNode (graph, nid)

val info = G.nodeInfo node
val {def=def, use=use, move=move, liveIn=oldLiveIn, liveOut=oldLiveOut} = info

val succs = G.succs (node)
val preds = G.preds (node)

val newLiveIn = TempSet.union (use, (TempSet.difference (oldLiveOut, def)))
val newLiveOut = foldl (fn (nid, set) => let val iterNode = G.getNode (graph, nid)
val lIn = #liveIn (G.nodeInfo iterNode)
in TempSet.union (set, lIn)
end) TempSet.empty succs
val unchanged : bool = ((TempSet.equal (oldLiveIn, newLiveIn)) andalso (TempSet.equal (oldLiveOut, newLiveOut)))
val newInfo = {def=def, use=use, move=move, liveIn=newLiveIn, liveOut=newLiveOut}
val newGraph = G.changeNodeData (graph, nid, newInfo)
in (unchanged, newGraph)
end

fun untilUnchanged (true, graph) = graph
| untilUnchanged (false, graph) =
untilUnchanged (G.foldNodes (fn (node, (unchanged, graph)) =>
(let val nid = G.getNodeID(node)
val (newUnchanged, newGraph) = iterGraph (nid, graph)
in (unchanged andalso newUnchanged, newGraph)
end )) (true, graph) graph)
in untilUnchanged (false, edgedGraph)
end

val initializedGraph : livegraph = G.foldNodes init G.empty flow
val edgedGraph : livegraph = G.foldNodes copyEdges initializedGraph flow
val liveGraph : livegraph = iterateLiveness edgedGraph

in liveGraph
end
in convertFlowToLive ()
end

(* Uses a flow graph with liveness info to make an interference graph *)
(* fun interferenceGraph (flow) = let val liveGraph = flowToLiveGraph flow
in {graph=graph,
tnode=tnode,
gtemp=gtemp,
moves=moves}
end *)

fun moveToString (SOME (t1, t2)) = (Temp.makestring t1 ^ " <- " ^ Temp.makestring t2)
| moveToString (NONE) = "N/A"

fun showLiveGraph (liveGraph : livegraph) =
(print "\n--- Live Graph: --- \n";
G.printGraph (fn (nid, liveObj:live) =>
let val liveIn : Temp.set = #liveIn liveObj
val liveOut : Temp.set = #liveOut liveObj
val move = #move liveObj
in ("nid = " ^ (Int.toString nid) ^ " \tliveIn: " ^ (Temp.tempSetToString liveIn) ^
" \tliveOut: " ^ (Temp.tempSetToString liveOut) ^
" \tmove: " ^ (moveToString move))
end) liveGraph false)


end
13 changes: 6 additions & 7 deletions liveness/makegraph.sml
Original file line number Diff line number Diff line change
Expand Up @@ -19,9 +19,9 @@ struct

(* Converts an instruction to one node
Returns: a node *)
fun makenode (A.OPER {assem, dst, src, jump}) = (assem, dst, src, false, jump)
| makenode (A.LABEL {assem, lab}) = (assem, [], [], false, NONE)
| makenode (A.MOVE {assem, dst, src}) = (assem, [dst], [src], true, NONE)
fun makenode (A.OPER {assem, dst, src, jump}) = (assem, dst, src, NONE, jump)
| makenode (A.LABEL {assem, lab}) = (assem, [], [], NONE, NONE)
| makenode (A.MOVE {assem, dst, src}) = (assem, [dst], [src], SOME(dst, src), NONE)


(* Adds all of the instructions as nodes to the graph
Expand All @@ -45,12 +45,11 @@ struct
val nodeValue = case nodeOption of
SOME (nodeVal) => nodeVal
| NONE => (Err.error 0 ("name = " ^ Symbol.name lbl); raise NoneJump ("name = " ^ Symbol.name lbl))
in G.addEdge (graph, {from=G.getNodeID (node),
to=G.getNodeID (valOf (S.look (labelmap, lbl)))})
in G.addEdge (graph, {from=G.getNodeID (node),
to=G.getNodeID nodeValue})
end)
graph
jumps


(* Adds edges to the control flow graph
Returns: graph *)
Expand All @@ -60,7 +59,7 @@ struct
in (case jump of
NONE => addedges (addnextedge (graph, node, prev),
labelmap, nodes, SOME (node))
| SOME (jumps) => addedges (addnextedge (addjumps (graph, labelmap, node, jumps), node, prev), labelmap, nodes, SOME(node)))
| SOME (jumps) => addedges (addnextedge (addjumps (graph, labelmap, node, jumps), node, prev), labelmap, nodes, NONE))
end

fun instrs2graph (instrs) = let val (nodeGraph, labelmap) = addnodes (G.empty, instrs, S.empty, 0)
Expand Down
34 changes: 27 additions & 7 deletions main.sml
Original file line number Diff line number Diff line change
Expand Up @@ -8,32 +8,52 @@ struct

fun emitproc out (F.PROC{body,frame}) =
let val _ = print ("emit " ^ F.name frame ^ "\n")
(* Linearize the statements of the body and trace schedule *)
(* val _ = Printtree.printtree(out,body); *)
val stms = Canon.linearize body
(* val _ = app (fn s => Printtree.printtree(out,s)) stms; *)
val _ = app (fn s => Printtree.printtree(TextIO.stdOut,s)) stms;
val stms' = Canon.traceSchedule(Canon.basicBlocks stms)

(* Convert to list of instructions *)
val instrs = F.procEntryExit2 (frame, List.concat (map (MIPSGen.codeGen frame) stms'))
val {prolog, body, epilog} = F.procEntryExit3 (frame, instrs)

val (graph, nodelist) = MakeGraph.instrs2graph (body)
val printgraph = Flow.G.printGraph (Flow.printNode)
val _ = printgraph graph
(* Format those instructions using temp names *)
val format0 = Assem.format(Temp.makestring)

(* Make a flow graph *)
val (graph, nodelist) = MakeGraph.instrs2graph (body)
val _ = (print "\n--- Control Flow Graph: ---\n")
val _ = Flow.G.printGraph (Flow.printNode) graph true

(* Print the ready-to-plot flow graph *)
val _ = print "\n--- CFG for usage in https://csacademy.com/app/graph_editor/ : ---\n"
val _ = Flow.G.printGraphVis (Flow.printNodeForVis) graph

(* Convert to a liveGraph *)
val liveGraph : Liveness.livegraph = Liveness.flowToLiveGraph graph
val _ = Liveness.showLiveGraph liveGraph

(* Convert to an interference graph *)
(* TODO *)
in (TextIO.output (out, prolog); (app (fn i => TextIO.output(out, (format0 i) ^ "\n")) instrs); TextIO.output (out, epilog))
end
| emitproc out (F.STRING(lab,s)) = TextIO.output(out, (F.string (lab,s)) ^ "\n")

fun withOpenFile fname f =
let val out = TextIO.openOut fname
in ((f TextIO.stdOut); (f out before TextIO.closeOut out))
in ((*(f TextIO.stdOut);*) (f out before TextIO.closeOut out))
handle e => (TextIO.closeOut out; raise e)
end

fun compile filename =
let val absyn = Parse.parse (filename ^ ".tig")
let val absyn = Parse.parse (filename ^ ".tig")
val _ = print "\nAbstract Syntax Tree: \n";
val _ = PrintAbsyn.print (TextIO.stdOut, absyn)
val _ = Temp.reset ()
val frags = ((*FindEscape.prog absyn;*) S.transProg absyn)
in withOpenFile (filename ^ ".s")
(fn out => (app (emitproc out) frags))
(fn out => (app (emitproc out) (List.rev frags)))
end

end
Binary file modified mips/.cm/amd64-unix/mipsframe.sml
Binary file not shown.
Binary file modified mips/.cm/amd64-unix/mipsgen.sml
Binary file not shown.
8 changes: 5 additions & 3 deletions mips/mipsframe.sml
Original file line number Diff line number Diff line change
Expand Up @@ -114,14 +114,16 @@ struct

fun procEntryExit1(frame', stm') = stm'

(* TODO: add the sink back (see page 208) *)
fun procEntryExit2(frame, body) =
body @
body
(* body @
[A.OPER{assem="",
src =[ZERO,RA,SP]@calleesaves,
dst=[], jump=SOME[]}]
dst=[], jump=SOME[]}] *)

fun procEntryExit3({name, formals, numLocals, curOffset}, body) =
{prolog = "PROCEDURE " ^ Symbol.name name ^ "\n",
{prolog = "PROCEDURE " ^ Symbol.name name ^ "\n" ^ Symbol.name name ^ ": \n",
body = body,
epilog = "END " ^ Symbol.name name ^ "\n"}

Expand Down
Loading

0 comments on commit 5dafc5f

Please sign in to comment.