Revision 1147e80a
Added by Pierre-Loïc Garoche almost 5 years ago
src/backends/C/c_backend_common.ml | ||
---|---|---|
13 | 13 |
open Lustre_types |
14 | 14 |
open Corelang |
15 | 15 |
open Machine_code_types |
16 |
open Machine_code_common
|
|
16 |
(*open Machine_code_common*)
|
|
17 | 17 |
|
18 | 18 |
|
19 | 19 |
let print_version fmt = |
... | ... | |
244 | 244 |
| Cst c -> pp_c_const fmt c |
245 | 245 |
| Array vl -> fprintf fmt "{%a}" (Utils.fprintf_list ~sep:", " pp_c_val) vl |
246 | 246 |
| Access (t, i) -> fprintf fmt "%a[%a]" pp_c_val t pp_c_val i |
247 |
| Power (v, n) -> (Format.eprintf "internal error: C_backend_common.pp_c_val %a@." (pp_val m) v; assert false) |
|
247 |
| Power (v, n) -> (Format.eprintf "internal error: C_backend_common.pp_c_val %a@." (Machine_code_common.pp_val m) v; assert false)
|
|
248 | 248 |
| Var v -> |
249 |
if is_memory m v then ( |
|
249 |
if Machine_code_common.is_memory m v then (
|
|
250 | 250 |
(* array memory vars are represented by an indirection to a local var with the right type, |
251 | 251 |
in order to avoid casting everywhere. *) |
252 | 252 |
if Types.is_array_type v.var_type && not (Types.is_real_type v.var_type && !Options.mpfr) |
... | ... | |
267 | 267 |
(* mpfr_t is a static array, not treated as general arrays *) |
268 | 268 |
if Types.is_address_type id.var_type |
269 | 269 |
then |
270 |
if is_memory m id && not (Types.is_real_type id.var_type && !Options.mpfr) |
|
270 |
if Machine_code_common.is_memory m id && not (Types.is_real_type id.var_type && !Options.mpfr)
|
|
271 | 271 |
then fprintf fmt "(*%s)" id.var_id |
272 | 272 |
else fprintf fmt "%s" id.var_id |
273 | 273 |
else |
274 |
if is_output m id |
|
274 |
if Machine_code_common.is_output m id
|
|
275 | 275 |
then fprintf fmt "*%s" id.var_id |
276 | 276 |
else fprintf fmt "%s" id.var_id |
277 | 277 |
|
... | ... | |
285 | 285 |
then |
286 | 286 |
fprintf fmt "%s" id.var_id |
287 | 287 |
else |
288 |
if is_output m id |
|
288 |
if Machine_code_common.is_output m id
|
|
289 | 289 |
then |
290 | 290 |
fprintf fmt "%s" id.var_id |
291 | 291 |
else |
... | ... | |
322 | 322 |
then |
323 | 323 |
Format.fprintf fmt "%a = %a" |
324 | 324 |
(pp_c_type ~var_opt:(Some id) id.var_id) id.var_type |
325 |
(pp_c_val m "" (pp_c_var_read m)) (get_const_assign m id) |
|
325 |
(pp_c_val m "" (pp_c_var_read m)) (Machine_code_common.get_const_assign m id)
|
|
326 | 326 |
else |
327 | 327 |
Format.fprintf fmt "%a" |
328 | 328 |
(pp_c_type ~var_opt:(Some id) id.var_id) id.var_type |
... | ... | |
370 | 370 |
() |
371 | 371 |
|
372 | 372 |
let print_machine_struct machines fmt m = |
373 |
if fst (get_stateless_status m) then |
|
373 |
if fst (Machine_code_common.get_stateless_status m) then
|
|
374 | 374 |
begin |
375 | 375 |
end |
376 | 376 |
else |
... | ... | |
512 | 512 |
fprintf fmt "&%s" id.var_id |
513 | 513 |
|
514 | 514 |
let pp_main_call mname self fmt m (inputs: value_t list) (outputs: var_decl list) = |
515 |
if fst (get_stateless_status m) |
|
515 |
if fst (Machine_code_common.get_stateless_status m)
|
|
516 | 516 |
then |
517 | 517 |
fprintf fmt "%a (%a%t%a);" |
518 | 518 |
pp_machine_step_name mname |
... | ... | |
529 | 529 |
self |
530 | 530 |
|
531 | 531 |
let pp_c_var m self pp_var fmt var = |
532 |
pp_c_val m self pp_var fmt (mk_val (Var var) var.var_type) |
|
532 |
pp_c_val m self pp_var fmt (Machine_code_common.mk_val (Var var) var.var_type)
|
|
533 | 533 |
|
534 | 534 |
|
535 | 535 |
let pp_array_suffix fmt loop_vars = |
... | ... | |
561 | 561 |
end |
562 | 562 |
|
563 | 563 |
let pp_const_initialize m pp_var fmt const = |
564 |
let var = mk_val (Var (Corelang.var_decl_of_const const)) const.const_type in |
|
564 |
let var = Machine_code_common.mk_val (Var (Corelang.var_decl_of_const const)) const.const_type in
|
|
565 | 565 |
let rec aux indices value fmt typ = |
566 | 566 |
if Types.is_array_type typ |
567 | 567 |
then |
... | ... | |
616 | 616 |
end |
617 | 617 |
|
618 | 618 |
let pp_const_clear pp_var fmt const = |
619 |
let m = empty_machine in |
|
619 |
let m = Machine_code_common.empty_machine in
|
|
620 | 620 |
let var = Corelang.var_decl_of_const const in |
621 | 621 |
let rec aux indices fmt typ = |
622 | 622 |
if Types.is_array_type typ |
src/backends/C/c_backend_src.ml | ||
---|---|---|
112 | 112 |
var_loops @ int_loops |
113 | 113 |
|
114 | 114 |
(* Prints a one loop variable suffix for arrays *) |
115 |
let pp_loop_var m fmt lv = |
|
115 |
let pp_loop_var m pp_val fmt lv =
|
|
116 | 116 |
match snd lv with |
117 | 117 |
| LVar v -> fprintf fmt "[%s]" v |
118 | 118 |
| LInt r -> fprintf fmt "[%d]" !r |
119 |
| LAcc i -> fprintf fmt "[%a]" (pp_val m) i
|
|
119 |
| LAcc i -> fprintf fmt "[%a]" pp_val i
|
|
120 | 120 |
|
121 | 121 |
(* Prints a suffix of loop variables for arrays *) |
122 |
let pp_suffix m fmt loop_vars = |
|
123 |
Utils.fprintf_list ~sep:"" (pp_loop_var m) fmt loop_vars |
|
122 |
let pp_suffix m pp_val fmt loop_vars =
|
|
123 |
Utils.fprintf_list ~sep:"" (pp_loop_var m pp_val) fmt loop_vars
|
|
124 | 124 |
|
125 | 125 |
(* Prints a value expression [v], with internal function calls only. |
126 | 126 |
[pp_var] is a printer for variables (typically [pp_c_var_read]), |
... | ... | |
140 | 140 |
|
141 | 141 |
|
142 | 142 |
(* Prints a [value] of type [var_type] indexed by the suffix list [loop_vars] *) |
143 |
let rec pp_value_suffix m self var_type loop_vars pp_value fmt value =
|
|
143 |
let rec pp_value_suffix m self var_type loop_vars pp_var fmt value =
|
|
144 | 144 |
(*Format.eprintf "pp_value_suffix: %a %a %a@." Types.print_ty var_type Machine_code.pp_val value pp_suffix loop_vars;*) |
145 |
let pp_suffix = pp_suffix m in |
|
145 |
let pp_suffix = pp_suffix m (pp_value_suffix m self var_type [] pp_var) in
|
|
146 | 146 |
( |
147 | 147 |
match loop_vars, value.value_desc with |
148 | 148 |
| (x, LAcc i) :: q, _ when is_const_index i -> |
149 | 149 |
let r = ref (Dimension.size_const_dimension (dimension_of_value i)) in |
150 |
pp_value_suffix m self var_type ((x, LInt r)::q) pp_value fmt value
|
|
150 |
pp_value_suffix m self var_type ((x, LInt r)::q) pp_var fmt value
|
|
151 | 151 |
| (_, LInt r) :: q, Cst (Const_array cl) -> |
152 | 152 |
let var_type = Types.array_element_type var_type in |
153 |
pp_value_suffix m self var_type q pp_value fmt (mk_val (Cst (List.nth cl !r)) Type_predef.type_int)
|
|
153 |
pp_value_suffix m self var_type q pp_var fmt (mk_val (Cst (List.nth cl !r)) Type_predef.type_int)
|
|
154 | 154 |
| (_, LInt r) :: q, Array vl -> |
155 | 155 |
let var_type = Types.array_element_type var_type in |
156 |
pp_value_suffix m self var_type q pp_value fmt (List.nth vl !r)
|
|
156 |
pp_value_suffix m self var_type q pp_var fmt (List.nth vl !r)
|
|
157 | 157 |
| loop_var :: q, Array vl -> |
158 | 158 |
let var_type = Types.array_element_type var_type in |
159 |
Format.fprintf fmt "(%a[]){%a }%a" (pp_c_type "") var_type (Utils.fprintf_list ~sep:", " (pp_value_suffix m self var_type q pp_value)) vl pp_suffix [loop_var]
|
|
159 |
Format.fprintf fmt "(%a[]){%a }%a" (pp_c_type "") var_type (Utils.fprintf_list ~sep:", " (pp_value_suffix m self var_type q pp_var)) vl pp_suffix [loop_var]
|
|
160 | 160 |
| [] , Array vl -> |
161 | 161 |
let var_type = Types.array_element_type var_type in |
162 |
Format.fprintf fmt "(%a[]){%a }" (pp_c_type "") var_type (Utils.fprintf_list ~sep:", " (pp_value_suffix m self var_type [] pp_value)) vl
|
|
162 |
Format.fprintf fmt "(%a[]){%a }" (pp_c_type "") var_type (Utils.fprintf_list ~sep:", " (pp_value_suffix m self var_type [] pp_var)) vl
|
|
163 | 163 |
| _ :: q, Power (v, n) -> |
164 |
pp_value_suffix m self var_type q pp_value fmt v
|
|
164 |
pp_value_suffix m self var_type q pp_var fmt v
|
|
165 | 165 |
| _ , Fun (n, vl) -> |
166 |
pp_basic_lib_fun (Types.is_int_type value.value_type) n (pp_value_suffix m self var_type loop_vars pp_value) fmt vl
|
|
166 |
pp_basic_lib_fun (Types.is_int_type value.value_type) n (pp_value_suffix m self var_type loop_vars pp_var) fmt vl
|
|
167 | 167 |
| _ , Access (v, i) -> |
168 | 168 |
let var_type = Type_predef.type_array (Dimension.mkdim_var ()) var_type in |
169 |
pp_value_suffix m self var_type ((Dimension.mkdim_var (), LAcc i) :: loop_vars) pp_value fmt v
|
|
169 |
pp_value_suffix m self var_type ((Dimension.mkdim_var (), LAcc i) :: loop_vars) pp_var fmt v
|
|
170 | 170 |
| _ , Var v -> |
171 | 171 |
if is_memory m v then ( |
172 | 172 |
(* array memory vars are represented by an indirection to a local var with the right type, |
173 | 173 |
in order to avoid casting everywhere. *) |
174 | 174 |
if Types.is_array_type v.var_type |
175 |
then Format.fprintf fmt "%a%a" pp_value v pp_suffix loop_vars
|
|
176 |
else Format.fprintf fmt "%s->_reg.%a%a" self pp_value v pp_suffix loop_vars
|
|
175 |
then Format.fprintf fmt "%a%a" pp_var v pp_suffix loop_vars
|
|
176 |
else Format.fprintf fmt "%s->_reg.%a%a" self pp_var v pp_suffix loop_vars
|
|
177 | 177 |
) |
178 | 178 |
else ( |
179 |
Format.fprintf fmt "%a%a" pp_value v pp_suffix loop_vars
|
|
179 |
Format.fprintf fmt "%a%a" pp_var v pp_suffix loop_vars
|
|
180 | 180 |
) |
181 | 181 |
| _ , Cst cst -> pp_c_const_suffix var_type fmt cst |
182 | 182 |
| _ , _ -> (Format.eprintf "internal error: C_backend_src.pp_value_suffix %a %a %a@." Types.print_ty var_type (pp_val m) value pp_suffix loop_vars; assert false) |
src/compiler_common.ml | ||
---|---|---|
237 | 237 |
let stmts = in_assigns :: out_assigns :: imp_nd.node_stmts @ stmts in |
238 | 238 |
let c = merge_contracts c imp_c in |
239 | 239 |
stmts, locals, c |
240 |
with Not_found -> Format.eprintf "Where is contract %s@.@?" name; assert false; raise (Error (loc, (Error.Unbound_symbol ("contract " ^ name))))
|
|
240 |
with Not_found -> Format.eprintf "Where is contract %s@.@?" name; raise (Error (loc, (Error.Unbound_symbol ("contract " ^ name)))) |
|
241 | 241 |
|
242 | 242 |
|
243 | 243 |
) ([], c.consts@c.locals, c) c.imports |
src/corelang.ml | ||
---|---|---|
533 | 533 |
(* Conversion from dimension expr to standard expr, for the purpose of printing, typing, etc... *) |
534 | 534 |
let rec expr_of_dimension dim = |
535 | 535 |
let open Dimension in |
536 |
let expr = |
|
536 | 537 |
match dim.dim_desc with |
537 | 538 |
| Dbool b -> |
538 | 539 |
mkexpr dim.dim_loc (Expr_const (const_of_bool b)) |
... | ... | |
548 | 549 |
| Dvar |
549 | 550 |
| Dunivar -> (Format.eprintf "internal error: Corelang.expr_of_dimension %a@." Dimension.pp_dimension dim; |
550 | 551 |
assert false) |
551 |
|
|
552 |
in |
|
553 |
{ expr |
|
554 |
with |
|
555 |
expr_type = Types.new_ty Types.type_int; |
|
556 |
} |
|
557 |
|
|
552 | 558 |
let dimension_of_const loc const = |
553 | 559 |
let open Dimension in |
554 | 560 |
match const with |
src/machine_code.ml | ||
---|---|---|
77 | 77 |
let typ = (typedef_of_top (Hashtbl.find Corelang.tag_table id)).tydef_id in |
78 | 78 |
mk_val (Cst (Const_tag id)) (Type_predef.type_const typ) |
79 | 79 |
with Not_found -> (Format.eprintf |
80 |
"internal error: Machine_code.translate_ident %s" |
|
80 |
"internal error: Machine_code.translate_ident %s@.@?"
|
|
81 | 81 |
id; |
82 | 82 |
assert false) |
83 | 83 |
|
src/normalization.ml | ||
---|---|---|
112 | 112 |
expr_tag = Utils.new_tag (); |
113 | 113 |
expr_desc = Expr_tuple (List.map expr_of_vdecl locals) } |
114 | 114 |
|
115 |
let unfold_offsets e offsets = |
|
116 |
let add_offset e d = |
|
117 |
(*Format.eprintf "add_offset %a(%a) %a @." Printers.pp_expr e Types.print_ty e.expr_type Dimension.pp_dimension d; |
|
118 |
let res = *) |
|
119 |
{ e with |
|
120 |
expr_tag = Utils.new_tag (); |
|
121 |
expr_loc = d.Dimension.dim_loc; |
|
122 |
expr_type = Types.array_element_type e.expr_type; |
|
123 |
expr_desc = Expr_access (e, d) } |
|
124 |
(*in (Format.eprintf "= %a @." Printers.pp_expr res; res) *) |
|
125 |
in |
|
126 |
List.fold_left add_offset e offsets |
|
127 |
|
|
115 |
|
|
128 | 116 |
(* IS IT USED ? TODO |
129 | 117 |
(* Create an alias for [expr], if none exists yet *) |
130 | 118 |
let mk_expr_alias (parentid, vars) (defs, vars) expr = |
... | ... | |
147 | 135 |
*) |
148 | 136 |
|
149 | 137 |
(* Create an alias for [expr], if [expr] is not already an alias (i.e. an ident) |
150 |
and [opt] is true *) |
|
138 |
and [opt] is true |
|
139 |
|
|
140 |
|
|
141 |
*) |
|
151 | 142 |
let mk_expr_alias_opt opt norm_ctx (defs, vars) expr = |
152 | 143 |
if !debug then |
153 | 144 |
Log.report ~plugin:"normalization" ~level:2 |
... | ... | |
189 | 180 |
else |
190 | 181 |
(defs, vars), expr |
191 | 182 |
|
183 |
(* Similar fonctions for dimensions *) |
|
184 |
let mk_dim_alias opt norm_ctx (defs, vars) dim = |
|
185 |
match dim.Dimension.dim_desc with |
|
186 |
| Dimension.Dbool _ | Dint _ |
|
187 |
| Dident _ -> (defs, vars), dim (* Keep the same *) |
|
188 |
| _ when opt -> (* Cast to expression, normalizing *) |
|
189 |
let e = expr_of_dimension dim in |
|
190 |
let defvars, e = mk_expr_alias_opt true norm_ctx (defs, vars) e in |
|
191 |
defvars, dimension_of_expr e |
|
192 |
|
|
193 |
| _ -> (defs, vars), dim (* Keep the same *) |
|
194 |
|
|
195 |
|
|
196 |
let unfold_offsets norm_ctx defvars e offsets = |
|
197 |
let add_offset (defvars, e) d = |
|
198 |
(*Format.eprintf "add_offset %a(%a) %a @." Printers.pp_expr e Types.print_ty e.expr_type Dimension.pp_dimension d; *) |
|
199 |
let defvars, d = mk_dim_alias !params.force_alias_internal_fun norm_ctx defvars d in |
|
200 |
let new_e = |
|
201 |
{ e with |
|
202 |
expr_tag = Utils.new_tag (); |
|
203 |
expr_loc = d.Dimension.dim_loc; |
|
204 |
expr_type = Types.array_element_type e.expr_type; |
|
205 |
expr_desc = Expr_access (e, d) } |
|
206 |
in |
|
207 |
defvars, new_e |
|
208 |
(*in (Format.eprintf "= %a @." Printers.pp_expr res; res) *) |
|
209 |
in |
|
210 |
List.fold_left add_offset (defvars, e) offsets |
|
211 |
|
|
212 |
|
|
192 | 213 |
(* Create a (normalized) expression from [ref_e], |
193 | 214 |
replacing description with [norm_d], |
194 | 215 |
taking propagated [offsets] into account |
... | ... | |
210 | 231 |
) elist (defvars, []) |
211 | 232 |
|
212 | 233 |
let rec normalize_expr ?(alias=true) ?(alias_basic=false) norm_ctx offsets defvars expr = |
213 |
(*Format.eprintf "normalize %B %a:%a [%a]@." alias Printers.pp_expr expr Types.print_ty expr.expr_type (Utils.fprintf_list ~sep:"," Dimension.pp_dimension) offsets;*)
|
|
234 |
(* Format.eprintf "normalize %B %a:%a [%a]@." alias Printers.pp_expr expr Types.print_ty expr.expr_type (Utils.fprintf_list ~sep:"," Dimension.pp_dimension) offsets; *)
|
|
214 | 235 |
match expr.expr_desc with |
215 | 236 |
| Expr_const _ |
216 |
| Expr_ident _ -> defvars, unfold_offsets expr offsets |
|
237 |
| Expr_ident _ -> |
|
238 |
unfold_offsets norm_ctx defvars expr offsets |
|
217 | 239 |
| Expr_array elist -> |
218 | 240 |
let defvars, norm_elist = normalize_list alias norm_ctx offsets (fun _ -> normalize_array_expr ~alias:true) defvars elist in |
219 | 241 |
let norm_expr = mk_norm_expr offsets expr (Expr_array norm_elist) in |
... | ... | |
225 | 247 |
| Expr_power (e1, d) -> |
226 | 248 |
normalize_expr ~alias:alias norm_ctx (List.tl offsets) defvars e1 |
227 | 249 |
| Expr_access (e1, d) -> |
228 |
normalize_expr ~alias:alias norm_ctx (d::offsets) defvars e1 |
|
250 |
normalize_expr ~alias:alias norm_ctx (d::offsets) defvars e1 |
|
251 |
|
|
229 | 252 |
| Expr_tuple elist -> |
230 | 253 |
let defvars, norm_elist = |
231 | 254 |
normalize_list alias norm_ctx offsets (fun alias -> normalize_expr ~alias:alias ~alias_basic:false) defvars elist in |
232 | 255 |
defvars, mk_norm_expr offsets expr (Expr_tuple norm_elist) |
233 | 256 |
| Expr_appl (id, args, None) |
234 | 257 |
when Basic_library.is_homomorphic_fun id |
235 |
&& Types.is_array_type expr.expr_type -> |
|
258 |
&& Types.is_array_type expr.expr_type ->
|
|
236 | 259 |
let defvars, norm_args = |
237 | 260 |
normalize_list |
238 | 261 |
alias |
... | ... | |
330 | 353 |
| _ -> normalize_expr ~alias:alias norm_ctx offsets defvars expr |
331 | 354 |
|
332 | 355 |
and normalize_cond_expr ?(alias=true) norm_ctx offsets defvars expr = |
333 |
(*Format.eprintf "normalize_cond %B %a [%a]@." alias Printers.pp_expr expr (Utils.fprintf_list ~sep:"," Dimension.pp_dimension) offsets;*)
|
|
356 |
(* Format.eprintf "normalize_cond %B %a [%a]@." alias Printers.pp_expr expr (Utils.fprintf_list ~sep:"," Dimension.pp_dimension) offsets; *)
|
|
334 | 357 |
match expr.expr_desc with |
335 | 358 |
| Expr_access (e1, d) -> |
336 | 359 |
normalize_cond_expr ~alias:alias norm_ctx (d::offsets) defvars e1 |
Also available in: Unified diff
Array access: solved issues in C backend when basic operations in array access dimensions. Also better handling in EMF, ie further normalization through new equations