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-inputs-util.sml
ViewVC logotype

Annotation of /branches/vis15/src/compiler/cxx-util/gen-inputs-util.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 5302 - (view) (download)

1 : jhr 3810 (* gen-inputs-util.sml
2 :     *
3 :     * This code is part of the Diderot Project (http://diderot-language.cs.uchicago.edu)
4 :     *
5 :     * COPYRIGHT (c) 2015 The University of Chicago
6 :     * All rights reserved.
7 :     *)
8 :    
9 :     structure GenInputsUtil : sig
10 :    
11 : jhr 3897 type input_desc = TreeGlobalVar.t Inputs.input
12 : jhr 3810
13 :     (*** Support for standalone executables ***)
14 :    
15 : jhr 3912 (* generate the input initialization structure that we use to initialize input
16 :     * globals from command-line arguments in stand-alone executables.
17 :     *)
18 :     val genInputsStruct : CodeGenEnv.t * input_desc list -> CLang.decl list
19 :    
20 : jhr 3810 (* generate the common functions that handle inputs for standalone executables. These are:
21 : jhr 3897 * init_defaults -- called to initialize the default input values
22 :     * register_inputs -- called to register the command-line options for the input globals
23 : jhr 3810 *)
24 : jhr 3897 val genExecInputFuns : CodeGenEnv.t * TreeIR.program -> CLang.decl list
25 : jhr 3810
26 :     (*** Support for libraries ***)
27 :    
28 :     (* generate the typedef for the defined-input flag struct. *)
29 : jhr 3897 val genDefinedInpStruct : input_desc list -> CLang.decl list
30 : jhr 3810
31 :     (* generate the function that initializes the defined-input flag struct. *)
32 : jhr 3897 val genDefineInp : input_desc list -> CLang.decl
33 : jhr 3810
34 : jhr 4244 (* generate the common functions that handle inputs for libraries. These are:
35 : jhr 4317 * init_defined_inputs -- function that initializes the defined-input flag struct
36 : jhr 4244 * init_defaults -- fucntion to initialize the default input values
37 :     *)
38 :     val genLibraryInputFuns : CodeGenEnv.t * TreeIR.program -> CLang.decl list
39 :    
40 : jhr 3912 (*** Utility functions ***)
41 :    
42 : jhr 5058 val castAPIPtr : {
43 :     env : CodeGenEnv.t, ty : APITypes.t, src : CLang.exp
44 :     } -> CLang.exp
45 :    
46 : jhr 4241 (* generate code to copy from a C++ global variable to a C reference *)
47 :     val copyToC : {
48 : jhr 4317 env : CodeGenEnv.t, ty : APITypes.t, src : CLang.exp, dst : CLang.exp
49 :     } -> CLang.stm
50 : jhr 3912
51 : jhr 4241 (* generate code to copy from a C input argument to the C++ global *)
52 :     val copyToCxx : {
53 : jhr 4317 env : CodeGenEnv.t, ty : APITypes.t, src : CLang.exp, dst : CLang.exp
54 :     } -> CLang.stm
55 : jhr 4241
56 :     (* generate code to copy a value from one variable to another *)
57 :     val copy : {
58 : jhr 4317 env : CodeGenEnv.t, ty : APITypes.t, src : CLang.exp, dst : CLang.exp
59 :     } -> CLang.stm
60 : jhr 4241
61 : jhr 3912 (* an l-value expression for accessing a defined-input flag for the given global input *)
62 :     val defined : TreeGlobalVar.t -> CLang.exp
63 :    
64 : jhr 3810 end = struct
65 :    
66 :     structure IR = TreeIR
67 : jhr 3897 structure Ty = APITypes
68 : jhr 3866 structure GVar = TreeGlobalVar
69 : jhr 3810 structure CL = CLang
70 : jhr 3870 structure ToC = TreeToCxx
71 : jhr 3896 structure Env = CodeGenEnv
72 : jhr 3897 structure Inp = Inputs
73 : jhr 3906 structure RN = CxxNames
74 : jhr 3810
75 : jhr 3897 type input_desc = GVar.t Inp.input
76 : jhr 3810
77 : jhr 3910 val worldPtrTy = RN.worldPtrTy
78 :     val globalPtrTy = RN.globalPtrTy
79 : jhr 3897
80 : jhr 4111 (* translate the API type of an input to the C++ type used to representation the input
81 :     * in the input struct. Note that the representation of nrrd inputs (images and
82 :     * dynamic sequences) depends on if we are building a library or stand-alone executable.
83 :     * In the former case, we use a nrrd pointer, whereas we use a string in the latter case.
84 :     *)
85 :     local
86 :     fun nrrdTy env = if #exec(Env.target env)
87 : jhr 4317 then CL.T_Named "std::string"
88 :     else CL.T_Ptr(CL.T_Named "Nrrd")
89 : jhr 4111 in
90 :     fun trType (env, ty) = (case ty
91 : jhr 4317 of Ty.IntTy => Env.intTy env
92 :     | Ty.BoolTy => CL.boolTy
93 :     | Ty.TensorTy[] => Env.realTy env
94 :     | Ty.TensorTy dd => RN.tensorTy dd
95 :     | Ty.StringTy => CL.T_Named "std::string"
96 :     | Ty.ImageTy(dim, shp) => nrrdTy env
97 :     | Ty.SeqTy(ty, NONE) => nrrdTy env
98 :     | Ty.SeqTy(ty, SOME n) => CL.T_Array(trType(env, ty), SOME n)
99 :     (* end case *))
100 : jhr 4111 end (* local *)
101 : jhr 3810
102 : jhr 3912 (* generate the input initialization structure that we use to initialize input
103 :     * globals from command-line arguments in stand-alone executables.
104 :     *)
105 :     fun genInputsStruct (_, []) = []
106 :     | genInputsStruct (env : Env.t, inputs) = let
107 : jhr 4111 fun mkField (Inp.INP{var, ty, ...}) = (trType(env, ty), GVar.qname var)
108 : jhr 3912 in
109 : jhr 3931 [CL.D_StructDef(NONE, List.map mkField inputs, SOME RN.inputsTyName)]
110 : jhr 3912 end
111 :    
112 : jhr 3810 (* generate code to initialize the default input values *)
113 : jhr 4244 fun genInitDefaults (env, inputs, dstTy, dst, IR.Block{locals, body}) = let
114 : jhr 4317 (* initialization for dynamic sequence and image inputs, which are specified by
115 :     * strings.
116 :     *)
117 :     val mkNrrdInit = if #exec(Env.target env)
118 :     then (fn (field, nrrd, stms) => CL.mkAssign(
119 :     CL.mkIndirect(CL.mkVar dst, field),
120 :     CL.mkStr nrrd) :: stms)
121 :     else (fn (_, _, stms) => stms)
122 :     fun initDefault (Inp.INP{var, init, ...}, stms) = (case init
123 :     of Inp.LoadSeq nrrd => mkNrrdInit (GVar.qname var, nrrd, stms)
124 :     | Inp.Proxy(nrrd, _) => mkNrrdInit (GVar.qname var, nrrd, stms)
125 :     | _ => stms
126 :     (* end case *))
127 :     val inputInits = List.foldr initDefault
128 :     val body = ToC.trWithLocals (
129 :     Env.insert(env, PseudoVars.global, dst),
130 :     !locals,
131 :     fn env => List.foldr initDefault (#2 (ToC.trStms (env, body))) inputs)
132 :     in
133 :     CL.D_Func(
134 :     ["static"], CL.voidTy, [], "init_defaults",
135 :     [CL.PARAM([], dstTy, dst)],
136 :     body)
137 :     end
138 : jhr 3810
139 :     (* generate code to register command-line options for setting the input variables *)
140 : jhr 3896 fun genRegisterInputs (env, inputs) = let
141 : jhr 4317 (* pointer to the inputs *)
142 :     val inputsV = "inp"
143 :     val inputsE = CL.mkVar inputsV
144 : jhr 3810 (* some common variables *)
145 :     val optsV = CL.mkVar "opts"
146 :     (* register a given input *)
147 : jhr 3931 fun registerInput (Inp.INP{var, name, ty, desc, init}) = let
148 : jhr 4426 val args = [CL.mkBool(Inp.isDefault init)]
149 : jhr 4317 val args = (case ty
150 :     of Ty.TensorTy(shape as _::_) =>
151 :     CL.mkInt(IntLit.fromInt (List.foldl Int.* 1 shape)) ::
152 :     CL.mkSelect(
153 :     CL.mkIndirect(inputsE, GVar.qname var), "_data") ::
154 :     args
155 :     | Ty.SeqTy(_, SOME n) =>
156 :     CL.mkInt(IntLit.fromInt n) ::
157 :     CL.mkIndirect(inputsE, GVar.qname var) ::
158 :     args
159 :     | _ => CL.mkAddrOf(CL.mkIndirect(inputsE, GVar.qname var)) :: args
160 :     (* end case *))
161 :     val args = (case desc
162 :     of NONE => CL.mkStr "" :: args
163 :     | SOME s => CL.mkStr s :: args
164 :     (* end case *))
165 :     val args = CL.mkStr name :: args
166 :     in
167 :     CL.mkExpStm (CL.mkIndirectDispatch (optsV, "add", args))
168 : jhr 3931 end
169 : jhr 3810 in
170 :     CL.D_Func(
171 : jhr 4028 ["static"], CL.voidTy, [], "register_inputs",
172 : jhr 4833 [CL.PARAM([], RN.inputsPtrTy, inputsV), CL.PARAM([], RN.optionsPtrTy, "opts")],
173 : jhr 3810 CL.mkBlock(List.map registerInput inputs))
174 :     end
175 :    
176 :     (* generate the common functions that handle inputs for standalone executables. These are:
177 : jhr 3897 * init_defaults -- called to initialize the default input values
178 :     * register_inputs -- called to register the command-line options for the input globals
179 : jhr 3810 *)
180 : jhr 4251 fun genExecInputFuns (env, IR.Program{inputs=[], constInit, ...}) =
181 : jhr 4317 if IR.emptyBlk constInit
182 :     then []
183 :     else [genInitDefaults (env, [], RN.inputsPtrTy, "inp", constInit)]
184 : jhr 4251 | genExecInputFuns (env, IR.Program{inputs, constInit, ...}) = [
185 : jhr 4244 genInitDefaults (env, inputs, RN.inputsPtrTy, "inp", constInit),
186 : jhr 3897 genRegisterInputs (env, inputs)
187 : jhr 3810 ]
188 :    
189 : jhr 3897 (* an l-value expression for accessing a defined-input flag *)
190 : jhr 4234 fun defined gv = CL.mkSelect(CL.mkIndirect(CL.mkVar "wrld", "_definedInp"), GVar.qname gv)
191 : jhr 3897
192 : jhr 3810 (* generate the typedef for the defined-input flag struct. *)
193 : jhr 3897 fun genDefinedInpStruct [] = []
194 :     | genDefinedInpStruct inputs = let
195 : jhr 3924 fun mkField (Inp.INP{var, ...}) = (CL.boolTy, GVar.qname var)
196 : jhr 3810 in
197 : jhr 3896 [CL.D_StructDef(NONE, List.map mkField inputs, SOME "defined_inputs")]
198 : jhr 3810 end
199 :    
200 :     (* generate the function that initializes the defined-input flag struct. *)
201 : jhr 3897 fun genDefineInp inputs = let
202 : jhr 3810 (* the world pointer type *)
203 :     val wrldParam = CL.PARAM([], worldPtrTy, "wrld")
204 : jhr 3897 fun initFlag (Inp.INP{var, ...}) = CL.mkAssign(defined var, CL.mkBool false)
205 : jhr 3810 in
206 :     CL.D_Func(
207 : jhr 4028 ["static"], CL.voidTy, [], "init_defined_inputs",
208 : jhr 3810 [wrldParam],
209 :     CL.mkBlock(List.map initFlag inputs))
210 :     end
211 :    
212 : jhr 4244 (* generate the common functions that handle inputs for libraries. These are:
213 : jhr 4317 * init_defined_inputs -- function that initializes the defined-input flag struct
214 : jhr 4244 * init_defaults -- fucntion to initialize the default input values
215 :     *)
216 : jhr 4251 fun genLibraryInputFuns (env, IR.Program{inputs=[], constInit, ...}) =
217 : jhr 4317 if IR.emptyBlk constInit
218 :     then []
219 :     else [genInitDefaults (env, [], RN.globalPtrTy, RN.globalsVar, constInit)]
220 : jhr 4251 | genLibraryInputFuns (env, IR.Program{inputs, constInit, ...}) = [
221 : jhr 4317 genDefineInp inputs,
222 : jhr 4244 genInitDefaults (env, inputs, RN.globalPtrTy, RN.globalsVar, constInit)
223 : jhr 4317 ]
224 : jhr 4244
225 : jhr 5058 (* generate a static cast to a pointer to the given type *)
226 :     fun castAPIPtr {env, ty, src} = (case ty
227 : jhr 5215 of Ty.IntTy => CL.mkStaticCast(CL.T_Ptr(Env.intTy env), src)
228 :     | Ty.BoolTy => CL.mkStaticCast(CL.T_Ptr CL.boolTy, src)
229 :     | Ty.TensorTy _ => CL.mkStaticCast(CL.T_Ptr(Env.realTy env), src)
230 :     | Ty.StringTy => raise Fail "cast for StringTy"
231 :     | Ty.ImageTy _ => raise Fail "cast for ImageTy"
232 :     | Ty.SeqTy(ty, SOME _) => castAPIPtr {env=env, ty=ty, src=src}
233 :     | Ty.SeqTy(_, NONE) => raise Fail "cast for dynamic SeqTy"
234 :     (* end case *))
235 : jhr 5058
236 : jhr 4241 (* generate code to copy from a C++ global variable to a C reference *)
237 :     fun copyToC {env, ty, src, dst} = let
238 :     fun assign () = CL.mkAssign(dst, src)
239 : jhr 4317 fun addrOf (CL.E_UnOp(CL.%*, x)) = x
240 : jhr 4241 | addrOf x = CL.mkUnOp(CL.%&, x)
241 :     fun memcpy src =
242 : jhr 5302 CL.mkCall("std::memcpy", [dst, src, CL.mkSizeof(trType(env, ty))])
243 : jhr 4317 in
244 :     case ty
245 :     of Ty.IntTy => assign ()
246 :     | Ty.BoolTy => assign ()
247 :     | Ty.TensorTy[] => assign ()
248 :     | Ty.TensorTy shp => memcpy(CL.mkDispatch(src, "addr", [CL.mkInt 0]))
249 : jhr 4438 | Ty.StringTy => CL.mkCall("std::memcpy", [
250 : jhr 4833 addrOf dst, CL.mkDispatch(src, "c_str", []), CL.mkDispatch(src, "size", [])
251 :     ])
252 : jhr 4317 | Ty.ImageTy _ => raise Fail "unexpected image copy"
253 :     | Ty.SeqTy(_, SOME _) => memcpy(addrOf src)
254 :     | Ty.SeqTy(_, NONE) => raise Fail "unexpected dynamic sequence copy"
255 :     (* end case *)
256 :     end
257 : jhr 5302
258 : jhr 4241 (* generate code to copy from a C input argument to the C++ global *)
259 :     fun copyToCxx {env, ty, src, dst} = let
260 :     fun assign () = CL.mkAssign(dst, src)
261 : jhr 4317 fun addrOf (CL.E_UnOp(CL.%*, x)) = x
262 : jhr 4241 | addrOf x = CL.mkUnOp(CL.%&, x)
263 :     fun memcpy () =
264 : jhr 4317 CL.mkCall("std::memcpy", [addrOf dst, addrOf src, CL.mkSizeof(trType(env, ty))])
265 :     in
266 :     case ty
267 :     of Ty.IntTy => assign ()
268 :     | Ty.BoolTy => assign ()
269 :     | Ty.TensorTy[] => assign ()
270 :     | Ty.TensorTy shp => assign () (* uses overloaded assignment *)
271 : jhr 4438 | Ty.StringTy => assign()
272 : jhr 4317 | Ty.ImageTy _ => raise Fail "unexpected image copy"
273 :     | Ty.SeqTy(_, SOME _) => memcpy()
274 :     | Ty.SeqTy(_, NONE) => raise Fail "unexpected dynamic sequence copy"
275 :     (* end case *)
276 :     end
277 : jhr 4241
278 :     (* generate code to copy a value from one variable to another *)
279 : jhr 3912 fun copy {env, ty, src, dst} = let
280 :     fun assign () = CL.mkAssign(dst, src)
281 : jhr 4317 fun addrOf (CL.E_UnOp(CL.%*, x)) = x
282 : jhr 3912 | addrOf x = CL.mkUnOp(CL.%&, x)
283 :     fun memcpy () =
284 : jhr 4317 CL.mkCall("std::memcpy", [addrOf dst, addrOf src, CL.mkSizeof(trType(env, ty))])
285 :     in
286 :     case ty
287 :     of Ty.IntTy => assign ()
288 :     | Ty.BoolTy => assign ()
289 :     | Ty.TensorTy[] => assign ()
290 :     | Ty.TensorTy shp => assign () (* uses overloaded assignment *)
291 : jhr 4438 | Ty.StringTy => assign()
292 : jhr 4317 | Ty.ImageTy _ => raise Fail "unexpected image copy"
293 :     | Ty.SeqTy(_, SOME _) => memcpy()
294 :     | Ty.SeqTy(_, NONE) => raise Fail "unexpected dynamic sequence copy"
295 :     (* end case *)
296 :     end
297 : jhr 3912
298 : jhr 3810 end

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