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

SCM Repository

[diderot] Annotation of /branches/charisee/src/compiler/mid-to-low/mid-to-low.sml
ViewVC logotype

Annotation of /branches/charisee/src/compiler/mid-to-low/mid-to-low.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 2611 - (view) (download)

1 : lamonts 345 (* mid-to-low.sml
2 :     *
3 : jhr 435 * COPYRIGHT (c) 2010 The Diderot Project (http://diderot-language.cs.uchicago.edu)
4 : lamonts 345 * All rights reserved.
5 :     *
6 :     * Translation from MidIL to LowIL representations.
7 :     *)
8 :    
9 :     structure MidToLow : sig
10 :    
11 : jhr 459 val translate : MidIL.program -> LowIL.program
12 : lamonts 345
13 : jhr 387 end = struct
14 : lamonts 345
15 :     structure SrcIL = MidIL
16 :     structure SrcOp = MidOps
17 : jhr 1640 structure SrcSV = SrcIL.StateVar
18 :     structure SrcTy = MidILTypes
19 : jhr 387 structure VTbl = SrcIL.Var.Tbl
20 : lamonts 345 structure DstIL = LowIL
21 : jhr 464 structure DstTy = LowILTypes
22 : lamonts 345 structure DstOp = LowOps
23 : cchiw 2521 structure E=Ein
24 : cchiw 2522 structure P=Printer
25 : cchiw 2611 structure X=checkEin
26 : cchiw 2523
27 : cchiw 2522 structure genEin=genEin
28 : lamonts 345
29 : cchiw 2522
30 : cchiw 2521
31 : jhr 1640 (* instantiate the translation environment *)
32 :     local
33 :     type var_env = DstIL.var VTbl.hash_table
34 :     type state_var_env = DstIL.state_var SrcSV.Tbl.hash_table
35 : jhr 387
36 : jhr 1640 fun rename (env : var_env, x) = (case VTbl.find env x
37 :     of SOME x' => x'
38 :     | NONE => let
39 :     val x' = DstIL.Var.new (SrcIL.Var.name x, SrcIL.Var.ty x)
40 :     in
41 :     VTbl.insert env (x, x');
42 :     x'
43 :     end
44 :     (* end case *))
45 : lamonts 345
46 : jhr 1640 fun renameSV (env : state_var_env, x) = (case SrcSV.Tbl.find env x
47 :     of SOME x' => x'
48 :     | NONE => let
49 :     val x' = DstIL.StateVar.new (SrcSV.isOutput x, SrcSV.name x, SrcSV.ty x)
50 :     in
51 :     SrcSV.Tbl.insert env (x, x');
52 :     x'
53 :     end
54 :     (* end case *))
55 :     in
56 :     structure Env = TranslateEnvFn (
57 :     struct
58 :     structure SrcIL = SrcIL
59 :     structure DstIL = DstIL
60 : cchiw 2522
61 : jhr 1640 type var_env = var_env
62 :     type state_var_env = state_var_env
63 :     val rename = rename
64 :     val renameSV = renameSV
65 :     end)
66 :     end (* local *)
67 :    
68 : cchiw 2398
69 : cchiw 2397 fun iadd (r : DstIL.var, a, b) = (r, DstIL.OP(DstOp.IAdd, [a, b]))
70 : jhr 1116 fun ilit (r : DstIL.var, n) = (r, DstIL.LIT(Literal.Int(IntInf.fromInt n)))
71 : cchiw 2522 fun ilit (r : DstIL.var, n) = (r, DstIL.LIT(Literal.Int(IntInf.fromInt n)))
72 :     fun imul (r : DstIL.var, a, b) = (r, DstIL.OP(DstOp.IMul, [a, b]))
73 : jhr 511
74 : cchiw 2522
75 : cchiw 2400
76 : jhr 1116 (* FIXME: we will get better down-stream CSE if we structure the address computation
77 :     * as
78 :     * (base + stride * (...)) + offset
79 :     * since the lhs argument will be the same for each sample.
80 :     *)
81 :     (* add code to handle the offset and stride when addressing non-scalar image data *)
82 :     fun adjustForStrideAndOffset (1, _, ix, code) = (ix, code)
83 :     | adjustForStrideAndOffset (stride, 0, ix, code) = let
84 :     val offp = DstIL.Var.new ("offp", DstTy.intTy)
85 :     val stride' = DstIL.Var.new ("stride", DstTy.intTy)
86 :     in
87 :     (offp, imul(offp, stride', ix) :: ilit(stride', stride) :: code)
88 :     end
89 :     | adjustForStrideAndOffset (stride, offset, ix, code) = let
90 :     val offp = DstIL.Var.new ("offp", DstTy.intTy)
91 :     val stride' = DstIL.Var.new ("stride", DstTy.intTy)
92 :     val offset' = DstIL.Var.new ("offset", DstTy.intTy)
93 :     val t = DstIL.Var.new ("t", DstTy.intTy)
94 :     val code =
95 :     iadd(offp, offset', t) ::
96 :     ilit (offset', offset) ::
97 :     imul(t, stride', ix) ::
98 :     ilit (stride', stride) ::
99 :     code
100 :     in
101 :     (offp, code)
102 :     end
103 : cchiw 2522
104 :    
105 : jhr 1116
106 : jhr 465 (* compute the load address for a given set of voxels indices. For the
107 :     * operation
108 :     *
109 : jhr 1116 * VoxelAddress<info,offset>(i_1, ..., i_d)
110 : jhr 465 *
111 :     * the address is given by
112 :     *
113 : jhr 1116 * base + offset + stride * (i_1 + N_1 * (i_2 + N_2 * (... + N_{d-1} * i_d) ...))
114 : jhr 465 *
115 :     * where
116 :     * base -- base address of the image data
117 : jhr 1116 * stride -- number of samples per voxel
118 :     * offset -- offset of sample being addressed
119 : jhr 465 * N_i -- size of ith axis in elements
120 : jhr 1116 *
121 :     * Note that we are following the Nrrd convention that the axes are ordered
122 :     * in fastest to slowest order. We are also assuming the C semantics of address
123 :     * arithmetic, where the offset will be automatically scaled by the size of the
124 :     * elements.
125 : jhr 465 *)
126 : cchiw 2398
127 :    
128 : jhr 1116 fun expandVoxelAddress (result, info, offset, [img, ix]) = let
129 :     val dim = ImageInfo.dim info
130 :     val stride = ImageInfo.stride info
131 :     val shape = ImageInfo.voxelShape info
132 :     val (offp, code) = adjustForStrideAndOffset (stride, offset, ix, [])
133 :     val addrTy = DstTy.AddrTy info
134 :     val base = DstIL.Var.new ("imgBaseAddr", addrTy)
135 : cchiw 2398
136 :     (*Add here is of address type, assume it is okay to keep IADD since not tensors*)
137 : cchiw 2522 val code = (result, DstIL.OP(DstOp.IAdd , [base, offp])) ::
138 : jhr 1116 (base, DstIL.OP(DstOp.ImageAddress info, [img])) ::
139 :     code
140 :     in
141 :     List.rev code
142 :     end
143 :     | expandVoxelAddress (result, info, offset, img::ix1::indices) = let
144 :     val dim = ImageInfo.dim info
145 :     val sizes = ImageInfo.sizes info
146 :     val stride = ImageInfo.stride info
147 :     val shape = ImageInfo.voxelShape info
148 :     (* get N_1 ... N_{d-1} *)
149 : jhr 2356 (* FIXME: sizes is [] when the image does not have a proxy *)
150 : jhr 1116 val sizes = List.take (sizes, List.length sizes - 1)
151 : jhr 511 (* generate the address computation code in reverse order *)
152 :     fun gen (d, [n], [ix]) = let
153 :     val n' = DstIL.Var.new ("n" ^ Int.toString d, DstTy.intTy)
154 :     val t = DstIL.Var.new ("t", DstTy.intTy)
155 :     val code = [
156 :     imul(t, n', ix),
157 : jhr 1116 ilit(n', n)
158 : jhr 511 ]
159 :     in
160 :     (t, code)
161 :     end
162 :     | gen (d, n::ns, ix::ixs) = let
163 :     val n' = DstIL.Var.new ("n" ^ Int.toString d, DstTy.intTy)
164 :     val t1 = DstIL.Var.new ("t1", DstTy.intTy)
165 :     val t2 = DstIL.Var.new ("t2", DstTy.intTy)
166 :     val (t, code) = gen (d+1, ns, ixs)
167 :     val code =
168 :     imul(t2, n', t1) ::
169 : jhr 1116 ilit(n', n) ::
170 : jhr 511 iadd(t1, ix, t) :: code
171 :     in
172 :     (t2, code)
173 :     end
174 : jhr 2356 (* FIXME: sizes is [] when the image does not have a proxy *)
175 : jhr 1116 val (tmp, code) = gen (0, sizes, indices)
176 :     val t = DstIL.Var.new ("index", DstTy.intTy)
177 :     val code = iadd(t, ix1, tmp) :: code
178 :     val (offp, code) = adjustForStrideAndOffset (stride, offset, t, code)
179 :     val addrTy = DstTy.AddrTy info
180 :     val base = DstIL.Var.new ("imgBaseAddr", addrTy)
181 : cchiw 2522 val code = (result, DstIL.OP(DstOp.IAdd , [base, offp])) ::
182 : jhr 1116 (base, DstIL.OP(DstOp.ImageAddress info, [img])) ::
183 : jhr 511 code
184 :     in
185 :     List.rev code
186 :     end
187 : lamonts 345
188 : jhr 1370
189 : cchiw 2397
190 : jhr 431 fun expandOp (env, y, rator, args) = let
191 : jhr 1640 val args' = Env.renameList (env, args)
192 : jhr 465 fun assign rator' = [(y, DstIL.OP(rator', args'))]
193 : cchiw 2525 fun dummy () = [(y, DstIL.LIT(Literal.Int 0))]
194 : jhr 431 in
195 :     case rator
196 : cchiw 2521 of SrcOp.IAdd => assign (DstOp.IAdd )
197 :     | SrcOp.ISub => assign (DstOp.ISub )
198 :     | SrcOp.IMul => assign (DstOp.IMul )
199 :     | SrcOp.IDiv => assign (DstOp.IDiv )
200 :     | SrcOp.INeg => assign (DstOp.INeg )
201 : jhr 1116 | SrcOp.Abs ty => assign (DstOp.Abs ty)
202 : jhr 459 | SrcOp.LT ty => assign (DstOp.LT ty)
203 :     | SrcOp.LTE ty => assign (DstOp.LTE ty)
204 :     | SrcOp.EQ ty => assign (DstOp.EQ ty)
205 :     | SrcOp.NEQ ty => assign (DstOp.NEQ ty)
206 :     | SrcOp.GT ty => assign (DstOp.GT ty)
207 :     | SrcOp.GTE ty => assign (DstOp.GTE ty)
208 :     | SrcOp.Not => assign (DstOp.Not)
209 :     | SrcOp.Max => assign (DstOp.Max)
210 :     | SrcOp.Min => assign (DstOp.Min)
211 : jhr 1295 | SrcOp.Clamp ty => assign (DstOp.Clamp ty)
212 : jhr 1116 | SrcOp.Lerp ty => assign (DstOp.Lerp ty)
213 : cchiw 2397 | SrcOp.Norm ty => assign (DstOp.Norm ty)
214 : jhr 1116 | SrcOp.Normalize d => assign (DstOp.Normalize d)
215 : cchiw 2398
216 : jhr 1116 | SrcOp.Zero ty => assign (DstOp.Zero ty)
217 : jhr 459 | SrcOp.PrincipleEvec ty => assign (DstOp.PrincipleEvec ty)
218 : cchiw 2414 | SrcOp.EigenVals2x2 => assign (DstOp.EigenVals2x2)
219 :     | SrcOp.EigenVals3x3 => assign (DstOp.EigenVals3x3)
220 :     | SrcOp.Select(ty as SrcTy.TupleTy tys, i) => assign (DstOp.Select(ty, i))
221 :     | SrcOp.Index(ty, i) => assign (DstOp.Index(ty, i))
222 : cchiw 2521 | SrcOp.Subscript ty => assign (DstOp.Subscript ty)
223 : jhr 1116 | SrcOp.Ceiling d => assign (DstOp.Ceiling d)
224 : jhr 459 | SrcOp.Floor d => assign (DstOp.Floor d)
225 : jhr 1116 | SrcOp.Round d => assign (DstOp.Round d)
226 :     | SrcOp.Trunc d => assign (DstOp.Trunc d)
227 : jhr 459 | SrcOp.IntToReal => assign (DstOp.IntToReal)
228 : jhr 1116 | SrcOp.RealToInt d => assign (DstOp.RealToInt d)
229 :     | SrcOp.VoxelAddress(info, offset) => expandVoxelAddress (y, info, offset, args')
230 : jhr 459 | SrcOp.LoadVoxels(rty, d) => assign (DstOp.LoadVoxels(rty, d))
231 : cchiw 2525 | SrcOp.Kernel h => assign(DstOp.Kernel h)
232 :     | SrcOp.LoadImage info => assign (DstOp.LoadImage info)
233 : jhr 459 | SrcOp.Inside info => assign (DstOp.Inside info)
234 : cchiw 2522
235 :     (*Input problems *)
236 :     (*| SrcOp.Input(ty, s, desc) => assign (DstOp.Input(ty, s, desc))
237 :     | SrcOp.InputWithDefault(ty, s, desc) =>assign (DstOp.InputWithDefault(ty, s, desc))
238 : cchiw 2525 *)
239 : cchiw 2521 | SrcOp.Transform V=> assign (DstOp.Transform V)
240 : cchiw 2525 | SrcOp.Translate V=> assign(DstOp.Translate V)
241 : jhr 1640 | rator => raise Fail("bogus operator " ^ SrcOp.toString rator)
242 : jhr 431 (* end case *)
243 :     end
244 : cchiw 2522
245 :    
246 : cchiw 2608 val testing=1
247 : cchiw 2605
248 : cchiw 2522 fun expandEinOp (env, y, e, args) = let
249 : cchiw 2611
250 : cchiw 2605 val einargs=Env.renameList(env, args)
251 : cchiw 2611
252 : cchiw 2605 val _ =(case testing
253 :     of 0 => 1
254 :     | _ => (print(String.concat(["\n\n new ein \n", DstIL.Var.toString(y),"=",P.printerE(e)]@(List.map (fn e=> (DstIL.Var.toString(e)^",")) einargs)@["\n ** pre gen**"]));1)
255 :     (*end case*))
256 : cchiw 2611
257 :     val _ = X.checkEIN(e)
258 :    
259 : cchiw 2605 val (_,code)=genEin.genfn(y,e,args,einargs)
260 : cchiw 2611
261 : cchiw 2605 val DstIL.ASSGN (a1,DstIL.OP(opss1,args1))=List.hd(List.rev(code))
262 : cchiw 2611
263 : cchiw 2605 val c=DstIL.ASSGN (y,DstIL.OP(opss1,args1))
264 : cchiw 2611
265 : cchiw 2605 val _ =(case testing
266 :     of 0 => 1
267 :     | _ => (print(String.concat(["**\n post gen",Int.toString(length(code)), "\n NEW-- ", DstIL.Var.toString y,"===", DstOp.toString opss1,"-"]@(List.map (fn e=> (DstIL.Var.toString(e)^",")) args1)@ ["\n made it post code"]));1)
268 :     (*end case*))
269 :     in code@[c]
270 :     end
271 : jhr 431
272 : cchiw 2522
273 : cchiw 2521 handle ex => (print(concat["error converting \n"]); raise ex)
274 : cchiw 2398
275 :    
276 : jhr 1116 (* expand a SrcIL assignment to a DstIL CFG *)
277 : jhr 387 fun expand (env, (y, rhs)) = let
278 : jhr 1640 val y' = Env.rename (env, y)
279 : cchiw 2522
280 : jhr 1640 fun assign rhs = [DstIL.ASSGN(y', rhs)]
281 : jhr 387 in
282 :     case rhs
283 : cchiw 2522 of SrcIL.STATE x => (assign (DstIL.STATE(Env.renameSV(env, x))))
284 :     | SrcIL.VAR x => assign (DstIL.VAR(Env.rename(env, x)))
285 :     | SrcIL.LIT lit => (assign (DstIL.LIT lit))
286 :     | SrcIL.OP(rator, args) => (List.map DstIL.ASSGN (expandOp (env, y', rator, args)))
287 : jhr 1640 | SrcIL.APPLY(f, args) => assign (DstIL.APPLY(f, Env.renameList(env, args)))
288 :     | SrcIL.CONS(ty, args) => assign (DstIL.CONS(ty, Env.renameList(env, args)))
289 : cchiw 2605 | SrcIL.EINAPP(rator, args) => let
290 :     val _ = (case testing
291 :     of 0 => 1
292 :     | _ => (print(String.concat["\n ------------------------last name",SrcIL.Var.toString(y)]);1)
293 :     (*end case *))
294 :     in
295 :     expandEinOp (env, Env.rename (env, y), rator, args)
296 :     end
297 : cchiw 2398 (* end case *)
298 :     end
299 : lamonts 345
300 : cchiw 2398
301 : jhr 1640 (* expand a SrcIL multi-assignment to a DstIL CFG *)
302 :     fun mexpand (env, (ys, rator, xs)) = let
303 :     val ys' = Env.renameList(env, ys)
304 :     val rator' = (case rator
305 :     of SrcOp.EigenVecs2x2 => DstOp.EigenVecs2x2
306 :     | SrcOp.EigenVecs3x3 => DstOp.EigenVecs3x3
307 :     | SrcOp.Print tys => DstOp.Print tys
308 :     | _ => raise Fail("bogus operator " ^ SrcOp.toString rator)
309 :     (* end case *))
310 :     val xs' = Env.renameList(env, xs)
311 :     val nd = DstIL.Node.mkMASSIGN(ys', rator', xs')
312 :     in
313 :     DstIL.CFG{entry=nd, exit=nd}
314 :     end
315 :    
316 : jhr 387 structure Trans = TranslateFn (
317 :     struct
318 : jhr 1640 open Env
319 :     val expand = DstIL.CFG.mkBlock o expand
320 :     val mexpand = mexpand
321 : jhr 387 end)
322 :    
323 : jhr 1116 fun translate prog = let
324 :     val prog = Trans.translate prog
325 : jhr 387 in
326 : jhr 1116 LowILCensus.init prog;
327 :     prog
328 : jhr 387 end
329 :    
330 : jhr 435 end

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