Skip to content

Commit

Permalink
Collected files and made them run the full stack
Browse files Browse the repository at this point in the history
  • Loading branch information
jake-derry committed Apr 11, 2020
1 parent 682e129 commit e4aba9c
Show file tree
Hide file tree
Showing 67 changed files with 584 additions and 32 deletions.
3 changes: 2 additions & 1 deletion .cm/SKEL/main.sml
Original file line number Diff line number Diff line change
@@ -1,2 +1,3 @@
Skeleton 5
d2f4d"Parse"d"Symbol"d"TextIO"d"Printtree"ad"Main"h3aä¢F"gp1d"MIPSFrame"aä¢R"jgp1ÿ5gp1e"Translate"ad"S"jgp1ÿ gp1e"Semant"
d2f7d"List"d"Temp"Cd"Assem"d"Canon"d"Parse"d"TextIO"d"MIPSGen"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.
Binary file modified absyn/.cm/amd64-unix/absyn.sml
Binary file not shown.
Binary file modified absyn/.cm/amd64-unix/prabsyn.sml
Binary file not shown.
Binary file modified absyn/.cm/amd64-unix/types.sml
Binary file not shown.
1 change: 1 addition & 0 deletions assem/.cm/GUID/assem.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
guid-(sources.cm):assem/assem.sml-1586561322.670
1 change: 1 addition & 0 deletions assem/.cm/GUID/canon.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
guid-(sources.cm):assem/canon.sml-1586561087.582
1 change: 1 addition & 0 deletions assem/.cm/GUID/codegen.sig
Original file line number Diff line number Diff line change
@@ -0,0 +1 @@
guid-(sources.cm):assm/codegen.sig-1586560191.741
File renamed without changes.
File renamed without changes.
2 changes: 2 additions & 0 deletions assem/.cm/SKEL/assem.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Skeleton 5
d2f4d"List"d"Temp"d"Symbol"d"ErrorMsg"ad"Assem"h0
2 changes: 2 additions & 0 deletions assem/.cm/SKEL/canon.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Skeleton 5
d3f3d"Temp"ä¢Tree"d"Symbol"aã¢CANON"h0ad"Canon"jh1ad"T"gp1ÿ gp1ÿ
2 changes: 2 additions & 0 deletions assem/.cm/SKEL/codegen.sig
Original file line number Diff line number Diff line change
@@ -0,0 +1,2 @@
Skeleton 5
d2f2d"Tree"d"Assem"ac"CODEGEN"h1ad"Frame"gp1c"FRAME"
File renamed without changes.
File renamed without changes.
Binary file added assem/.cm/amd64-unix/assem.sml
Binary file not shown.
Binary file added assem/.cm/amd64-unix/canon.sml
Binary file not shown.
Binary file added assem/.cm/amd64-unix/codegen.sig
Binary file not shown.
Binary file added assem/.cm/amd64-unix/frame.sig
Binary file not shown.
File renamed without changes.
39 changes: 39 additions & 0 deletions assem/assem.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1,39 @@
structure Assem = struct

type reg = string
type temp = Temp.temp
type label = Temp.label

datatype instr = OPER of {assem: string,
dst: temp list,
src: temp list,
jump: label list option}
| LABEL of {assem: string, lab: Temp.label}
| MOVE of {assem: string,
dst: temp,
src: temp}

fun format saytemp =
let
fun speak(assem,dst,src,jump) =
let val saylab = Symbol.name
fun f(#"`":: #"s":: i::rest) =
(explode(saytemp(List.nth(src,ord i - ord #"0"))) @ f rest)
| f( #"`":: #"d":: i:: rest) =
(explode(saytemp(List.nth(dst,ord i - ord #"0"))) @ f rest)
| f( #"`":: #"j":: i:: rest) =
(explode(saylab(List.nth(jump,ord i - ord #"0"))) @ f rest)
| f( #"`":: #"`":: rest) = #"`" :: f rest
| f( #"`":: _ :: rest) = ErrorMsg.impossible "bad Assem format"
| f(c :: rest) = (c :: f rest)
| f nil = nil
in implode(f(explode assem))
end
in fn OPER{assem,dst,src,jump=NONE} => speak(assem,dst,src,nil)
| OPER{assem,dst,src,jump=SOME j} => speak(assem,dst,src,j)
| LABEL{assem,...} => assem
| MOVE{assem,dst,src} => speak(assem,[dst],[src],nil)
end

end

183 changes: 183 additions & 0 deletions assem/canon.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1,183 @@
signature CANON =
sig
val linearize : Tree.stm -> Tree.stm list
(* From an arbitrary Tree statement, produce a list of cleaned trees
satisfying the following properties:
1. No SEQ's or ESEQ's
2. The parent of every CALL is an EXP(..) or a MOVE(TEMP t,..)
*)

val basicBlocks : Tree.stm list -> (Tree.stm list list * Tree.label)
(* From a list of cleaned trees, produce a list of
basic blocks satisfying the following properties:
1. and 2. as above;
3. Every block begins with a LABEL;
4. A LABEL appears only at the beginning of a block;
5. Any JUMP or CJUMP is the last stm in a block;
6. Every block ends with a JUMP or CJUMP;
Also produce the "label" to which control will be passed
upon exit.
*)

val traceSchedule : Tree.stm list list * Tree.label -> Tree.stm list
(* From a list of basic blocks satisfying properties 1-6,
along with an "exit" label,
produce a list of stms such that:
1. and 2. as above;
7. Every CJUMP(_,t,f) is immediately followed by LABEL f.
The blocks are reordered to satisfy property 7; also
in this reordering as many JUMP(T.NAME(lab)) statements
as possible are eliminated by falling through into T.LABEL(lab).
*)
end

structure Canon : CANON =
struct

structure T = Tree

fun linearize(stm0: T.stm) : T.stm list =
let
infix %
fun (T.EXP(T.CONST _)) % x = x
| x % (T.EXP(T.CONST _)) = x
| x % y = T.SEQ(x,y)

fun commute(T.EXP(T.CONST _), _) = true
| commute(_, T.NAME _) = true
| commute(_, T.CONST _) = true
| commute _ = false

val nop = T.EXP(T.CONST 0)

fun reorder ((e as T.CALL _ )::rest) =
let val t = Temp.newtemp()
in reorder(T.ESEQ(T.MOVE(T.TEMP t, e), T.TEMP t) :: rest)
end
| reorder (a::rest) =
let val (stms,e) = do_exp a
val (stms',el) = reorder rest
in if commute(stms',e)
then (stms % stms',e::el)
else let val t = Temp.newtemp()
in (stms % T.MOVE(T.TEMP t, e) % stms', T.TEMP t :: el)
end
end
| reorder nil = (nop,nil)

and reorder_exp(el,build) = let val (stms,el') = reorder el
in (stms, build el')
end

and reorder_stm(el,build) = let val (stms,el') = reorder (el)
in stms % build(el')
end

and do_stm(T.SEQ(a,b)) =
do_stm a % do_stm b
| do_stm(T.JUMP(e,labs)) =
reorder_stm([e],fn [e] => T.JUMP(e,labs))
| do_stm(T.CJUMP(p,a,b,t,f)) =
reorder_stm([a,b], fn[a,b]=> T.CJUMP(p,a,b,t,f))
| do_stm(T.MOVE(T.TEMP t,T.CALL(e,el))) =
reorder_stm(e::el,fn e::el => T.MOVE(T.TEMP t,T.CALL(e,el)))
| do_stm(T.MOVE(T.TEMP t,b)) =
reorder_stm([b],fn[b]=>T.MOVE(T.TEMP t,b))
| do_stm(T.MOVE(T.MEM e,b)) =
reorder_stm([e,b],fn[e,b]=>T.MOVE(T.MEM e,b))
| do_stm(T.MOVE(T.ESEQ(s,e),b)) =
do_stm(T.SEQ(s,T.MOVE(e,b)))
| do_stm(T.EXP(T.CALL(e,el))) =
reorder_stm(e::el,fn e::el => T.EXP(T.CALL(e,el)))
| do_stm(T.EXP e) =
reorder_stm([e],fn[e]=>T.EXP e)
| do_stm s = reorder_stm([],fn[]=>s)

and do_exp(T.BINOP(p,a,b)) =
reorder_exp([a,b], fn[a,b]=>T.BINOP(p,a,b))
| do_exp(T.MEM(a)) =
reorder_exp([a], fn[a]=>T.MEM(a))
| do_exp(T.ESEQ(s,e)) =
let val stms = do_stm s
val (stms',e) = do_exp e
in (stms%stms',e)
end
| do_exp(T.CALL(e,el)) =
reorder_exp(e::el, fn e::el => T.CALL(e,el))
| do_exp e = reorder_exp([],fn[]=>e)

(* linear gets rid of the top-level SEQ's, producing a list *)
fun linear(T.SEQ(a,b),l) = linear(a,linear(b,l))
| linear(s,l) = s::l

in (* body of linearize *)
linear(do_stm stm0, nil)
end

type block = T.stm list

(* Take list of statements and make basic blocks satisfying conditions
3 and 4 above, in addition to the extra condition that
every block ends with a JUMP or CJUMP *)

fun basicBlocks stms =
let val done = Temp.newlabel()
fun blocks((head as T.LABEL _) :: tail, blist) =
let fun next((s as (T.JUMP _))::rest, thisblock) =
endblock(rest, s::thisblock)
| next((s as (T.CJUMP _))::rest, thisblock) =
endblock(rest,s::thisblock)
| next(stms as (T.LABEL lab :: _), thisblock) =
next(T.JUMP(T.NAME lab,[lab]) :: stms, thisblock)
| next(s::rest, thisblock) = next(rest, s::thisblock)
| next(nil, thisblock) =
next([T.JUMP(T.NAME done, [done])], thisblock)

and endblock(stms, thisblock) =
blocks(stms, rev thisblock :: blist)

in next(tail, [head])
end
| blocks(nil, blist) = rev blist
| blocks(stms, blist) = blocks(T.LABEL(Temp.newlabel())::stms, blist)
in (blocks(stms,nil), done)
end

fun enterblock(b as (T.LABEL s :: _), table) = Symbol.enter(table,s,b)
| enterblock(_, table) = table

fun splitlast([x]) = (nil,x)
| splitlast(h::t) = let val (t',last) = splitlast t in (h::t', last) end

fun trace(table,b as (T.LABEL lab :: _),rest) =
let val table = Symbol.enter(table, lab, nil)
in case splitlast b
of (most,T.JUMP(T.NAME lab, _)) =>
(case Symbol.look(table, lab)
of SOME(b' as _::_) => most @ trace(table, b', rest)
| _ => b @ getnext(table,rest))
| (most,T.CJUMP(opr,x,y,t,f)) =>
(case (Symbol.look(table,t), Symbol.look(table,f))
of (_, SOME(b' as _::_)) => b @ trace(table, b', rest)
| (SOME(b' as _::_), _) =>
most @ [T.CJUMP(T.notRel opr,x,y,f,t)]
@ trace(table, b', rest)
| _ => let val f' = Temp.newlabel()
in most @ [T.CJUMP(opr,x,y,t,f'),
T.LABEL f', T.JUMP(T.NAME f,[f])]
@ getnext(table,rest)
end)
| (most, T.JUMP _) => b @ getnext(table,rest)
end

and getnext(table,(b as (T.LABEL lab::_))::rest) =
(case Symbol.look(table, lab)
of SOME(_::_) => trace(table,b,rest)
| _ => getnext(table,rest))
| getnext(table,nil) = nil

fun traceSchedule(blocks,done) =
getnext(foldr enterblock Symbol.empty blocks, blocks)
@ [T.LABEL done]

end
5 changes: 5 additions & 0 deletions assem/codegen.sig
Original file line number Diff line number Diff line change
@@ -0,0 +1,5 @@
signature CODEGEN =
sig
structure Frame : FRAME
val codeGen : Frame.frame -> Tree.stm -> Assem.instr list
end
3 changes: 2 additions & 1 deletion frame/frame.sig → assem/frame.sig
Original file line number Diff line number Diff line change
Expand Up @@ -12,9 +12,10 @@ sig
val wordSize : int

val exp : access * Tree.exp -> Tree.exp
val name : frame -> Temp.label
val name : frame -> string
val formals : frame -> access list
val nextFrame : {name: Temp.label, formals: bool list} -> frame
val string: Temp.label * string -> string

val allocateLocal : frame -> bool -> access

Expand Down
23 changes: 23 additions & 0 deletions assem/graph/flowgraph.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
structure Flow =
struct
datatype flowgraph = FGRAPH of {control: Graph.graph,
def: Temp.temp list Graph.Table.table,
use: Temp.temp list Graph.Table.table,
ismove: bool Graph.Table.table}

(* Note: any "use" within the block is assumed to be BEFORE a "def"
of the same variable. If there is a def(x) followed by use(x)
in the same block, do not mention the use in this data structure,
mention only the def.
More generally:
If there are any nonzero number of defs, mention def(x).
If there are any nonzero number of uses BEFORE THE FIRST DEF,
mention use(x).
For any node in the graph,
Graph.Table.look(def,node) = SOME(def-list)
Graph.Table.look(use,node) = SOME(use-list)
*)

end
23 changes: 23 additions & 0 deletions assem/graph/graph.sig
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
signature GRAPH =
sig
type graph
type node

val nodes: graph -> node list
val succ: node -> node list
val pred: node -> node list
val adj: node -> node list (* succ+pred *)
val eq: node*node -> bool

val newGraph: unit -> graph
val newNode : graph -> node
exception GraphEdge
val mk_edge: {from: node, to: node} -> unit
val rm_edge: {from: node, to: node} -> unit

structure Table : TABLE
sharing type Table.key = node

val nodename: node->string (* for debugging only *)

end
80 changes: 80 additions & 0 deletions assem/graph/graph.sml
Original file line number Diff line number Diff line change
@@ -0,0 +1,80 @@
structure Graph :> GRAPH =
struct
type node' = int
type temp = Temp.temp

datatype noderep = NODE of {succ: node' list, pred: node' list}

val emptyNode = NODE{succ=[],pred=[]}

val bogusNode = NODE{succ=[~1],pred=[]}

fun isBogus(NODE{succ= ~1::_,...}) = true
| isBogus _ = false

structure A = DynamicArrayFn(struct open Array
type elem = noderep
type vector = noderep vector
type array = noderep array
end)

type graph = A.array

type node = graph * node'
fun eq((_,a),(_,b)) = a=b

fun augment (g: graph) (n: node') : node = (g,n)

fun newGraph() = A.array(0,bogusNode)

fun nodes g = let val b = A.bound g
fun f i = if isBogus( A.sub(g,i)) then nil
else (g,i)::f(i+1)
in f 0
end

fun succ(g,i) = let val NODE{succ=s,...} = A.sub(g,i)
in map (augment g) s
end
fun pred(g,i) = let val NODE{pred=p,...} = A.sub(g,i)
in map (augment g) p
end
fun adj gi = pred gi @ succ gi

fun newNode g = (* binary search for unused node *)
let fun look(lo,hi) =
(* i < lo indicates i in use
i >= hi indicates i not in use *)
if lo=hi then (A.update(g,lo,emptyNode); (g,lo))
else let val m = (lo+hi) div 2
in if isBogus(A.sub(g,m)) then look(lo,m) else look(m+1,hi)
end
in look(0, 1 + A.bound g)
end

exception GraphEdge
fun check(g,g') = (* if g=g' then () else raise GraphEdge *) ()

fun delete(i,j::rest) = if i=j then rest else j::delete(i,rest)
| delete(_,nil) = raise GraphEdge

fun diddle_edge change {from=(g:graph, i),to=(g':graph, j)} =
let val _ = check(g,g')
val NODE{succ=si,pred=pi} = A.sub(g,i)
val _ = A.update(g,i,NODE{succ=change(j,si),pred=pi})
val NODE{succ=sj,pred=pj} = A.sub(g,j)
val _ = A.update(g,j,NODE{succ=sj,pred=change(i,pj)})
in ()
end

val mk_edge = diddle_edge (op ::)
val rm_edge = diddle_edge delete

structure Table = IntMapTable(type key = node
fun getInt(g,n) = n)


fun nodename(g,i:int) = "n" ^ Int.toString(i)

end

Binary file removed frame/.cm/amd64-unix/frame.sig
Binary file not shown.
Loading

0 comments on commit e4aba9c

Please sign in to comment.