Home My Page Projects Code Snippets Project Openings diderot
Summary Activity Tracker Tasks SCM

SCM Repository

[diderot] Annotation of /trunk/src/compiler/codegen/codegen-fn.sml
ViewVC logotype

Annotation of /trunk/src/compiler/codegen/codegen-fn.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 456 - (view) (download)

1 : jhr 454 (* codegen-fn.sml
2 :     *
3 :     * COPYRIGHT (c) 2010 The Diderot Project (http://diderot-language.cs.uchicago.edu)
4 :     * All rights reserved.
5 : jhr 455 *
6 :     * Generic support for translating LowIL code to the target representation. We
7 :     * assume that the LowIL has first been run through the splitting pass to match
8 :     * the target's vector widths.
9 : jhr 454 *)
10 :    
11 :     functor CodeGenFn (T : TARGET) : sig
12 :    
13 :     val generate : LowIL.program -> T.program
14 :    
15 :     end = struct
16 :    
17 :     structure Src = LowIL
18 :     structure SrcV = LowIL.Var
19 : jhr 455 structure SrcOp = LowOps
20 : jhr 456 structure SrcNd = LowIL.Node
21 : jhr 454
22 : jhr 456 (* a property marking nodes that are directly referenced by statememts. *)
23 :     local
24 :     val {getFn, setFn, ...} = SrcNd.newFlag ()
25 :     in
26 :     val isFirst = getFn
27 :     fun markFirst nd = setFn(nd, true)
28 :     end
29 :    
30 :     (* walk the statements, marking the first nodes of the statements *)
31 :     fun markNodes (stm as SrcIL.STM{kind, next}) = (
32 :     case kind
33 :     of SrcIL.S_SIMPLE nd => markFirst (nd, stm)
34 :     | SrcIL.S_IF{cond, thenBranch, elseBranch} => (
35 :     markFirst (cond, stm);
36 :     markNodes thenBranch;
37 :     markNodes elseBranch)
38 :     | SrcIL.S_LOOP{hdr, cond, body} => (
39 :     markNodes hdr;
40 :     markFirst (cond, stm);
41 :     markNodes body)
42 :     (* end case *);
43 :     case next
44 :     of NONE => ()
45 :     | SOME stm => markNodes stm
46 :     (* end case *))
47 :    
48 : jhr 454 (* a mapping from LowIL variables to target expressions. Variables get
49 :     * removed when the expressions are used as arguments.
50 :     *)
51 :     structure VDefTbl : sig
52 :     type tbl
53 :    
54 :     val newTbl : unit -> tbl
55 :     val getDefOf : tbl -> SrcV.var -> T.exp
56 :     val useDefOf : tbl -> SrcV.var -> T.exp
57 :     val setDefOf : tbl -> (SrcV.var * T.exp) -> unit
58 :    
59 :     val clear : tbl -> unit
60 :    
61 : jhr 455 val bind : tbl -> (SrcV.var * T.exp) -> T.stm list
62 : jhr 454
63 : jhr 455 (* force all pending expressions into variables *)
64 :     val flush : tbl -> T.stm list
65 :    
66 : jhr 454 end = struct
67 :    
68 : jhr 455 type info = {
69 :     cnt : int ref, (* count of oustanding uses (usually 1) *)
70 :     bind : T.exp
71 :     }
72 :    
73 :     type tbl = info SrcV.Tbl.hash_table
74 :    
75 :     fun newTbl () = SrcV.Tbl.mkTable (512, Fail "vtbl")
76 :    
77 :     fun getDefOf tbl x = (case SrcV.Tbl.find tbl x
78 :     of NONE => ??
79 :     | SOME{bind, cnt} => bind
80 :     (* end case *))
81 :    
82 :     fun useDefOf tbl x = (case SrcV.Tbl.find tbl x
83 :     of NONE => ??
84 :     | SOME{cnt=ref n, bind} => (
85 :     ignore (SrcV.Tbl.remove tbl x);
86 :     bind)
87 :     | SOME{cnt, bind} => => (
88 :     cnt := !cnt - 1;
89 :     bind)
90 :     (* end case *))
91 :    
92 :     fun setDefOf tbl (x, exp) =
93 :     SrcV.Tbl.insert tbl (x, {cnt = ref(SrcV.useCount x), bind = exp})
94 :    
95 :     fun assign tbl (x, exp) = let
96 :     val lhs : T.local_var = ??
97 :     in
98 :     SrcV.Tbl.insert tbl
99 :     (x, {cnt = SrcV.useCount x, bind = T.Expr.var lhs});
100 :     [T.Stmt.assign(lhs, exp)]
101 :     end
102 :    
103 :     fun bind tbl (x, exp) = (case SrcV.useCount lhs
104 :     of 1 => (SrcV.Tbl.insert tbl (x, {cnt = 1, bind = exp}); [])
105 :     | n => let (* bind exp to a new target variable *)
106 :     val lhs : T.local_var = ??
107 :     in
108 :     SrcV.Tbl.insert tbl (x, {cnt = n, bind = T.Expr.var lhs});
109 :     [T.Stmt.assign(lhs, exp)]
110 :     end
111 :     (* end case *))
112 :    
113 : jhr 454 end (* VDefTbl *)
114 :    
115 : jhr 455 (* FIXME: what about splitting code where the target width doesn't match the
116 :     * source width?
117 :     *)
118 :     fun doRator (vtbl, lhs, rator, args) = let
119 :     val args' = List.map (VDefTbl.useDefOf vtbl) args
120 :     val rhs' = (case rator
121 :     (* ??? *)
122 :     (* end case *))
123 :     in
124 :     VDefTbl.bind vtbl (lhs, rhs')
125 :     end
126 : jhr 454
127 : jhr 455 (* translate a LowIL assignment to a list of zero or more target statements *)
128 :     fun doAssign vtbl (lhs, rhs) = let
129 :     fun setDef rhs = (VTbl.setDefOf vtbl (lhs, rhs); [])
130 :     in
131 :     case rhs
132 :     of Src.VAR x => setDef (T.Expr.var(VDefTbl.useDefOf vtbl x))
133 :     | Src.LIT(Literal.Int n) => setDef (T.Expr.intLit n)
134 :     | Src.LIT(Literal.Bool b) => setDef (T.Expr.boolLit b)
135 :     | Src.LIT(Literal.Float f) => setDef (T.Expr.floatLit f)
136 :     | Src.LIT(Literal.String s) => setDef (T.Expr.stringLit s)
137 :     | Src.OP(rator, args) => doRator(vtbl, lhs, rator, args)
138 :     | Src.CONS args =>
139 :     VTbl.assign ctbl (lhs, T.Expr.vector (List.map (VDefTbl.useDefOf vtbl) args))
140 :     (* end case *)
141 :     end
142 :    
143 :     fun gen (vtbl, stm) = let
144 :     val doAssign = doAssign vtbl
145 : jhr 456 fun mkBlock [] = ?
146 :     | mkBlock [s] = s
147 :     | mkBlock stms = T.Stmt.block stms
148 : jhr 455 fun doStmt (SrcIL.STM{kind, next, ...}) = let
149 :     val stms = (case kind
150 :     of SrcIL.S_SIMPLE nd => doNode nd
151 : jhr 456 | SrcIL.S_IF{cond, thenBranch, elseBranch} => let
152 :     val SrcIL.ND{kind=SrcIL.COND{cond, ...}, ...} = cond
153 :     val s1 = mkBlock(doStmt thenBranch)
154 :     val s2 = mkBlock(doStmt elseBranch)
155 :     in
156 :     (* FIXME: check for empty else branch *)
157 :     T.ifthenelse(VDefTbl.useDefOf vtbl cond, s1, s2)
158 :     end
159 :     | SrcIL.S_LOOP{hdr, cond, body} => raise Fail "LOOP not supported yet"
160 : jhr 455 (* end case *))
161 :     val rest = (case next
162 :     of NONE => VDefTbl.flush vtbl
163 :     | SOME stm = doStmt stm
164 :     (* end case *))
165 :     in
166 :     stms @ rest
167 :     end
168 : jhr 456 and doNode (SrcIL.ND{kind, ...}) = (case kind
169 :     of SrcIL.NULL => ??
170 :     | SrcIL.ENTRY{succ} => nextNode succ
171 :     | SrcIL.JOIN{succ, ...} =>
172 :     | SrcIL.COND{cond, ...} =>
173 :     | SrcIL.BLOCK{body, succ, ...} =>
174 :     List.app doAssign body @ nextNode succ
175 :     | SrcIL.NEW{actor, args, ...} =>
176 :     | SrcIL.DIE _ =>
177 :     | SrcIL.STABILIZE _ =>
178 :     | SrcIL.EXIT _ =>
179 :     (* end case *))
180 :     and nextNode nd = if isFirst nd then [] else doNode nd
181 : jhr 455 in
182 : jhr 456 mkBlock (doStmt stm)
183 : jhr 455 end
184 :    
185 : jhr 454 end

root@smlnj-gforge.cs.uchicago.edu
ViewVC Help
Powered by ViewVC 1.0.0