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

SCM Repository

[diderot] Annotation of /branches/pure-cfg/src/compiler/codegen/codegen-fn.sml
ViewVC logotype

Annotation of /branches/pure-cfg/src/compiler/codegen/codegen-fn.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 514 - (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 : jhr 512 structure IL = LowIL
18 :     structure V = LowIL.Var
19 :     structure Op = LowOps
20 :     structure Nd = LowIL.Node
21 : jhr 514 structure CFG = LowIL.CFG
22 : jhr 454
23 :     (* a mapping from LowIL variables to target expressions. Variables get
24 :     * removed when the expressions are used as arguments.
25 :     *)
26 :     structure VDefTbl : sig
27 :     type tbl
28 :    
29 : jhr 514 datatype binding = C of T.cond | E of T.exp
30 :    
31 : jhr 454 val newTbl : unit -> tbl
32 : jhr 514 val getDefOf : tbl -> IL.var -> binding
33 :     val useDefOf : tbl -> IL.var -> binding
34 :     val setDefOf : tbl -> (IL.var * T.exp) -> unit
35 : jhr 454
36 :     val clear : tbl -> unit
37 :    
38 : jhr 514 val assign : tbl -> (IL.var * T.exp) -> T.stm list
39 :     val bind : tbl -> (IL.var * T.exp) -> T.stm list
40 :     val cbind : tbl -> (IL.var * T.cond) -> T.stm list
41 : jhr 454
42 : jhr 455 (* force all pending expressions into variables *)
43 :     val flush : tbl -> T.stm list
44 :    
45 : jhr 454 end = struct
46 :    
47 : jhr 514 datatype binding = C of T.cond | E of T.exp
48 :    
49 : jhr 455 type info = {
50 :     cnt : int ref, (* count of oustanding uses (usually 1) *)
51 : jhr 514 bind : binding
52 : jhr 455 }
53 :    
54 : jhr 512 type tbl = info V.Tbl.hash_table
55 : jhr 455
56 : jhr 512 fun newTbl () = V.Tbl.mkTable (512, Fail "vtbl")
57 : jhr 455
58 : jhr 512 fun getDefOf tbl x = (case V.Tbl.find tbl x
59 : jhr 514 of NONE => raise Fail(concat["getDefOf(", V.toString x, ")"])
60 : jhr 455 | SOME{bind, cnt} => bind
61 :     (* end case *))
62 :    
63 : jhr 512 fun useDefOf tbl x = (case V.Tbl.find tbl x
64 : jhr 514 of NONE => raise Fail(concat["useDefOf(", V.toString x, ")"])
65 : jhr 512 | SOME{cnt=ref 1, bind} => (
66 :     ignore (V.Tbl.remove tbl x);
67 : jhr 455 bind)
68 : jhr 514 | SOME{cnt, bind} => (
69 : jhr 455 cnt := !cnt - 1;
70 :     bind)
71 :     (* end case *))
72 :    
73 :     fun setDefOf tbl (x, exp) =
74 : jhr 514 V.Tbl.insert tbl (x, {cnt = ref(V.useCount x), bind = E exp})
75 : jhr 455
76 :     fun assign tbl (x, exp) = let
77 : jhr 514 val lhs = T.Var.tmpVar()
78 : jhr 455 in
79 : jhr 512 V.Tbl.insert tbl
80 : jhr 514 (x, {cnt = ref(V.useCount x), bind = E(T.Expr.var lhs)});
81 : jhr 455 [T.Stmt.assign(lhs, exp)]
82 :     end
83 :    
84 : jhr 514 fun bind tbl (x, exp) = (case V.useCount x
85 :     of 1 => (V.Tbl.insert tbl (x, {cnt = ref 1, bind = E exp}); [])
86 : jhr 455 | n => let (* bind exp to a new target variable *)
87 : jhr 514 val lhs = T.Var.tmpVar()
88 : jhr 455 in
89 : jhr 514 V.Tbl.insert tbl (x, {cnt = ref n, bind = E(T.Expr.var lhs)});
90 : jhr 455 [T.Stmt.assign(lhs, exp)]
91 :     end
92 :     (* end case *))
93 :    
94 : jhr 514 fun cbind tbl (x, cond) = (case V.useCount x
95 :     of 1 => (V.Tbl.insert tbl (x, {cnt = ref 1, bind = C cond}); [])
96 :     | n => let (* bind exp to a new target variable *)
97 :     val lhs = T.Var.tmpVar()
98 :     in
99 :     V.Tbl.insert tbl (x, {cnt = ref n, bind = C(T.Cond.var lhs)});
100 :     [T.Stmt.assignb(lhs, cond)]
101 :     end
102 :     (* end case *))
103 :    
104 :     val clear = V.Tbl.clear
105 :    
106 :     fun flush tbl = raise Fail "flush"
107 :    
108 : jhr 454 end (* VDefTbl *)
109 :    
110 : jhr 455 (* FIXME: what about splitting code where the target width doesn't match the
111 :     * source width?
112 :     *)
113 : jhr 514 fun doRator vtbl = let
114 :     val useDefOf = VDefTbl.useDefOf vtbl
115 :     val bind = VDefTbl.bind vtbl
116 :     val cbind = VDefTbl.cbind vtbl
117 :     fun f (lhs, rator, args) = let
118 :     fun exp x = (case useDefOf x
119 :     of VDefTbl.E e => e
120 :     | _ => raise Fail "expected exp"
121 :     (* end case *))
122 :     fun cond x = (case useDefOf x
123 :     of VDefTbl.C c => c
124 :     | _ => raise Fail "expected cond"
125 :     (* end case *))
126 :     in
127 :     case (rator, args)
128 :     of (Op.Add ty, [a, b]) => bind (lhs, T.Expr.add(exp a, exp b))
129 :     | (Op.Sub ty, [a, b]) => bind (lhs, T.Expr.sub(exp a, exp b))
130 :     | (Op.Mul ty, [a, b]) => bind (lhs, T.Expr.mul(exp a, exp b))
131 :     | (Op.Div ty, [a, b]) => bind (lhs, T.Expr.divide(exp a, exp b))
132 :     | (Op.Neg ty, [a]) => bind (lhs, T.Expr.neg(exp a))
133 :     | (Op.LT ty, [a, b]) => cbind (lhs, T.Cond.lt(exp a, exp b))
134 :     | (Op.LTE ty, [a, b]) => cbind (lhs, T.Cond.lte(exp a, exp b))
135 :     | (Op.EQ ty, [a, b]) => cbind (lhs, T.Cond.equ(exp a, exp b))
136 :     | (Op.NEQ ty, [a, b]) => cbind (lhs, T.Cond.neq(exp a, exp b))
137 :     | (Op.GT ty, [a, b]) => cbind (lhs, T.Cond.gt(exp a, exp b))
138 :     | (Op.GTE ty, [a, b]) => cbind (lhs, T.Cond.gte(exp a, exp b))
139 :     | (Op.Not, [a]) => cbind (lhs, T.Cond.not(cond a))
140 :     | (Op.Max, [a, b]) => bind (lhs, T.Expr.max(exp a, exp b))
141 :     | (Op.Min, [a, b]) => bind (lhs, T.Expr.min(exp a, exp b))
142 :     | (Op.Sin, [a]) => bind (lhs, T.Expr.sin(exp a))
143 :     | (Op.Cos, [a]) => bind (lhs, T.Expr.cos(exp a))
144 :     | (Op.Pow, [a, b]) => bind (lhs, T.Expr.pow(exp a, exp b))
145 :     | (Op.Dot d, [a, b]) => bind (lhs, T.Expr.dot(exp a, exp b))
146 :     | (Op.Cross, [a, b]) => bind (lhs, T.Expr.cross(exp a, exp b))
147 :     | (Op.Select(ty, i), [a]) => bind (lhs, T.Expr.select(i, exp a))
148 :     | (Op.Norm d, [a]) => bind (lhs, T.Expr.length(exp a))
149 :     | (Op.Scale d, [a, b]) => bind (lhs, T.Expr.mul(exp a, exp b))
150 :     | (Op.InvScale d, [a, b]) => bind (lhs, T.Expr.divide(exp a, exp b))
151 :     | (Op.CL, _) => raise Fail "CL unimplemented"
152 :     | (Op.PrincipleEvec ty, _) => raise Fail "PrincipleEvec unimplemented"
153 :     (*
154 :     | (Op.Subscript ty,
155 :     *)
156 :     | (Op.Floor d, [a]) => bind (lhs, T.Expr.floor(exp a))
157 :     | (Op.IntToReal, [a]) => bind (lhs, T.Expr.toReal(exp a))
158 :     | (Op.TruncToInt d, [a]) => bind (lhs, T.Expr.truncToInt(exp a))
159 :     | (Op.RoundToInt d, [a]) => bind (lhs, T.Expr.roundToInt(exp a))
160 :     | (Op.CeilToInt d, [a]) => bind (lhs, T.Expr.ceilToInt(exp a))
161 :     | (Op.FloorToInt d, [a]) => bind (lhs, T.Expr.floorToInt(exp a))
162 :     (*
163 :     | (Op.ImageAddress of ImageInfo.info
164 :     | (Op.LoadVoxels of RawTypes.ty * int
165 :     | (Op.PosToImgSpace of ImageInfo.info
166 :     | (Op.GradToWorldSpace of ImageInfo.info
167 :     | (Op.LoadImage of ImageInfo.info
168 :     | (Op.Inside of ImageInfo.info
169 :     | (Op.Input of ty * string
170 :     | (Op.InputWithDefault of ty * string
171 :     *)
172 :     (* end case *)
173 :     end
174 : jhr 455 in
175 : jhr 514 f
176 : jhr 455 end
177 : jhr 454
178 : jhr 455 (* translate a LowIL assignment to a list of zero or more target statements *)
179 :     fun doAssign vtbl (lhs, rhs) = let
180 : jhr 514 val setDefOf = VDefTbl.setDefOf vtbl
181 :     val doRator = doRator vtbl
182 :     fun assign (lhs, rhs) = let
183 :     fun setDef rhs = (setDefOf (lhs, rhs); [])
184 :     in
185 :     case rhs
186 :     of IL.VAR x => setDef (T.Expr.var(VDefTbl.useDefOf vtbl x))
187 :     | IL.LIT(Literal.Int n) => setDef (T.Expr.intLit n)
188 :     | IL.LIT(Literal.Bool b) => setDef (T.Expr.boolLit b)
189 :     | IL.LIT(Literal.Float f) => setDef (T.Expr.floatLit f)
190 :     | IL.LIT(Literal.String s) => setDef (T.Expr.stringLit s)
191 :     | IL.OP(rator, args) => doRator(lhs, rator, args)
192 :     | IL.CONS args =>
193 :     VDefTbl.assign vtbl
194 :     (lhs, T.Expr.vector (List.map (VDefTbl.useDefOf vtbl) args))
195 :     (* end case *)
196 :     end
197 : jhr 455 in
198 : jhr 514 assign
199 : jhr 455 end
200 :    
201 : jhr 512 fun gen (vtbl, cfg) = let
202 :     val doAssign = doAssign vtbl
203 : jhr 513 fun doNode (vtbl, ifCont, stms, nd) = (case Nd.kind nd
204 :     of IL.NULL => raise Fail "unexpected NULL"
205 : jhr 514 | IL.ENTRY{succ} => doNode (vtbl, ifCont, stms, !succ)
206 :     | IL.JOIN{phis, succ, ...} => ifCont (stms, Node.kind nd)
207 : jhr 512 | IL.COND{cond, trueBranch, falseBranch, ...} => let
208 :     fun kThen (stms', _) = let
209 :     val thenBlk = T.Stmt.block (List.rev stms')
210 : jhr 513 fun kElse (stms', IL.JOIN{phis, succ, ...}) = let
211 : jhr 512 val stm = T.Stmt.ifthenelse (
212 :     VDefTbl.useDefOf vtbl cond,
213 :     thenBlk,
214 :     T.Stmt.block (List.rev stms'))
215 :     in
216 : jhr 513 (* FIXME: what do we do about phis? *)
217 : jhr 514 doNode (vtbl, ifCont, stm::stms, !succ)
218 : jhr 512 end
219 :     in
220 : jhr 514 doNode (vtbl, kElse, [], !falseBranch)
221 : jhr 512 end
222 :     in
223 : jhr 514 doNode (vtbl, kThen, [], !trueBranch)
224 : jhr 512 end
225 :     | IL.COM {text, succ, ...} =>
226 : jhr 514 doNode (vtbl, ifCont, T.Stmt.comment text :: stms, !succ)
227 : jhr 512 | IL.ASSIGN{stm, succ, ...} =>
228 : jhr 514 doNode (vtbl, ifCont, doAssign stm :: stms, !succ)
229 : jhr 513 | IL.NEW{strand, args, succ, ...} => raise Fail "NEW unimplemented"
230 : jhr 512 | IL.DIE _ =>
231 : jhr 514 T.Stmt.block (List.rev (T.Stmt.die() :: stms))
232 : jhr 512 | IL.STABILIZE _ =>
233 : jhr 514 T.Stmt.block (List.rev stms)
234 :     | IL.EXIT _ => T.Stmt.block (List.rev (T.Stmt.stabilize() :: stms))
235 : jhr 512 (* end case *))
236 :     in
237 : jhr 513 doNode (vtbl, fn _ => raise Fail "bogus ifCont at JOIN node", [], CFG.entry cfg)
238 : jhr 512 end
239 :    
240 : jhr 454 end

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