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 754 - (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 : jhr 518 val generate : string * LowIL.program -> unit
14 : jhr 454
15 :     end = struct
16 :    
17 : jhr 532 structure IL = TreeIL
18 :     structure Ty = IL.Ty
19 :     structure Op = IL.Op
20 :     structure V = IL.Var
21 : jhr 454
22 : jhr 525 (* convert LowIL types to T types *)
23 :     fun cvtTy ty = (case ty
24 :     of Ty.BoolTy => T.boolTy
25 : jhr 533 | Ty.StringTy => T.stringTy
26 : jhr 525 | Ty.IVecTy 1 => T.intTy
27 :     | Ty.IVecTy n => T.ivecTy n (* FIXME: what about vector splits? *)
28 : jhr 736 | Ty.TensorTy[] => T.realTy
29 :     | Ty.TensorTy[d] => T.vecTy d (* FIXME: what about vector splits? *)
30 :     | Ty.TensorTy dd => T.tensorTy dd
31 : jhr 548 | Ty.AddrTy info => T.imageDataTy info
32 :     | Ty.ImageTy info => T.imageTy info
33 : jhr 525 (* end case *))
34 :    
35 : jhr 544 fun addBindings (env, xs, ys) =
36 :     ListPair.foldlEq (fn (x, y, env) => V.Map.insert(env, x, y)) env (xs, ys)
37 :    
38 : jhr 532 fun lookup (env, x) = (case V.Map.find (env, x)
39 :     of SOME x' => x'
40 : jhr 534 | NONE => raise Fail(concat["lookup(_, ", V.name x, ")"])
41 : jhr 532 (* end case *))
42 :    
43 :     fun trExp (env, e) = (case e
44 :     of IL.E_Var x => (case V.kind x
45 :     of IL.VK_Global => T.Expr.global(lookup(env, x))
46 : jhr 552 | IL.VK_State strand => T.Expr.getState(lookup(env, x))
47 : jhr 532 | IL.VK_Local => T.Expr.var(lookup(env, x))
48 :     (* end case *))
49 :     | IL.E_Lit(Literal.Int n) => T.Expr.intLit n
50 :     | IL.E_Lit(Literal.Bool b) => T.Expr.boolLit b
51 :     | IL.E_Lit(Literal.Float f) => T.Expr.floatLit f
52 :     | IL.E_Lit(Literal.String s) => T.Expr.stringLit s
53 :     | IL.E_Op(rator, args) => (case (rator, trExps(env, args))
54 :     of (Op.Add ty, [a, b]) => T.Expr.add(a, b)
55 :     | (Op.Sub ty, [a, b]) => T.Expr.sub(a, b)
56 :     | (Op.Mul ty, [a, b]) => T.Expr.mul(a, b)
57 :     | (Op.Div ty, [a, b]) => T.Expr.divide(a, b)
58 :     | (Op.Neg ty, [a]) => T.Expr.neg a
59 : jhr 718 | (Op.Abs ty, [a]) => T.Expr.abs a
60 : jhr 532 | (Op.LT ty, [a, b]) => T.Expr.lt(a, b)
61 :     | (Op.LTE ty, [a, b]) => T.Expr.lte(a, b)
62 :     | (Op.EQ ty, [a, b]) => T.Expr.equ(a, b)
63 :     | (Op.NEQ ty, [a, b]) => T.Expr.neq(a, b)
64 :     | (Op.GT ty, [a, b]) => T.Expr.gt(a, b)
65 :     | (Op.GTE ty, [a, b]) => T.Expr.gte(a, b)
66 :     | (Op.Not, [a]) => T.Expr.not a
67 :     | (Op.Max, [a, b]) => T.Expr.max(a, b)
68 :     | (Op.Min, [a, b]) => T.Expr.min(a, b)
69 : jhr 754 | (Op.Lerp ty, [a, b, c]) => T.Expr.lerp(a, b, c)
70 : jhr 532 | (Op.Dot d, [a, b]) => T.Expr.dot(a, b)
71 :     | (Op.Cross, [a, b]) => T.Expr.cross(a, b)
72 :     | (Op.Select(ty, i), [a]) => T.Expr.select(i, a)
73 :     | (Op.Norm d, [a]) => T.Expr.length a
74 : jhr 718 | (Op.Normalize d, [a]) => T.Expr.normalize a
75 : jhr 739 | (Op.Trace d, [a]) => T.Expr.trace a
76 : jhr 532 | (Op.Scale d, [a, b]) => T.Expr.mul(a, b)
77 :     | (Op.InvScale d, [a, b]) => T.Expr.divide(a, b)
78 : jhr 518 | (Op.CL, _) => raise Fail "CL unimplemented"
79 :     | (Op.PrincipleEvec ty, _) => raise Fail "PrincipleEvec unimplemented"
80 : jhr 705 | (Op.Subscript ty, [t, ix]) => T.Expr.subscript(t, ix)
81 : jhr 701 | (Op.Subscript ty, t::(ixs as _::_)) => raise Fail "Subscript unimplemented"
82 : jhr 565 | (Op.Ceiling d, [a]) => T.Expr.ceil a
83 : jhr 532 | (Op.Floor d, [a]) => T.Expr.floor a
84 : jhr 565 | (Op.Round d, [a]) => T.Expr.round a
85 :     | (Op.Trunc d, [a]) => T.Expr.trunc a
86 : jhr 532 | (Op.IntToReal, [a]) => T.Expr.toReal a
87 : jhr 565 | (Op.RealToInt d, [a]) => T.Expr.toInt a
88 : jhr 548 | (Op.ImageAddress d, [a]) => T.Expr.imageAddr a
89 :     | (Op.LoadVoxels(info, 1), [a]) => T.Expr.getImgData a
90 :     | (Op.LoadVoxels _, [a]) => raise Fail "impossible"
91 :     | (Op.PosToImgSpace d, [v, x]) => T.Expr.posToImgSpace(v, x)
92 : jhr 532 | (Op.GradToWorldSpace d, [v, x]) => T.Expr.intLit 0 (* FIXME *)
93 : jhr 547 | (Op.LoadImage info, [a]) => raise Fail "impossible"
94 : jhr 548 | (Op.Inside(d, s), [x, v]) => T.Expr.inside(x, v, s)
95 : jhr 547 | (Op.Input(ty, name), []) => raise Fail "impossible"
96 : jhr 532 | (Op.InputWithDefault(ty, name), [a]) => T.Expr.intLit 0 (* FIXME *)
97 : jhr 528 | _ => raise Fail(concat[
98 : jhr 754 "unknown or incorrect operator ", Op.toString rator
99 : jhr 528 ])
100 : jhr 518 (* end case *))
101 : jhr 695 | IL.E_Apply(f, args) => T.Expr.apply(f, trExps(env, args))
102 : jhr 532 (* end case *))
103 : jhr 454
104 : jhr 532 and trExps (env, exps) = List.map (fn exp => trExp(env, exp)) exps
105 : jhr 455
106 : jhr 624 fun trBlock (env, saveState, blk) = let
107 : jhr 563 fun trStmt (env, stm) = (case stm
108 :     of IL.S_Comment text => [T.Stmt.comment text]
109 :     | IL.S_Assign(x, exp) => (case V.kind x
110 :     of IL.VK_Global => [T.Stmt.assign(lookup(env, x), trExp(env, exp))]
111 :     | IL.VK_State strand =>
112 :     [T.Stmt.assignState(lookup(env, x), trExp(env, exp))]
113 :     | IL.VK_Local => [T.Stmt.assign(lookup(env, x), trExp(env, exp))]
114 :     (* end case *))
115 : jhr 615 | IL.S_IfThen(cond, thenBlk) =>
116 : jhr 624 [T.Stmt.ifthen(trExp(env, cond), trBlk(env, thenBlk))]
117 : jhr 615 | IL.S_IfThenElse(cond, thenBlk, elseBlk) =>
118 :     [T.Stmt.ifthenelse(trExp(env, cond),
119 : jhr 624 trBlk(env, thenBlk),
120 :     trBlk(env, elseBlk))]
121 : jhr 615 | IL.S_For(x, e1, e2, blk) => let
122 :     val x' = T.Var.var(cvtTy(V.ty x), V.name x)
123 :     val env' = V.Map.insert(env, x, x')
124 :     in [
125 : jhr 624 T.Stmt.for(x', trExp(env, e1), trExp(env, e2), trBlk(env', blk))
126 : jhr 615 ] end
127 : jhr 563 | IL.S_Cons(lhs, args) =>
128 :     [T.Stmt.cons(lookup(env, lhs), trExps(env, args))]
129 :     | IL.S_LoadVoxels(lhs, dim, addr) =>
130 :     T.Stmt.getImgData(lookup(env, lhs), trExp(env, addr))
131 :     | IL.S_LoadImage(lhs, dim, name) =>
132 :     T.Stmt.loadImage (lookup(env, lhs), dim, trExp(env, name))
133 :     | IL.S_Input(lhs, name, optDflt) =>
134 :     T.Stmt.input(lookup(env, lhs), name, Option.map (fn e => trExp(env, e)) optDflt)
135 :     (* FIXME: what about the args? *)
136 :     | IL.S_Exit args => [T.Stmt.exit()]
137 : jhr 624 | IL.S_Active args => saveState (env, args, T.Stmt.active())
138 :     | IL.S_Stabilize args => saveState (env, args, T.Stmt.stabilize())
139 : jhr 563 | IL.S_Die => [T.Stmt.die()]
140 : jhr 512 (* end case *))
141 : jhr 624 and trBlk (env, IL.Block{locals, body}) = let
142 : jhr 563 val env = List.foldl
143 :     (fn (x, env) => V.Map.insert(env, x, T.Var.var(cvtTy(V.ty x), V.name x)))
144 :     env locals
145 :     val stms = List.foldr (fn (stm, stms) => trStmt(env, stm)@stms) [] body
146 :     val stms = List.foldr
147 :     (fn (x, stms) => T.Stmt.decl(lookup(env, x), NONE)::stms)
148 :     stms locals
149 :     in
150 :     T.Stmt.block stms
151 :     end
152 : jhr 544 in
153 : jhr 624 trBlk (env, blk)
154 : jhr 544 end
155 : jhr 528
156 : jhr 624 fun trTopBlock (env, blk) = trBlock (env, fn _ => raise Fail "unexpected state save", blk)
157 : jhr 547
158 : jhr 624 fun trMethod (strand, stateVars, env) (IL.Method{name, body}) = let
159 :     fun saveState (env, args, stm) =
160 :     ListPair.foldrEq
161 :     (fn (x, e, stms) => T.Stmt.assignState(x, trExp(env, e))::stms)
162 :     [stm]
163 :     (stateVars, args)
164 :     val body = trBlock (env, saveState, body)
165 :     in
166 :     T.Strand.method (strand, Atom.toString name, body)
167 :     end
168 :    
169 : jhr 544 fun trStrand (prog, env) (IL.Strand{name, params, state, stateInit, methods}) = let
170 : jhr 624 val strand = T.Strand.define(prog, name)
171 : jhr 654 (* map the state variables to target state variables, while extending the environment
172 :     * and registering the output variables.
173 :     *)
174 :     val (env, state') = let
175 :     fun cvtSVar ((isOut, x), (env, xs)) = let
176 :     val x' = T.Var.state(strand, cvtTy(V.ty x), V.name x)
177 :     in
178 :     if isOut then T.Strand.output(strand, x') else ();
179 :     (V.Map.insert(env, x, x'), x'::xs)
180 :     end
181 :     in
182 :     List.foldr cvtSVar (env, []) state
183 :     end
184 : jhr 544 (* define the parameters and add them to the environment *)
185 :     val params' = List.map (fn x => T.Var.param(cvtTy(V.ty x), V.name x)) params
186 :     val env = addBindings (env, params, params')
187 :     in
188 : jhr 624 T.Strand.init (strand, params', trTopBlock (env, stateInit));
189 : jhr 563 List.app (trMethod (strand, state', env)) methods
190 : jhr 544 end
191 :    
192 : jhr 624 fun trInitially (env0, prog, {isArray, iterPrefix, iters, createPrefix, strand, args}) = let
193 :     fun trIter ((param, lo, hi), (env, iters)) = let
194 :     val param' = T.Var.var(cvtTy(V.ty param), V.name param)
195 :     val env = V.Map.insert(env, param, param')
196 :     val iter = (param', trExp (env0, lo), trExp (env0, hi))
197 :     in
198 :     (env, iter::iters)
199 :     end
200 :     val (env, iters) = List.foldr trIter (env0, []) iters
201 :     in
202 :     T.initially {
203 :     prog = prog,
204 :     isArray = isArray,
205 :     iterPrefix = trTopBlock (env0, iterPrefix),
206 :     iters = iters,
207 :     createPrefix = trTopBlock (env, createPrefix),
208 :     strand = strand,
209 :     args = trExps (env, args)
210 :     }
211 :     end
212 :    
213 : jhr 531 fun generate (fileStem, srcProg) = let
214 : jhr 624 val treeProg as TreeIL.Program{globals, globalInit, strands, initially} = LowToTree.translate srcProg
215 : jhr 535 val _ = (
216 :     TextIO.output(Log.logFile(), "********** After translation to TreeIL **********\n");
217 :     TreeILPP.program (Log.logFile(), treeProg))
218 : jhr 527 val prog = T.newProgram ()
219 : jhr 532 (* define the globals and initialize the environment *)
220 :     val env = let
221 :     fun gvar (x, env) =
222 :     V.Map.insert(env, x, T.Var.global(prog, cvtTy(V.ty x), V.name x))
223 :     in
224 :     List.foldl gvar V.Map.empty globals
225 :     end
226 : jhr 527 in
227 : jhr 533 (* global initialization *)
228 : jhr 624 T.globalInit (prog, trTopBlock (env, globalInit));
229 : jhr 544 (* translate strands *)
230 :     List.app (trStrand (prog, env)) strands;
231 : jhr 624 (* generate the initially function *)
232 :     trInitially (env, prog, initially);
233 : jhr 528 (* output the program *)
234 : jhr 527 T.generate (fileStem, prog)
235 :     end
236 : jhr 518
237 : jhr 454 end

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