Project

General

Profile

« Previous | Next » 

Revision 4b596770

Added by Lélio Brun about 4 years ago

first draft: to be tested with frama-c

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
module Mpfr = Lustrec_mpfr
18 18

  
19 19
let pp_print_version fmt () =
......
447 447
  | None -> false
448 448
  | Some nd -> (match nd.nodei_prototype with Some "C" -> true | _ -> false)
449 449

  
450
(* Computes the depth to which multi-dimension array assignments should be expanded.
451
   It equals the maximum number of nested static array constructions accessible from root [v].
452
*)
453
let rec expansion_depth v =
454
  match v.value_desc with
455
  | Cst cst -> expansion_depth_cst cst
456
  | Var _ -> 0
457
  | Fun (_, vl) -> List.fold_right (fun v -> max (expansion_depth v)) vl 0
458
  | Array vl    -> 1 + List.fold_right (fun v -> max (expansion_depth v)) vl 0
459
  | Access (v, _) -> max 0 (expansion_depth v - 1)
460
  | Power _  -> 0 (*1 + expansion_depth v*)
461
and expansion_depth_cst c =
462
  match c with
463
  | Const_array cl ->
464
    1 + List.fold_right (fun c -> max (expansion_depth_cst c)) cl 0
465
  | _ -> 0
466

  
467
type loop_index = LVar of ident | LInt of int ref | LAcc of value_t
468
(*
469
let rec value_offsets v offsets =
470
 match v, offsets with
471
 | _                        , []          -> v
472
 | Power (v, n)             , _ :: q      -> value_offsets v q
473
 | Array vl                 , LInt r :: q -> value_offsets (List.nth vl !r) q
474
 | Cst (Const_array cl)     , LInt r :: q -> value_offsets (Cst (List.nth cl !r)) q
475
 | Fun (f, vl)              , _           -> Fun (f, List.map (fun v -> value_offsets v offsets) vl)
476
 | _                        , LInt r :: q -> value_offsets (Access (v, Cst (Const_int !r))) q
477
 | _                        , LVar i :: q -> value_offsets (Access (v, Var i)) q
478
*)
479
(* Computes the list of nested loop variables together with their dimension bounds.
480
   - LInt r stands for loop expansion (no loop variable, but int loop index)
481
   - LVar v stands for loop variable v
482
*)
483
let rec mk_loop_variables m ty depth =
484
  match (Types.repr ty).Types.tdesc, depth with
485
  | Types.Tarray (d, ty'), 0 ->
486
    let v = mk_loop_var m () in
487
    (d, LVar v) :: mk_loop_variables m ty' 0
488
  | Types.Tarray (d, ty'), _ ->
489
    let r = ref (-1) in
490
    (d, LInt r) :: mk_loop_variables m ty' (depth - 1)
491
  | _, 0 -> []
492
  | _ -> assert false
493

  
494
let reorder_loop_variables loop_vars =
495
  let (int_loops, var_loops) =
496
    List.partition (function (_, LInt _) -> true | _ -> false) loop_vars
497
  in
498
  var_loops @ int_loops
499

  
500
(* Prints a one loop variable suffix for arrays *)
501
let pp_loop_var pp_val fmt lv =
502
  match snd lv with
503
  | LVar v -> fprintf fmt "[%s]" v
504
  | LInt r -> fprintf fmt "[%d]" !r
505
  | LAcc i -> fprintf fmt "[%a]" pp_val i
506

  
507
(* Prints a suffix of loop variables for arrays *)
508
let pp_suffix pp_val =
509
  pp_print_list ~pp_sep:pp_print_nothing (pp_loop_var pp_val)
510

  
511
let rec is_const_index v =
512
  match v.value_desc with
513
  | Cst (Const_int _) -> true
514
  | Fun (_, vl)       -> List.for_all is_const_index vl
515
  | _                 -> false
516

  
517
(* Prints a value expression [v], with internal function calls only.
518
   [pp_var] is a printer for variables (typically [pp_c_var_read]),
519
   but an offset suffix may be added for array variables
520
*)
521
(* Prints a constant value before a suffix (needs casting) *)
522
let rec pp_c_const_suffix var_type fmt c =
523
  match c with
524
  | Const_int i ->
525
    pp_print_int fmt i
526
  | Const_real r ->
527
    Real.pp fmt r
528
  | Const_tag t ->
529
    pp_c_tag fmt t
530
  | Const_array ca ->
531
    let var_type = Types.array_element_type var_type in
532
    fprintf fmt "(%a[])%a"
533
      (pp_c_type "") var_type
534
      (pp_print_braced (pp_c_const_suffix var_type)) ca
535
  | Const_struct fl ->
536
    pp_print_braced
537
      (fun fmt (f, c) ->
538
         (pp_c_const_suffix (Types.struct_field_type var_type f)) fmt c)
539
      fmt fl
540
  | Const_string _
541
  | Const_modeid _ -> assert false (* string occurs in annotations not in C *)
542

  
543
(* Prints a [value] of type [var_type] indexed by the suffix list [loop_vars] *)
544
let rec pp_value_suffix ?(indirect=true) m self var_type loop_vars pp_var fmt value =
545
  (*eprintf "pp_value_suffix: %a %a %a@." Types.print_ty var_type Machine_code.pp_val value pp_suffix loop_vars;*)
546
  let pp_suffix = pp_suffix (pp_value_suffix ~indirect m self var_type [] pp_var) in
547
  match loop_vars, value.value_desc with
548
  | (x, LAcc i) :: q, _ when is_const_index i ->
549
    let r = ref (Dimension.size_const_dimension (dimension_of_value i)) in
550
    pp_value_suffix ~indirect m self var_type ((x, LInt r)::q) pp_var fmt value
551
  | (_, LInt r) :: q, Cst (Const_array cl) ->
552
    let var_type = Types.array_element_type var_type in
553
    pp_value_suffix ~indirect m self var_type q pp_var fmt
554
      (mk_val (Cst (List.nth cl !r)) Type_predef.type_int)
555
  | (_, LInt r) :: q, Array vl ->
556
    let var_type = Types.array_element_type var_type in
557
    pp_value_suffix ~indirect m self var_type q pp_var fmt (List.nth vl !r)
558
  | loop_var :: q, Array vl      ->
559
    let var_type = Types.array_element_type var_type in
560
    fprintf fmt "(%a[])%a%a"
561
      (pp_c_type "") var_type
562
      (pp_print_braced (pp_value_suffix ~indirect m self var_type q pp_var)) vl
563
      pp_suffix [loop_var]
564
  | [], Array vl      ->
565
    let var_type = Types.array_element_type var_type in
566
    fprintf fmt "(%a[])%a"
567
      (pp_c_type "") var_type
568
      (pp_print_braced (pp_value_suffix ~indirect m self var_type [] pp_var)) vl
569
  | _ :: q, Power (v, _)  ->
570
    pp_value_suffix ~indirect m self var_type q pp_var fmt v
571
  | _, Fun (n, vl)   ->
572
    pp_basic_lib_fun (Types.is_int_type value.value_type) n
573
      (pp_value_suffix ~indirect m self var_type loop_vars pp_var) fmt vl
574
  | _, Access (v, i) ->
575
    let var_type = Type_predef.type_array (Dimension.mkdim_var ()) var_type in
576
    pp_value_suffix m self var_type
577
      ((Dimension.mkdim_var (), LAcc i) :: loop_vars) pp_var fmt v
578
  | _, Var v ->
579
    if is_memory m v then
580
      (* array memory vars are represented by an indirection to a local var with the right type,
581
         in order to avoid casting everywhere. *)
582
      if Types.is_array_type v.var_type
583
      then fprintf fmt "%a%a" pp_var v pp_suffix loop_vars
584
      else fprintf fmt "%s%s_reg.%a%a"
585
          self (if indirect then "->" else ".") pp_var v pp_suffix loop_vars
586
    else
587
      fprintf fmt "%a%a" pp_var v pp_suffix loop_vars
588
  | _, Cst cst ->
589
    pp_c_const_suffix var_type fmt cst
590
  | _, _ ->
591
    eprintf "internal error: C_backend_src.pp_value_suffix %a %a %a@."
592
      Types.print_ty var_type (pp_val m) value pp_suffix loop_vars;
593
    assert false
594

  
450 595
(********************************************************************************************)
451 596
(*                       Struct Printing functions                                          *)
452 597
(********************************************************************************************)

Also available in: Unified diff