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

SCM Repository

[diderot] Annotation of /branches/vis15/src/compiler/target-cpu/gen-world.sml
ViewVC logotype

Annotation of /branches/vis15/src/compiler/target-cpu/gen-world.sml

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4519 - (view) (download)

1 : jhr 3924 (* gen-world.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 GenWorld : sig
10 :    
11 : jhr 4349 val genStruct : CodeGenEnv.t * Atom.atom * int -> CLang.decl
12 : jhr 3924
13 : jhr 4407 (* generate the function that creates the initial set of strands *)
14 :     val genCreateFun : CodeGenEnv.t * TreeIR.block * TreeIR.strand * TreeIR.create -> CLang.decl
15 : jhr 3924
16 :     end = struct
17 :    
18 : jhr 3974 structure IR = TreeIR
19 : jhr 3924 structure CL = CLang
20 :     structure RN = CxxNames
21 :     structure Env = CodeGenEnv
22 : jhr 3927 structure Util = CodeGenUtil
23 : jhr 3926 structure ToCxx = TreeToCxx
24 : jhr 3924
25 :     (* generate the struct declaration for the world representation *)
26 : jhr 4349 fun genStruct (env : CodeGenEnv.t, strandName, nAxes) = let
27 : jhr 4369 val spec = Env.target env
28 : jhr 4317 fun memberVar (ty, name) = CL.mkVarDcl(ty, name)
29 : jhr 4500 val members = [memberVar(CL.T_Named "strand_array", "_strands")]
30 : jhr 4317 val members = if #hasGlobals spec
31 :     then memberVar(RN.globalPtrTy, "_globals") :: members
32 :     else members
33 :     val members = if #exec spec orelse not(#hasInputs spec)
34 :     then members
35 :     else memberVar(CL.T_Named "defined_inputs", "_definedInp") :: members
36 :     val members = if TargetSpec.isParallel spec
37 :     then members
38 :     else memberVar(CL.T_Named "uint32_t", "_nactive") ::
39 :     memberVar(CL.T_Named "uint32_t", "_nstable") :: members
40 : jhr 4369 val members = (case #spatialDim spec
41 :     of SOME d => memberVar(CL.T_Ptr(CL.T_Template("diderot::kdtree", [
42 : jhr 4500 CL.T_Named(Int.toString d), Env.realTy env, CL.T_Named "strand_array"
43 : jhr 4369 ])), "_tree") :: members
44 :     | NONE => members
45 :     (* end case *))
46 : jhr 4317 (* add world method decls *)
47 :     fun memberFun (ty, name, params) = CL.mkProto(ty, name, params)
48 : jhr 4407 val members = CL.mkConstrProto("world", []) :: members
49 :     val members = CL.mkDestrProto "world" :: members
50 :     val members = memberFun (CL.boolTy, "init", []) :: members
51 :     val members = memberFun (CL.boolTy, "alloc", [
52 :     CL.PARAM([], CL.T_Array(CL.int32, SOME nAxes), "base"),
53 :     CL.PARAM([], CL.T_Array(CL.uint32, SOME nAxes), "size")
54 :     ]) :: members
55 :     val members = memberFun (CL.boolTy, "create_strands", []) :: members
56 : jhr 4500 val members = if #hasStartMeth spec
57 :     then memberFun (CL.voidTy, "run_start_methods", []) :: members
58 : jhr 4407 else members
59 :     val members = memberFun (CL.uint32, "run", [CL.PARAM([], CL.uint32, "max_nsteps")]) :: members
60 :     val members = memberFun (CL.voidTy, "swap_state", []) :: members
61 : jhr 4500 val members = if #hasGlobalStart spec
62 :     then memberFun (CL.voidTy, "global_start", []) :: members
63 : jhr 4317 else members
64 :     val members = if #hasGlobalUpdate spec
65 :     then memberFun (CL.voidTy, "global_update", []) :: members
66 :     else members
67 : jhr 4500 val members = if #hasStabilizeAll spec
68 :     then memberFun (CL.voidTy, "stabilize_all", []) :: members
69 :     else members
70 : jhr 4317 in
71 :     CL.D_ClassDef{
72 :     name = "world",
73 :     args = NONE,
74 :     from = SOME "public diderot::world_base",
75 :     public = List.rev members,
76 :     protected = [],
77 :     private = []
78 :     }
79 :     end
80 : jhr 3924
81 : jhr 4407 fun genCreateFun (env : CodeGenEnv.t, globInit, strand, create) = let
82 : jhr 4317 val IR.Strand{name, stateInit=IR.Method{hasG, needsW, ...}, ...} = strand
83 :     val strandName = Atom.toString name
84 :     val env = Env.insert(env, PseudoVars.world, "this")
85 :     val thisV = CL.mkVar "this"
86 :     val spec = Env.target env
87 :     val {dim, locals, prefix, loops, body} = Util.decomposeCreate create
88 :     (* for each loop in the nest, we return the tuple
89 :     * (stms, loExp, hiExp, szExp, mkLoop)
90 :     * where `stms` are the statements needed to define any new variables,
91 :     * `loExp` and `hiExp` are CLang expressions for the low and high loop
92 :     * bounds, `szExp` is the number of loop iterations, and mkLoop is a
93 :     * function for buildÃ¥ing the CLang representation of the loop.
94 :     *)
95 :     fun doLoop env (Util.ForLoop(i, lo, hi)) = let
96 :     val (loV, loStms) = ToCxx.trExpToVar (env, CL.intTy, "lo", lo)
97 :     val (hiV, hiStms) = ToCxx.trExpToVar (env, CL.intTy, "hi", hi)
98 :     val szE = CL.mkBinOp(CL.mkBinOp(hiV, CL.#-, loV), CL.#+, CL.mkInt 1)
99 :     val stms = loStms @ hiStms
100 :     fun mkLoop (env, mkBody) = let
101 :     val iV = TreeVar.name i
102 :     in
103 :     CL.mkFor(
104 :     CL.intTy, [( iV, loV)],
105 :     CL.mkBinOp(CL.mkVar iV, CL.#<=, hiV),
106 :     [CL.mkPostOp(CL.mkVar iV, CL.^++)],
107 :     mkBody (Env.insert (env, i, iV)))
108 :     end
109 :     in
110 :     (stms, loV, hiV, szE, mkLoop)
111 :     end
112 :     | doLoop env (Util.ForeachLoop(i, seq)) = let
113 :     val seqTy = ToCxx.trType (env, TreeTypes.SeqTy(TreeVar.ty i, NONE))
114 :     val (seqV, stms) = ToCxx.trExpToVar (env, seqTy, "seq", seq)
115 :     val szE = CL.mkDispatch(seqV, "length", [])
116 :     fun mkLoop (env, mkBody) = raise Fail "FIXME"
117 :     in
118 :     (stms, CL.mkInt 0, szE, szE, mkLoop)
119 :     end
120 :     fun tr env = let
121 :     val (env, prefixCode) = TreeToCxx.trStms (env, prefix)
122 :     val loopInfo = List.map (doLoop env) loops
123 :     (* collect the statements that define the loop bounds *)
124 :     val bndsStms = List.foldr
125 :     (fn ((stms, _, _, _, _), stms') => stms @ stms')
126 :     [] loopInfo
127 :     val allocStm =
128 : jhr 3927 CL.mkIfThen(CL.mkIndirectDispatch(thisV, "alloc", [
129 :     CL.mkVar "base",
130 :     CL.mkVar "size"
131 : jhr 3926 ]),
132 :     (* then *)
133 :     CL.mkBlock [
134 :     CL.mkReturn(SOME(CL.mkVar "true"))
135 :     ])
136 :     (* endif *)
137 : jhr 4317 fun mkArrDcl (ty, name, dim, init) = CL.mkDecl(
138 :     CL.T_Array(ty, SOME dim), name,
139 :     SOME(CL.I_Exps(List.map CL.I_Exp init)))
140 :     (* code to allocate strands *)
141 :     val allocCode = (case dim
142 :     of NONE => let (* collection of strands *)
143 :     val (sz1::szs) = List.map #4 loopInfo
144 :     val sizeExp = List.foldl
145 :     (fn (sz, lhs) => CL.mkBinOp(lhs, CL.#*, sz))
146 :     sz1 szs
147 :     in [
148 :     mkArrDcl(CL.int32, "base", 1, [CL.mkInt 0]),
149 :     mkArrDcl(CL.uint32, "size", 1, [CL.mkStaticCast(CL.uint32, sizeExp)]),
150 :     allocStm
151 :     ] end
152 :     | SOME d => let (* grid of strands *)
153 :     val baseInit = List.map #2 loopInfo
154 :     val sizeInit = List.map
155 :     (fn info => CL.mkStaticCast(CL.uint32, #4 info))
156 :     loopInfo
157 :     in [
158 :     mkArrDcl(CL.int32, "base", d, baseInit),
159 :     mkArrDcl(CL.uint32, "size", d, sizeInit),
160 :     allocStm
161 :     ] end
162 :     (* end case *))
163 :     val idx = "ix" (* for indexing into the strand-state array *)
164 :     val loopCode = let
165 :     val idxV = CL.mkVar idx
166 :     fun statePtr inout =
167 :     CL.mkAddrOf(CL.mkSubscript(CL.mkIndirect(thisV, inout), idxV))
168 :     fun mkNest [] env = ToCxx.trWithLocals (env, #locals body,
169 :     fn env => let
170 :     val (env, stms') = ToCxx.trStms (env, #stms body)
171 :     val (_, args) = #newStm body
172 :     (* NOTE: the args' list must match the parameters in GenStrand *)
173 :     val args' = List.map (fn e => ToCxx.trExp(env, e)) args
174 : jhr 4500 val args' =
175 : jhr 4505 CL.mkDispatch(RN.strandArray env, "strand", [idxV])
176 : jhr 4500 :: args'
177 : jhr 4317 val args' = if hasG
178 :     then CL.mkIndirect(thisV, "_globals") :: args'
179 :     else args'
180 :     val args' = if needsW
181 :     then thisV :: args'
182 :     else args'
183 :     val newStm = CL.mkCall(strandName ^ "_init", args')
184 :     val incStm = CL.mkExpStm (CL.mkUnOp(CL.%++, idxV))
185 :     in
186 : jhr 4500 stms' @ [newStm, incStm]
187 : jhr 4317 end)
188 :     | mkNest ((_, _, _, _, mkLoop)::r) env = mkLoop (env, mkNest r)
189 :     in
190 :     mkNest loopInfo env
191 :     end
192 :     val stms = prefixCode @ bndsStms @ allocCode @ [
193 :     CL.mkDecl(CL.uint32, idx, SOME(CL.I_Exp(CL.E_Int(0, CL.uint32)))),
194 :     loopCode,
195 : jhr 3927 CL.mkAssign(
196 : jhr 4317 CL.mkIndirect(thisV, "_stage"),
197 : jhr 4387 CL.mkVar "diderot::POST_CREATE"),
198 : jhr 3927 CL.mkReturn(SOME(CL.mkVar "false"))
199 :     ]
200 : jhr 4317 val stms = if #hasGlobals spec
201 :     then CL.mkDeclInit (
202 :     RN.globalPtrTy, RN.globalsVar, CL.mkIndirect(thisV, "_globals")) ::
203 :     stms
204 :     else stms
205 :     val stms = if #hasGlobalInit spec
206 :     then CL.mkIfThen (CL.mkApply ("init_globals", [thisV]),
207 :     CL.mkReturn(SOME(CL.mkVar "true"))
208 :     ) :: stms
209 :     else stms
210 :     in
211 :     stms
212 :     end (* tr *)
213 :     val body = TreeToCxx.trWithLocals (env, locals, tr)
214 :     in
215 : jhr 4407 CL.mkFuncDcl(CL.boolTy, "world::create_strands", [], body)
216 : jhr 4317 end
217 : jhr 3924
218 :     end

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