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

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

Parent Directory Parent Directory | Revision Log Revision Log


Revision 4451 - (view) (download)

1 : jhr 3902 (* gen.sml
2 :     *
3 :     * Code generation for the sequential and parallel targets.
4 :     *
5 :     * COPYRIGHT (c) 2016 The Diderot Project (http://diderot-language.cs.uchicago.edu)
6 :     * All rights reserved.
7 :     *)
8 :    
9 :     structure Gen : sig
10 :    
11 :     val exec : TargetSpec.t * TreeIR.program -> unit
12 :    
13 :     val library : TargetSpec.t * TreeIR.program -> unit
14 :    
15 :     end = struct
16 :    
17 :     structure IR = TreeIR
18 : jhr 3924 structure GV = TreeGlobalVar
19 : jhr 3902 structure CL = CLang
20 : jhr 3905 structure Env = CodeGenEnv
21 :     structure Out = CodeOutput
22 : jhr 3906 structure RN = CxxNames
23 : jhr 4407 structure Frags = CPUFragments
24 : jhr 3902
25 : jhr 3905 val openCxxOut = Out.openOut {ext = "cxx", ppDecl = PrintAsCxx.output}
26 :    
27 : jhr 3908 fun mkEnv spec = if TargetSpec.dualState spec
28 : jhr 4317 then Env.new {
29 :     world = RN.worldVar,
30 :     global = RN.globalsVar,
31 :     selfIn = RN.selfInVar,
32 :     selfOut = RN.selfOutVar,
33 :     spec = spec
34 :     }
35 :     else Env.new {
36 :     world = RN.worldVar,
37 :     global = RN.globalsVar,
38 :     selfIn = RN.selfVar,
39 :     selfOut = RN.selfVar,
40 :     spec = spec
41 :     }
42 : jhr 3908
43 : jhr 3905 (* create the target-specific substitution list *)
44 : jhr 4045 fun mkSubs (spec, strand, create) = let
45 : jhr 4317 val IR.Strand{name, stateInit, initM, updateM, stabilizeM, ...} = strand
46 :     fun mkMethodArgs (name, NONE) = (name, "")
47 :     | mkMethodArgs (name, SOME(IR.Method{needsW, hasG, ...})) = let
48 :     val value = if needsW
49 :     then if TargetSpec.isParallel spec then "wrld, " else "this, "
50 :     else ""
51 :     val value = if hasG then value ^ "glob, " else value
52 :     in
53 :     (name, value)
54 :     end
55 :     in [
56 :     ("CFILE", OS.Path.joinBaseExt{base= #outBase spec, ext= SOME "c"}),
57 :     ("CXXFILE", OS.Path.joinBaseExt{base= #outBase spec, ext= SOME "cxx"}),
58 :     ("H_FILE", OS.Path.joinBaseExt{base= #outBase spec, ext= SOME "h"}),
59 :     ("PREFIX", #namespace spec),
60 :     ("SRCFILE", #srcFile spec),
61 :     ("PROG_NAME", #outBase spec),
62 :     ("STRAND", Atom.toString name),
63 :     ("STRANDTY", Atom.toString name ^ "_strand"),
64 :     ("IS_GRID", Bool.toString(#isGrid spec)),
65 :     ("NUM_AXES", Int.toString(Option.getOpt(Create.gridDim create, 1))),
66 : jhr 4369 ("SPATIAL_DIM", Int.toString(Option.getOpt(#spatialDim spec, 0))),
67 : jhr 4317 ("DIDEROTC_CMD", #diderotc spec),
68 :     ("DIDEROTC_ARGV", String.concatWith " " (#argv spec)),
69 :     ("DIDEROTC_VERSION", #version spec),
70 :     ("DIDEROT_FLOAT_PRECISION", TargetSpec.floatPrecisionDef spec),
71 :     ("DIDEROT_INT_PRECISION", TargetSpec.intPrecisionDef spec),
72 :     ("DIDEROT_TARGET", TargetSpec.targetDef spec),
73 :     ("REALTY", if #double spec then "double" else "float"),
74 :     ("INTTY", if #longint spec then "int64_t" else "int32_t"),
75 :     ("BOOLTY", SizeOf.c_bool),
76 :     mkMethodArgs ("STATE_INIT_ARGS", SOME stateInit),
77 :     mkMethodArgs ("INITIALLY_ARGS", initM),
78 :     mkMethodArgs ("UPDATE_ARGS", SOME updateM),
79 :     mkMethodArgs ("STABILIZE_ARGS", stabilizeM)
80 :     ] end
81 : jhr 3905
82 :     fun condCons (true, x, xs) = x::xs
83 :     | condCons (false, _, xs) = xs
84 :    
85 : jhr 3906 fun verbFrag (spec, parFrag, seqFrag, subs) =
86 : jhr 4317 CL.verbatimDcl [if (TargetSpec.isParallel spec) then parFrag else seqFrag] subs
87 : jhr 3905
88 : jhr 3917 (* generate the struct declaration for the global variables *)
89 : jhr 3918 (* FIXME: what about constants? *)
90 :     fun genGlobalStruct (env, consts, inputs, globals) =
91 : jhr 4317 if #hasGlobals(Env.target env)
92 :     then let
93 :     fun mkField gv = (TreeToCxx.trType(env, GV.ty gv), GV.qname gv)
94 :     val fields = List.map (mkField o Inputs.varOf) inputs
95 :     val fields = fields @ List.map mkField globals
96 :     in
97 :     [CL.D_StructDef(SOME "globals", fields, NONE)]
98 :     end
99 :     else []
100 : jhr 3917
101 : jhr 4174 (* generate code for a user-defined function *)
102 :     fun genFunc spec (IR.Func{name, params, body}) = let
103 : jhr 4317 val (resTy, _) = TreeFunc.ty name
104 :     val (env, params) = List.foldr
105 :     (fn (x, (env, ps)) => let
106 :     val (env, p) = TreeToCxx.trParam(env, x)
107 :     in
108 :     (env, p::ps)
109 :     end)
110 :     (Env.empty spec, []) params
111 :     val (env, params) = if TreeFunc.hasGlobals name
112 :     then (
113 :     Env.insert(env, PseudoVars.global, RN.globalsVar),
114 :     CL.PARAM([], RN.globalPtrTy, RN.globalsVar) :: params
115 :     )
116 :     else (env, params)
117 :     val (env, params) = if TreeFunc.needsWorld name
118 :     then (
119 :     Env.insert(env, PseudoVars.world, RN.worldVar),
120 :     CL.PARAM([], RN.worldPtrTy, RN.worldVar) :: params
121 :     )
122 :     else (env, params)
123 :     in
124 :     CL.D_Func([], TreeToCxx.trType(env, resTy), [], TreeFunc.qname name, params,
125 :     TreeToCxx.trBlock (env, body))
126 :     end
127 : jhr 4174
128 : jhr 4131 (* QUESTION: should init_globals be a member of the world struct? *)
129 : jhr 4168 fun genInitGlobals (env, IR.Block{locals, body}) = let
130 : jhr 4317 (* the init_globals function should return false on success *)
131 :     val body = IR.Block{
132 :     locals=locals,
133 :     body=body@[IR.S_Return(IR.E_Lit(Literal.Bool false))]
134 :     }
135 :     in
136 :     CL.D_Func(["static"], CL.boolTy, [], "init_globals",
137 :     [RN.worldParam],
138 : jhr 4364 GenUtil.genBodyWithGlobPtr (env, body))
139 : jhr 4317 end
140 : jhr 3931
141 : jhr 4407 (* specialize the fragments that implement the run and run_initially world methods *)
142 :     fun runFrag (spec, subs) = let
143 :     val code = if TargetSpec.noBSP spec
144 :     then [verbFrag (spec, Frags.parRunNoBSP, Frags.seqRunNoBSP, subs)]
145 :     else [verbFrag (spec, Frags.parRun, Frags.seqRun, subs)]
146 :     in
147 :     if #hasInitiallyMeth spec
148 :     then verbFrag (spec, Frags.parRunInit, Frags.seqRunInit, subs) :: code
149 :     else code
150 :     end
151 : jhr 3917
152 : jhr 3905 fun compile (spec : TargetSpec.t, basename) = let
153 : jhr 4317 (* generate the C compiler flags *)
154 :     val cflags = ["-I" ^ Paths.diderotInclude(), "-I" ^ Paths.teemInclude()]
155 : jhr 4417 val cflags = condCons (TargetSpec.isParallel spec, #parallel Paths.cxxFlags, cflags)
156 : jhr 4317 val cflags = if #debug spec
157 : jhr 4417 then #debug Paths.cxxFlags :: cflags
158 :     else #ndebug Paths.cxxFlags :: cflags
159 :     val cflags = #base Paths.cxxFlags :: cflags
160 : jhr 4317 in
161 :     RunCC.compile (basename, cflags)
162 :     end
163 : jhr 3905
164 : jhr 3906 fun ldFlags (spec : TargetSpec.t) = if #exec spec
165 : jhr 4317 then let
166 : jhr 4417 val extraLibs = condCons (TargetSpec.isParallel spec, #parallel Paths.extraLibs, [])
167 : jhr 4317 val extraLibs = Paths.teemLinkFlags() @ #base Paths.extraLibs :: extraLibs
168 :     val rtLib = TargetSpec.runtimeLibName spec
169 :     in
170 : jhr 4417 condCons (TargetSpec.isParallel spec, #parallel Paths.cxxFlags, rtLib :: extraLibs)
171 : jhr 4317 end
172 :     else [TargetSpec.runtimeLibName spec]
173 : jhr 3905
174 : jhr 4367 (* generate defines that control specialization of the code for various features (e.g.,
175 :     * parallelism, global updates, ...
176 :     *)
177 :     fun outputDefines (outS, spec, substitutions) = let
178 : jhr 4369 val ppDecl = Out.decl outS
179 : jhr 4387 fun pp (true, dcl) = ppDecl (CL.D_Verbatim ["#define " ^ dcl])
180 : jhr 4369 | pp _ = ()
181 :     in
182 : jhr 4407 pp (#hasStabilizeMeth spec, "DIDEROT_HAS_STABILIZE");
183 : jhr 4387 pp (TargetSpec.dualState spec, "DIDEROT_DUAL_STATE");
184 : jhr 4451 pp (TargetSpec.indirectState spec, "DIDEROT_INDIRECT_STATE");
185 : jhr 4387 pp (not(#hasGlobals spec), "DIDEROT_NO_GLOBALS");
186 :     pp (not(#hasInputs spec), "DIDEROT_NO_INPUTS");
187 :     pp (#hasCom spec, "DIDEROT_HAS_STRAND_COMMUNICATION");
188 :     pp (#hasGlobalInitially spec, "DIDEROT_HAS_GLOBAL_INITIALLY");
189 :     pp (#hasGlobalUpdate spec, "DIDEROT_HAS_GLOBAL_UPDATE");
190 :     pp (#hasReduce spec, "DIDEROT_HAS_MAPREDUCE")
191 : jhr 4369 end
192 : jhr 4367
193 : jhr 3912 (* generate source code that is common to both libraries and standalone executables *)
194 : jhr 3917 fun outputSrc (outS, env, spec, prog, strand, substitutions, genInputCode) = let
195 : jhr 4317 val IR.Program{consts, inputs, globals, funcs, globInit, create, init, update, ...} = prog
196 :     val IR.Strand{name=strandName, ...} = strand
197 :     val dim = Create.gridDim create
198 :     val ppDecl = Out.decl outS
199 :     val {structDef, methods} = GenStrand.gen (env, strand)
200 :     val outputs = OutputUtil.gatherOutputs prog
201 :     in
202 :     List.app ppDecl (genGlobalStruct (env, consts, inputs, globals));
203 :     ppDecl structDef;
204 : jhr 4349 ppDecl (GenWorld.genStruct(env, strandName, Option.getOpt(dim, 1)));
205 : jhr 4382 if (TargetSpec.isParallel spec)
206 : jhr 4407 then ppDecl (CL.verbatimDcl [Frags.parExtras] substitutions)
207 : jhr 4382 else ();
208 : jhr 4317 List.app ppDecl (genInputCode());
209 :     List.app (ppDecl o genFunc spec) funcs;
210 :     if #hasGlobalInit spec
211 :     then ppDecl (genInitGlobals (env, globInit))
212 :     else ();
213 :     List.app ppDecl methods;
214 :     List.app ppDecl (GenOutputs.gen (env, dim, outputs));
215 : jhr 4407 ppDecl (CL.verbatimDcl [Frags.worldMethods] substitutions);
216 :     ppDecl (GenWorld.genCreateFun (env, globInit, strand, create));
217 :     List.app ppDecl (runFrag (spec, substitutions));
218 : jhr 4386 Option.app (fn blk => ppDecl (GenGlobalUpdate.gen (env, "initially", blk))) init;
219 :     Option.app (fn blk => ppDecl (GenGlobalUpdate.gen (env, "update", blk))) update
220 : jhr 4317 end
221 : jhr 3931
222 : jhr 3990 fun exec (spec : TargetSpec.t, prog) = let
223 : jhr 4317 val IR.Program{inputs, strand, create, ...} = prog
224 :     val env = mkEnv spec
225 :     val baseName = OS.Path.joinDirFile{dir = #outDir spec, file = #outBase spec}
226 :     val substitutions = mkSubs (spec, strand, create)
227 :     (* output to C++ file *)
228 :     val outS = openCxxOut baseName
229 :     val ppDecl = Out.decl outS
230 :     val fragment = Out.fragment substitutions outS
231 : jhr 4369 val {preWorld, postWorld} = GenTysAndOps.gen (env, CollectInfo.collect prog)
232 : jhr 4317 in
233 :     ppDecl (CL.verbatimDcl [CxxFragments.execHead] substitutions);
234 : jhr 4369 outputDefines (outS, spec, substitutions);
235 : jhr 4367 ppDecl (CL.verbatimDcl [CxxFragments.execIncl] substitutions);
236 : jhr 4351 List.app ppDecl preWorld;
237 : jhr 4317 ppDecl (CL.verbatimDcl [CxxFragments.namespaceOpen] substitutions);
238 :     ppDecl (CL.verbatimDcl [CxxFragments.nrrdSaveHelper] substitutions);
239 :     outputSrc (outS, env, spec, prog, strand, substitutions,
240 :     fn () => (
241 : jhr 4369 postWorld @
242 : jhr 4317 GenInputs.genInputsStruct (env, inputs) @
243 :     GenInputs.genExecInputFuns (env, prog) @
244 :     GenOutputsUtil.genRegisterOutputOpts (env, OutputUtil.gatherOutputs prog)));
245 :     ppDecl (CL.verbatimDcl [CxxFragments.namespaceClose] substitutions);
246 :     (* generate main function after closing off the namespace *)
247 : jhr 4407 ppDecl (verbFrag (spec, Frags.parMain, Frags.seqMain, substitutions));
248 : jhr 4317 Out.closeOut outS;
249 :     compile (spec, baseName);
250 :     RunCC.linkExec (baseName, ldFlags spec)
251 :     end
252 : jhr 3990
253 :     fun library (spec : TargetSpec.t, prog) = let
254 : jhr 4317 val IR.Program{inputs, strand, create, ...} = prog
255 :     val env = mkEnv spec
256 :     val baseName = OS.Path.joinDirFile{dir = #outDir spec, file = #outBase spec}
257 :     val substitutions = mkSubs (spec, strand, create)
258 :     (* output to C++ file *)
259 :     val outS = openCxxOut baseName
260 :     val ppDecl = Out.decl outS
261 :     val fragment = Out.fragment substitutions outS
262 :     (* gather the outputs *)
263 :     val outputs = OutputUtil.gatherOutputs prog
264 : jhr 4369 val {preWorld, postWorld} = GenTysAndOps.gen (env, CollectInfo.collect prog)
265 : jhr 4317 in
266 :     (* generate the library .h file *)
267 :     GenLibraryInterface.gen {
268 :     subs = substitutions,
269 :     env = env,
270 :     rt = NONE, (* ?? *)
271 :     inputs = inputs,
272 :     outputs = outputs
273 :     };
274 :     ppDecl (CL.verbatimDcl [CxxFragments.libCXXHead] substitutions);
275 : jhr 4369 outputDefines (outS, spec, substitutions);
276 : jhr 4367 ppDecl (CL.verbatimDcl [CxxFragments.libCXXIncl] substitutions);
277 : jhr 4351 List.app ppDecl preWorld;
278 : jhr 4317 ppDecl (CL.verbatimDcl [CxxFragments.namespaceOpen] substitutions);
279 :     ppDecl (CL.verbatimDcl [CxxFragments.nrrdSaveHelper] substitutions);
280 :     List.app ppDecl (GenInputs.genDefinedInpStruct inputs);
281 :     outputSrc (outS, env, spec, prog, strand, substitutions,
282 : jhr 4351 fn () => (postWorld @ GenInputs.genLibraryInputFuns (env, prog)));
283 : jhr 4317 ppDecl (CL.verbatimDcl [CxxFragments.namespaceClose] substitutions);
284 : jhr 4407 ppDecl (CL.verbatimDcl [Frags.cWrappers] substitutions);
285 : jhr 4317 Out.closeOut outS;
286 :     (* compile and link *)
287 :     compile (spec, baseName);
288 :     RunCC.linkLib (baseName, ldFlags spec)
289 :     end
290 : jhr 3908
291 : jhr 3902 end

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