18 |
18 |
|
19 |
19 |
exception NormalizationError
|
20 |
20 |
|
|
21 |
(* Questions:
|
|
22 |
|
|
23 |
- where are used the mconst. They contain initialization of
|
|
24 |
constant in nodes. But they do not seem to be used by c_backend *)
|
21 |
25 |
|
22 |
26 |
|
23 |
27 |
(* translate_<foo> : vars -> context -> <foo> -> machine code/expression *)
|
... | ... | |
26 |
30 |
(* j : node aka machine instances *)
|
27 |
31 |
(* d : local variables *)
|
28 |
32 |
(* s : step instructions *)
|
29 |
|
let translate_ident vars _ (* (m, si, j, d, s) *) id =
|
|
33 |
|
|
34 |
(* Machine processing requires knowledge about variables and local
|
|
35 |
variables. Local could be memories while other could not. *)
|
|
36 |
type machine_env = {
|
|
37 |
is_local: string -> bool;
|
|
38 |
get_var: string -> var_decl
|
|
39 |
}
|
|
40 |
|
|
41 |
|
|
42 |
let build_env locals non_locals =
|
|
43 |
let all = VSet.union locals non_locals in
|
|
44 |
{
|
|
45 |
is_local = (fun id -> VSet.exists (fun v -> v.var_id = id) locals);
|
|
46 |
get_var = (fun id -> try
|
|
47 |
VSet.get id all
|
|
48 |
with Not_found -> (
|
|
49 |
Format.eprintf "Impossible to find variable %s in set %a@.@?"
|
|
50 |
id
|
|
51 |
VSet.pp all;
|
|
52 |
raise Not_found
|
|
53 |
)
|
|
54 |
)
|
|
55 |
}
|
|
56 |
|
|
57 |
|
|
58 |
|
|
59 |
(****************************************************************)
|
|
60 |
(* Basic functions to translate to machine values, instructions *)
|
|
61 |
(****************************************************************)
|
|
62 |
|
|
63 |
let translate_ident env id =
|
30 |
64 |
(* Format.eprintf "trnaslating ident: %s@." id; *)
|
31 |
65 |
try (* id is a var that shall be visible here , ie. in vars *)
|
32 |
|
let var_id = get_var id vars in
|
|
66 |
let var_id = env.get_var id in
|
33 |
67 |
mk_val (Var var_id) var_id.var_type
|
34 |
68 |
with Not_found ->
|
35 |
69 |
try (* id is a constant *)
|
... | ... | |
38 |
72 |
in
|
39 |
73 |
mk_val (Var vdecl) vdecl.var_type
|
40 |
74 |
with Not_found ->
|
41 |
|
(* id is a tag *)
|
42 |
|
(* DONE construire une liste des enum declarés et alors chercher
|
43 |
|
dedans la liste qui contient id *)
|
|
75 |
(* id is a tag, getting its type in the list of declared enums *)
|
44 |
76 |
try
|
45 |
77 |
let typ = (typedef_of_top (Hashtbl.find Corelang.tag_table id)).tydef_id in
|
46 |
78 |
mk_val (Cst (Const_tag id)) (Type_predef.type_const typ)
|
... | ... | |
49 |
81 |
id;
|
50 |
82 |
assert false)
|
51 |
83 |
|
52 |
|
let rec control_on_clock vars ((m, si, j, d, s) as args) ck inst =
|
|
84 |
let rec control_on_clock env ck inst =
|
53 |
85 |
match (Clocks.repr ck).cdesc with
|
54 |
86 |
| Con (ck1, cr, l) ->
|
55 |
87 |
let id = Clocks.const_of_carrier cr in
|
56 |
|
control_on_clock vars args ck1 (mkinstr
|
57 |
|
(* TODO il faudrait prendre le lustre
|
58 |
|
associé à instr et rajouter print_ck_suffix
|
59 |
|
ck) de clocks.ml *)
|
60 |
|
(MBranch (translate_ident vars args id,
|
61 |
|
[l, [inst]] )))
|
|
88 |
control_on_clock env ck1
|
|
89 |
(mkinstr
|
|
90 |
(MBranch (translate_ident env id,
|
|
91 |
[l, [inst]] )))
|
62 |
92 |
| _ -> inst
|
63 |
93 |
|
64 |
94 |
|
65 |
|
(* specialize predefined (polymorphic) operators
|
66 |
|
wrt their instances, so that the C semantics
|
67 |
|
is preserved *)
|
|
95 |
(* specialize predefined (polymorphic) operators wrt their instances,
|
|
96 |
so that the C semantics is preserved *)
|
68 |
97 |
let specialize_to_c expr =
|
69 |
98 |
match expr.expr_desc with
|
70 |
99 |
| Expr_appl (id, e, r) ->
|
... | ... | |
83 |
112 |
| "C" -> specialize_to_c expr
|
84 |
113 |
| _ -> expr
|
85 |
114 |
|
86 |
|
let rec translate_expr vars ((m, si, j, d, s) as args) expr =
|
|
115 |
let rec translate_expr env expr =
|
87 |
116 |
let expr = specialize_op expr in
|
88 |
|
(* all calls are using the same arguments (vars for the variable
|
89 |
|
enviroment and args for computed memories). No fold constructs
|
90 |
|
here. We can do partial evaluation of translate_expr *)
|
91 |
|
let translate_expr = translate_expr vars args in
|
|
117 |
let translate_expr = translate_expr env in
|
92 |
118 |
let value_desc =
|
93 |
119 |
match expr.expr_desc with
|
94 |
120 |
| Expr_const v -> Cst v
|
95 |
|
| Expr_ident x -> (translate_ident vars args x).value_desc
|
|
121 |
| Expr_ident x -> (translate_ident env x).value_desc
|
96 |
122 |
| Expr_array el -> Array (List.map translate_expr el)
|
97 |
123 |
| Expr_access (t, i) -> Access (translate_expr t,
|
98 |
124 |
translate_expr
|
... | ... | |
115 |
141 |
let nd = node_from_name id in
|
116 |
142 |
Fun (node_name nd, List.map translate_expr (expr_list_of_expr e))
|
117 |
143 |
| Expr_ite (g,t,e) -> (
|
118 |
|
(* special treatment depending on the active backend. For horn backend, ite
|
119 |
|
are preserved in expression. While they are removed for C or Java
|
120 |
|
backends. *)
|
121 |
|
match !Options.output with
|
122 |
|
| "horn" ->
|
123 |
|
Fun ("ite", [translate_expr g; translate_expr t; translate_expr e])
|
124 |
|
| "C" | "java" | _ ->
|
125 |
|
(Format.eprintf "Normalization error for backend %s: %a@."
|
126 |
|
!Options.output
|
127 |
|
Printers.pp_expr expr;
|
128 |
|
raise NormalizationError)
|
|
144 |
(* special treatment depending on the active backend. For
|
|
145 |
functional ones, like horn backend, ite are preserved in
|
|
146 |
expression. While they are removed for C or Java backends. *)
|
|
147 |
if Backends.is_functional () then
|
|
148 |
Fun ("ite", [translate_expr g; translate_expr t; translate_expr e])
|
|
149 |
else
|
|
150 |
(Format.eprintf "Normalization error for backend %s: %a@."
|
|
151 |
!Options.output
|
|
152 |
Printers.pp_expr expr;
|
|
153 |
raise NormalizationError)
|
129 |
154 |
)
|
130 |
155 |
| _ -> raise NormalizationError
|
131 |
156 |
in
|
132 |
157 |
mk_val value_desc expr.expr_type
|
133 |
158 |
|
134 |
|
let translate_guard vars args expr =
|
|
159 |
let translate_guard env expr =
|
135 |
160 |
match expr.expr_desc with
|
136 |
|
| Expr_ident x -> translate_ident vars args x
|
|
161 |
| Expr_ident x -> translate_ident env x
|
137 |
162 |
| _ -> (Format.eprintf "internal error: translate_guard %a@."
|
138 |
163 |
Printers.pp_expr expr;
|
139 |
164 |
assert false)
|
140 |
165 |
|
141 |
|
let rec translate_act vars ((m, si, j, d, s) as args) (y, expr) =
|
142 |
|
let translate_act = translate_act vars args in
|
143 |
|
let translate_guard = translate_guard vars args in
|
144 |
|
let translate_ident = translate_ident vars args in
|
145 |
|
let translate_expr = translate_expr vars args in
|
|
166 |
let rec translate_act env (y, expr) =
|
|
167 |
let translate_act = translate_act env in
|
|
168 |
let translate_guard = translate_guard env in
|
|
169 |
let translate_ident = translate_ident env in
|
|
170 |
let translate_expr = translate_expr env in
|
146 |
171 |
let eq = Corelang.mkeq Location.dummy_loc ([y.var_id], expr) in
|
147 |
172 |
match expr.expr_desc with
|
148 |
173 |
| Expr_ite (c, t, e) -> let g = translate_guard c in
|
... | ... | |
157 |
182 |
| _ -> mkinstr ?lustre_eq:(Some eq)
|
158 |
183 |
(MLocalAssign (y, translate_expr expr))
|
159 |
184 |
|
160 |
|
let reset_instance vars args i r c =
|
|
185 |
let reset_instance env i r c =
|
161 |
186 |
match r with
|
162 |
187 |
| None -> []
|
163 |
|
| Some r -> let g = translate_guard vars args r in
|
|
188 |
| Some r -> let g = translate_guard env r in
|
164 |
189 |
[control_on_clock
|
165 |
|
vars
|
166 |
|
args
|
|
190 |
env
|
167 |
191 |
c
|
168 |
192 |
(mk_conditional
|
169 |
193 |
g
|
... | ... | |
171 |
195 |
[mkinstr (MNoReset i)])
|
172 |
196 |
]
|
173 |
197 |
|
174 |
|
let translate_eq vars ((m, si, j, d, s) as args) eq =
|
175 |
|
let translate_expr = translate_expr vars args in
|
176 |
|
let translate_act = translate_act vars args in
|
177 |
|
let control_on_clock = control_on_clock vars args in
|
178 |
|
let reset_instance = reset_instance vars args in
|
|
198 |
|
|
199 |
(* Datastructure updated while visiting equations *)
|
|
200 |
type machine_ctx = {
|
|
201 |
m: VSet.t; (* Memories *)
|
|
202 |
si: instr_t list;
|
|
203 |
j: (Lustre_types.top_decl * Dimension.dim_expr list) Utils.IMap.t;
|
|
204 |
s: instr_t list;
|
|
205 |
}
|
|
206 |
|
|
207 |
let ctx_init = { m = VSet.empty; (* memories *)
|
|
208 |
si = []; (* init instr *)
|
|
209 |
j = Utils.IMap.empty;
|
|
210 |
s = [] }
|
|
211 |
|
|
212 |
(****************************************************************)
|
|
213 |
(* Main function to translate equations into this machine context we
|
|
214 |
are building *)
|
|
215 |
(****************************************************************)
|
|
216 |
|
|
217 |
|
|
218 |
|
|
219 |
let translate_eq env ctx eq =
|
|
220 |
let translate_expr = translate_expr env in
|
|
221 |
let translate_act = translate_act env in
|
|
222 |
let control_on_clock = control_on_clock env in
|
|
223 |
let reset_instance = reset_instance env in
|
179 |
224 |
|
180 |
225 |
(* Format.eprintf "translate_eq %a with clock %a@."
|
181 |
226 |
Printers.pp_node_eq eq Clocks.print_ck eq.eq_rhs.expr_clock; *)
|
182 |
227 |
match eq.eq_lhs, eq.eq_rhs.expr_desc with
|
183 |
228 |
| [x], Expr_arrow (e1, e2) ->
|
184 |
|
let var_x = get_var x vars in
|
|
229 |
let var_x = env.get_var x in
|
185 |
230 |
let o = new_instance Arrow.arrow_top_decl eq.eq_rhs.expr_tag in
|
186 |
231 |
let c1 = translate_expr e1 in
|
187 |
232 |
let c2 = translate_expr e2 in
|
188 |
|
(m,
|
189 |
|
mkinstr (MReset o) :: si,
|
190 |
|
Utils.IMap.add o (Arrow.arrow_top_decl, []) j,
|
191 |
|
d,
|
192 |
|
(control_on_clock eq.eq_rhs.expr_clock (mkinstr ?lustre_eq:(Some eq) (MStep ([var_x], o, [c1;c2])))) :: s)
|
193 |
|
| [x], Expr_pre e1 when VSet.mem (get_var x vars) d ->
|
194 |
|
let var_x = get_var x vars in
|
195 |
|
(VSet.add var_x m,
|
196 |
|
si,
|
197 |
|
j,
|
198 |
|
d,
|
199 |
|
control_on_clock eq.eq_rhs.expr_clock (mkinstr ?lustre_eq:(Some eq) (MStateAssign (var_x, translate_expr e1))) :: s)
|
200 |
|
| [x], Expr_fby (e1, e2) when VSet.mem (get_var x vars) d ->
|
201 |
|
let var_x = get_var x vars in
|
202 |
|
(VSet.add var_x m,
|
203 |
|
mkinstr ?lustre_eq:(Some eq) (MStateAssign (var_x, translate_expr e1)) :: si,
|
204 |
|
j,
|
205 |
|
d,
|
206 |
|
control_on_clock eq.eq_rhs.expr_clock (mkinstr ?lustre_eq:(Some eq) (MStateAssign (var_x, translate_expr e2))) :: s)
|
|
233 |
{ ctx with
|
|
234 |
si = mkinstr (MReset o) :: ctx.si;
|
|
235 |
j = Utils.IMap.add o (Arrow.arrow_top_decl, []) ctx.j;
|
|
236 |
s = (control_on_clock
|
|
237 |
eq.eq_rhs.expr_clock
|
|
238 |
(mkinstr ?lustre_eq:(Some eq) (MStep ([var_x], o, [c1;c2])))
|
|
239 |
) :: ctx.s
|
|
240 |
}
|
|
241 |
| [x], Expr_pre e1 when env.is_local x ->
|
|
242 |
let var_x = env.get_var x in
|
|
243 |
|
|
244 |
{ ctx with
|
|
245 |
m = VSet.add var_x ctx.m;
|
|
246 |
s = control_on_clock
|
|
247 |
eq.eq_rhs.expr_clock
|
|
248 |
(mkinstr ?lustre_eq:(Some eq)
|
|
249 |
(MStateAssign (var_x, translate_expr e1)))
|
|
250 |
:: ctx.s
|
|
251 |
}
|
|
252 |
| [x], Expr_fby (e1, e2) when env.is_local x ->
|
|
253 |
let var_x = env.get_var x in
|
|
254 |
{ ctx with
|
|
255 |
m = VSet.add var_x ctx.m;
|
|
256 |
si = mkinstr ?lustre_eq:(Some eq)
|
|
257 |
(MStateAssign (var_x, translate_expr e1))
|
|
258 |
:: ctx.si;
|
|
259 |
s = control_on_clock
|
|
260 |
eq.eq_rhs.expr_clock
|
|
261 |
(mkinstr ?lustre_eq:(Some eq)
|
|
262 |
(MStateAssign (var_x, translate_expr e2)))
|
|
263 |
:: ctx.s
|
|
264 |
}
|
207 |
265 |
|
208 |
266 |
| p , Expr_appl (f, arg, r) when not (Basic_library.is_expr_internal_fun eq.eq_rhs) ->
|
209 |
|
let var_p = List.map (fun v -> get_var v vars) p in
|
|
267 |
let var_p = List.map (fun v -> env.get_var v) p in
|
210 |
268 |
let el = expr_list_of_expr arg in
|
211 |
269 |
let vl = List.map translate_expr el in
|
212 |
270 |
let node_f = node_from_name f in
|
... | ... | |
219 |
277 |
(*Clocks.new_var true in
|
220 |
278 |
Clock_calculus.unify_imported_clock (Some call_ck) eq.eq_rhs.expr_clock eq.eq_rhs.expr_loc;
|
221 |
279 |
Format.eprintf "call %a: %a: %a@," Printers.pp_expr eq.eq_rhs Clocks.print_ck (Clock_predef.ck_tuple env_cks) Clocks.print_ck call_ck;*)
|
222 |
|
(m,
|
223 |
|
(if Stateless.check_node node_f then si else mkinstr (MReset o) :: si),
|
224 |
|
Utils.IMap.add o call_f j,
|
225 |
|
d,
|
226 |
|
(if Stateless.check_node node_f
|
227 |
|
then []
|
228 |
|
else reset_instance o r call_ck) @
|
229 |
|
(control_on_clock call_ck (mkinstr ?lustre_eq:(Some eq) (MStep (var_p, o, vl)))) :: s)
|
230 |
|
(*
|
231 |
|
(* special treatment depending on the active backend. For horn backend, x = ite (g,t,e)
|
232 |
|
are preserved. While they are replaced as if g then x = t else x = e in C or Java
|
233 |
|
backends. *)
|
234 |
|
| [x], Expr_ite (c, t, e)
|
235 |
|
when (match !Options.output with | "horn" -> true | "C" | "java" | _ -> false)
|
236 |
|
->
|
237 |
|
let var_x = get_node_var x node in
|
238 |
|
(m,
|
239 |
|
si,
|
240 |
|
j,
|
241 |
|
d,
|
242 |
|
(control_on_clock node args eq.eq_rhs.expr_clock
|
243 |
|
(MLocalAssign (var_x, translate_expr node args eq.eq_rhs))::s)
|
244 |
|
)
|
|
280 |
{ ctx with
|
|
281 |
si =
|
|
282 |
(if Stateless.check_node node_f then ctx.si else mkinstr (MReset o) :: ctx.si);
|
|
283 |
j = Utils.IMap.add o call_f ctx.j;
|
|
284 |
s = (if Stateless.check_node node_f
|
|
285 |
then []
|
|
286 |
else reset_instance o r call_ck) @
|
|
287 |
(control_on_clock call_ck
|
|
288 |
(mkinstr ?lustre_eq:(Some eq) (MStep (var_p, o, vl))))
|
|
289 |
:: ctx.s
|
|
290 |
}
|
245 |
291 |
|
246 |
|
*)
|
247 |
292 |
| [x], _ -> (
|
248 |
|
let var_x = get_var x vars in
|
249 |
|
(m, si, j, d,
|
250 |
|
control_on_clock
|
|
293 |
let var_x = env.get_var x in
|
|
294 |
{ ctx with
|
|
295 |
s =
|
|
296 |
control_on_clock
|
251 |
297 |
eq.eq_rhs.expr_clock
|
252 |
|
(translate_act (var_x, eq.eq_rhs)) :: s
|
253 |
|
)
|
|
298 |
(translate_act (var_x, eq.eq_rhs)) :: ctx.s
|
|
299 |
}
|
254 |
300 |
)
|
255 |
301 |
| _ ->
|
256 |
302 |
begin
|
257 |
|
Format.eprintf "internal error: Machine_code.translate_eq %a@?" Printers.pp_node_eq eq;
|
|
303 |
Format.eprintf "internal error: Machine_code.translate_eq %a@?"
|
|
304 |
Printers.pp_node_eq eq;
|
258 |
305 |
assert false
|
259 |
306 |
end
|
260 |
307 |
|
261 |
308 |
|
262 |
309 |
|
263 |
|
let constant_equations nd =
|
264 |
|
List.fold_right (fun vdecl eqs ->
|
|
310 |
let constant_equations locals =
|
|
311 |
VSet.fold (fun vdecl eqs ->
|
265 |
312 |
if vdecl.var_dec_const
|
266 |
313 |
then
|
267 |
314 |
{ eq_lhs = [vdecl.var_id];
|
... | ... | |
269 |
316 |
eq_loc = vdecl.var_loc
|
270 |
317 |
} :: eqs
|
271 |
318 |
else eqs)
|
272 |
|
nd.node_locals []
|
|
319 |
locals []
|
273 |
320 |
|
274 |
|
let translate_eqs node args eqs =
|
275 |
|
List.fold_right (fun eq args -> translate_eq node args eq) eqs args;;
|
|
321 |
let translate_eqs env ctx eqs =
|
|
322 |
List.fold_right (fun eq ctx -> translate_eq env ctx eq) eqs ctx;;
|
|
323 |
|
|
324 |
|
|
325 |
(****************************************************************)
|
|
326 |
(* Processing nodes *)
|
|
327 |
(****************************************************************)
|
276 |
328 |
|
277 |
329 |
let process_asserts nd =
|
278 |
330 |
|
... | ... | |
299 |
351 |
in
|
300 |
352 |
assert_var.var_type <- Type_predef.type_bool (* Types.new_ty (Types.Tbool) *);
|
301 |
353 |
let eq = mkeq loc ([var_id], expr) in
|
302 |
|
(i+1, assert_var::vars, eq::eqlist, {expr with expr_desc = Expr_ident var_id}::assertlist)
|
|
354 |
(i+1,
|
|
355 |
assert_var::vars,
|
|
356 |
eq::eqlist,
|
|
357 |
{expr with expr_desc = Expr_ident var_id}::assertlist)
|
303 |
358 |
) (1, [], [], []) exprl
|
304 |
359 |
in
|
305 |
360 |
vars, eql, assertl
|
|
361 |
|
|
362 |
let translate_core sorted_eqs locals other_vars =
|
|
363 |
let constant_eqs = constant_equations locals in
|
306 |
364 |
|
307 |
|
let translate_decl nd sch =
|
308 |
|
(*Log.report ~level:1 (fun fmt -> Printers.pp_node fmt nd);*)
|
309 |
|
let schedule = sch.Scheduling_type.schedule in
|
310 |
|
let sorted_eqs = Scheduling.sort_equations_from_schedule nd schedule in
|
311 |
|
let constant_eqs = constant_equations nd in
|
|
365 |
let env = build_env locals other_vars in
|
|
366 |
|
|
367 |
(* Compute constants' instructions *)
|
|
368 |
let ctx0 = translate_eqs env ctx_init constant_eqs in
|
|
369 |
assert (VSet.is_empty ctx0.m);
|
|
370 |
assert (ctx0.si = []);
|
|
371 |
assert (Utils.IMap.is_empty ctx0.j);
|
|
372 |
|
|
373 |
(* Compute ctx for all eqs *)
|
|
374 |
let ctx = translate_eqs env ctx_init sorted_eqs in
|
|
375 |
|
|
376 |
ctx, ctx0.s
|
312 |
377 |
|
|
378 |
let translate_decl nd sch =
|
|
379 |
(* Extracting eqs, variables .. *)
|
|
380 |
let eqs, auts = get_node_eqs nd in
|
|
381 |
assert (auts = []); (* Automata should be expanded by now *)
|
|
382 |
|
313 |
383 |
(* In case of non functional backend (eg. C), additional local variables have
|
314 |
384 |
to be declared for each assert *)
|
315 |
385 |
let new_locals, assert_instrs, nd_node_asserts = process_asserts nd in
|
|
386 |
|
|
387 |
(* Build the env: variables visible in the current scope *)
|
316 |
388 |
let locals_list = nd.node_locals @ new_locals in
|
317 |
|
let nd = { nd with node_locals = locals_list } in
|
318 |
|
let vars = get_node_vars nd in
|
|
389 |
let locals = VSet.of_list locals_list in
|
|
390 |
let inout_vars = (VSet.of_list (nd.node_inputs @ nd.node_outputs)) in
|
|
391 |
let env = build_env locals inout_vars in
|
|
392 |
|
|
393 |
(* Computing main content *)
|
|
394 |
let schedule = sch.Scheduling_type.schedule in
|
|
395 |
let sorted_eqs = Scheduling.sort_equations_from_schedule eqs schedule in
|
|
396 |
|
|
397 |
let ctx, ctx0_s = translate_core (assert_instrs@sorted_eqs) locals inout_vars in
|
|
398 |
(* CODE QUI MARCHE
|
|
399 |
let constant_eqs = constant_equations locals in
|
319 |
400 |
|
320 |
|
let init_args = VSet.empty, [], Utils.IMap.empty, List.fold_right (fun l -> VSet.add l) locals_list VSet.empty, [] in
|
321 |
|
(* memories, init instructions, node calls, local variables (including memories), step instrs *)
|
|
401 |
(* Compute constants' instructions *)
|
|
402 |
let ctx0 = translate_eqs env ctx_init constant_eqs in
|
|
403 |
assert (VSet.is_empty ctx0.m);
|
|
404 |
assert (ctx0.si = []);
|
|
405 |
assert (Utils.IMap.is_empty ctx0.j);
|
322 |
406 |
|
323 |
|
let m0, init0, j0, locals0, s0 =
|
324 |
|
translate_eqs vars init_args constant_eqs
|
|
407 |
(* Compute ctx for all eqs *)
|
|
408 |
let ctx = translate_eqs env ctx_init (assert_instrs@sorted_eqs) in
|
|
409 |
*)
|
|
410 |
|
|
411 |
(*
|
|
412 |
(* Processing spec: locals would be actual locals of the spec while
|
|
413 |
non locals would be inputs/ouptpus of the node. Locals of the
|
|
414 |
node are not visible. *)
|
|
415 |
let spec =
|
|
416 |
match nd.node_spec with
|
|
417 |
| None -> None
|
|
418 |
| Some spec -> translate_spec inout_vars spec
|
325 |
419 |
in
|
326 |
420 |
|
327 |
|
assert (VSet.is_empty m0);
|
328 |
|
assert (init0 = []);
|
329 |
|
assert (Utils.IMap.is_empty j0);
|
330 |
421 |
|
331 |
|
let m, init, j, locals, s as context_with_asserts =
|
332 |
|
translate_eqs
|
333 |
|
vars
|
334 |
|
(m0, init0, j0, locals0, [])
|
335 |
|
(assert_instrs@sorted_eqs)
|
336 |
|
in
|
337 |
|
let mmap = Utils.IMap.fold (fun i n res -> (i, n)::res) j [] in
|
|
422 |
inout_vars spec =
|
|
423 |
let locals = VSet.of_list spec.locals in
|
|
424 |
let spec_consts = VSet.of_list spec.consts in
|
|
425 |
let other_spec_vars = VSet.union inout_vars spec_consts in
|
|
426 |
let spec_env = build_env spec_locals other_spec_vars in
|
|
427 |
*)
|
|
428 |
let mmap = Utils.IMap.elements ctx.j in
|
338 |
429 |
{
|
339 |
430 |
mname = nd;
|
340 |
|
mmemory = VSet.elements m;
|
|
431 |
mmemory = VSet.elements ctx.m;
|
341 |
432 |
mcalls = mmap;
|
342 |
433 |
minstances = List.filter (fun (_, (n,_)) -> not (Stateless.check_node n)) mmap;
|
343 |
|
minit = init;
|
344 |
|
mconst = s0;
|
|
434 |
minit = ctx.si;
|
|
435 |
mconst = ctx0_s;
|
345 |
436 |
mstatic = List.filter (fun v -> v.var_dec_const) nd.node_inputs;
|
346 |
437 |
mstep = {
|
347 |
|
step_inputs = nd.node_inputs;
|
348 |
|
step_outputs = nd.node_outputs;
|
349 |
|
step_locals = VSet.elements (VSet.diff locals m);
|
350 |
|
step_checks = List.map (fun d -> d.Dimension.dim_loc,
|
351 |
|
translate_expr vars init_args
|
352 |
|
(expr_of_dimension d))
|
353 |
|
nd.node_checks;
|
354 |
|
step_instrs = (
|
355 |
|
(* special treatment depending on the active backend. For horn backend,
|
|
438 |
step_inputs = nd.node_inputs;
|
|
439 |
step_outputs = nd.node_outputs;
|
|
440 |
step_locals = (* Removing computed memories from locals *)
|
|
441 |
VSet.elements (VSet.diff locals ctx.m);
|
|
442 |
step_checks = List.map (fun d -> d.Dimension.dim_loc,
|
|
443 |
translate_expr env
|
|
444 |
(expr_of_dimension d))
|
|
445 |
nd.node_checks;
|
|
446 |
step_instrs = (
|
|
447 |
(* special treatment depending on the active backend. For horn backend,
|
356 |
448 |
common branches are not merged while they are in C or Java
|
357 |
449 |
backends. *)
|
358 |
|
(*match !Options.output with
|
359 |
|
| "horn" -> s
|
360 |
|
| "C" | "java" | _ ->*)
|
361 |
|
if !Backends.join_guards then
|
362 |
|
join_guards_list s
|
363 |
|
else
|
364 |
|
s
|
365 |
|
);
|
366 |
|
step_asserts = List.map (translate_expr vars context_with_asserts) nd_node_asserts;
|
367 |
|
};
|
|
450 |
if !Backends.join_guards then
|
|
451 |
join_guards_list ctx.s
|
|
452 |
else
|
|
453 |
ctx.s
|
|
454 |
);
|
|
455 |
step_asserts = List.map (translate_expr env) nd_node_asserts;
|
|
456 |
};
|
368 |
457 |
mspec = nd.node_spec;
|
369 |
458 |
mannot = nd.node_annot;
|
370 |
459 |
msch = Some sch;
|
Major refreshing of machine generation