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_src.ml
37 37
  (********************************************************************************************)
38 38

  
39 39

  
40
  (* Computes the depth to which multi-dimension array assignments should be expanded.
41
     It equals the maximum number of nested static array constructions accessible from root [v].
42
  *)
43
  let rec expansion_depth v =
44
    match v.value_desc with
45
    | Cst cst -> expansion_depth_cst cst
46
    | Var _ -> 0
47
    | Fun (_, vl) -> List.fold_right (fun v -> max (expansion_depth v)) vl 0
48
    | Array vl    -> 1 + List.fold_right (fun v -> max (expansion_depth v)) vl 0
49
    | Access (v, _) -> max 0 (expansion_depth v - 1)
50
    | Power _  -> 0 (*1 + expansion_depth v*)
51
  and expansion_depth_cst c = 
52
    match c with
53
    | Const_array cl ->
54
      1 + List.fold_right (fun c -> max (expansion_depth_cst c)) cl 0
55
    | _ -> 0
56

  
57 40
  let rec merge_static_loop_profiles lp1 lp2 =
58 41
    match lp1, lp2 with
59 42
    | []      , _        -> lp2
......
82 65
        cl []
83 66
    | _ -> [] 
84 67

  
85
  let rec is_const_index v =
86
    match v.value_desc with
87
    | Cst (Const_int _) -> true
88
    | Fun (_, vl)       -> List.for_all is_const_index vl
89
    | _                 -> false
90

  
91
  type loop_index = LVar of ident | LInt of int ref | LAcc of value_t
92
(*
93
let rec value_offsets v offsets =
94
 match v, offsets with
95
 | _                        , []          -> v
96
 | Power (v, n)             , _ :: q      -> value_offsets v q
97
 | Array vl                 , LInt r :: q -> value_offsets (List.nth vl !r) q
98
 | Cst (Const_array cl)     , LInt r :: q -> value_offsets (Cst (List.nth cl !r)) q
99
 | Fun (f, vl)              , _           -> Fun (f, List.map (fun v -> value_offsets v offsets) vl)
100
 | _                        , LInt r :: q -> value_offsets (Access (v, Cst (Const_int !r))) q
101
 | _                        , LVar i :: q -> value_offsets (Access (v, Var i)) q
102
*)
103
  (* Computes the list of nested loop variables together with their dimension bounds.
104
     - LInt r stands for loop expansion (no loop variable, but int loop index)
105
     - LVar v stands for loop variable v
106
  *)
107
  let rec mk_loop_variables m ty depth =
108
    match (Types.repr ty).Types.tdesc, depth with
109
    | Types.Tarray (d, ty'), 0 ->
110
      let v = mk_loop_var m () in
111
      (d, LVar v) :: mk_loop_variables m ty' 0
112
    | Types.Tarray (d, ty'), _ ->
113
      let r = ref (-1) in
114
      (d, LInt r) :: mk_loop_variables m ty' (depth - 1)
115
    | _, 0 -> []
116
    | _ -> assert false
117

  
118
  let reorder_loop_variables loop_vars =
119
    let (int_loops, var_loops) =
120
      List.partition (function (_, LInt _) -> true | _ -> false) loop_vars
121
    in
122
    var_loops @ int_loops
123

  
124
  (* Prints a one loop variable suffix for arrays *)
125
  let pp_loop_var pp_val fmt lv =
126
    match snd lv with
127
    | LVar v -> fprintf fmt "[%s]" v
128
    | LInt r -> fprintf fmt "[%d]" !r
129
    | LAcc i -> fprintf fmt "[%a]" pp_val i
130

  
131
  (* Prints a suffix of loop variables for arrays *)
132
  let pp_suffix pp_val =
133
    pp_print_list ~pp_sep:pp_print_nothing (pp_loop_var pp_val)
134

  
135
  (* Prints a value expression [v], with internal function calls only.
136
     [pp_var] is a printer for variables (typically [pp_c_var_read]),
137
     but an offset suffix may be added for array variables
138
  *)
139
  (* Prints a constant value before a suffix (needs casting) *)
140
  let rec pp_c_const_suffix var_type fmt c =
141
    match c with
142
    | Const_int i ->
143
      pp_print_int fmt i
144
    | Const_real r ->
145
      Real.pp fmt r
146
    | Const_tag t ->
147
      pp_c_tag fmt t
148
    | Const_array ca ->
149
      let var_type = Types.array_element_type var_type in
150
      fprintf fmt "(%a[])%a"
151
        (pp_c_type "") var_type
152
        (pp_print_braced (pp_c_const_suffix var_type)) ca
153
    | Const_struct fl ->
154
      pp_print_braced
155
        (fun fmt (f, c) ->
156
           (pp_c_const_suffix (Types.struct_field_type var_type f)) fmt c)
157
        fmt fl
158
    | Const_string _
159
    | Const_modeid _ -> assert false (* string occurs in annotations not in C *)
160

  
161
  (* Prints a [value] of type [var_type] indexed by the suffix list [loop_vars] *)
162
  let rec pp_value_suffix m self var_type loop_vars pp_var fmt value =
163
    (*eprintf "pp_value_suffix: %a %a %a@." Types.print_ty var_type Machine_code.pp_val value pp_suffix loop_vars;*)
164
    let pp_suffix = pp_suffix (pp_value_suffix m self var_type [] pp_var) in
165
    match loop_vars, value.value_desc with
166
    | (x, LAcc i) :: q, _ when is_const_index i ->
167
      let r = ref (Dimension.size_const_dimension (dimension_of_value i)) in
168
      pp_value_suffix m self var_type ((x, LInt r)::q) pp_var fmt value
169
    | (_, LInt r) :: q, Cst (Const_array cl) ->
170
      let var_type = Types.array_element_type var_type in
171
      pp_value_suffix m self var_type q pp_var fmt
172
        (mk_val (Cst (List.nth cl !r)) Type_predef.type_int)
173
    | (_, LInt r) :: q, Array vl ->
174
      let var_type = Types.array_element_type var_type in
175
      pp_value_suffix m self var_type q pp_var fmt (List.nth vl !r)
176
    | loop_var :: q, Array vl      ->
177
      let var_type = Types.array_element_type var_type in
178
      fprintf fmt "(%a[])%a%a"
179
        (pp_c_type "") var_type
180
        (pp_print_braced (pp_value_suffix m self var_type q pp_var)) vl
181
        pp_suffix [loop_var]
182
    | [], Array vl      ->
183
      let var_type = Types.array_element_type var_type in
184
      fprintf fmt "(%a[])%a"
185
        (pp_c_type "") var_type
186
        (pp_print_braced (pp_value_suffix m self var_type [] pp_var)) vl
187
    | _ :: q, Power (v, _)  ->
188
      pp_value_suffix m self var_type q pp_var fmt v
189
    | _, Fun (n, vl)   ->
190
      pp_basic_lib_fun (Types.is_int_type value.value_type) n
191
        (pp_value_suffix m self var_type loop_vars pp_var) fmt vl
192
    | _, Access (v, i) ->
193
      let var_type = Type_predef.type_array (Dimension.mkdim_var ()) var_type in
194
      pp_value_suffix m self var_type
195
        ((Dimension.mkdim_var (), LAcc i) :: loop_vars) pp_var fmt v
196
    | _, Var v ->
197
      if is_memory m v then
198
        (* array memory vars are represented by an indirection to a local var with the right type,
199
           in order to avoid casting everywhere. *)
200
        if Types.is_array_type v.var_type
201
        then fprintf fmt "%a%a" pp_var v pp_suffix loop_vars
202
        else fprintf fmt "%s->_reg.%a%a" self pp_var v pp_suffix loop_vars
203
      else
204
        fprintf fmt "%a%a" pp_var v pp_suffix loop_vars
205
    | _, Cst cst ->
206
      pp_c_const_suffix var_type fmt cst
207
    | _, _ ->
208
      eprintf "internal error: C_backend_src.pp_value_suffix %a %a %a@."
209
        Types.print_ty var_type (pp_val m) value pp_suffix loop_vars;
210
      assert false
211 68

  
212 69
  (* Subsumes C_backend_common.pp_c_val to cope with aggressive substitution
213 70
     which may yield constant arrays in expressions.
......
393 250
    pp_machine_instr dependencies m self fmt instr
394 251

  
395 252
  let pp_machine_step_instr dependencies m self fmt i instr =
396
    fprintf fmt "%a%a%a"
253
    fprintf fmt "%a@,%a%a"
397 254
      (if i = 0 then
398
         (fun fmt () -> Mod.pp_step_instr_spec m self fmt (i-1, instr))
255
         (fun fmt () -> Mod.pp_step_instr_spec m self fmt (i, instr))
399 256
       else
400 257
         pp_print_nothing) ()
401 258
      (pp_machine_instr dependencies m self) instr
402
      (Mod.pp_step_instr_spec m self) (i, instr)
259
      (Mod.pp_step_instr_spec m self) (i+1, instr)
403 260

  
404 261
  (********************************************************************************************)
405 262
  (*                         C file Printing functions                                        *)

Also available in: Unified diff