Project

General

Profile

« Previous | Next » 

Revision 1147e80a

Added by Pierre-Loïc Garoche almost 5 years ago

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

View differences:

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