Project

General

Profile

Download (6.17 KB) Statistics
| Branch: | Tag: | Revision:
1
open Format
2
open Utils
3
open Compiler_common
4
open LustreSpec
5

    
6
exception StopPhase1 of program
7

    
8
let dynamic_checks () =
9
  match !Options.output, !Options.spec with
10
  | "C", "C" -> true
11
  | _ -> false
12
     
13

    
14
(* check whether a source file has a compiled header, if not, generate the
15
   compiled header *)
16
let compile_source_to_header prog computed_types_env computed_clocks_env dirname basename extension =
17
  let destname = !Options.dest_dir ^ "/" ^ basename in
18
  let lusic_ext = extension ^ "c" in
19
  let header_name = destname ^ lusic_ext in
20
  begin
21
    if not (Sys.file_exists header_name) then
22
      begin
23
	Log.report ~level:1 (fun fmt -> fprintf fmt ".. generating compiled header file %s@," header_name);
24
	Lusic.write_lusic false (Lusic.extract_header dirname basename prog) destname lusic_ext;
25
	Lusic.print_lusic_to_h destname lusic_ext
26
      end
27
    else
28
      let lusic = Lusic.read_lusic destname lusic_ext in
29
      if not lusic.Lusic.from_lusi then
30
	begin
31
	  Log.report ~level:1 (fun fmt -> fprintf fmt ".. generating compiled header file %s@," header_name);
32
       	  Lusic.write_lusic false (Lusic.extract_header dirname basename prog) destname lusic_ext;
33
	  (*List.iter (fun top_decl -> Format.eprintf "lusic: %a@." Printers.pp_decl top_decl) lusic.Lusic.contents;*)
34
	  Lusic.print_lusic_to_h destname lusic_ext
35
	end
36
      else
37
	begin
38
	  Log.report ~level:1 (fun fmt -> fprintf fmt ".. loading compiled header file %s@," header_name);
39
	  Modules.check_dependency lusic destname;
40
	  let header = lusic.Lusic.contents in
41
	  let (declared_types_env, declared_clocks_env) = get_envs_from_top_decls header in
42
	  check_compatibility
43
	    (prog, computed_types_env, computed_clocks_env)
44
	    (header, declared_types_env, declared_clocks_env)
45
	end
46
  end
47

    
48

    
49
(* From prog to prog *)
50
let stage1 prog dirname basename =
51
  (* Removing automata *)
52
  let prog = expand_automata prog in
53
  Log.report ~level:4 (fun fmt -> fprintf fmt ".. after automata expansion:@,  @[<v 2>@,%a@]@ " Printers.pp_prog prog);
54

    
55
  (* Importing source *)
56
  let _ = Modules.load_program ISet.empty prog in
57

    
58
  (* Extracting dependencies *)
59
  let dependencies, type_env, clock_env = import_dependencies prog in
60

    
61
  (* Sorting nodes *)
62
  let prog = SortProg.sort prog in
63

    
64
  (* Perform inlining before any analysis *)
65
  let orig, prog =
66
    if !Options.global_inline && !Options.main_node <> "" then
67
      (if !Options.witnesses then prog else []),
68
      Inliner.global_inline basename prog type_env clock_env
69
    else (* if !Option.has_local_inline *)
70
      [],
71
      Inliner.local_inline prog (* type_env clock_env *)
72
  in
73

    
74
  (* Checking stateless/stateful status *)
75
  if Plugins.check_force_stateful () then
76
    force_stateful_decls prog
77
  else
78
    check_stateless_decls prog;
79

    
80
  (* Typing *)
81
  let computed_types_env = type_decls type_env prog in
82

    
83
  (* Clock calculus *)
84
  let computed_clocks_env = clock_decls clock_env prog in
85

    
86
  (* Generating a .lusi header file only *)
87
  if !Options.lusi then
88
    (* We stop here the processing and produce the current prog. It will be
89
       exported as a lusi *)
90
    raise (StopPhase1 prog);
91

    
92
  (* Optimization of prog: 
93
     - Unfold consts 
94
     - eliminate trivial expressions
95
  *)
96
  (*
97
    let prog = 
98
    if !Options.const_unfold || !Options.optimization >= 5 then
99
    begin
100
    Log.report ~level:1 (fun fmt -> fprintf fmt ".. eliminating constants and aliases@,");
101
    Optimize_prog.prog_unfold_consts prog
102
    end
103
    else
104
    prog
105
    in
106
  *)
107
  (* Delay calculus *)
108
  (* TO BE DONE LATER (Xavier)
109
     if(!Options.delay_calculus)
110
     then
111
     begin
112
     Log.report ~level:1 (fun fmt -> fprintf fmt ".. initialisation analysis@?");
113
     try
114
     Delay_calculus.delay_prog Basic_library.delay_env prog
115
     with (Delay.Error (loc,err)) as exc ->
116
     Location.print loc;
117
     eprintf "%a" Delay.pp_error err;
118
     Utils.track_exception ();
119
     raise exc
120
     end;
121
  *)
122

    
123
  (* Creating destination directory if needed *)
124
  create_dest_dir ();
125

    
126
  (* Compatibility with Lusi *)
127
  (* Checking the existence of a lusi (Lustre Interface file) *)
128
  let extension = ".lusi" in
129
  compile_source_to_header prog computed_types_env computed_clocks_env dirname basename extension;
130

    
131
  Typing.uneval_prog_generics prog;
132
  Clock_calculus.uneval_prog_generics prog;
133

    
134
  if !Options.global_inline && !Options.main_node <> "" && !Options.witnesses then
135
    begin
136
      let orig = Corelang.copy_prog orig in
137
      Log.report ~level:1 (fun fmt -> fprintf fmt ".. generating witness file@,");
138
      check_stateless_decls orig;
139
      let _ = Typing.type_prog type_env orig in
140
      let _ = Clock_calculus.clock_prog clock_env orig in
141
      Typing.uneval_prog_generics orig;
142
      Clock_calculus.uneval_prog_generics orig;
143
      Inliner.witness
144
	basename
145
	!Options.main_node
146
	orig prog type_env clock_env
147
    end;
148
  
149
  (* Computes and stores generic calls for each node,
150
     only useful for ANSI C90 compliant generic node compilation *)
151
  if !Options.ansi then Causality.NodeDep.compute_generic_calls prog;
152
  (*Hashtbl.iter (fun id td -> match td.Corelang.top_decl_desc with
153
    Corelang.Node nd -> Format.eprintf "%s calls %a" id
154
    Causality.NodeDep.pp_generic_calls nd | _ -> ()) Corelang.node_table;*)
155

    
156
  (* If some backend involving dynamic checks are active, then node annotations become runtime checks *)
157
  let prog =
158
    if dynamic_checks () then
159
      Spec.enforce_spec_prog prog
160
    else
161
      prog
162
  in
163
  
164
  (* Normalization phase *)
165
  Log.report ~level:1 (fun fmt -> fprintf fmt ".. normalization@,");
166
  let prog = Normalization.normalize_prog ~backend:!Options.output prog in
167
  Log.report ~level:2 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@," Printers.pp_prog prog);
168

    
169
  let prog =
170
    if !Options.mpfr
171
    then
172
      begin
173
	Log.report ~level:1 (fun fmt -> fprintf fmt ".. targetting MPFR library@,");
174
	Mpfr.inject_prog prog
175
      end
176
    else
177
      begin
178
	Log.report ~level:1 (fun fmt -> fprintf fmt ".. keeping floating-point numbers@,");
179
	prog
180
      end in
181
  Log.report ~level:2 (fun fmt -> fprintf fmt "@[<v 2>@ %a@]@," Printers.pp_prog prog);
182

    
183
  (* Checking array accesses *)
184
  if !Options.check then
185
    begin
186
      Log.report ~level:1 (fun fmt -> fprintf fmt ".. checking array accesses@,");
187
      Access.check_prog prog;
188
    end;
189

    
190
  let prog = SortProg.sort_nodes_locals prog in
191
  
192
  prog, dependencies
(14-14/66)