Revision 66359a5e
Added by Pierre-Loïc Garoche about 7 years ago
src/compiler_stages.ml | ||
---|---|---|
48 | 48 |
|
49 | 49 |
(* From prog to prog *) |
50 | 50 |
let stage1 prog dirname basename = |
51 |
(* Updating parent node information for variables *) |
|
52 |
Compiler_common.update_vdecl_parents_prog prog; |
|
53 |
|
|
51 | 54 |
(* Removing automata *) |
52 | 55 |
let prog = expand_automata prog in |
53 | 56 |
Log.report ~level:4 (fun fmt -> fprintf fmt ".. after automata expansion:@, @[<v 2>@,%a@]@ " Printers.pp_prog prog); |
... | ... | |
83 | 86 |
(* Clock calculus *) |
84 | 87 |
let computed_clocks_env = clock_decls clock_env prog in |
85 | 88 |
|
89 |
(* Registering and checking machine types *) |
|
90 |
Machine_types.load prog; |
|
91 |
|
|
92 |
|
|
86 | 93 |
(* Generating a .lusi header file only *) |
87 | 94 |
if !Options.lusi then |
88 | 95 |
(* We stop here the processing and produce the current prog. It will be |
... | ... | |
131 | 138 |
Typing.uneval_prog_generics prog; |
132 | 139 |
Clock_calculus.uneval_prog_generics prog; |
133 | 140 |
|
141 |
|
|
134 | 142 |
if !Options.global_inline && !Options.main_node <> "" && !Options.witnesses then |
135 | 143 |
begin |
136 | 144 |
let orig = Corelang.copy_prog orig in |
... | ... | |
160 | 168 |
else |
161 | 169 |
prog |
162 | 170 |
in |
163 |
|
|
171 |
|
|
172 |
|
|
173 |
(* (\* Registering and checking machine types *\) *) |
|
174 |
(* Machine_types.load prog; *) |
|
175 |
|
|
164 | 176 |
(* Normalization phase *) |
165 | 177 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. normalization@,"); |
166 | 178 |
let prog = Normalization.normalize_prog ~backend:!Options.output prog in |
... | ... | |
187 | 199 |
Access.check_prog prog; |
188 | 200 |
end; |
189 | 201 |
|
202 |
|
|
190 | 203 |
let prog = SortProg.sort_nodes_locals prog in |
191 | 204 |
|
192 | 205 |
prog, dependencies |
206 |
|
|
207 |
|
|
208 |
(* from source to machine code, with optimization *) |
|
209 |
let stage2 prog = |
|
210 |
(* Computation of node equation scheduling. It also breaks dependency cycles |
|
211 |
and warns about unused input or memory variables *) |
|
212 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. @[<v 2>scheduling@ "); |
|
213 |
let prog, node_schs = |
|
214 |
try |
|
215 |
Scheduling.schedule_prog prog |
|
216 |
with Causality.Error _ -> (* Error is not kept. It is recomputed in a more |
|
217 |
systemtic way in AlgebraicLoop module *) |
|
218 |
AlgebraicLoop.analyze prog |
|
219 |
in |
|
220 |
Log.report ~level:1 (fun fmt -> fprintf fmt "%a" Scheduling.pp_warning_unused node_schs); |
|
221 |
Log.report ~level:3 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@," Scheduling.pp_schedule node_schs); |
|
222 |
Log.report ~level:3 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@," Scheduling.pp_fanin_table node_schs); |
|
223 |
Log.report ~level:5 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@," Scheduling.pp_dep_graph node_schs); |
|
224 |
Log.report ~level:3 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@," Printers.pp_prog prog); |
|
225 |
Log.report ~level:1 (fun fmt -> fprintf fmt "@]@ "); |
|
226 |
|
|
227 |
(* TODO Salsa optimize prog: |
|
228 |
- emits warning for programs with pre inside expressions |
|
229 |
- make sure each node arguments and memory is bounded by a local annotation |
|
230 |
- introduce fresh local variables for each real pure subexpression |
|
231 |
*) |
|
232 |
(* DFS with modular code generation *) |
|
233 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. machines generation@,"); |
|
234 |
let machine_code = Machine_code.translate_prog prog node_schs in |
|
235 |
|
|
236 |
Log.report ~level:3 (fun fmt -> fprintf fmt ".. generated machines (unoptimized):@ %a@ "Machine_code.pp_machines machine_code); |
|
237 |
|
|
238 |
(* Optimize machine code *) |
|
239 |
Optimize_machine.optimize prog node_schs machine_code |
|
240 |
|
|
241 |
|
|
242 |
(* printing code *) |
|
243 |
let stage3 prog machine_code dependencies basename = |
|
244 |
let basename = Filename.basename basename in |
|
245 |
match !Options.output with |
|
246 |
"C" -> |
|
247 |
begin |
|
248 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. C code generation@,"); |
|
249 |
C_backend.translate_to_c |
|
250 |
(* alloc_header_file source_lib_file source_main_file makefile_file *) |
|
251 |
basename prog machine_code dependencies |
|
252 |
end |
|
253 |
| "java" -> |
|
254 |
begin |
|
255 |
(Format.eprintf "internal error: sorry, but not yet supported !"; assert false) |
|
256 |
(*let source_file = basename ^ ".java" in |
|
257 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. opening file %s@,@?" source_file); |
|
258 |
let source_out = open_out source_file in |
|
259 |
let source_fmt = formatter_of_out_channel source_out in |
|
260 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. java code generation@,@?"); |
|
261 |
Java_backend.translate_to_java source_fmt basename normalized_prog machine_code;*) |
|
262 |
end |
|
263 |
| "horn" -> |
|
264 |
begin |
|
265 |
let destname = !Options.dest_dir ^ "/" ^ basename in |
|
266 |
let source_file = destname ^ ".smt2" in (* Could be changed *) |
|
267 |
let source_out = open_out source_file in |
|
268 |
let fmt = formatter_of_out_channel source_out in |
|
269 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. hornification@,"); |
|
270 |
Horn_backend.translate fmt basename prog (Machine_code.arrow_machine::machine_code); |
|
271 |
(* Tracability file if option is activated *) |
|
272 |
if !Options.traces then ( |
|
273 |
let traces_file = destname ^ ".traces.xml" in (* Could be changed *) |
|
274 |
let traces_out = open_out traces_file in |
|
275 |
let fmt = formatter_of_out_channel traces_out in |
|
276 |
Log.report ~level:1 (fun fmt -> fprintf fmt ".. tracing info@,"); |
|
277 |
Horn_backend_traces.traces_file fmt basename prog machine_code; |
|
278 |
) |
|
279 |
end |
|
280 |
| "lustre" -> |
|
281 |
begin |
|
282 |
let destname = !Options.dest_dir ^ "/" ^ basename in |
|
283 |
let source_file = destname ^ ".lustrec.lus" in (* Could be changed *) |
|
284 |
let source_out = open_out source_file in |
|
285 |
let fmt = formatter_of_out_channel source_out in |
|
286 |
Printers.pp_prog fmt prog; |
|
287 |
Format.fprintf fmt "@.@?"; |
|
288 |
(* Lustre_backend.translate fmt basename normalized_prog machine_code *) |
|
289 |
() |
|
290 |
end |
|
291 |
| "emf" -> |
|
292 |
begin |
|
293 |
let destname = !Options.dest_dir ^ "/" ^ basename in |
|
294 |
let source_file = destname ^ ".emf" in (* Could be changed *) |
|
295 |
let source_out = open_out source_file in |
|
296 |
let fmt = formatter_of_out_channel source_out in |
|
297 |
EMF_backend.translate fmt basename prog machine_code; |
|
298 |
() |
|
299 |
end |
|
300 |
|
|
301 |
| _ -> assert false |
Also available in: Unified diff
[general] large modification: added machine types, a second typing phase dealing with machine types (eg uint8)
typing was transformed as a functor and parametrized by basic types (int/real/bool)
it can also be applied multiple times on the same program