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 3917 - (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 :     structure CL = CLang
19 : jhr 3905 structure Env = CodeGenEnv
20 :     structure Out = CodeOutput
21 : jhr 3906 structure RN = CxxNames
22 : jhr 3902
23 : jhr 3905 val openCxxOut = Out.openOut {ext = "cxx", ppDecl = PrintAsCxx.output}
24 :    
25 : jhr 3908 fun mkEnv spec = if TargetSpec.dualState spec
26 :     then Env.new {
27 :     global = RN.globalsVar,
28 :     selfIn = RN.selfInVar,
29 :     selfOut = RN.selfOutVar,
30 :     spec = spec
31 :     }
32 :     else Env.new {
33 :     global = RN.globalsVar,
34 :     selfIn = RN.selfVar,
35 :     selfOut = RN.selfVar,
36 :     spec = spec
37 :     }
38 :    
39 : jhr 3905 (* create the target-specific substitution list *)
40 :     fun mkSubs (spec, IR.Strand{name, ...}) = [
41 :     ("CFILE", OS.Path.joinBaseExt{base= #outBase spec, ext= SOME "c"}),
42 :     ("CXXFILE", OS.Path.joinBaseExt{base= #outBase spec, ext= SOME "cxx"}),
43 :     ("HDRFILE", OS.Path.joinBaseExt{base= #outBase spec, ext= SOME "h"}),
44 :     ("PREFIX", #namespace spec),
45 :     ("SRCFILE", #srcFile spec),
46 :     ("PROG_NAME", #outBase spec),
47 :     ("STRAND", Atom.toString name),
48 :     ("STRANDTY", Atom.toString name ^ "_strand"),
49 :     ("DIDEROTC_CMD", #diderotc spec),
50 :     ("DIDEROTC_ARGV", String.concatWith " " (#argv spec)),
51 :     ("DIDEROTC_VERSION", #version spec),
52 :     ("DIDEROT_FLOAT_PRECISION", TargetSpec.floatPrecisionDef spec),
53 :     ("DIDEROT_INT_PRECISION", TargetSpec.intPrecisionDef spec),
54 : jhr 3916 ("DIDEROT_TARGET", TargetSpec.targetDef spec),
55 :     ("REALTY", if #double spec then "double" else "float"),
56 :     ("INTTY", if #longint spec then "int64_t" else "int32_t")
57 : jhr 3905 ]
58 :    
59 :     fun condCons (true, x, xs) = x::xs
60 :     | condCons (false, _, xs) = xs
61 :    
62 : jhr 3906 fun verbFrag (spec, parFrag, seqFrag, subs) =
63 :     CL.verbatimDcl [if (TargetSpec.isParallel spec) then parFrag else seqFrag] subs
64 : jhr 3905
65 : jhr 3917 (* generate declarations for the types and operations that are used in the program *)
66 :     fun genTypesAndOperations (outS, spec : TargetSpec.t, info) = let
67 :     fun doType (ty, isPrint) = ()
68 :     in
69 :     CollectInfo.applyToTypes doType info
70 :     end
71 : jhr 3905
72 : jhr 3917 (* generate the struct declaration for the global variables *)
73 :     fun genGlobalStruct (spec : TargetSpec.t, globals) =
74 :     if #hasGlobals spec
75 :     then let
76 :     val fields = [] (* FIXME *)
77 :     in
78 :     [CL.D_StructDef(SOME "globals", fields, NONE)]
79 :     end
80 :     else []
81 :    
82 :     (* generate the struct declaration for the world representation *)
83 :     fun genWorldStruct (spec : TargetSpec.t, strandName) = let
84 :     fun memberVar (ty, name) = CL.D_Var([], ty, name, NONE)
85 :     val members = []
86 :     val statePtrTy = CL.T_Ptr(CL.T_Ptr(CL.T_Named(Atom.toString strandName ^ "_strand")))
87 :     val members = if TargetSpec.dualState spec
88 :     then memberVar(statePtrTy, "_inState") ::
89 :     memberVar(statePtrTy, "_inState") :: members
90 :     else memberVar(statePtrTy, "_state") :: members
91 :     val members = memberVar(CL.T_Ptr CL.uint8, "_status") :: members
92 :     val members = if #hasGlobals spec
93 :     then memberVar(RN.globalPtrTy, "_globals") :: members
94 :     else members
95 :     val members = if #exec spec orelse not(#hasInputs spec)
96 :     then members
97 :     else memberVar(CL.T_Named "inputs", "_definedInp") :: members
98 :     val members = if TargetSpec.isParallel spec
99 :     then memberVar(CL.T_Ptr(CL.T_Named "sched_info"), "_sched") :: members
100 :     else memberVar(CL.T_Named "uint32_t", "_nactive") ::
101 :     memberVar(CL.T_Named "uint32_t", "_nstable") :: members
102 :     (* add world method decls *)
103 :     fun memberFun (ty, name, params) = CL.D_Proto([], ty, name, params)
104 :     val members =
105 :     memberFun (CL.voidTy, "swap_state", []) ::
106 :     memberFun (CL.uint32, "run", [CL.PARAM([], CL.uint32, "max_nsteps")]) ::
107 :     memberFun (CL.voidTy, "initially", []) ::
108 :     CL.D_Destr([], NONE, "world", NONE) ::
109 :     CL.D_Constr([], NONE, "world", [], [], NONE) ::
110 :     members
111 :     in
112 :     CL.D_ClassDef{
113 :     name = "world",
114 :     from = SOME "public diderot::world_base",
115 :     public = List.rev members,
116 :     protected = [],
117 :     private = []
118 :     }
119 :     end
120 :    
121 :     fun runFrag (spec, subs) = if TargetSpec.noBSP spec
122 :     then verbFrag (spec, Fragments.parallelRunNoBSP, Fragments.sequentialRunNoBSP, subs)
123 :     else verbFrag (spec, Fragments.parallelRun, Fragments.sequentialRun, subs)
124 :    
125 : jhr 3905 fun compile (spec : TargetSpec.t, basename) = let
126 :     (* generate the C compiler flags *)
127 :     val cflags = ["-I" ^ Paths.diderotInclude(), "-I" ^ Paths.teemInclude()]
128 : jhr 3914 val cflags = condCons (TargetSpec.isParallel spec, #pthread Paths.cxxflags, cflags)
129 : jhr 3906 val cflags = if #debug spec
130 : jhr 3914 then #debug Paths.cxxflags :: cflags
131 :     else #ndebug Paths.cxxflags :: cflags
132 :     val cflags = #base Paths.cxxflags :: cflags
133 : jhr 3905 in
134 :     RunCC.compile (basename, cflags)
135 :     end
136 :    
137 : jhr 3906 fun ldFlags (spec : TargetSpec.t) = if #exec spec
138 : jhr 3905 then let
139 : jhr 3906 val extraLibs = condCons (TargetSpec.isParallel spec, #pthread Paths.extraLibs, [])
140 : jhr 3905 val extraLibs = Paths.teemLinkFlags() @ #base Paths.extraLibs :: extraLibs
141 : jhr 3906 val rtLib = TargetSpec.runtimeLibName spec
142 : jhr 3905 in
143 : jhr 3914 condCons (TargetSpec.isParallel spec, #pthread Paths.cxxflags, rtLib :: extraLibs)
144 : jhr 3905 end
145 : jhr 3906 else [TargetSpec.runtimeLibName spec]
146 : jhr 3905
147 : jhr 3912 (* generate source code that is common to both libraries and standalone executables *)
148 : jhr 3917 fun outputSrc (outS, env, spec, prog, strand, substitutions, genInputCode) = let
149 :     val IR.Program{globals, create=IR.Create{dim, ...}, ...} = prog
150 :     val IR.Strand{name=strandName, ...} = strand
151 :     val ppDecl = Out.decl outS
152 :     val outputs = OutputUtil.gatherOutputs prog
153 : jhr 3912 in
154 :     if (TargetSpec.isParallel spec)
155 : jhr 3917 then ppDecl (CL.verbatimDcl [Fragments.parallelExtras] substitutions)
156 : jhr 3912 else ();
157 :     if TargetSpec.dualState spec
158 :     then ppDecl (CL.D_Verbatim ["#define DIDEROT_DUAL_STATE\n"])
159 :     else ();
160 :     if not(#hasGlobals spec)
161 :     then ppDecl (CL.D_Verbatim ["#define DIDEROT_NO_GLOBALS\n"])
162 :     else ();
163 :     if not(#hasInputs spec)
164 :     then ppDecl (CL.D_Verbatim ["#define DIDEROT_NO_INPUTS\n"])
165 :     else ();
166 : jhr 3917 (* FIXME: what about constants and inputs? *)
167 :     List.app ppDecl (genGlobalStruct (spec, globals));
168 :     ppDecl (genWorldStruct(spec, strandName));
169 : jhr 3912 List.app ppDecl (genInputCode());
170 : jhr 3917 (* FIXME: need to gather/generate topDecls
171 : jhr 3912 List.app ppDecl (!topDecls);
172 : jhr 3917 *)
173 :     List.app ppDecl (GenStrand.gen (env, strand));
174 :     List.app ppDecl (GenOutputs.gen (env, dim, outputs));
175 :     ppDecl (CL.verbatimDcl [Fragments.worldMethods] substitutions);
176 :     (* TODO
177 : jhr 3912 ppDecl (CL.verbatimDcl [InitFrag.text] substitutions);
178 :     ppDecl (CL.verbatimDcl [AllocFrag.text] substitutions);
179 :     ppDecl (!initially);
180 : jhr 3917 *)
181 :     ppDecl (runFrag (spec, substitutions))
182 : jhr 3912 end
183 : jhr 3917
184 : jhr 3905 (********************
185 : jhr 3903 fun outputLibSrc (baseName, prog as Prog{props, inputs, strands, ...}) = let
186 :     val [strand] = AtomTable.listItems strands
187 :     val substitutions = mkSubs (props, strand)
188 :     (* output to C file *)
189 :     val out = openOut baseName
190 :     fun ppDecl dcl = PrintAsC.output(#ppStrm out, dcl)
191 :     in
192 :     ppDecl (CL.verbatimDcl [LibHdrFrag.text] substitutions);
193 :     List.app ppDecl (GenInputs.genDefinedInpStruct (props, !inputs));
194 :     outputSrc (out, prog, strand, substitutions,
195 :     fn () => GenInputs.genInputFuns(props, !inputs));
196 :     ppDecl (CL.verbatimDcl [CBodyFrag.text] substitutions);
197 :     closeOut out
198 :     end
199 :    
200 :     fun generateLib (prog as Prog{props, inputs, strands, ...}) = let
201 : jhr 3906 val {outDir, outBase, exec, double, debug, ...} = props
202 : jhr 3903 val basename = OS.Path.joinDirFile{dir=outDir, file=outBase}
203 :     val [Strand{state, output, ...}] = AtomTable.listItems strands
204 :     in
205 :     (* generate the library .h file *)
206 :     GenLibraryInterface.gen {
207 :     props = props,
208 : jhr 3906 rt = if TargetSpec.isParallel spec
209 : jhr 3903 then SOME LibInterfaceParFrag.text
210 :     else NONE,
211 :     inputs = !inputs,
212 :     outputs = output
213 :     };
214 :     (* *)
215 :     outputLibSrc (basename, prog);
216 :     (* compile and link *)
217 :     compile (props, basename);
218 :     RunCC.linkLib (basename, ldFlags props)
219 :     end
220 : jhr 3905 ********************)
221 : jhr 3903
222 : jhr 3902 fun exec (spec : TargetSpec.t, prog) = let
223 : jhr 3912 val IR.Program{inputs, strand, ...} = prog
224 : jhr 3908 val env = mkEnv spec
225 : jhr 3905 val baseName = OS.Path.joinDirFile{dir = #outDir spec, file = #outBase spec}
226 : jhr 3906 val substitutions = mkSubs (spec, strand)
227 : jhr 3903 (* output to C++ file *)
228 : jhr 3905 val outS = openCxxOut baseName
229 :     val ppDecl = Out.decl outS
230 :     val fragment = Out.fragment substitutions outS
231 : jhr 3902 in
232 : jhr 3912 GenExecUtil.execHead (outS, substitutions);
233 : jhr 3917 genTypesAndOperations (outS, spec, CollectInfo.collect prog);
234 :     outputSrc (outS, env, spec, prog, strand, substitutions,
235 : jhr 3903 fn () => (
236 : jhr 3906 GenInputs.genInputsStruct (env, inputs) @
237 : jhr 3912 GenInputs.genExecInputFuns (env, prog) @
238 :     OutputUtil.genRegisterOutputOpts (env, OutputUtil.gatherOutputs prog)));
239 :     ppDecl (verbFrag (spec, Fragments.parallelMain, Fragments.sequentialMain, substitutions));
240 : jhr 3916 GenExecUtil.execFoot (outS, substitutions);
241 : jhr 3906 Out.closeOut outS;
242 :     compile (spec, baseName);
243 :     RunCC.linkExec (baseName, ldFlags spec)
244 : jhr 3902 end
245 : jhr 3908
246 : jhr 3902 fun library (spec : TargetSpec.t, prog) = let
247 :     val IR.Program{
248 :     props, target, consts, inputs, constInit,
249 :     globals, globalInit, strand, create, update
250 :     } = prog
251 : jhr 3906 val {outDir, outBase, exec, double, debug, ...} = spec
252 : jhr 3908 val env = mkEnv spec
253 : jhr 3902 in
254 :     raise Fail "FIXME"
255 :     end
256 : jhr 3908
257 : jhr 3902 end

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