source: src/Clight/label.ma @ 2505

Last change on this file since 2505 was 2505, checked in by mckinna, 7 years ago

Cleaned up compiler.ma; some refactoring/additional code needed in Clight/label, and a tweak to translate_cst in RTLabsToRTL to restore its checked status.

File size: 10.5 KB
Line 
1include "Clight/Csyntax.ma".
2
3(* Extract cost labels from a program. *)
4
5let rec labels_of_expr (e:expr) : list costlabel ≝
6match e with
7[ Expr e' _ ⇒
8  match e' with
9  [ Ederef e1 ⇒ labels_of_expr e1
10  | Eaddrof e1 ⇒ labels_of_expr e1
11  | Eunop _ e1 ⇒ labels_of_expr e1
12  | Ebinop _ e1 e2 ⇒ labels_of_expr e1 @ labels_of_expr e2
13  | Ecast _ e1 ⇒ labels_of_expr e1
14  | Econdition e1 e2 e3 ⇒ labels_of_expr e1 @ labels_of_expr e2 @ labels_of_expr e3
15  | Eandbool e1 e2 ⇒ labels_of_expr e1 @ labels_of_expr e2
16  | Eorbool e1 e2 ⇒ labels_of_expr e1 @ labels_of_expr e2
17  | Efield e1 _ ⇒ labels_of_expr e1
18  | Ecost cl e1 ⇒ cl::(labels_of_expr e1)
19  | _ ⇒ [ ]
20  ]
21].
22
23let rec labels_of_statement (s:statement) : list costlabel ≝
24match s with
25[ Sassign e1 e2 ⇒ labels_of_expr e1 @ labels_of_expr e2
26| Scall oe e1 es ⇒ option_map_def … labels_of_expr [ ] oe @ labels_of_expr e1 @ foldl … (λls,e. labels_of_expr e @ ls) [ ] es
27| Ssequence s1 s2 ⇒ labels_of_statement s1 @ labels_of_statement s2
28| Sifthenelse e1 s1 s2 ⇒ labels_of_expr e1 @ labels_of_statement s1 @ labels_of_statement s2
29| Swhile e1 s1 ⇒ labels_of_expr e1 @ labels_of_statement s1
30| Sdowhile e1 s1 ⇒ labels_of_expr e1 @ labels_of_statement s1
31| Sfor s1 e1 s2 s3 ⇒ labels_of_statement s1 @ labels_of_expr e1 @ labels_of_statement s2 @ labels_of_statement s3
32| Sreturn oe ⇒ option_map_def … labels_of_expr [ ] oe
33| Sswitch e1 ls ⇒ labels_of_expr e1 @ labels_of_labeled_statements ls
34| Slabel _ s1 ⇒ labels_of_statement s1
35| Scost cl s1 ⇒ cl::(labels_of_statement s1)
36| _ ⇒ [ ]
37] and labels_of_labeled_statements (ls:labeled_statements) : list costlabel ≝
38match ls with
39[ LSdefault s1 ⇒ labels_of_statement s1
40| LScase _ _ s1 ls1 ⇒ labels_of_statement s1 @ labels_of_labeled_statements ls1
41].
42
43definition labels_of_clight_fundef : ident × clight_fundef → list costlabel ≝
44λifd. match \snd ifd with
45[ CL_Internal f ⇒ labels_of_statement (fn_body f)
46| _ ⇒ [ ]
47].
48
49definition labels_of_clight : clight_program → list costlabel ≝
50λp. foldl … (λls,f. labels_of_clight_fundef f @ ls) [ ] (prog_funct ?? p).
51
52definition in_clight_program : clight_program → costlabel → Prop ≝
53λp,l. Exists … (λx.x=l) (labels_of_clight p).
54
55definition in_clight_label ≝
56  λp. Σl. in_clight_program p l.
57
58definition clight_cost_map ≝
59  λp. (in_clight_label p) → ℕ.
60
61definition clight_label_free : clight_program → bool ≝
62λp. match labels_of_clight p with [ nil ⇒ true | _ ⇒ false ].
63
64(* Adding labels *)
65
66definition add_cost_before : statement → universe CostTag → statement × (universe CostTag) ≝
67λs,gen.
68  let 〈l,gen〉 ≝ fresh … gen in
69  〈Scost l s, gen〉.
70
71definition add_cost_after : statement → universe CostTag → statement × (universe CostTag) ≝
72λs,gen.
73  let 〈l,gen〉 ≝ fresh … gen in
74  〈Ssequence s (Scost l Sskip), gen〉.
75
76definition add_cost_expr : expr → universe CostTag → expr × (universe CostTag) ≝
77λe,gen.
78  let 〈l,gen〉 ≝ fresh … gen in
79  〈Expr (Ecost l e) (typeof e), gen〉.
80
81definition const_int : nat → expr ≝
82λn. Expr (Econst_int ? (repr I32 n)) (Tint I32 Signed).
83
84let rec label_expr (e:expr) (costgen:universe CostTag)
85        on e : expr × (universe CostTag) ≝
86match e with
87[ Expr ed ty ⇒ let 〈ed,costgen〉 ≝ label_expr_descr ed costgen ty in
88               〈Expr ed ty, costgen〉
89]
90and label_expr_descr (e:expr_descr) (costgen:universe CostTag) (ty:type)
91    on e : expr_descr × (universe CostTag) ≝
92match e with
93[ Ederef e' ⇒
94    let 〈e',costgen〉 ≝ label_expr e' costgen in
95    〈Ederef e', costgen〉
96| Eaddrof e' ⇒
97    let 〈e',costgen〉 ≝ label_expr e' costgen in
98    〈Eaddrof e', costgen〉
99| Eunop op e' ⇒
100    let 〈e',costgen〉 ≝ label_expr e' costgen in
101    〈Eunop op e', costgen〉
102| Ebinop op e1 e2 ⇒
103    let 〈e1,costgen〉 ≝ label_expr e1 costgen in
104    let 〈e2,costgen〉 ≝ label_expr e2 costgen in
105    〈Ebinop op e1 e2, costgen〉
106| Ecast ty e' ⇒
107    let 〈e',costgen〉 ≝ label_expr e' costgen in
108    〈Ecast ty e', costgen〉
109| Econdition e' e1 e2 ⇒
110    let 〈e',costgen〉 ≝ label_expr e' costgen in
111    let 〈e1,costgen〉 ≝ label_expr e1 costgen in
112    let 〈e1,costgen〉 ≝ add_cost_expr e1 costgen in
113    let 〈e2,costgen〉 ≝ label_expr e2 costgen in
114    let 〈e2,costgen〉 ≝ add_cost_expr e2 costgen in
115    〈Econdition e' e1 e2, costgen〉
116(* andbool and orbool are changed to conditionals to capture their
117   short-circuiting cost difference; note that we have to return 0 or 1, and
118   we get rather more cost labels than I'd like *)
119| Eandbool e1 e2 ⇒
120    let 〈e1,costgen〉 ≝ label_expr e1 costgen in
121    let 〈e2,costgen〉 ≝ label_expr e2 costgen in
122    let 〈et,costgen〉 ≝ add_cost_expr (const_int 1) costgen in
123    let 〈ef,costgen〉 ≝ add_cost_expr (const_int 0) costgen in
124    let 〈e2,costgen〉 ≝ add_cost_expr (Expr (Econdition e2 et ef) ty) costgen in
125    let 〈ef,costgen〉 ≝ add_cost_expr (const_int 0) costgen in
126    〈Econdition e1 e2 ef, costgen〉
127| Eorbool e1 e2 ⇒
128    let 〈e1,costgen〉 ≝ label_expr e1 costgen in
129    let 〈e2,costgen〉 ≝ label_expr e2 costgen in
130    let 〈et,costgen〉 ≝ add_cost_expr (const_int 1) costgen in
131    let 〈ef,costgen〉 ≝ add_cost_expr (const_int 0) costgen in
132    let 〈e2,costgen〉 ≝ add_cost_expr (Expr (Econdition e2 et ef) ty) costgen in
133    let 〈et,costgen〉 ≝ add_cost_expr (const_int 1) costgen in
134    〈Econdition e1 et e2, costgen〉
135
136| Efield e' id ⇒
137    let 〈e',costgen〉 ≝ label_expr e' costgen in
138    〈Efield e' id, costgen〉
139(* The prototype asserts on preexisting cost labels, but I'd quite like to
140   keep them. *)
141| Ecost l e' ⇒
142    let 〈e',costgen〉 ≝ label_expr e' costgen in
143    〈Ecost l e', costgen〉
144
145(* The remaining expressions don't have subexpressions. *)
146| _ ⇒ 〈e,costgen〉
147].
148
149let rec label_exprs (l:list expr) (costgen:universe CostTag)
150        on l : list expr × (universe CostTag) ≝
151match l with
152[ nil ⇒ 〈nil ?,costgen〉
153| cons e es ⇒
154    let 〈e,costgen〉 ≝ label_expr e costgen in
155    let 〈es,costgen〉 ≝ label_exprs es costgen in
156    〈e::es,costgen〉
157].
158
159definition label_opt_expr ≝
160λoe,costgen. match oe with
161[ None ⇒ 〈None ?, costgen〉
162| Some e ⇒ let 〈e,costgen〉 ≝ label_expr e costgen in 〈Some ? e,costgen〉
163].
164
165
166let rec label_statement (s:statement) (costgen:universe CostTag)
167        on s : statement × (universe CostTag) ≝
168match s with
169[ Sskip ⇒ 〈Sskip,costgen〉
170| Sassign e1 e2 ⇒
171    let 〈e1,costgen〉 ≝ label_expr e1 costgen in
172    let 〈e2,costgen〉 ≝ label_expr e2 costgen in
173    〈Sassign e1 e2, costgen〉
174| Scall e_ret e_fn e_args ⇒
175    let 〈e_ret,costgen〉 ≝ label_opt_expr e_ret costgen in
176    let 〈e_fn,costgen〉 ≝ label_expr e_fn costgen in
177    let 〈e_args,costgen〉 ≝ label_exprs e_args costgen in
178    〈Scall e_ret e_fn e_args, costgen〉
179| Ssequence s1 s2 ⇒
180    let 〈s1,costgen〉 ≝ label_statement s1 costgen in
181    let 〈s2,costgen〉 ≝ label_statement s2 costgen in
182    〈Ssequence s1 s2, costgen〉
183| Sifthenelse e s1 s2 ⇒
184    let 〈e,costgen〉 ≝ label_expr e costgen in
185    let 〈s1,costgen〉 ≝ label_statement s1 costgen in
186    let 〈s1,costgen〉 ≝ add_cost_before s1 costgen in
187    let 〈s2,costgen〉 ≝ label_statement s2 costgen in
188    let 〈s2,costgen〉 ≝ add_cost_before s2 costgen in
189    〈Sifthenelse e s1 s2, costgen〉
190| Swhile e s' ⇒
191    let 〈e,costgen〉 ≝ label_expr e costgen in
192    let 〈s',costgen〉 ≝ label_statement s' costgen in
193    let 〈s',costgen〉 ≝ add_cost_before s' costgen in
194    let 〈s,costgen〉 ≝ add_cost_after (Swhile e s') costgen in
195    〈s,costgen〉
196| Sdowhile e s' ⇒
197    let 〈e,costgen〉 ≝ label_expr e costgen in
198    let 〈s',costgen〉 ≝ label_statement s' costgen in
199    let 〈s',costgen〉 ≝ add_cost_before s' costgen in
200    let 〈s,costgen〉 ≝ add_cost_after (Sdowhile e s') costgen in
201    〈s,costgen〉
202| Sfor s1 e s2 s3 ⇒
203    let 〈e,costgen〉 ≝ label_expr e costgen in
204    let 〈s1,costgen〉 ≝ label_statement s1 costgen in
205    let 〈s2,costgen〉 ≝ label_statement s2 costgen in
206    let 〈s3,costgen〉 ≝ label_statement s3 costgen in
207    let 〈s3,costgen〉 ≝ add_cost_before s3 costgen in
208    let 〈s,costgen〉 ≝ add_cost_after (Sfor s1 e s2 s3) costgen in
209    〈s,costgen〉
210| Sbreak ⇒ 〈Sbreak,costgen〉
211| Scontinue ⇒ 〈Scontinue,costgen〉
212| Sreturn opt_e ⇒
213    let 〈opt_e,costgen〉 ≝ label_opt_expr opt_e costgen in
214    〈Sreturn opt_e,costgen〉
215| Sswitch e ls ⇒
216    let 〈e,costgen〉 ≝ label_expr e costgen in
217    let 〈ls,costgen〉 ≝ label_lstatements ls costgen in
218    〈Sswitch e ls, costgen〉
219| Slabel l s' ⇒
220    let 〈s',costgen〉 ≝ label_statement s' costgen in
221    let 〈s',costgen〉 ≝ add_cost_before s' costgen in
222    〈Slabel l s', costgen〉
223| Sgoto l ⇒ 〈Sgoto l, costgen〉
224
225(* The prototype asserts on preexisting cost labels, but I'd quite like to
226   keep them. *)
227| Scost l s' ⇒
228    let 〈s',costgen〉 ≝ label_statement s' costgen in
229    〈Scost l s', costgen〉
230]
231and label_lstatements (ls:labeled_statements) (costgen:universe CostTag)
232        on ls : labeled_statements × (universe CostTag) ≝
233match ls with
234[ LSdefault s ⇒
235    let 〈s,costgen〉 ≝ label_statement s costgen in
236    let 〈s,costgen〉 ≝ add_cost_before s costgen in
237    〈LSdefault s, costgen〉
238| LScase sz i s ls' ⇒
239    let 〈s,costgen〉 ≝ label_statement s costgen in
240    let 〈s,costgen〉 ≝ add_cost_before s costgen in
241    let 〈ls',costgen〉 ≝ label_lstatements ls' costgen in
242    〈LScase sz i s ls', costgen〉
243].
244
245definition label_function : universe CostTag → function → function × (universe CostTag) ≝
246λcostgen,f.
247  let 〈body,costgen〉 ≝ label_statement (fn_body f) costgen in
248  let 〈body,costgen〉 ≝ add_cost_before body costgen in
249    〈mk_function (fn_return f) (fn_params f) (fn_vars f) body, costgen〉.
250
251definition label_fundef : universe CostTag → clight_fundef → clight_fundef × (universe CostTag) ≝
252λgen,f. match f with
253[ CL_Internal f ⇒
254    let 〈f',gen'〉 ≝ label_function gen f in
255    〈CL_Internal f', gen'〉
256| CL_External id args ty ⇒ 〈CL_External id args ty, gen〉
257].
258
259
260
261definition clight_label : clight_program → clight_program × costlabel ≝
262λp.
263  let costgen ≝ new_universe CostTag in
264  let 〈init_cost, costgen〉 ≝ fresh … costgen in
265  〈\fst (transform_program_gen … costgen p (λ_.label_fundef)), init_cost〉.
Note: See TracBrowser for help on using the repository browser.