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 4028 - (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 3902
24 : jhr 3905 val openCxxOut = Out.openOut {ext = "cxx", ppDecl = PrintAsCxx.output}
25 :    
26 : jhr 3908 fun mkEnv spec = if TargetSpec.dualState spec
27 :     then Env.new {
28 :     global = RN.globalsVar,
29 :     selfIn = RN.selfInVar,
30 :     selfOut = RN.selfOutVar,
31 :     spec = spec
32 :     }
33 :     else Env.new {
34 :     global = RN.globalsVar,
35 :     selfIn = RN.selfVar,
36 :     selfOut = RN.selfVar,
37 :     spec = spec
38 :     }
39 :    
40 : jhr 3905 (* create the target-specific substitution list *)
41 : jhr 3954 fun mkSubs (spec, strand, IR.Create{dim, ...}) = let
42 :     val IR.Strand{name, stateInit, initM, updateM, stabilizeM, ...} = strand
43 :     fun mkMethodArgs (name, NONE) = (name, "")
44 :     | mkMethodArgs (name, SOME(IR.Method{usesGlobals, needsWorld, ...})) = let
45 :     val value = if needsWorld then "this, " else ""
46 :     val value = if usesGlobals then value ^ "glob, " else value
47 :     in
48 :     (name, value)
49 :     end
50 :     in [
51 : jhr 3905 ("CFILE", OS.Path.joinBaseExt{base= #outBase spec, ext= SOME "c"}),
52 :     ("CXXFILE", OS.Path.joinBaseExt{base= #outBase spec, ext= SOME "cxx"}),
53 : jhr 3990 ("H_FILE", OS.Path.joinBaseExt{base= #outBase spec, ext= SOME "h"}),
54 : jhr 3905 ("PREFIX", #namespace spec),
55 :     ("SRCFILE", #srcFile spec),
56 :     ("PROG_NAME", #outBase spec),
57 :     ("STRAND", Atom.toString name),
58 :     ("STRANDTY", Atom.toString name ^ "_strand"),
59 : jhr 3958 ("IS_GRID", Bool.toString(#isGrid spec)),
60 : jhr 3924 ("NUM_AXES", Int.toString(Option.getOpt(dim, 1))),
61 : jhr 3905 ("DIDEROTC_CMD", #diderotc spec),
62 :     ("DIDEROTC_ARGV", String.concatWith " " (#argv spec)),
63 :     ("DIDEROTC_VERSION", #version spec),
64 :     ("DIDEROT_FLOAT_PRECISION", TargetSpec.floatPrecisionDef spec),
65 :     ("DIDEROT_INT_PRECISION", TargetSpec.intPrecisionDef spec),
66 : jhr 3916 ("DIDEROT_TARGET", TargetSpec.targetDef spec),
67 :     ("REALTY", if #double spec then "double" else "float"),
68 : jhr 3954 ("INTTY", if #longint spec then "int64_t" else "int32_t"),
69 :     mkMethodArgs ("STATE_INIT_ARGS", SOME stateInit),
70 :     mkMethodArgs ("INITIALLY_ARGS", initM),
71 :     mkMethodArgs ("UPDATE_ARGS", SOME updateM),
72 :     mkMethodArgs ("STABILIZE_ARGS", stabilizeM)
73 :     ] end
74 : jhr 3905
75 :     fun condCons (true, x, xs) = x::xs
76 :     | condCons (false, _, xs) = xs
77 :    
78 : jhr 3906 fun verbFrag (spec, parFrag, seqFrag, subs) =
79 :     CL.verbatimDcl [if (TargetSpec.isParallel spec) then parFrag else seqFrag] subs
80 : jhr 3905
81 : jhr 3917 (* generate the struct declaration for the global variables *)
82 : jhr 3918 (* FIXME: what about constants? *)
83 :     fun genGlobalStruct (env, consts, inputs, globals) =
84 :     if #hasGlobals(Env.target env)
85 : jhr 3917 then let
86 : jhr 3924 fun mkField gv = (TreeToCxx.trType(env, GV.ty gv), GV.qname gv)
87 : jhr 3918 val fields = List.map (mkField o Inputs.varOf) inputs
88 :     val fields = fields @ List.map mkField globals
89 : jhr 3917 in
90 :     [CL.D_StructDef(SOME "globals", fields, NONE)]
91 :     end
92 :     else []
93 :    
94 : jhr 3959 fun genInitGlobals (env, IR.Block{locals, body}) = let
95 :     val env = Env.setExitHandler (env, fn _ => [CL.mkReturn(SOME(CL.mkVar "false"))])
96 :     val dcl = CL.mkDeclInit(
97 :     RN.globalPtrTy, RN.globalsVar,
98 :     CL.mkIndirect(CL.mkVar RN.worldVar, "_globals"))
99 :     in
100 : jhr 4028 CL.D_Func(["static"], CL.boolTy, [], "init_globals",
101 : jhr 3959 [RN.worldParam],
102 :     TreeToCxx.trWithLocals (env, !locals,
103 :     fn env => dcl :: #2(TreeToCxx.trStms(env, body))))
104 :     end
105 : jhr 3931
106 : jhr 3917 fun runFrag (spec, subs) = if TargetSpec.noBSP spec
107 : jhr 3996 then verbFrag (spec, CPUFragments.parallelRunNoBSP, CPUFragments.sequentialRunNoBSP, subs)
108 :     else verbFrag (spec, CPUFragments.parallelRun, CPUFragments.sequentialRun, subs)
109 : jhr 3917
110 : jhr 3905 fun compile (spec : TargetSpec.t, basename) = let
111 :     (* generate the C compiler flags *)
112 :     val cflags = ["-I" ^ Paths.diderotInclude(), "-I" ^ Paths.teemInclude()]
113 : jhr 3914 val cflags = condCons (TargetSpec.isParallel spec, #pthread Paths.cxxflags, cflags)
114 : jhr 3906 val cflags = if #debug spec
115 : jhr 3914 then #debug Paths.cxxflags :: cflags
116 :     else #ndebug Paths.cxxflags :: cflags
117 :     val cflags = #base Paths.cxxflags :: cflags
118 : jhr 3905 in
119 :     RunCC.compile (basename, cflags)
120 :     end
121 :    
122 : jhr 3906 fun ldFlags (spec : TargetSpec.t) = if #exec spec
123 : jhr 3905 then let
124 : jhr 3906 val extraLibs = condCons (TargetSpec.isParallel spec, #pthread Paths.extraLibs, [])
125 : jhr 3905 val extraLibs = Paths.teemLinkFlags() @ #base Paths.extraLibs :: extraLibs
126 : jhr 3906 val rtLib = TargetSpec.runtimeLibName spec
127 : jhr 3905 in
128 : jhr 3914 condCons (TargetSpec.isParallel spec, #pthread Paths.cxxflags, rtLib :: extraLibs)
129 : jhr 3905 end
130 : jhr 3906 else [TargetSpec.runtimeLibName spec]
131 : jhr 3905
132 : jhr 3912 (* generate source code that is common to both libraries and standalone executables *)
133 : jhr 3917 fun outputSrc (outS, env, spec, prog, strand, substitutions, genInputCode) = let
134 : jhr 3931 val IR.Program{
135 : jhr 3995 consts, inputs, globals, globInit, create as IR.Create{dim, ...},
136 :     init, update, ...
137 : jhr 3931 } = prog
138 : jhr 3917 val IR.Strand{name=strandName, ...} = strand
139 :     val ppDecl = Out.decl outS
140 : jhr 3918 val {structDef, methods} = GenStrand.gen (env, strand)
141 : jhr 3917 val outputs = OutputUtil.gatherOutputs prog
142 : jhr 3912 in
143 :     if (TargetSpec.isParallel spec)
144 : jhr 3996 then ppDecl (CL.verbatimDcl [CPUFragments.parallelExtras] substitutions)
145 : jhr 3912 else ();
146 :     if TargetSpec.dualState spec
147 :     then ppDecl (CL.D_Verbatim ["#define DIDEROT_DUAL_STATE\n"])
148 :     else ();
149 :     if not(#hasGlobals spec)
150 :     then ppDecl (CL.D_Verbatim ["#define DIDEROT_NO_GLOBALS\n"])
151 :     else ();
152 :     if not(#hasInputs spec)
153 :     then ppDecl (CL.D_Verbatim ["#define DIDEROT_NO_INPUTS\n"])
154 :     else ();
155 : jhr 3918 List.app ppDecl (genGlobalStruct (env, consts, inputs, globals));
156 :     ppDecl structDef;
157 : jhr 3924 ppDecl (GenWorld.genStruct(spec, strandName, Option.getOpt(dim, 1)));
158 : jhr 3912 List.app ppDecl (genInputCode());
159 : jhr 3962 if #hasGlobals spec
160 : jhr 3995 then ppDecl (genInitGlobals (env, globInit))
161 : jhr 3962 else ();
162 : jhr 3918 List.app ppDecl methods;
163 : jhr 3917 List.app ppDecl (GenOutputs.gen (env, dim, outputs));
164 : jhr 3996 ppDecl (CL.verbatimDcl [CPUFragments.worldMethods] substitutions);
165 : jhr 3974 ppDecl (GenWorld.genInitiallyFun (env, strand, create));
166 : jhr 3917 ppDecl (runFrag (spec, substitutions))
167 : jhr 3995 (* FIXME: what about the global initially and update code? *)
168 : jhr 3912 end
169 : jhr 3931
170 : jhr 3990 fun exec (spec : TargetSpec.t, prog) = let
171 :     val IR.Program{inputs, strand, create, ...} = prog
172 :     val env = mkEnv spec
173 :     val baseName = OS.Path.joinDirFile{dir = #outDir spec, file = #outBase spec}
174 :     val substitutions = mkSubs (spec, strand, create)
175 :     (* output to C++ file *)
176 :     val outS = openCxxOut baseName
177 :     val ppDecl = Out.decl outS
178 :     val fragment = Out.fragment substitutions outS
179 :     in
180 : jhr 3996 ppDecl (CL.verbatimDcl [CxxFragments.execHead] substitutions);
181 : jhr 3990 List.app ppDecl (GenTysAndOps.gen (env, CollectInfo.collect prog));
182 : jhr 3996 ppDecl (CL.verbatimDcl [CxxFragments.namespaceOpen] substitutions);
183 :     ppDecl (CL.verbatimDcl [CxxFragments.nrrdSaveHelper] substitutions);
184 : jhr 3990 outputSrc (outS, env, spec, prog, strand, substitutions,
185 :     fn () => (
186 :     GenInputs.genInputsStruct (env, inputs) @
187 :     GenInputs.genExecInputFuns (env, prog) @
188 :     GenOutputsUtil.genRegisterOutputOpts (env, OutputUtil.gatherOutputs prog)));
189 : jhr 3996 ppDecl (CL.verbatimDcl [CxxFragments.namespaceClose] substitutions);
190 : jhr 3990 (* generate main function after closing off the namespace *)
191 : jhr 3996 ppDecl (verbFrag (spec, CPUFragments.parallelMain, CPUFragments.sequentialMain, substitutions));
192 : jhr 3990 Out.closeOut outS;
193 :     compile (spec, baseName);
194 :     RunCC.linkExec (baseName, ldFlags spec)
195 :     end
196 :    
197 : jhr 3905 (********************
198 : jhr 3903 fun outputLibSrc (baseName, prog as Prog{props, inputs, strands, ...}) = let
199 :     val [strand] = AtomTable.listItems strands
200 :     val substitutions = mkSubs (props, strand)
201 :     (* output to C file *)
202 :     val out = openOut baseName
203 :     fun ppDecl dcl = PrintAsC.output(#ppStrm out, dcl)
204 :     in
205 :     ppDecl (CL.verbatimDcl [LibHdrFrag.text] substitutions);
206 :     List.app ppDecl (GenInputs.genDefinedInpStruct (props, !inputs));
207 :     outputSrc (out, prog, strand, substitutions,
208 :     fn () => GenInputs.genInputFuns(props, !inputs));
209 :     ppDecl (CL.verbatimDcl [CBodyFrag.text] substitutions);
210 :     closeOut out
211 :     end
212 :    
213 :     fun generateLib (prog as Prog{props, inputs, strands, ...}) = let
214 : jhr 3906 val {outDir, outBase, exec, double, debug, ...} = props
215 : jhr 3903 val basename = OS.Path.joinDirFile{dir=outDir, file=outBase}
216 :     val [Strand{state, output, ...}] = AtomTable.listItems strands
217 :     in
218 :     (* generate the library .h file *)
219 :     GenLibraryInterface.gen {
220 :     props = props,
221 : jhr 3906 rt = if TargetSpec.isParallel spec
222 : jhr 3903 then SOME LibInterfaceParFrag.text
223 :     else NONE,
224 :     inputs = !inputs,
225 :     outputs = output
226 :     };
227 :     (* *)
228 :     outputLibSrc (basename, prog);
229 :     (* compile and link *)
230 :     compile (props, basename);
231 :     RunCC.linkLib (basename, ldFlags props)
232 :     end
233 : jhr 3905 ********************)
234 : jhr 3903
235 : jhr 3990 fun library (spec : TargetSpec.t, prog) = let
236 : jhr 3924 val IR.Program{inputs, strand, create, ...} = prog
237 : jhr 3908 val env = mkEnv spec
238 : jhr 3905 val baseName = OS.Path.joinDirFile{dir = #outDir spec, file = #outBase spec}
239 : jhr 3924 val substitutions = mkSubs (spec, strand, create)
240 : jhr 3903 (* output to C++ file *)
241 : jhr 3905 val outS = openCxxOut baseName
242 :     val ppDecl = Out.decl outS
243 :     val fragment = Out.fragment substitutions outS
244 : jhr 3990 (* gather the outputs *)
245 :     val outputs = OutputUtil.gatherOutputs prog
246 : jhr 3902 in
247 : jhr 3990 (* generate the library .h file *)
248 :     GenLibraryInterface.gen {
249 :     subs = substitutions,
250 :     env = env,
251 :     rt = NONE, (* ?? *)
252 :     inputs = inputs,
253 :     outputs = outputs
254 :     };
255 : jhr 3996 ppDecl (CL.verbatimDcl [CxxFragments.libCXXHead] substitutions);
256 : jhr 3918 List.app ppDecl (GenTysAndOps.gen (env, CollectInfo.collect prog));
257 : jhr 3996 ppDecl (CL.verbatimDcl [CxxFragments.namespaceOpen] substitutions);
258 :     ppDecl (CL.verbatimDcl [CxxFragments.nrrdSaveHelper] substitutions);
259 :     List.app ppDecl (GenTysAndOps.gen (env, CollectInfo.collect prog));
260 : jhr 3917 outputSrc (outS, env, spec, prog, strand, substitutions,
261 : jhr 3903 fn () => (
262 : jhr 3906 GenInputs.genInputsStruct (env, inputs) @
263 : jhr 3990 (* FIXME: generate input functions for library
264 : jhr 3912 GenInputs.genExecInputFuns (env, prog) @
265 : jhr 3990 GenOutputsUtil.genRegisterOutputOpts (env, OutputUtil.gatherOutputs prog)));
266 :     *)[]));
267 : jhr 3996 ppDecl (CL.verbatimDcl [CxxFragments.namespaceClose] substitutions);
268 : jhr 3993 (* FIXME: generate the extern "C" decls for the exported functions *)
269 : jhr 3906 Out.closeOut outS;
270 : jhr 3990 (* compile and link *)
271 : jhr 3906 compile (spec, baseName);
272 : jhr 3990 RunCC.linkLib (baseName, ldFlags spec)
273 : jhr 3902 end
274 : jhr 3908
275 : jhr 3902 end

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