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

SCM Repository

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

Annotation of /trunk/src/compiler/mid-to-low/mid-to-low.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 464 - (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 387 structure VTbl = SrcIL.Var.Tbl
18 : lamonts 345 structure DstIL = LowIL
19 : jhr 464 structure DstTy = LowILTypes
20 : lamonts 345 structure DstOp = LowOps
21 :    
22 : jhr 387 type var_env = DstIL.var VTbl.hash_table
23 :    
24 :     fun rename (env : var_env, x) = (case VTbl.find env x
25 : lamonts 345 of SOME x' => x'
26 : jhr 387 | NONE => let
27 : jhr 460 val x' = DstIL.Var.new (SrcIL.Var.name x, SrcIL.Var.ty x)
28 : jhr 387 in
29 :     VTbl.insert env (x, x');
30 :     x'
31 :     end
32 : lamonts 345 (* end case *))
33 : jhr 387 fun renameList (env, xs) = List.map (fn x => rename(env, x)) xs
34 : lamonts 345
35 : jhr 463 (* convert a rational to a FloatLit.float value. We do this by long division
36 :     * with a cutoff when we get to 12 digits.
37 :     *)
38 :     fun ratToFloat r = (case Rational.explode r
39 : jhr 464 of {sign=0, ...} => FloatLit.zero false
40 : jhr 463 | {sign, num, denom=1} => FloatLit.fromInt(sign * IntInf.toInt num)
41 :     | {sign, num, denom} => let
42 :     (* normalize so that num <= denom *)
43 :     val (denom, exp) = let
44 :     fun lp (n, denom) = if (denom < num)
45 :     then lp(n+1, denom*10)
46 : jhr 464 else (denom, n)
47 : jhr 463 in
48 : jhr 464 lp (1, denom)
49 : jhr 463 end
50 :     (* normalize so that num <= denom < 10*num *)
51 : jhr 464 val (num, exp) = let
52 :     fun lp (n, num) = if (10*num < denom)
53 :     then lp(n-1, 10*num)
54 :     else (num, n)
55 :     in
56 :     lp (exp, num)
57 :     end
58 : jhr 463 (* divide num/denom, computing the resulting digits *)
59 :     fun divLp (n, a) = let
60 :     val (q, r) = IntInf.divMod(a, denom)
61 :     in
62 :     if (r = 0) then (q, [])
63 :     else if (n < 12) then let
64 :     val (d, dd) = divLp(n+1, 10*r)
65 :     in
66 : jhr 464 if (d < 10)
67 :     then (q, (IntInf.toInt d)::dd)
68 :     else (q+1, 0::dd)
69 : jhr 463 end
70 :     else if (IntInf.div(10*r, denom) < 5)
71 :     then (q, [])
72 :     else (q+1, []) (* round up *)
73 :     end
74 : jhr 464 val digits = let
75 :     val (d, dd) = divLp (0, num)
76 :     in
77 :     (IntInf.toInt d)::dd
78 :     end
79 : jhr 463 in
80 : jhr 464 FloatLit.fromDigits{isNeg=(sign < 0), digits=digits, exp=exp}
81 : jhr 463 end
82 : jhr 464 (* end case *))
83 : jhr 463
84 : jhr 459 (* expand the EvalKernel operations into vector operations. The parameters are
85 :     * result -- the lhs variable to store the result
86 :     * d -- the vector width of the operation, which should be equal to twice the
87 :     * support of the kernel
88 :     * h -- the kernel
89 :     * k -- the derivative of the kernel to evaluate
90 :     *)
91 : jhr 463 fun expandEvalKernel (result, d, h, k, [x]) = let
92 : jhr 459 val {isCont, segs} = Kernel.curve (h, k)
93 : jhr 464 val deg = List.length segs - 1
94 : jhr 463 (* convert to a vector of vectors to give fast access *)
95 :     val segs = Vector.fromList (List.map Vector.fromList segs)
96 :     (* get the kernel coefficient value for the d'th term of the i'th
97 :     * segment.
98 :     *)
99 : jhr 464 fun coefficient d i = Literal.Float(ratToFloat (Vector.sub (Vector.sub(segs, i), d)))
100 : jhr 463 val ty = DstTy.VecTy d
101 :     val coeffs = List.tabulate (deg+1,
102 : jhr 464 fn i => DstIL.Var.new(str(chr(ord #"a" + (deg - i))), ty))
103 :     (* code to define the coefficient vectors *)
104 :     val coeffVecs = let
105 :     fun mk (x, (i, code)) = let
106 :     val lits = List.tabulate(d, coefficient i)
107 :     val vars = List.tabulate(d, fn _ => DstIL.Var.new("_f", DstTy.realTy))
108 :     val code =
109 :     ListPair.map (fn (x, lit) => (x, DstIL.LIT lit)) (vars, lits) @
110 :     (x, DstIL.CONS vars) :: code
111 :     in
112 :     (i-1, code)
113 :     end
114 :     in
115 :     #2 (List.foldr mk (deg, []) coeffs)
116 :     end
117 : jhr 463 (* build the evaluation of the polynomials in reverse order *)
118 : jhr 464 fun eval [coeff] = (coeff, [])
119 : jhr 463 | eval (coeff::r) = let
120 :     val (t1, stms) = eval r
121 :     val t2 = DstIL.Var.new ("_t", ty)
122 :     val t3 = DstIL.Var.new ("_s", ty)
123 :     val stms =
124 :     (t3, DstIL.OP(DstOp.Add ty, [coeff, t2])) ::
125 :     (t2, DstIL.OP(DstOp.Mul ty, [x, t1])) ::
126 :     stms
127 :     in
128 :     (t3, stms)
129 :     end
130 : jhr 464 (* FIXME: need to get result into "result" variable! *)
131 :     val (t, evalCode) = eval coeffs
132 : jhr 459 in
133 : jhr 464 coeffVecs @ evalCode
134 : jhr 459 end
135 : jhr 387
136 : lamonts 345 (* compute the load address for a given set of voxels indices *)
137 : jhr 460 fun expandVoxelAddress (result, info) = raise Fail "unimplemented"
138 : lamonts 345
139 : jhr 431 fun expandOp (env, y, rator, args) = let
140 :     fun assign rator' =
141 :     [(y, DstIL.OP(rator', renameList(env, args)))]
142 :     in
143 :     case rator
144 : jhr 459 of SrcOp.Add ty => assign (DstOp.Add ty)
145 :     | SrcOp.Sub ty => assign (DstOp.Sub ty)
146 :     | SrcOp.Mul ty => assign (DstOp.Mul ty)
147 :     | SrcOp.Div ty => assign (DstOp.Div ty)
148 :     | SrcOp.Neg ty => assign (DstOp.Neg ty)
149 :     | SrcOp.LT ty => assign (DstOp.LT ty)
150 :     | SrcOp.LTE ty => assign (DstOp.LTE ty)
151 :     | SrcOp.EQ ty => assign (DstOp.EQ ty)
152 :     | SrcOp.NEQ ty => assign (DstOp.NEQ ty)
153 :     | SrcOp.GT ty => assign (DstOp.GT ty)
154 :     | SrcOp.GTE ty => assign (DstOp.GTE ty)
155 :     | SrcOp.Not => assign (DstOp.Not)
156 :     | SrcOp.Max => assign (DstOp.Max)
157 :     | SrcOp.Min => assign (DstOp.Min)
158 :     | SrcOp.Sin => assign (DstOp.Sin)
159 :     | SrcOp.Cos => assign (DstOp.Cos)
160 :     | SrcOp.Pow => assign (DstOp.Pow)
161 :     | SrcOp.Dot d => assign (DstOp.Dot d)
162 :     | SrcOp.Cross => assign (DstOp.Cross)
163 : jhr 460 | SrcOp.Select(ty, i)=> assign (DstOp.Select(ty, i))
164 : jhr 459 | SrcOp.Norm d => assign (DstOp.Norm d)
165 :     | SrcOp.Scale d => assign (DstOp.Scale d)
166 :     | SrcOp.InvScale d => assign (DstOp.InvScale d)
167 :     | SrcOp.CL => assign (DstOp.CL)
168 :     | SrcOp.PrincipleEvec ty => assign (DstOp.PrincipleEvec ty)
169 :     | SrcOp.Subscript ty => assign (DstOp.Subscript ty)
170 :     | SrcOp.Floor d => assign (DstOp.Floor d)
171 :     | SrcOp.IntToReal => assign (DstOp.IntToReal)
172 :     | SrcOp.TruncToInt d => assign (DstOp.TruncToInt d)
173 :     | SrcOp.RoundToInt d => assign (DstOp.RoundToInt d)
174 :     | SrcOp.CeilToInt d => assign (DstOp.CeilToInt d)
175 :     | SrcOp.FloorToInt d => assign (DstOp.FloorToInt d)
176 :     | SrcOp.VoxelAddress info => expandVoxelAddress (y, info)
177 :     | SrcOp.LoadVoxels(rty, d) => assign (DstOp.LoadVoxels(rty, d))
178 : jhr 460 | SrcOp.PosToImgSpace info => assign (DstOp.PosToImgSpace info)
179 :     | SrcOp.GradToWorldSpace info => assign (DstOp.GradToWorldSpace info)
180 : jhr 464 | SrcOp.EvalKernel(d, h, k) => expandEvalKernel(y, d, h, k, renameList(env, args))
181 : jhr 459 | SrcOp.LoadImage info => assign (DstOp.LoadImage info)
182 :     | SrcOp.Inside info => assign (DstOp.Inside info)
183 :     | SrcOp.Input(ty, name) => assign (DstOp.Input(ty, name))
184 :     | SrcOp.InputWithDefault(ty, name) => assign (DstOp.InputWithDefault(ty, name))
185 : jhr 431 (* end case *)
186 :     end
187 :    
188 : jhr 387 (* expand a SrcIL assignment to a list of DstIL assignments *)
189 :     fun expand (env, (y, rhs)) = let
190 :     val y' = rename (env, y)
191 :     fun assign rhs = [(y', rhs)]
192 :     in
193 :     case rhs
194 :     of SrcIL.VAR x => assign (DstIL.VAR(rename(env, x)))
195 :     | SrcIL.LIT lit => assign (DstIL.LIT lit)
196 :     | SrcIL.OP(rator, args) => expandOp (env, y', rator, args)
197 :     | SrcIL.CONS args => assign (DstIL.CONS(renameList(env, args)))
198 :     (* end case *)
199 :     end
200 : lamonts 345
201 : jhr 387 structure Trans = TranslateFn (
202 :     struct
203 :     structure SrcIL = SrcIL
204 :     structure DstIL = DstIL
205 :    
206 :     type var_env = var_env
207 :    
208 :     val rename = rename
209 :     val expand = expand
210 :     end)
211 :    
212 :     fun translate (SrcIL.Program{globals, globalInit, actors}) = let
213 :     val env = VTbl.mkTable (256, Fail "env")
214 :     fun transMethod (SrcIL.Method{name, stateIn, stateOut, body}) =
215 :     DstIL.Method{
216 :     name = name,
217 :     stateIn = renameList (env, stateIn),
218 :     stateOut = renameList (env, stateOut),
219 :     body = Trans.translate (env, body)
220 :     }
221 :     fun transActor (SrcIL.Actor{name, params, state, stateInit, methods}) =
222 :     DstIL.Actor{
223 :     name = name,
224 :     params = renameList (env, params),
225 :     state = renameList (env, state),
226 :     stateInit = Trans.translate (env, stateInit),
227 :     methods = List.map transMethod methods
228 :     }
229 :     in
230 :     DstIL.Program{
231 :     globals = renameList (env, globals),
232 :     globalInit = Trans.translate (env, globalInit),
233 :     actors = List.map transActor actors
234 :     }
235 :     end
236 :    
237 : jhr 435 end

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