1 : |
jhr |
1677 |
(* tree-to-cuda.sml
|
2 : |
|
|
*
|
3 : |
|
|
* COPYRIGHT (c) 2011 The Diderot Project (http://diderot-language.cs.uchicago.edu)
|
4 : |
|
|
* All rights reserved.
|
5 : |
|
|
*
|
6 : |
|
|
* Translate TreeIL to the CUDA version of CLang.
|
7 : |
|
|
*)
|
8 : |
|
|
|
9 : |
|
|
structure TreeToCUDA : sig
|
10 : |
|
|
|
11 : |
|
|
datatype var = V of (CLang.ty * CLang.var)
|
12 : |
|
|
|
13 : |
|
|
type env = var TreeIL.Var.Map.map
|
14 : |
|
|
|
15 : |
|
|
val trType : TreeIL.Ty.ty -> CLang.ty
|
16 : |
|
|
|
17 : |
|
|
val trBlock : env * TreeIL.block -> CLang.stm
|
18 : |
|
|
|
19 : |
|
|
val trFragment : env * TreeIL.block -> env * CLang.stm list
|
20 : |
|
|
|
21 : |
|
|
val trAssign : env * TreeIL.var * TreeIL.exp -> CLang.stm list
|
22 : |
|
|
|
23 : |
|
|
val trExp : env * TreeIL.exp -> CLang.exp
|
24 : |
|
|
|
25 : |
|
|
(* vector indexing support. Arguments are: vector, index *)
|
26 : |
|
|
val vecIndex : CLang.exp * int -> CLang.exp
|
27 : |
|
|
|
28 : |
|
|
end = struct
|
29 : |
|
|
|
30 : |
|
|
structure CL = CLang
|
31 : |
|
|
structure RN = RuntimeNames
|
32 : |
|
|
structure IL = TreeIL
|
33 : |
|
|
structure Op = IL.Op
|
34 : |
|
|
structure Ty = IL.Ty
|
35 : |
|
|
structure V = IL.Var
|
36 : |
|
|
|
37 : |
|
|
datatype var = datatype CLang.typed_var
|
38 : |
|
|
|
39 : |
|
|
type env = var TreeIL.Var.Map.map
|
40 : |
|
|
|
41 : |
|
|
fun lookup (env, x) = (case V.Map.find (env, x)
|
42 : |
|
|
of SOME(V(_, x')) => x'
|
43 : |
|
|
| NONE => raise Fail(concat["lookup(_, ", V.name x, ")"])
|
44 : |
|
|
(* end case *))
|
45 : |
|
|
|
46 : |
|
|
(* integer literal expression *)
|
47 : |
|
|
fun intExp (i : int) = CL.mkInt(IntInf.fromInt i)
|
48 : |
|
|
|
49 : |
|
|
(* the type of an image-data pointer. *)
|
50 : |
|
|
fun imageDataPtrTy rTy = CL.T_Qual("__global", CL.T_Ptr(CL.T_Num rTy))
|
51 : |
|
|
|
52 : |
|
|
(* translate TreeIL types to CLang types *)
|
53 : |
|
|
fun trType ty = (case ty
|
54 : |
|
|
of Ty.BoolTy => CLang.T_Named "uint"
|
55 : |
|
|
| Ty.StringTy => CL.charPtr
|
56 : |
|
|
| Ty.IntTy => !RN.gIntTy
|
57 : |
|
|
| Ty.TensorTy[] => !RN.gRealTy
|
58 : |
|
|
| Ty.TensorTy[n] => CL.T_Named(RN.vecTy n)
|
59 : |
|
|
| Ty.TensorTy[n, m] => CL.T_Named(RN.matTy(n,m))
|
60 : |
|
|
| Ty.SeqTy(Ty.IntTy, n) => CL.T_Named(RN.ivecTy n)
|
61 : |
|
|
| Ty.SeqTy(Ty.TensorTy[] , n) => CL.T_Named(RN.vecTy n)
|
62 : |
|
|
| Ty.AddrTy(ImageInfo.ImgInfo{ty=(_, rTy), ...}) => imageDataPtrTy rTy
|
63 : |
|
|
| Ty.ImageTy(ImageInfo.ImgInfo{dim, ...}) => CL.T_Named(RN.imageTy dim)
|
64 : |
|
|
| _ => raise Fail(concat["TreeToC.trType(", Ty.toString ty, ")"])
|
65 : |
|
|
(* end case *))
|
66 : |
|
|
|
67 : |
|
|
(* generate new variables *)
|
68 : |
|
|
local
|
69 : |
|
|
val count = ref 0
|
70 : |
|
|
fun freshName prefix = let
|
71 : |
|
|
val n = !count
|
72 : |
|
|
in
|
73 : |
|
|
count := n+1;
|
74 : |
|
|
concat[prefix, "_", Int.toString n]
|
75 : |
|
|
end
|
76 : |
|
|
in
|
77 : |
|
|
fun tmpVar ty = freshName "tmp"
|
78 : |
|
|
fun freshVar prefix = freshName prefix
|
79 : |
|
|
end (* local *)
|
80 : |
|
|
|
81 : |
|
|
(* translate IL basis functions *)
|
82 : |
|
|
fun trApply (f, args) = CL.mkApply(ILBasis.toString f, args)
|
83 : |
|
|
|
84 : |
|
|
(* vector indexing support. Arguments are: vector, index *)
|
85 : |
|
|
local
|
86 : |
|
|
val fields = Vector.fromList [
|
87 : |
|
|
"s0", "s1", "s2", "s3",
|
88 : |
|
|
"s4", "s5", "s6", "s7",
|
89 : |
|
|
"s8", "s9", "sa", "sb",
|
90 : |
|
|
"sc", "sd", "se", "sf"
|
91 : |
|
|
]
|
92 : |
|
|
in
|
93 : |
|
|
fun vecIndex (v, ix) = CL.mkSelect(v, Vector.sub(fields, ix))
|
94 : |
|
|
end
|
95 : |
|
|
|
96 : |
|
|
(* translate a variable use *)
|
97 : |
|
|
fun trVar (env, x) = (case V.kind x
|
98 : |
|
|
of IL.VK_Global => CL.mkIndirect(CL.E_Var RN.globalsVarName, lookup(env, x))
|
99 : |
|
|
| IL.VK_Local => CL.mkVar(lookup(env, x))
|
100 : |
|
|
(* end case *))
|
101 : |
|
|
|
102 : |
|
|
(* translate a state-variable use *)
|
103 : |
|
|
fun trStateVar (IL.SV{name, ...}) = CL.mkIndirect(CL.mkVar "selfIn", name)
|
104 : |
|
|
|
105 : |
|
|
fun castArgs ty = List.map (fn e => CL.mkCast(ty, e))
|
106 : |
|
|
|
107 : |
|
|
(* Translate a TreeIL operator application to a CLang expression *)
|
108 : |
|
|
fun trOp (rator, args) = (case (rator, args)
|
109 : |
|
|
of (Op.Add ty, [a, b]) => CL.mkBinOp(a, CL.#+, b)
|
110 : |
|
|
| (Op.Sub ty, [a, b]) => CL.mkBinOp(a, CL.#-, b)
|
111 : |
|
|
| (Op.Mul ty, [a, b]) => CL.mkBinOp(a, CL.#*, b)
|
112 : |
|
|
| (Op.Div ty, [a, b]) => CL.mkBinOp(a, CL.#/, b)
|
113 : |
|
|
| (Op.Neg ty, [a]) => CL.mkUnOp(CL.%-, a)
|
114 : |
|
|
| (Op.Abs(Ty.IntTy), args) => CL.mkApply("abs", args)
|
115 : |
|
|
| (Op.Abs(Ty.TensorTy[]), args) => CL.mkApply(RN.fabs, args)
|
116 : |
|
|
| (Op.Abs(Ty.TensorTy[_]), args) => CL.mkApply(RN.fabs, args)
|
117 : |
|
|
| (Op.Abs ty, [a]) => raise Fail(concat["Abs<", Ty.toString ty, ">"])
|
118 : |
|
|
| (Op.LT ty, [a, b]) => CL.mkBinOp(a, CL.#<, b)
|
119 : |
|
|
| (Op.LTE ty, [a, b]) => CL.mkBinOp(a, CL.#<=, b)
|
120 : |
|
|
| (Op.EQ ty, [a, b]) => CL.mkBinOp(a, CL.#==, b)
|
121 : |
|
|
| (Op.NEQ ty, [a, b]) => CL.mkBinOp(a, CL.#!=, b)
|
122 : |
|
|
| (Op.GTE ty, [a, b]) => CL.mkBinOp(a, CL.#>=, b)
|
123 : |
|
|
| (Op.GT ty, [a, b]) => CL.mkBinOp(a, CL.#>, b)
|
124 : |
|
|
| (Op.Not, [a]) => CL.mkUnOp(CL.%!, a)
|
125 : |
|
|
| (Op.Max, args) => CL.mkApply(RN.max, castArgs (!RN.gRealTy) args)
|
126 : |
|
|
| (Op.Min, args) => CL.mkApply(RN.min, castArgs (!RN.gRealTy) args)
|
127 : |
|
|
| (Op.Clamp ty, [lo, hi, x]) => CL.mkApply(RN.clamp, [x, lo, hi])
|
128 : |
|
|
| (Op.Lerp ty, args) => (case ty
|
129 : |
|
|
of Ty.TensorTy[] => CL.mkApply(RN.lerp, castArgs (!RN.gRealTy) args)
|
130 : |
|
|
| Ty.TensorTy[n] => CL.mkApply(RN.lerp, castArgs (CL.T_Named(RN.vecTy n)) args)
|
131 : |
|
|
| _ => raise Fail(concat[
|
132 : |
|
|
"lerp<", Ty.toString ty, "> not supported"
|
133 : |
|
|
])
|
134 : |
|
|
(* end case *))
|
135 : |
|
|
| (Op.Dot d, args) => CL.E_Apply(RN.dot, args)
|
136 : |
|
|
| (Op.MulVecMat(m, n), args) =>
|
137 : |
|
|
if (1 < m) andalso (m < 4) andalso (m = n)
|
138 : |
|
|
then CL.E_Apply(RN.mulVecMat(m,n), args)
|
139 : |
|
|
else raise Fail "unsupported vector-matrix multiply"
|
140 : |
|
|
| (Op.MulMatVec(m, n), args) =>
|
141 : |
|
|
if (1 < m) andalso (m < 4) andalso (m = n)
|
142 : |
|
|
then CL.E_Apply(RN.mulMatVec(m,n), args)
|
143 : |
|
|
else raise Fail "unsupported matrix-vector multiply"
|
144 : |
|
|
| (Op.MulMatMat(m, n, p), args) =>
|
145 : |
|
|
if (1 < m) andalso (m < 4) andalso (m = n) andalso (n = p)
|
146 : |
|
|
then CL.E_Apply(RN.mulMatMat(m,n,p), args)
|
147 : |
|
|
else raise Fail "unsupported matrix-matrix multiply"
|
148 : |
|
|
| (Op.Cross, args) => CL.E_Apply(RN.cross, args)
|
149 : |
|
|
| (Op.Norm(Ty.TensorTy[n]), args) => CL.E_Apply(RN.length, args)
|
150 : |
|
|
| (Op.Norm(Ty.TensorTy[m,n]), args) => CL.E_Apply(RN.norm(m,n), args)
|
151 : |
|
|
| (Op.Normalize d, args) => CL.E_Apply(RN.normalize, args)
|
152 : |
|
|
| (Op.Scale(Ty.TensorTy[n]), [s, v]) => CL.mkBinOp(s, CL.#*, v)
|
153 : |
|
|
| (Op.PrincipleEvec ty, _) => raise Fail "PrincipleEvec unimplemented"
|
154 : |
|
|
| (Op.Select(Ty.TupleTy tys, i), [a]) => raise Fail "Select unimplemented"
|
155 : |
|
|
| (Op.Index(Ty.SeqTy(Ty.IntTy, n), i), [a]) => vecIndex (a, i)
|
156 : |
|
|
| (Op.Index(Ty.TensorTy[n], i), [a]) => vecIndex (a, i)
|
157 : |
|
|
| (Op.Subscript(Ty.SeqTy(Ty.IntTy, n)), [v, CL.E_Int(ix, _)]) => vecIndex (v, Int.fromLarge ix)
|
158 : |
|
|
| (Op.Subscript(Ty.SeqTy(Ty.IntTy, n)), [v, ix]) => let
|
159 : |
|
|
val unionTy = CL.T_Named(concat["union", Int.toString n, !RN.gIntSuffix, "_t"])
|
160 : |
|
|
val vecExp = CL.mkSelect(CL.mkCast(unionTy, v), "i")
|
161 : |
|
|
in
|
162 : |
|
|
CL.mkSubscript(vecExp, ix)
|
163 : |
|
|
end
|
164 : |
|
|
| (Op.Subscript(Ty.TensorTy[n]), [v, CL.E_Int(ix, _)]) => vecIndex (v, Int.fromLarge ix)
|
165 : |
|
|
| (Op.Subscript(Ty.TensorTy[n]), [v, ix]) => let
|
166 : |
|
|
val unionTy = CL.T_Named(concat["union", Int.toString n, !RN.gRealSuffix, "_t"])
|
167 : |
|
|
val vecExp = CL.mkSelect(CL.mkCast(unionTy, v), "r")
|
168 : |
|
|
in
|
169 : |
|
|
CL.mkSubscript(vecExp, ix)
|
170 : |
|
|
end
|
171 : |
|
|
| (Op.Subscript(Ty.TensorTy[_,_]), [m, ix, CL.E_Int(jx, _)]) =>
|
172 : |
|
|
vecIndex(CL.mkSubscript(m, ix), Int.fromLarge jx)
|
173 : |
|
|
| (Op.Subscript(Ty.TensorTy[_,n]), [m, ix, jx]) => let
|
174 : |
|
|
val unionTy = CL.T_Named(concat["union", Int.toString n, !RN.gRealSuffix, "_t"])
|
175 : |
|
|
val vecExp = CL.mkSelect(CL.mkCast(unionTy, CL.mkSubscript(m, ix)), "r")
|
176 : |
|
|
in
|
177 : |
|
|
CL.mkSubscript(vecExp, jx)
|
178 : |
|
|
end
|
179 : |
|
|
| (Op.Subscript ty, t::(ixs as _::_)) =>
|
180 : |
|
|
raise Fail(concat["Subscript<", Ty.toString ty, "> unsupported"])
|
181 : |
|
|
| (Op.Ceiling d, args) => CL.mkApply("ceil", args)
|
182 : |
|
|
| (Op.Floor d, args) => CL.mkApply("floor", args)
|
183 : |
|
|
| (Op.Round d, args) => CL.mkApply("round", args)
|
184 : |
|
|
| (Op.Trunc d, args) => CL.mkApply("trunc", args)
|
185 : |
|
|
| (Op.IntToReal, [a]) => CL.mkCast(!RN.gRealTy, a)
|
186 : |
|
|
| (Op.RealToInt 1, [a]) => CL.mkCast(!RN.gIntTy, a)
|
187 : |
|
|
| (Op.RealToInt d, args) => CL.mkApply(RN.vecftoi d, args)
|
188 : |
|
|
(* FIXME: need type info *)
|
189 : |
|
|
| (Op.ImageAddress(ImageInfo.ImgInfo{ty=(_,rTy), ...}), [a as CL.E_Indirect(_,field)]) => let
|
190 : |
|
|
val cTy = imageDataPtrTy rTy
|
191 : |
|
|
in
|
192 : |
|
|
CL.mkCast(cTy,
|
193 : |
|
|
CL.mkSelect(CL.mkVar RN.globalImageDataName, RN.imageDataName field))
|
194 : |
|
|
end
|
195 : |
|
|
| (Op.LoadVoxels(info, 1), [a]) => let
|
196 : |
|
|
val realTy as CL.T_Num rTy = !RN.gRealTy
|
197 : |
|
|
val a = CL.E_UnOp(CL.%*, a)
|
198 : |
|
|
in
|
199 : |
|
|
if (rTy = ImageInfo.sampleTy info)
|
200 : |
|
|
then a
|
201 : |
|
|
else CL.E_Cast(realTy, a)
|
202 : |
|
|
end
|
203 : |
|
|
| (Op.LoadVoxels _, [a]) =>
|
204 : |
|
|
raise Fail("impossible " ^ Op.toString rator)
|
205 : |
|
|
| (Op.PosToImgSpace(ImageInfo.ImgInfo{dim, ...}), [img, pos]) =>
|
206 : |
|
|
CL.mkApply(RN.toImageSpace dim, [CL.mkUnOp(CL.%&,img), pos])
|
207 : |
|
|
| (Op.TensorToWorldSpace(info, ty), [v, x]) =>
|
208 : |
|
|
CL.mkApply(RN.toWorldSpace ty, [CL.mkUnOp(CL.%&,v), x])
|
209 : |
|
|
| (Op.LoadImage info, [a]) =>
|
210 : |
|
|
raise Fail("impossible " ^ Op.toString rator)
|
211 : |
|
|
| (Op.Inside(ImageInfo.ImgInfo{dim, ...}, s), [pos, img]) =>
|
212 : |
|
|
CL.mkApply(RN.inside dim, [pos, CL.mkUnOp(CL.%&,img), intExp s])
|
213 : |
|
|
| (Op.Input(ty, name, desc), []) =>
|
214 : |
|
|
raise Fail("impossible " ^ Op.toString rator)
|
215 : |
|
|
| (Op.InputWithDefault(ty, name, desc), [a]) =>
|
216 : |
|
|
raise Fail("impossible " ^ Op.toString rator)
|
217 : |
|
|
| _ => raise Fail(concat[
|
218 : |
|
|
"unknown or incorrect operator ", Op.toString rator
|
219 : |
|
|
])
|
220 : |
|
|
(* end case *))
|
221 : |
|
|
|
222 : |
|
|
fun trExp (env, e) = (case e
|
223 : |
|
|
of IL.E_State x => trStateVar x
|
224 : |
|
|
| IL.E_Var x => trVar (env, x)
|
225 : |
|
|
| IL.E_Lit(Literal.Int n) => CL.mkIntTy(n, !RN.gIntTy)
|
226 : |
|
|
| IL.E_Lit(Literal.Bool b) => CL.mkBool b
|
227 : |
|
|
| IL.E_Lit(Literal.Float f) => CL.mkFlt(f, !RN.gRealTy)
|
228 : |
|
|
| IL.E_Lit(Literal.String s) => CL.mkStr s
|
229 : |
|
|
| IL.E_Op(rator, args) => trOp (rator, trExps(env, args))
|
230 : |
|
|
| IL.E_Apply(f, args) => trApply(f, trExps(env, args))
|
231 : |
|
|
| IL.E_Cons(Ty.TensorTy[n], args) => CL.mkApply(RN.mkVec n, trExps(env, args))
|
232 : |
|
|
| IL.E_Cons(ty, _) => raise Fail(concat["E_Cons(", Ty.toString ty, ", _) in expression"])
|
233 : |
|
|
(* end case *))
|
234 : |
|
|
|
235 : |
|
|
and trExps (env, exps) = List.map (fn exp => trExp(env, exp)) exps
|
236 : |
|
|
|
237 : |
|
|
fun trLHSVar (env, lhs) = (case V.kind lhs
|
238 : |
|
|
of IL.VK_Global => CL.mkIndirect(CL.mkVar RN.globalsVarName, lookup(env, lhs))
|
239 : |
|
|
| IL.VK_Local => CL.mkVar(lookup(env, lhs))
|
240 : |
|
|
(* end case *))
|
241 : |
|
|
|
242 : |
|
|
fun trLHSStateVar (IL.SV{name, ...}) = CL.mkIndirect(CL.mkVar "selfOut", name)
|
243 : |
|
|
|
244 : |
|
|
fun trSet (env, lhs, rhs) = (
|
245 : |
|
|
(* certain rhs forms, such as those that return a matrix,
|
246 : |
|
|
* require a function call instead of an assignment
|
247 : |
|
|
*)
|
248 : |
|
|
case rhs
|
249 : |
|
|
of IL.E_Op(Op.Add(Ty.TensorTy[m,n]), args) =>
|
250 : |
|
|
[CL.mkCall(RN.addMat(m,n), lhs :: trExps(env, args))]
|
251 : |
|
|
| IL.E_Op(Op.Sub(Ty.TensorTy[m,n]), args) =>
|
252 : |
|
|
[CL.mkCall(RN.subMat(m,n), lhs :: trExps(env, args))]
|
253 : |
|
|
| IL.E_Op(Op.Neg(Ty.TensorTy[m,n]), args) =>
|
254 : |
|
|
[CL.mkCall(RN.scaleMat(m,n), lhs :: intExp ~1 :: trExps(env, args))]
|
255 : |
|
|
| IL.E_Op(Op.Scale(Ty.TensorTy[m,n]), args) =>
|
256 : |
|
|
[CL.mkCall(RN.scaleMat(m,n), lhs :: trExps(env, args))]
|
257 : |
|
|
| IL.E_Op(Op.MulMatMat(m,n,p), args) =>
|
258 : |
|
|
[CL.mkCall(RN.mulMatMat(m,n,p), lhs :: trExps(env, args))]
|
259 : |
|
|
| IL.E_Op(Op.Identity n, args) =>
|
260 : |
|
|
[CL.mkCall(RN.identityMat n, [lhs])]
|
261 : |
|
|
| IL.E_Op(Op.Zero(Ty.TensorTy[m,n]), args) =>
|
262 : |
|
|
[CL.mkCall(RN.zeroMat(m,n), [lhs])]
|
263 : |
|
|
| IL.E_Op(Op.TensorToWorldSpace(info, ty as Ty.TensorTy[_,_]), [img,src]) =>
|
264 : |
|
|
[CL.mkCall(RN.toWorldSpace ty, lhs :: [CL.mkUnOp(CL.%&,trExp(env, img)),trExp(env, src)] )]
|
265 : |
|
|
| IL.E_Op(Op.LoadVoxels(info, n), [a]) =>
|
266 : |
|
|
if (n > 1)
|
267 : |
|
|
then let
|
268 : |
|
|
val stride = ImageInfo.stride info
|
269 : |
|
|
val rTy = ImageInfo.sampleTy info
|
270 : |
|
|
val vp = freshVar "vp"
|
271 : |
|
|
val needsCast = (CL.T_Num rTy <> !RN.gRealTy)
|
272 : |
|
|
fun mkLoad i = let
|
273 : |
|
|
val e = CL.mkSubscript(CL.mkVar vp, intExp(i*stride))
|
274 : |
|
|
in
|
275 : |
|
|
if needsCast then CL.mkCast(!RN.gRealTy, e) else e
|
276 : |
|
|
end
|
277 : |
|
|
in [
|
278 : |
|
|
CL.mkDecl(imageDataPtrTy rTy, vp, SOME(CL.I_Exp(trExp(env, a)))),
|
279 : |
|
|
CL.mkAssign(lhs,
|
280 : |
|
|
CL.mkApply(RN.mkVec n, List.tabulate (n, mkLoad)))
|
281 : |
|
|
] end
|
282 : |
|
|
else [CL.mkAssign(lhs, trExp(env, rhs))]
|
283 : |
|
|
| IL.E_Cons(Ty.TensorTy[n,m], args) => let
|
284 : |
|
|
(* matrices are represented as arrays of union<d><ty>_t vectors *)
|
285 : |
|
|
fun doRows (_, []) = []
|
286 : |
|
|
| doRows (i, e::es) =
|
287 : |
|
|
CL.mkAssign(CL.mkSubscript(lhs, intExp i), e)
|
288 : |
|
|
:: doRows (i+1, es)
|
289 : |
|
|
in
|
290 : |
|
|
doRows (0, trExps(env, args))
|
291 : |
|
|
end
|
292 : |
|
|
| IL.E_Var x => (case IL.Var.ty x
|
293 : |
|
|
of Ty.TensorTy[n,m] => [CL.mkCall(RN.copyMat(n,m), [lhs, trVar(env, x)])]
|
294 : |
|
|
| _ => [CL.mkAssign(lhs, trVar(env, x))]
|
295 : |
|
|
(* end case *))
|
296 : |
|
|
| _ => [CL.mkAssign(lhs, trExp(env, rhs))]
|
297 : |
|
|
(* end case *))
|
298 : |
|
|
|
299 : |
|
|
fun trAssign (env, lhs, rhs) = trSet (env, trLHSVar (env, lhs), rhs)
|
300 : |
|
|
|
301 : |
|
|
fun trLocals (env : env, locals) =
|
302 : |
|
|
List.foldl
|
303 : |
|
|
(fn (x, env) => V.Map.insert(env, x, V(trType(V.ty x), V.name x)))
|
304 : |
|
|
env locals
|
305 : |
|
|
|
306 : |
|
|
(* generate code to check the status of runtime-system calls *)
|
307 : |
|
|
fun checkSts mkDecl = let
|
308 : |
|
|
val sts = freshVar "sts"
|
309 : |
|
|
in
|
310 : |
|
|
mkDecl sts @
|
311 : |
|
|
[CL.mkIfThen(
|
312 : |
|
|
CL.mkBinOp(CL.mkVar "DIDEROT_OK", CL.#!=, CL.mkVar sts),
|
313 : |
|
|
CL.mkCall("exit", [intExp 1]))]
|
314 : |
|
|
end
|
315 : |
|
|
|
316 : |
|
|
fun trStms (env, stms) = let
|
317 : |
|
|
fun trStmt (env, stm) = (case stm
|
318 : |
|
|
of IL.S_Comment text => [CL.mkComment text]
|
319 : |
|
|
| IL.S_Assign([x], exp) => trAssign (env, x, exp)
|
320 : |
|
|
| IL.S_IfThen(cond, thenBlk) =>
|
321 : |
|
|
[CL.mkIfThen(trExp(env, cond), trBlk(env, thenBlk))]
|
322 : |
|
|
| IL.S_IfThenElse(cond, thenBlk, elseBlk) =>
|
323 : |
|
|
[CL.mkIfThenElse(trExp(env, cond),
|
324 : |
|
|
trBlk(env, thenBlk),
|
325 : |
|
|
trBlk(env, elseBlk))]
|
326 : |
|
|
| IL.S_New _ => raise Fail "new not supported yet" (* FIXME *)
|
327 : |
|
|
| IL.S_Save([x], exp) => trSet (env, trLHSStateVar x, exp)
|
328 : |
|
|
(* FIXME: I think that S_LoadImage should never happen in OpenCL code [jhr] *)
|
329 : |
|
|
| IL.S_LoadImage(lhs, dim, name) => checkSts (fn sts => let
|
330 : |
|
|
val lhs = lookup(env, lhs)
|
331 : |
|
|
val name = trExp(env, name)
|
332 : |
|
|
val imgTy = CL.T_Named(RN.imageTy dim)
|
333 : |
|
|
val loadFn = RN.loadImage dim
|
334 : |
|
|
in [
|
335 : |
|
|
CL.mkDecl(
|
336 : |
|
|
CL.T_Named RN.statusTy, sts,
|
337 : |
|
|
SOME(CL.I_Exp(CL.E_Apply(loadFn, [name, CL.mkUnOp(CL.%&, CL.E_Var lhs)]))))
|
338 : |
|
|
] end)
|
339 : |
|
|
(* FIXME: I think that S_Input should never happen in OpenCL code [jhr] *)
|
340 : |
|
|
| IL.S_Input(lhs, name, desc, optDflt) => checkSts (fn sts => let
|
341 : |
|
|
val inputFn = RN.input(V.ty lhs)
|
342 : |
|
|
val lhs = lookup(env, lhs)
|
343 : |
|
|
val (initCode, hasDflt) = (case optDflt
|
344 : |
|
|
of SOME e => ([CL.mkAssign(CL.E_Var lhs, trExp(env, e))], true)
|
345 : |
|
|
| NONE => ([], false)
|
346 : |
|
|
(* end case *))
|
347 : |
|
|
val code = [
|
348 : |
|
|
CL.mkDecl(
|
349 : |
|
|
CL.T_Named RN.statusTy, sts,
|
350 : |
|
|
SOME(CL.I_Exp(CL.E_Apply(inputFn, [
|
351 : |
|
|
CL.E_Str name, CL.mkUnOp(CL.%&, CL.mkIndirect(CL.mkVar (RN.globalsVarName), lhs)), CL.mkBool hasDflt
|
352 : |
|
|
]))))
|
353 : |
|
|
]
|
354 : |
|
|
in
|
355 : |
|
|
initCode @ code
|
356 : |
|
|
end)
|
357 : |
|
|
| IL.S_Exit args => [CL.mkReturn NONE]
|
358 : |
|
|
| IL.S_Active => [CL.mkReturn(SOME(CL.mkVar RN.kActive))]
|
359 : |
|
|
| IL.S_Stabilize => [CL.mkReturn(SOME(CL.mkVar RN.kStabilize))]
|
360 : |
|
|
| IL.S_Die => [CL.mkReturn(SOME(CL.mkVar RN.kDie))]
|
361 : |
|
|
(* end case *))
|
362 : |
|
|
in
|
363 : |
|
|
List.foldr (fn (stm, stms) => trStmt(env, stm)@stms) [] stms
|
364 : |
|
|
end
|
365 : |
|
|
|
366 : |
|
|
and trBlk (env, IL.Block{locals, body}) = let
|
367 : |
|
|
val env = trLocals (env, locals)
|
368 : |
|
|
val stms = trStms (env, body)
|
369 : |
|
|
fun mkDecl (x, stms) = (case V.Map.find (env, x)
|
370 : |
|
|
of SOME(V(ty, x')) => CL.mkDecl(ty, x', NONE) :: stms
|
371 : |
|
|
| NONE => raise Fail(concat["mkDecl(", V.name x, ", _)"])
|
372 : |
|
|
(* end case *))
|
373 : |
|
|
val stms = List.foldr mkDecl stms locals
|
374 : |
|
|
in
|
375 : |
|
|
CL.mkBlock stms
|
376 : |
|
|
end
|
377 : |
|
|
|
378 : |
|
|
fun trFragment (env, IL.Block{locals, body}) = let
|
379 : |
|
|
val env = trLocals (env, locals)
|
380 : |
|
|
val stms = trStms (env, body)
|
381 : |
|
|
fun mkDecl (x, stms) = (case V.Map.find (env, x)
|
382 : |
|
|
of SOME(V(ty, x')) => CL.mkDecl(ty, x', NONE) :: stms
|
383 : |
|
|
| NONE => raise Fail(concat["mkDecl(", V.name x, ", _)"])
|
384 : |
|
|
(* end case *))
|
385 : |
|
|
val stms = List.foldr mkDecl stms locals
|
386 : |
|
|
in
|
387 : |
|
|
(env, stms)
|
388 : |
|
|
end
|
389 : |
|
|
|
390 : |
|
|
val trBlock = trBlk
|
391 : |
|
|
|
392 : |
|
|
end
|