source: src/Clight/label.ma @ 2399

Last change on this file since 2399 was 2399, checked in by campbell, 7 years ago

Fill in some details about the statement of correctness.

File size: 10.3 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 clight_label_free : clight_program → bool ≝
56λp. match labels_of_clight p with [ nil ⇒ true | _ ⇒ false ].
57
58(* Adding labels *)
59
60definition add_cost_before : statement → universe CostTag → statement × (universe CostTag) ≝
61λs,gen.
62  let 〈l,gen〉 ≝ fresh … gen in
63  〈Scost l s, gen〉.
64
65definition add_cost_after : statement → universe CostTag → statement × (universe CostTag) ≝
66λs,gen.
67  let 〈l,gen〉 ≝ fresh … gen in
68  〈Ssequence s (Scost l Sskip), gen〉.
69
70definition add_cost_expr : expr → universe CostTag → expr × (universe CostTag) ≝
71λe,gen.
72  let 〈l,gen〉 ≝ fresh … gen in
73  〈Expr (Ecost l e) (typeof e), gen〉.
74
75definition const_int : nat → expr ≝
76λn. Expr (Econst_int ? (repr I32 n)) (Tint I32 Signed).
77
78let rec label_expr (e:expr) (costgen:universe CostTag)
79        on e : expr × (universe CostTag) ≝
80match e with
81[ Expr ed ty ⇒ let 〈ed,costgen〉 ≝ label_expr_descr ed costgen ty in
82               〈Expr ed ty, costgen〉
83]
84and label_expr_descr (e:expr_descr) (costgen:universe CostTag) (ty:type)
85    on e : expr_descr × (universe CostTag) ≝
86match e with
87[ Ederef e' ⇒
88    let 〈e',costgen〉 ≝ label_expr e' costgen in
89    〈Ederef e', costgen〉
90| Eaddrof e' ⇒
91    let 〈e',costgen〉 ≝ label_expr e' costgen in
92    〈Eaddrof e', costgen〉
93| Eunop op e' ⇒
94    let 〈e',costgen〉 ≝ label_expr e' costgen in
95    〈Eunop op e', costgen〉
96| Ebinop op e1 e2 ⇒
97    let 〈e1,costgen〉 ≝ label_expr e1 costgen in
98    let 〈e2,costgen〉 ≝ label_expr e2 costgen in
99    〈Ebinop op e1 e2, costgen〉
100| Ecast ty e' ⇒
101    let 〈e',costgen〉 ≝ label_expr e' costgen in
102    〈Ecast ty e', costgen〉
103| Econdition e' e1 e2 ⇒
104    let 〈e',costgen〉 ≝ label_expr e' costgen in
105    let 〈e1,costgen〉 ≝ label_expr e1 costgen in
106    let 〈e1,costgen〉 ≝ add_cost_expr e1 costgen in
107    let 〈e2,costgen〉 ≝ label_expr e2 costgen in
108    let 〈e2,costgen〉 ≝ add_cost_expr e2 costgen in
109    〈Econdition e' e1 e2, costgen〉
110(* andbool and orbool are changed to conditionals to capture their
111   short-circuiting cost difference; note that we have to return 0 or 1, and
112   we get rather more cost labels than I'd like *)
113| Eandbool e1 e2 ⇒
114    let 〈e1,costgen〉 ≝ label_expr e1 costgen in
115    let 〈e2,costgen〉 ≝ label_expr e2 costgen in
116    let 〈et,costgen〉 ≝ add_cost_expr (const_int 1) costgen in
117    let 〈ef,costgen〉 ≝ add_cost_expr (const_int 0) costgen in
118    let 〈e2,costgen〉 ≝ add_cost_expr (Expr (Econdition e2 et ef) ty) costgen in
119    let 〈ef,costgen〉 ≝ add_cost_expr (const_int 0) costgen in
120    〈Econdition e1 e2 ef, costgen〉
121| Eorbool e1 e2 ⇒
122    let 〈e1,costgen〉 ≝ label_expr e1 costgen in
123    let 〈e2,costgen〉 ≝ label_expr e2 costgen in
124    let 〈et,costgen〉 ≝ add_cost_expr (const_int 1) costgen in
125    let 〈ef,costgen〉 ≝ add_cost_expr (const_int 0) costgen in
126    let 〈e2,costgen〉 ≝ add_cost_expr (Expr (Econdition e2 et ef) ty) costgen in
127    let 〈et,costgen〉 ≝ add_cost_expr (const_int 1) costgen in
128    〈Econdition e1 et e2, costgen〉
129
130| Efield e' id ⇒
131    let 〈e',costgen〉 ≝ label_expr e' costgen in
132    〈Efield e' id, costgen〉
133(* The prototype asserts on preexisting cost labels, but I'd quite like to
134   keep them. *)
135| Ecost l e' ⇒
136    let 〈e',costgen〉 ≝ label_expr e' costgen in
137    〈Ecost l e', costgen〉
138
139(* The remaining expressions don't have subexpressions. *)
140| _ ⇒ 〈e,costgen〉
141].
142
143let rec label_exprs (l:list expr) (costgen:universe CostTag)
144        on l : list expr × (universe CostTag) ≝
145match l with
146[ nil ⇒ 〈nil ?,costgen〉
147| cons e es ⇒
148    let 〈e,costgen〉 ≝ label_expr e costgen in
149    let 〈es,costgen〉 ≝ label_exprs es costgen in
150    〈e::es,costgen〉
151].
152
153definition label_opt_expr ≝
154λoe,costgen. match oe with
155[ None ⇒ 〈None ?, costgen〉
156| Some e ⇒ let 〈e,costgen〉 ≝ label_expr e costgen in 〈Some ? e,costgen〉
157].
158
159
160let rec label_statement (s:statement) (costgen:universe CostTag)
161        on s : statement × (universe CostTag) ≝
162match s with
163[ Sskip ⇒ 〈Sskip,costgen〉
164| Sassign e1 e2 ⇒
165    let 〈e1,costgen〉 ≝ label_expr e1 costgen in
166    let 〈e2,costgen〉 ≝ label_expr e2 costgen in
167    〈Sassign e1 e2, costgen〉
168| Scall e_ret e_fn e_args ⇒
169    let 〈e_ret,costgen〉 ≝ label_opt_expr e_ret costgen in
170    let 〈e_fn,costgen〉 ≝ label_expr e_fn costgen in
171    let 〈e_args,costgen〉 ≝ label_exprs e_args costgen in
172    〈Scall e_ret e_fn e_args, costgen〉
173| Ssequence s1 s2 ⇒
174    let 〈s1,costgen〉 ≝ label_statement s1 costgen in
175    let 〈s2,costgen〉 ≝ label_statement s2 costgen in
176    〈Ssequence s1 s2, costgen〉
177| Sifthenelse e s1 s2 ⇒
178    let 〈e,costgen〉 ≝ label_expr e costgen in
179    let 〈s1,costgen〉 ≝ label_statement s1 costgen in
180    let 〈s1,costgen〉 ≝ add_cost_before s1 costgen in
181    let 〈s2,costgen〉 ≝ label_statement s2 costgen in
182    let 〈s2,costgen〉 ≝ add_cost_before s2 costgen in
183    〈Sifthenelse e s1 s2, costgen〉
184| Swhile e s' ⇒
185    let 〈e,costgen〉 ≝ label_expr e costgen in
186    let 〈s',costgen〉 ≝ label_statement s' costgen in
187    let 〈s',costgen〉 ≝ add_cost_before s' costgen in
188    let 〈s,costgen〉 ≝ add_cost_after (Swhile e s') costgen in
189    〈s,costgen〉
190| Sdowhile 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 (Sdowhile e s') costgen in
195    〈s,costgen〉
196| Sfor s1 e s2 s3 ⇒
197    let 〈e,costgen〉 ≝ label_expr e costgen in
198    let 〈s1,costgen〉 ≝ label_statement s1 costgen in
199    let 〈s2,costgen〉 ≝ label_statement s2 costgen in
200    let 〈s3,costgen〉 ≝ label_statement s3 costgen in
201    let 〈s3,costgen〉 ≝ add_cost_before s3 costgen in
202    let 〈s,costgen〉 ≝ add_cost_after (Sfor s1 e s2 s3) costgen in
203    〈s,costgen〉
204| Sbreak ⇒ 〈Sbreak,costgen〉
205| Scontinue ⇒ 〈Scontinue,costgen〉
206| Sreturn opt_e ⇒
207    let 〈opt_e,costgen〉 ≝ label_opt_expr opt_e costgen in
208    〈Sreturn opt_e,costgen〉
209| Sswitch e ls ⇒
210    let 〈e,costgen〉 ≝ label_expr e costgen in
211    let 〈ls,costgen〉 ≝ label_lstatements ls costgen in
212    〈Sswitch e ls, costgen〉
213| Slabel l s' ⇒
214    let 〈s',costgen〉 ≝ label_statement s' costgen in
215    let 〈s',costgen〉 ≝ add_cost_before s' costgen in
216    〈Slabel l s', costgen〉
217| Sgoto l ⇒ 〈Sgoto l, costgen〉
218
219(* The prototype asserts on preexisting cost labels, but I'd quite like to
220   keep them. *)
221| Scost l s' ⇒
222    let 〈s',costgen〉 ≝ label_statement s' costgen in
223    〈Scost l s', costgen〉
224]
225and label_lstatements (ls:labeled_statements) (costgen:universe CostTag)
226        on ls : labeled_statements × (universe CostTag) ≝
227match ls with
228[ LSdefault s ⇒
229    let 〈s,costgen〉 ≝ label_statement s costgen in
230    let 〈s,costgen〉 ≝ add_cost_before s costgen in
231    〈LSdefault s, costgen〉
232| LScase sz i s ls' ⇒
233    let 〈s,costgen〉 ≝ label_statement s costgen in
234    let 〈s,costgen〉 ≝ add_cost_before s costgen in
235    let 〈ls',costgen〉 ≝ label_lstatements ls' costgen in
236    〈LScase sz i s ls', costgen〉
237].
238
239definition label_function : universe CostTag → function → function × (universe CostTag) ≝
240λcostgen,f.
241  let 〈body,costgen〉 ≝ label_statement (fn_body f) costgen in
242  let 〈body,costgen〉 ≝ add_cost_before body costgen in
243    〈mk_function (fn_return f) (fn_params f) (fn_vars f) body, costgen〉.
244
245definition label_fundef : universe CostTag → clight_fundef → clight_fundef × (universe CostTag) ≝
246λgen,f. match f with
247[ CL_Internal f ⇒
248    let 〈f',gen'〉 ≝ label_function gen f in
249    〈CL_Internal f', gen'〉
250| CL_External id args ty ⇒ 〈CL_External id args ty, gen〉
251].
252
253
254
255definition clight_label : clight_program → clight_program × costlabel ≝
256λp.
257  let costgen ≝ new_universe CostTag in
258  let 〈init_cost, costgen〉 ≝ fresh … costgen in
259  〈\fst (transform_program_gen … costgen p (λ_.label_fundef)), init_cost〉.
Note: See TracBrowser for help on using the repository browser.