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

SCM Repository

[diderot] Annotation of /branches/vis15/src/compiler/cxx-util/gen-tys-and-ops.sml
ViewVC logotype

Annotation of /branches/vis15/src/compiler/cxx-util/gen-tys-and-ops.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4098 - (view) (download)

1 : jhr 3918 (* gen-tys-and-ops.sml
2 :     *
3 :     * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
4 :     *
5 :     * COPYRIGHT (c) 2016 The University of Chicago
6 :     * All rights reserved.
7 :     *)
8 :    
9 :     structure GenTysAndOps : sig
10 :    
11 :     val gen : CodeGenEnv.t * CollectInfo.t -> CLang.decl list
12 :    
13 :     end = struct
14 :    
15 :     structure IR = TreeIR
16 :     structure Ty = TreeTypes
17 :     structure CL = CLang
18 :     structure RN = CxxNames
19 :     structure Env = CodeGenEnv
20 :    
21 : jhr 3927 val zero = RealLit.zero false
22 :    
23 :     fun mkReturn exp = CL.mkReturn(SOME exp)
24 : jhr 3931 fun mkInt i = CL.mkInt(IntInf.fromInt i)
25 : jhr 4028 fun mkFunc (ty, name, params, body) = CL.D_Func(["inline"], ty, [], name, params, body)
26 : jhr 4033 (* make a constructor function's prototype and out-of-line definition *)
27 :     fun mkConstr (cls, params, inits) = (
28 :     CL.D_Constr([], [], cls, params, NONE),
29 :     CL.D_Constr(["inline"], [CL.SC_Type(CL.T_Named cls)], cls, params, SOME(inits, CL.mkBlock[]))
30 :     )
31 :     (* make a member function prototype and out-of-line definition *)
32 :     fun mkMemberFn (cls, ty, f, params, body) = (
33 :     CL.D_Proto([], ty, f, params),
34 :     CL.D_Func(["inline"], ty, [CL.SC_Type(CL.T_Named cls)], f, params, body)
35 :     )
36 : jhr 3927
37 : jhr 3994 fun genTyDecl env = let
38 :     val (realTy, realTyName, realTySz) = if #double(Env.target env)
39 :     then (CL.double, "double", 8)
40 :     else (CL.float, "float", 4)
41 : jhr 4033 (* generate the type and member declarations for a recorded type *)
42 :     fun genDecl (ty, (tyDcls, fnDefs)) = (case ty
43 : jhr 3994 of Ty.VecTy(w, pw) => let
44 :     val cTyName = RN.vecTyName w
45 :     val cTy = CL.T_Named cTyName
46 :     val typedefDcl = CL.D_Verbatim[concat[
47 :     "typedef ", realTyName, " ", cTyName,
48 :     " __attribute__ ((vector_size (",
49 : jhr 3999 Int.toString(realTySz * pw), ")));"
50 : jhr 3994 ]]
51 :     in
52 : jhr 4033 (typedefDcl :: tyDcls, fnDefs)
53 : jhr 3994 end
54 : jhr 4026 | Ty.TensorRefTy shape => let
55 :     val name = RN.tensorRefStruct shape
56 :     val thisData = CL.mkIndirect(CL.mkVar "this", "_data")
57 :     (* constructor from float/double pointer *)
58 : jhr 4033 val (constrProto1, constrDef1) = mkConstr (name,
59 : jhr 4026 [CL.PARAM([], CL.constPtrTy realTy, "src")],
60 : jhr 4028 [CL.mkApply("_data", [CL.mkVar "src"])])
61 : jhr 4026 (* constructor from tensor struct *)
62 : jhr 4033 val (constrProto2, constrDef2) = mkConstr(name,
63 : jhr 4026 [CL.PARAM([],
64 :     CL.T_Named(concat["struct ", RN.tensorStruct shape, " const &"]),
65 :     "ten")
66 :     ],
67 : jhr 4033 [CL.mkApply("_data", [CL.mkSelect(CL.mkVar "ten", "_data")])])
68 : jhr 4026 (* copy constructor *)
69 : jhr 4033 val (constrProto3, constrDef3) = mkConstr (name,
70 : jhr 4026 [CL.PARAM([], CL.T_Named(name ^ " const &"), "ten")],
71 : jhr 4028 [CL.mkApply("_data", [CL.mkSelect(CL.mkVar "ten", "_data")])])
72 : jhr 4026 (* subscript operator *)
73 :     val subscriptDcl = CL.D_Func([], CL.T_Named(realTyName ^ " const &"),
74 : jhr 4028 [], "operator[]",
75 : jhr 4026 [CL.PARAM([], CL.uint32, "i")],
76 :     CL.mkReturn(SOME(CL.mkSubscript(thisData, CL.mkVar "i"))))
77 :     (* address at function *)
78 : jhr 4028 val addrAtDcl = CL.D_Func([], CL.constPtrTy(realTy), [], "addr",
79 : jhr 4026 [CL.PARAM([], CL.uint32, "i")],
80 :     CL.mkReturn(SOME(CL.mkAddrOf(CL.mkSubscript(thisData, CL.mkVar "i")))))
81 : jhr 4039 (* last vector as tensor_ref *)
82 :     val lastDcl = (case shape
83 :     of [] => raise Fail "unexpected TensorRef[]"
84 :     | [_] => []
85 :     | _::dd => let
86 :     val d = List.last dd
87 :     in [
88 :     CL.D_Func([], RN.tensorRefTy[d], [], "last",
89 :     [CL.PARAM([], CL.uint32, "i")],
90 :     CL.mkReturn(
91 :     SOME(CL.mkAddrOf(CL.mkSubscript(thisData, CL.mkVar "i")))))
92 :     ] end
93 :     (* end case *))
94 :     val members = CL.mkVarDcl(CL.constPtrTy realTy, "_data") ::
95 :     constrProto1 :: constrProto2 :: constrProto3 ::
96 :     subscriptDcl ::
97 :     addrAtDcl :: lastDcl
98 : jhr 4026 val structDcl = CL.D_ClassDef{
99 :     name = name,
100 :     args = NONE,
101 :     from = NONE,
102 : jhr 4039 public = members,
103 : jhr 4026 protected = [],
104 :     private = []
105 :     }
106 :     in
107 : jhr 4033 (structDcl :: tyDcls, constrDef1 :: constrDef2 :: constrDef3 :: fnDefs)
108 : jhr 4026 end
109 : jhr 3994 | Ty.TensorTy shape => let
110 :     val len = List.foldl Int.* 1 shape
111 :     val name = RN.tensorStruct shape
112 :     val thisData = CL.mkIndirect(CL.mkVar "this", "_data")
113 : jhr 4033 val returnThis = CL.mkReturn(SOME(CL.mkUnOp(CL.%*, CL.mkVar "this")))
114 :     (* code for initializing a tensor from pointer (src). *)
115 : jhr 3999 fun copyFromArray src = if (len < 4)
116 :     then let
117 :     fun cpy i = CL.mkAssign(
118 :     CL.mkSubscript(thisData, mkInt i),
119 :     CL.mkSubscript(src, mkInt i))
120 :     in
121 :     CL.mkBlock (List.tabulate (len, cpy))
122 :     end
123 :     else CL.mkCall("std::memcpy", [
124 :     thisData, src,
125 :     CL.mkBinOp(mkInt len, CL.#*, CL.mkSizeof realTy)
126 :     ])
127 : jhr 4033 (* loop for initializing tensor from an initializer_list *)
128 : jhr 3996 val copyFromInitializerList = [
129 :     CL.mkDeclInit(CL.int32, "i", CL.mkInt 0),
130 :     CL.mkFor(
131 :     CL.T_Named "auto",
132 :     [("it", CL.mkDispatch(CL.mkVar "il", "begin", []))],
133 :     CL.mkBinOp(CL.mkVar "it", CL.#!=, CL.mkDispatch(CL.mkVar "il", "end", [])),
134 :     [CL.mkUnOp(CL.%++, CL.mkVar "i"), CL.mkUnOp(CL.%++, CL.mkVar "it")],
135 :     CL.mkAssign(
136 :     CL.mkSubscript(thisData, CL.mkVar "i"),
137 :     CL.mkUnOp(CL.%*, CL.mkVar "it")))
138 :     ]
139 : jhr 3994 (* default constructor *)
140 : jhr 4033 val constrDcl1 = CL.D_Constr ([], [], name, [], SOME([], CL.mkBlock[]))
141 : jhr 3996 (* constructor from initializer list *)
142 : jhr 4028 val constrDcl2 = CL.D_Constr([], [], name,
143 : jhr 3996 [CL.PARAM([], CL.T_Template("std::initializer_list", [realTy]), "il")],
144 : jhr 4028 SOME([], CL.mkBlock copyFromInitializerList))
145 : jhr 3999 (* constructor from float/double pointer *)
146 : jhr 4028 val constrDcl3 = CL.D_Constr([], [], name,
147 : jhr 3999 [CL.PARAM([], CL.constPtrTy realTy, "src")],
148 : jhr 4028 SOME([], copyFromArray (CL.mkVar "src")))
149 : jhr 3999 (* copy constructor *)
150 : jhr 4028 val constrDcl4 = CL.D_Constr([], [], name,
151 : jhr 3999 [CL.PARAM([], CL.T_Named(name ^ " const &"), "ten")],
152 : jhr 4028 SOME([], copyFromArray (CL.mkSelect(CL.mkVar "ten", "_data"))))
153 : jhr 3994 (* destructor *)
154 : jhr 4028 val destrDcl = CL.D_Destr([], [], name, SOME(CL.mkBlock[]))
155 : jhr 4033 (* assignment from Tensor *)
156 :     val (assignProto1, assignDef1) = mkMemberFn(name,
157 :     CL.T_Named(name ^ " &"), "operator=",
158 :     [CL.PARAM([], CL.T_Named name, "const & src")],
159 :     CL.mkBlock[
160 :     copyFromArray(CL.mkSelect(CL.mkVar "src", "_data")),
161 :     returnThis
162 :     ])
163 :     (* assignment from TensorRef *)
164 :     val (assignProto2, assignDef2) = mkMemberFn(name,
165 :     CL.T_Named(name ^ " &"), "operator=",
166 :     [CL.PARAM([], CL.T_Named(RN.tensorRefStruct shape), "const & src")],
167 :     CL.mkBlock[
168 :     copyFromArray(CL.mkSelect(CL.mkVar "src", "_data")),
169 :     returnThis
170 :     ])
171 :     (* assignment from initializer list *)
172 :     val (assignProto3, assignDef3) = mkMemberFn(name,
173 :     CL.T_Named(name ^ " &"), "operator=",
174 :     [CL.PARAM([], CL.T_Template("std::initializer_list", [realTy]), "il")],
175 :     CL.mkBlock(copyFromInitializerList @ [returnThis]))
176 : jhr 3996 (* subscript operator *)
177 : jhr 4028 val subscriptDcl = CL.D_Func([], CL.T_Named(realTyName ^ " &"), [], "operator[]",
178 : jhr 3996 [CL.PARAM([], CL.uint32, "i")],
179 :     CL.mkReturn(SOME(CL.mkSubscript(thisData, CL.mkVar "i"))))
180 : jhr 3999 (* address at function *)
181 : jhr 4028 val addrAtDcl = CL.D_Func([], CL.constPtrTy realTy, [], "addr",
182 : jhr 3999 [CL.PARAM([], CL.uint32, "i")],
183 :     CL.mkReturn(SOME(CL.mkAddrOf(CL.mkSubscript(thisData, CL.mkVar "i")))))
184 : jhr 4092 (* last vector as tensor_ref *)
185 :     val lastDcl = (case shape
186 :     of [] => raise Fail "unexpected TensorTy[]"
187 :     | [_] => []
188 :     | _::dd => let
189 :     val d = List.last dd
190 :     in [
191 :     CL.D_Func([], RN.tensorRefTy[d], [], "last",
192 :     [CL.PARAM([], CL.uint32, "i")],
193 :     CL.mkReturn(
194 :     SOME(CL.mkAddrOf(CL.mkSubscript(thisData, CL.mkVar "i")))))
195 :     ] end
196 :     (* end case *))
197 : jhr 3994 val structDcl = CL.D_ClassDef{
198 :     name = name,
199 :     args = NONE,
200 :     from = NONE,
201 : jhr 4092 public =
202 :     CL.mkVarDcl(CL.T_Array(realTy, SOME len), "_data") ::
203 :     constrDcl1 :: constrDcl2 :: constrDcl3 :: constrDcl4 ::
204 :     destrDcl ::
205 :     assignProto1 :: assignProto2 :: assignProto3 ::
206 :     subscriptDcl ::
207 :     addrAtDcl ::
208 :     lastDcl,
209 : jhr 3994 protected = [],
210 :     private = []
211 :     }
212 : jhr 4092 val fnDefs = assignDef3 :: assignDef2 :: assignDef1 :: fnDefs
213 : jhr 3994 in
214 : jhr 4092 (structDcl :: tyDcls, fnDefs)
215 : jhr 3994 end
216 :     | Ty.TupleTy tys => raise Fail "FIXME: TupleTy"
217 : jhr 3918 (* TODO
218 : jhr 3994 | Ty.SeqTy(ty, NONE) =>
219 :     | Ty.SeqTy(ty, SOME n) =>
220 : jhr 3918 *)
221 : jhr 4033 | ty => (tyDcls, fnDefs)
222 : jhr 3994 (* end case *))
223 :     in
224 :     genDecl
225 :     end
226 : jhr 3918
227 : jhr 4014 fun genSeqTrait env = let
228 : jhr 4032 val ns = #namespace(Env.target env)
229 : jhr 4014 val realTy = Env.realTy env
230 : jhr 4032 fun trType ty = TypeToCxx.trQType(env, TypeToCxx.NSDiderot, ty)
231 : jhr 4028 fun trait ({argTy, baseTy, elemTy, ndims, dims}, dcls) = let
232 :     (* the name of the teem function table for the given base type *)
233 :     val loadTbl = (case baseTy
234 :     of Ty.BoolTy => "nrrdILoad"
235 :     | Ty.IntTy => "nrrdILoad"
236 :     | Ty.VecTy(1, 1) => if #double(Env.target env)
237 :     then "nrrdDLoad"
238 :     else "nrrdFLoad"
239 :     | ty => raise Fail("genSeqTrait.loadFn: unexpected type " ^ Ty.toString ty)
240 :     (* end case *))
241 : jhr 4029 val loadTblTy = CL.constPtrTy(CL.T_Named "__details::load_fn_ptr<base_type>")
242 :     val dimArrTy = CL.T_Array(CL.uint32, SOME ndims)
243 :     val seqTy = CL.T_Template("dynseq_traits", [argTy])
244 :     val scope = CL.SC_Type seqTy
245 : jhr 4028 in
246 :     CL.D_Template([], CL.D_ClassDef{
247 :     name = "dynseq_traits",
248 :     args = SOME[argTy],
249 :     from = NONE,
250 :     public = [
251 :     CL.D_Typedef("value_type", elemTy),
252 :     CL.D_Typedef("base_type", trType baseTy),
253 :     CL.D_Var(
254 : jhr 4029 ["static"],
255 : jhr 4028 CL.constPtrTy(CL.T_Named "__details::load_fn_ptr<base_type>"),
256 :     [], "load_fn_tbl", NONE),
257 :     CL.D_Var(
258 : jhr 4029 ["static", "const"], CL.uint32, [], "ndims", SOME(CL.I_Exp(mkInt ndims))),
259 : jhr 4028 CL.D_Var(
260 : jhr 4029 ["static", "const"], dimArrTy, [], "dims", NONE)
261 : jhr 4028 ],
262 :     protected = [],
263 :     private = []
264 :     }) ::
265 :     CL.D_Var(
266 : jhr 4029 ["const"],
267 :     CL.T_Ptr(
268 :     CL.T_Template("__details::load_fn_ptr", [CL.T_Member(seqTy, "base_type")])),
269 :     [scope], "load_fn_tbl",
270 : jhr 4028 SOME(CL.I_Exp(CL.mkVar loadTbl))) ::
271 : jhr 4029 CL.D_Var(
272 :     ["const"], dimArrTy, [scope], "dims",
273 :     SOME(CL.I_Exps(List.map (CL.I_Exp o mkInt) dims))) ::
274 : jhr 4028 dcls
275 :     end
276 : jhr 4014 fun genTrait (ty, dcls) = (case ty
277 : jhr 4028 of Ty.SeqTy(argTy, NONE) => let
278 : jhr 4014 fun baseTy (Ty.SeqTy(ty, _)) = baseTy ty
279 : jhr 4028 | baseTy (Ty.TensorTy[]) = Ty.realTy
280 : jhr 4014 | baseTy ty = ty
281 : jhr 4028 val argTy = trType argTy
282 : jhr 4064 (* for sequences of scalar values, we set nDims to 0 so that it matches the
283 :     * format of a nrrd, where the dimension is not represented.
284 :     *)
285 :     fun scalarSeqTrait ty = trait ({
286 :     argTy = argTy, baseTy = ty, elemTy = argTy,
287 :     ndims = 0, dims = []
288 :     },
289 :     dcls)
290 : jhr 4014 in
291 :     case baseTy ty
292 : jhr 4032 of ty as Ty.TensorTy(shp as _::_) => trait ({
293 : jhr 4028 argTy = argTy, baseTy = Ty.realTy,
294 : jhr 4032 elemTy = argTy, ndims = List.length shp,
295 : jhr 4028 dims = shp
296 :     },
297 :     dcls)
298 : jhr 4064 | ty as Ty.BoolTy => scalarSeqTrait ty
299 :     | ty as Ty.IntTy => scalarSeqTrait ty
300 :     | ty as Ty.VecTy(1, 1) => scalarSeqTrait ty
301 :     | ty => raise Fail "FIXME: unsupported dynamic sequence type"
302 : jhr 4014 (* end case *)
303 :     end
304 :     | _ => dcls
305 :     (* end case *))
306 :     in
307 :     genTrait
308 :     end
309 :    
310 :     datatype operation = datatype CollectInfo.operation
311 :    
312 : jhr 3918 val ostreamRef = CL.T_Named "std::ostream&"
313 :    
314 :     fun output (e, e') = CL.mkBinOp(e, CL.#<<, e')
315 :    
316 :     (* generate code for the expression "e << s", where "s" is string literal *)
317 :     fun outString (CL.E_BinOp(e, CL.#<<, CL.E_Str s1), s2) =
318 :     output (e, CL.mkStr(s1 ^ String.toCString s2))
319 :     | outString (e, s) = output (e, CL.mkStr(String.toCString s))
320 :    
321 :     (* generate a printing function for tensors with the given shape *)
322 :     fun genTensorPrinter shape = let
323 : jhr 3931 fun ten i = CL.mkSubscript(CL.mkSelect(CL.mkVar "ten", "_data"), mkInt i)
324 : jhr 3918 fun prefix (true, lhs) = lhs
325 :     | prefix (false, lhs) = outString(lhs, ",")
326 :     fun lp (isFirst, lhs, i, [d]) = let
327 :     fun lp' (_, lhs, i, 0) = (i, outString(lhs, "]"))
328 :     | lp' (isFirst, lhs, i, n) =
329 :     lp' (false, output (prefix (isFirst, lhs), ten i), i+1, n-1)
330 :     in
331 :     lp' (true, outString(lhs, "["), i, d)
332 :     end
333 :     | lp (isFirst, lhs, i, d::dd) = let
334 :     fun lp' (_, lhs, i, 0) = (i, outString(lhs, "]"))
335 :     | lp' (isFirst, lhs, i, n) = let
336 :     val (i, lhs) = lp (true, prefix (isFirst, lhs), i, dd)
337 :     in
338 :     lp' (false, lhs, i, n-1)
339 :     end
340 :     in
341 :     lp' (true, outString(lhs, "["), i, d)
342 :     end
343 :     val params = [
344 :     CL.PARAM([], ostreamRef, "outs"),
345 : jhr 4027 CL.PARAM([], RN.tensorRefTy shape, "const & ten")
346 : jhr 3918 ]
347 :     val (_, exp) = lp (true, CL.mkVar "outs", 0, shape)
348 :     in
349 : jhr 4028 CL.D_Func(["static"], ostreamRef, [], "operator<<", params, mkReturn exp)
350 : jhr 3918 end
351 :    
352 : jhr 3936 (* builds AST for the statememt "return (x <= lo) ? lo : (hi < x) ? hi : x;" *)
353 : jhr 3935 fun mkClampStm (x, lo, hi) =
354 :     mkReturn(
355 :     CL.mkCond(CL.mkBinOp(x, CL.#<=, lo), lo,
356 :     CL.mkCond(CL.mkBinOp(hi, CL.#<, x), hi,
357 :     x)))
358 :    
359 : jhr 3950 fun mkLerp (ty, name, realTy, mkT) = mkFunc(
360 :     ty, name,
361 : jhr 3927 [CL.PARAM([], ty, "a"), CL.PARAM([], ty, "b"), CL.PARAM([], realTy, "t")],
362 :     mkReturn (
363 :     CL.mkBinOp(
364 :     CL.mkVar "a",
365 :     CL.#+,
366 :     CL.mkBinOp(
367 :     mkT(CL.mkVar "t"),
368 :     CL.#*,
369 : jhr 3976 CL.mkBinOp(CL.mkVar "b", CL.#-, CL.mkVar "a")))))
370 : jhr 3927
371 : jhr 3921 fun doOp env (rator, dcls) = let
372 :     val realTy = Env.realTy env
373 : jhr 3927 fun mkVec (w, pw, f) = CL.mkVec(
374 :     RN.vecTy w,
375 :     List.tabulate(pw, fn i => if i < w then f i else CL.mkFlt(zero, realTy)))
376 : jhr 3949 fun mkVMap (ty, name, f, w, pw) = let
377 :     fun f' i = CL.mkApply(f, [CL.mkSubscript(CL.mkVar "v", mkInt i)])
378 :     in
379 : jhr 3950 mkFunc(ty, name, [CL.PARAM([], ty, "v")], mkReturn (mkVec (w, pw, f')))
380 : jhr 3949 end
381 : jhr 3921 val dcl = (case rator
382 : jhr 4014 of Print(Ty.TensorRefTy shape) => genTensorPrinter shape
383 :     | Print(Ty.TupleTy tys) => raise Fail "FIXME: printer for tuples"
384 :     | Print(Ty.SeqTy(ty, NONE)) => raise Fail "FIXME: printer for dynseq"
385 :     | Print(Ty.SeqTy(ty, SOME n)) => raise Fail "FIXME: printer for sequence"
386 :     | Print ty => CL.D_Verbatim[] (* no printer needed *)
387 :     | RClamp => let
388 : jhr 3935 val name = "clamp"
389 :     val params = [
390 :     CL.PARAM([], realTy, "x"),
391 :     CL.PARAM([], realTy, "lo"),
392 :     CL.PARAM([], realTy, "hi")
393 :     ]
394 :     in
395 : jhr 3950 mkFunc(realTy, name, params,
396 : jhr 3935 mkClampStm (CL.mkVar "x", CL.mkVar "lo", CL.mkVar "hi"))
397 :     end
398 : jhr 3927 | RLerp => mkLerp (realTy, "lerp", realTy, fn x => x)
399 : jhr 3949 | VScale(w, pw) => let
400 :     val cTy = RN.vecTy w
401 :     in
402 : jhr 4068 mkFunc(cTy, RN.vscale w,
403 : jhr 3949 [CL.PARAM([], realTy, "s"), CL.PARAM([], cTy, "v")],
404 :     mkReturn(
405 :     CL.mkBinOp(mkVec(w, pw, fn _ => CL.mkVar "s"), CL.#*, CL.mkVar "v")))
406 :     end
407 : jhr 3921 | VSum(w, pw) => let
408 :     val name = RN.vsum w
409 :     val params = [CL.PARAM([], RN.vecTy w, "v")]
410 :     fun mkSum 0 = CL.mkSubscript(CL.mkVar "v", mkInt 0)
411 :     | mkSum i = CL.mkBinOp(mkSum(i-1), CL.#+, CL.mkSubscript(CL.mkVar "v", mkInt i))
412 :     in
413 : jhr 3950 mkFunc(realTy, name, params, mkReturn(mkSum(w-1)))
414 : jhr 3921 end
415 : jhr 4056 | VDot(w, pw) => let
416 :     val name = RN.vdot w
417 :     val vTy = RN.vecTy w
418 :     val params = [CL.PARAM([], vTy, "u"), CL.PARAM([], vTy, "v")]
419 :     fun mkSum 0 = CL.mkSubscript(CL.mkVar "w", mkInt 0)
420 :     | mkSum i = CL.mkBinOp(mkSum(i-1), CL.#+, CL.mkSubscript(CL.mkVar "w", mkInt i))
421 :     in
422 :     mkFunc(realTy, name, params,
423 :     CL.mkBlock[
424 :     CL.mkDeclInit(vTy, "w", CL.mkBinOp(CL.mkVar "u", CL.#*, CL.mkVar "v")),
425 :     mkReturn(mkSum(w-1))
426 :     ])
427 :     end
428 : jhr 3935 | VClamp(w, pw) => let
429 :     val cTy = RN.vecTy w
430 : jhr 4068 val name = RN.vclamp w
431 : jhr 3935 val params = [
432 :     CL.PARAM([], cTy, "v"),
433 :     CL.PARAM([], realTy, "lo"),
434 :     CL.PARAM([], realTy, "hi")
435 :     ]
436 :     fun mkInit x = SOME(CL.I_Exps(List.tabulate(pw,
437 :     fn i => CL.I_Exp(if i < w then x else CL.mkFlt(zero, realTy)))))
438 :     val loDcl = CL.mkDecl(cTy, "vlo", mkInit(CL.mkVar "lo"))
439 :     val hiDcl = CL.mkDecl(cTy, "vhi", mkInit(CL.mkVar "hi"))
440 :     in
441 : jhr 3950 mkFunc(cTy, name, params,
442 : jhr 3935 CL.mkBlock [
443 :     loDcl, hiDcl,
444 :     mkClampStm (CL.mkVar "v", CL.mkVar "vlo", CL.mkVar "vhi")
445 :     ])
446 :     end
447 :     | VMapClamp(w, pw) => let
448 :     val cTy = RN.vecTy w
449 : jhr 4068 val name = RN.vclamp w
450 : jhr 3935 val params = [
451 :     CL.PARAM([], cTy, "v"),
452 :     CL.PARAM([], cTy, "vlo"),
453 :     CL.PARAM([], cTy, "vhi")
454 :     ]
455 :     in
456 : jhr 3950 mkFunc(cTy, name, params,
457 : jhr 3935 mkClampStm (CL.mkVar "v", CL.mkVar "vlo", CL.mkVar "vhi"))
458 :     end
459 : jhr 3927 | VLerp(w, pw) =>
460 : jhr 4068 mkLerp (RN.vecTy w, RN.vlerp w, realTy, fn x => mkVec(w, pw, fn i => x))
461 :     | VCeiling(w, pw) => mkVMap (RN.vecTy w, RN.vceiling w, "std::ceiling", w, pw)
462 :     | VFloor(w, pw) => mkVMap (RN.vecTy w, RN.vfloor w, "std::floor", w, pw)
463 :     | VRound(w, pw) => mkVMap (RN.vecTy w, RN.vround w, "std::round", w, pw)
464 :     | VTrunc(w, pw) => mkVMap (RN.vecTy w, RN.vtrunc w, "std::trunc", w, pw)
465 : jhr 3950 | VToInt(w, pw) => let
466 :     val intTy = Env.intTy env
467 :     in
468 : jhr 4068 mkFunc(CL.voidTy, RN.vtoi w,
469 : jhr 3950 [ CL.PARAM([], CL.T_Array(intTy, SOME w), "dst"),
470 :     CL.PARAM([], RN.vecTy w, "src")],
471 :     CL.mkBlock(List.tabulate (w,
472 :     fn i => CL.mkAssign(
473 :     CL.mkSubscript(CL.mkVar "dst", mkInt i),
474 :     CL.mkCons(intTy, [CL.mkSubscript(CL.mkVar "src", mkInt i)])))))
475 :     end
476 : jhr 3921 | VLoad(w, pw) => let
477 :     val name = RN.vload w
478 :     val cTy = RN.vecTy w
479 : jhr 3927 fun arg i = CL.mkSubscript(CL.mkVar "vp", mkInt i)
480 : jhr 3921 in
481 : jhr 3950 mkFunc(cTy, name,
482 : jhr 3934 [CL.PARAM(["const"], CL.T_Ptr realTy, "vp")],
483 : jhr 3927 mkReturn(mkVec (w, pw, arg)))
484 : jhr 3921 end
485 :     | VCons(w, pw) => let
486 :     val name = RN.vcons w
487 :     val cTy = RN.vecTy w
488 :     val params = List.tabulate(w, fn i => CL.PARAM([], realTy, "r"^Int.toString i))
489 : jhr 3927 fun arg i = CL.mkVar("r"^Int.toString i)
490 : jhr 3921 in
491 : jhr 3950 mkFunc(cTy, name, params, mkReturn(mkVec (w, pw, arg)))
492 : jhr 3921 end
493 : jhr 3931 | VPack layout => let
494 :     val name = RN.vpack (#wid layout)
495 :     val vParamTys = Ty.piecesOf layout
496 :     val vParams = List.mapi
497 :     (fn (i, Ty.VecTy(w, _)) => CL.PARAM([], RN.vecTy w, "v"^Int.toString i))
498 :     vParamTys
499 : jhr 4027 val dstTy = RN.tensorTy[#wid layout]
500 : jhr 3931 fun mkAssign (i, v, j) =
501 :     CL.mkAssign(
502 : jhr 3999 CL.mkSubscript(CL.mkSelect(CL.mkVar "dst", "_data"), mkInt i),
503 : jhr 3931 CL.mkSubscript(v, mkInt j))
504 :     fun mkAssignsForPiece (dstStart, pieceIdx, wid, stms) = let
505 :     val piece = CL.mkVar("v"^Int.toString pieceIdx)
506 :     fun mk (j, stms) = if (j < wid)
507 :     then mk (j+1, mkAssign (dstStart+j, piece, j) :: stms)
508 :     else stms
509 :     in
510 :     mk (0, stms)
511 :     end
512 :     fun mkAssigns (_, [], _, stms) = CL.mkBlock(List.rev stms)
513 :     | mkAssigns (i, Ty.VecTy(w, _)::tys, offset, stms) =
514 :     mkAssigns (i+1, tys, offset+w, mkAssignsForPiece(offset, i, w, stms))
515 :     in
516 : jhr 3950 mkFunc(CL.voidTy, name,
517 : jhr 4027 CL.PARAM([], dstTy, "&dst") :: vParams,
518 : jhr 3931 mkAssigns (0, vParamTys, 0, []))
519 :     end
520 : jhr 3999 | TensorCopy shp => CL.D_Verbatim[]
521 :     (*
522 : jhr 3955 | TensorCopy shp => let
523 :     val name = RN.tensorCopy shp
524 :     val dim = List.foldl Int.* 1 shp
525 :     val dstTy = CL.T_Array(realTy, SOME dim)
526 :     in
527 :     mkFunc(CL.voidTy, name,
528 :     [CL.PARAM([], dstTy, "dst"), CL.PARAM([], CL.constPtrTy realTy, "src")],
529 :     CL.mkCall("std::memcpy", [
530 :     CL.mkVar "dst", CL.mkVar "src", CL.mkSizeof dstTy
531 :     ]))
532 :     end
533 : jhr 3999 *)
534 : jhr 4027 | Transform d => let
535 :     val e = CL.mkDispatch(CL.mkVar "img", "world2image", [])
536 :     val (resTy, e) = if (d = 1)
537 :     then (realTy, e)
538 :     else let val ty = RN.tensorRefTy[d, d]
539 :     in (ty, CL.mkCons(ty, [e])) end
540 :     in
541 :     mkFunc(resTy, "world2image",
542 : jhr 4032 [CL.PARAM([], CL.T_Template(RN.qImageTyName d, [realTy]), "const & img")],
543 : jhr 4027 CL.mkReturn(SOME e))
544 :     end
545 :     | Translate d => let
546 :     val e = CL.mkDispatch(CL.mkVar "img", "translate", [])
547 :     val (resTy, e) = if (d = 1)
548 :     then (realTy, e)
549 :     else let val ty = RN.tensorRefTy[d]
550 :     in (ty, CL.mkCons(ty, [e])) end
551 :     in
552 :     mkFunc(resTy, "translate",
553 : jhr 4032 [CL.PARAM([], CL.T_Template(RN.qImageTyName d, [realTy]), "const & img")],
554 : jhr 4027 CL.mkReturn(SOME e))
555 :     end
556 : jhr 3921 (* end case *))
557 :     in
558 :     dcl :: dcls
559 :     end
560 :    
561 : jhr 3994 val first = CL.D_Comment["***** Begin synthesized types and operations *****"]
562 :     val last = CL.D_Comment["***** End synthesized types and operations *****"]
563 : jhr 3996 val noDcls = CL.D_Comment["***** No synthesized types or operations *****"]
564 : jhr 3994
565 : jhr 3918 fun gen (env, info) = let
566 :     val spec = Env.target env
567 : jhr 3994 val genTrait = genSeqTrait env
568 :     val genTyDecl = genTyDecl env
569 : jhr 4098 val opDcls = List.foldl (doOp env) [] (CollectInfo.listOps info)
570 : jhr 4013 val tys = CollectInfo.listTypes info
571 : jhr 4098 val (tyDcls, fnDefs) = List.foldr genTyDecl ([], []) tys
572 :     val dcls = tyDcls @ fnDefs @ opDcls
573 : jhr 4028 val traitDcls = List.foldl genTrait [] tys
574 : jhr 3996 in
575 : jhr 4027 if List.null dcls andalso List.null traitDcls
576 : jhr 3996 then [noDcls]
577 : jhr 4027 else let
578 :     val res = [last]
579 :     val res = if List.null traitDcls
580 :     then res
581 :     else CL.D_Namespace("diderot", traitDcls) :: res
582 :     val res = if List.null dcls
583 :     then res
584 :     else CL.D_Namespace(#namespace(Env.target env), dcls) :: res
585 :     in
586 :     first :: res
587 :     end
588 : jhr 3918 end
589 :    
590 :     end

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