1 (**************************************************************************)
4 (* ||A|| A project by Andrea Asperti *)
6 (* ||I|| Developers: *)
7 (* ||T|| The HELM team. *)
8 (* ||A|| http://helm.cs.unibo.it *)
10 (* \ / This file is distributed under the terms of the *)
11 (* v GNU General Public License Version 2 *)
13 (**************************************************************************)
15 (* ********************************************************************** *)
18 (* Cosimo Oliboni, oliboni@cs.unibo.it *)
20 (* ********************************************************************** *)
22 include "compiler/linearfe.ma".
24 (* ***************************** *)
25 (* PASSO 3 : da ASTFE a LINEARFE *)
26 (* ***************************** *)
29 ASTFE_STM_ASG: ∀t:ast_type.
30 astfe_var e false t → astfe_expr e t → astfe_stm e
31 | ASTFE_STM_INIT: ∀b:bool.∀t:ast_type.
32 astfe_id e b t → astfe_init e t → astfe_stm e
33 | ASTFE_STM_WHILE: astfe_base_expr e → astfe_body e → astfe_stm e
34 | ASTFE_STM_IF: ne_list (Prod (astfe_base_expr e) (astfe_body e)) → option (astfe_body e) → astfe_stm e
36 inductive astfe_to_linearfe_stm_record (fe:aux_flatEnv_type) : Type ≝
37 ASTFE_TO_LINEARFE_STM_RECORD_SINGLE: linearfe_stm fe → astfe_to_linearfe_stm_record fe
38 | ASTFE_TO_LINEARFE_STM_RECORD_MULTI: nat → jumpBlock fe → linearfe_prog fe → astfe_to_linearfe_stm_record fe.
40 definition defined_astfetolinearfe ≝
41 λfe.λl:linearfe_prog fe.match l with [ nil ⇒ False | cons _ _ ⇒ True ].
43 inductive astfe_to_linearfe_stm_record_aux (fe:aux_flatEnv_type) : Type ≝
44 ASTFE_TO_LINEARFE_STM_RECORD_AUX: nat → ∀prg:linearfe_prog fe.defined_astfetolinearfe fe prg → astfe_to_linearfe_stm_record_aux fe.
46 lemma append_to_definedAstfetolinearfe :
47 ∀fe.∀h:linearfe_elem fe.∀t:linearfe_prog fe.
48 defined_astfetolinearfe fe (cons ? h t).
54 let rec astfe_to_linearfe_stm fe (ast:astfe_stm fe) (nextL:nat) on ast
55 : astfe_to_linearfe_stm_record fe ≝
57 [ ASTFE_STM_ASG sType sVar sExpr ⇒
58 ASTFE_TO_LINEARFE_STM_RECORD_SINGLE fe (LINEARFE_STM_ASG fe sType sVar sExpr)
60 | ASTFE_STM_INIT sB sType sId sInit ⇒
61 ASTFE_TO_LINEARFE_STM_RECORD_SINGLE fe (LINEARFE_STM_INIT fe sB sType sId sInit)
63 | ASTFE_STM_WHILE sExpr sBody ⇒
64 (* while(EXP) { ... } diventa if(EXP) { do { ... } while (EXP); } *)
65 match astfe_to_linearfe_body fe sBody (S nextL) (JUMPBLOCK_COND fe sExpr (LABEL_N (N_LABEL (S nextL))) (LABEL_N (N_LABEL nextL))) (S (S nextL)) with
66 [ pair resNextL resProg ⇒
67 ASTFE_TO_LINEARFE_STM_RECORD_MULTI fe resNextL (JUMPBLOCK_COND fe sExpr (LABEL_N (N_LABEL (S nextL))) (LABEL_N (N_LABEL nextL))) resProg ]
69 | ASTFE_STM_IF sNelExprBody sOptBody ⇒
70 let rec aux (pNelExprBody:ne_list (Prod (astfe_base_expr fe) (astfe_body fe)))
71 (pBeginL:nat) (pNextL:nat) on pNelExprBody
72 : astfe_to_linearfe_stm_record_aux fe ≝
73 match pNelExprBody with
77 match astfe_to_linearfe_body fe (snd ?? h) pNextL (JUMPBLOCK_ABS fe (LABEL_N (N_LABEL nextL))) (S pNextL) with
78 [ pair resNextL resProg ⇒
79 ASTFE_TO_LINEARFE_STM_RECORD_AUX fe resNextL
80 (cons ? (LINEARFE_ELEM fe (N_LABEL pBeginL) [] (JUMPBLOCK_COND fe (fst ?? h) (LABEL_N (N_LABEL pNextL)) (LABEL_N (N_LABEL nextL)))) (resProg))
81 (append_to_definedAstfetolinearfe ???) ]
84 match astfe_to_linearfe_body fe (snd ?? h) pNextL (JUMPBLOCK_ABS fe (LABEL_N (N_LABEL nextL))) (S (S pNextL)) with
85 [ pair resNextL resProg ⇒
86 match astfe_to_linearfe_body fe optBody (S pNextL) (JUMPBLOCK_ABS fe (LABEL_N (N_LABEL nextL))) resNextL with
87 [ pair resNextL' resProg' ⇒
88 ASTFE_TO_LINEARFE_STM_RECORD_AUX fe resNextL'
89 (cons ? (LINEARFE_ELEM fe (N_LABEL pBeginL) [] (JUMPBLOCK_COND fe (fst ?? h) (LABEL_N (N_LABEL pNextL)) (LABEL_N (N_LABEL (S pNextL))))) (resProg@resProg'))
90 (append_to_definedAstfetolinearfe ???) ]]
95 match astfe_to_linearfe_body fe (snd ?? h) pNextL (JUMPBLOCK_ABS fe (LABEL_N (N_LABEL nextL))) (S (S pNextL)) with
96 [ pair resNextL resProg ⇒
97 match aux t (S pNextL) resNextL with
98 [ ASTFE_TO_LINEARFE_STM_RECORD_AUX resNextL' resProg' _ ⇒
99 ASTFE_TO_LINEARFE_STM_RECORD_AUX fe resNextL'
100 (cons ? (LINEARFE_ELEM fe (N_LABEL pBeginL) [] (JUMPBLOCK_COND fe (fst ?? h) (LABEL_N (N_LABEL pNextL)) (LABEL_N (N_LABEL (S pNextL))))) (resProg@resProg'))
101 (append_to_definedAstfetolinearfe ???) ]]
104 match aux sNelExprBody O (S nextL) with
105 [ ASTFE_TO_LINEARFE_STM_RECORD_AUX resNextL resProg resDefined ⇒
107 return λX:linearfe_prog fe.defined_astfetolinearfe fe X → astfe_to_linearfe_stm_record fe
109 (* caso dummy: impossibile! *)
110 [ nil ⇒ λp:(defined_astfetolinearfe fe (nil ?)).False_rect ? p
112 | cons h t ⇒ λp:(defined_astfetolinearfe fe (cons ? h t)).
114 [ LINEARFE_ELEM _ _ resJump ⇒
115 ASTFE_TO_LINEARFE_STM_RECORD_MULTI fe resNextL resJump t ]
121 ASTFE_BODY: list (astfe_stm e) → astfe_body e
123 and astfe_to_linearfe_body fe (ast:astfe_body fe)
124 (beginL:nat) (endJump:jumpBlock fe) (nextL:nat) on ast
125 : Prod nat (linearfe_prog fe) ≝
128 let rec aux (pLStm:list (astfe_stm fe)) (pRes:list (linearfe_stm fe))
129 (pBeginL:nat) (pEndJump:jumpBlock fe) (pNextL:nat)
130 on pLStm : Prod nat (linearfe_prog fe) ≝
133 pair ?? pNextL [ LINEARFE_ELEM fe (N_LABEL pBeginL) pRes pEndJump ]
136 match astfe_to_linearfe_stm fe h pNextL with
137 [ ASTFE_TO_LINEARFE_STM_RECORD_SINGLE resStm ⇒
138 aux t (pRes@[ resStm ]) pBeginL pEndJump pNextL
139 | ASTFE_TO_LINEARFE_STM_RECORD_MULTI resNextL resEndJump resProg ⇒
140 match aux t [] pNextL pEndJump resNextL with
141 [ pair resNextL' resProg' ⇒
142 pair ?? resNextL' ([ LINEARFE_ELEM fe (N_LABEL pBeginL) pRes resEndJump ] @ resProg @ resProg') ]]
144 ] in aux sLStm [] beginL endJump nextL
148 ASTFE_ROOT: astfe_body e → astfe_root e
150 definition astfe_to_linearfe ≝
151 λfe.λast:astfe_root fe.match ast with
152 [ ASTFE_ROOT body ⇒ astfe_to_linearfe_body fe body O (JUMPBLOCK_ABS fe LABEL_END) 1 ].
154 (* ***** OTTIMIZZAZIONE ***** *)
156 (* individuare gli elementi "x : [] : ABS ..." *)
157 let rec get_useless_linearfeElem fe (prog:linearfe_prog fe) (res:list (Prod nat nat)) on prog ≝
160 | cons h t ⇒ get_useless_linearfeElem fe t (res@(match h with
161 [ LINEARFE_ELEM lbl lStm jmpB ⇒ match lStm with
162 [ nil ⇒ match jmpB with
163 [ JUMPBLOCK_ABS jlbl ⇒ match lbl with
164 [ N_LABEL n ⇒ match jlbl with
165 [ LABEL_N jlbl' ⇒ match jlbl' with
166 [ N_LABEL n' ⇒ [ pair ?? n n' ] ]
169 | JUMPBLOCK_COND _ _ _ ⇒ [] ]
173 (* applicare una singola trasformazione *)
174 let rec useless_linearfeElem_trsf (ul:list (Prod nat nat)) (trsf:Prod nat nat) on ul ≝
177 | cons h t ⇒ (match eqb (snd ?? h) (fst ?? trsf) with [ true ⇒ pair ?? (fst ?? h) (snd ?? trsf) | false ⇒ h ]
178 )::(useless_linearfeElem_trsf t trsf)
181 (* applicare una passata completa di chiusura *)
182 let rec useless_linearfeElem_closure_aux (preUl,ul:list (Prod nat nat)) on ul ≝
185 | cons h t ⇒ useless_linearfeElem_closure_aux ((useless_linearfeElem_trsf preUl h)@[h]) t
188 definition useless_linearfeElem_closure ≝
189 λul:list (Prod nat nat).
190 reverse_list ? (useless_linearfeElem_closure_aux [] (reverse_list ? (useless_linearfeElem_closure_aux [] ul))).
192 inductive useless_linearfeElem_res : Type ≝
193 USELESS_LINEARFEELEM_RES_DISCARD: nat → useless_linearfeElem_res
194 | USELESS_LINEARFEELEM_RES_DIFF: nat → useless_linearfeElem_res.
196 (* interrogazione della mappa di trasformazione sottoposta a chiusura *)
197 let rec useless_linearfeElem_elim (ul:list (Prod nat nat)) (n:nat) (acc:nat) on ul ≝
199 [ nil ⇒ USELESS_LINEARFEELEM_RES_DIFF acc
200 | cons h t ⇒ match eqb n (fst ?? h) with
201 [ true ⇒ USELESS_LINEARFEELEM_RES_DISCARD (snd ?? h)
202 | false ⇒ useless_linearfeElem_elim t n (match gtb n (fst ?? h) with [ true ⇒ S acc | false ⇒ acc])
206 (* eliminazione delle triple useless e compattazione delle label *)
207 definition useless_linearfeProg_elim_aux ≝
208 λjmpL:jumpLabel.λul:list (Prod nat nat).
210 [ LABEL_N lbl ⇒ match lbl with
211 [ N_LABEL n ⇒ match useless_linearfeElem_elim ul n O with
212 [ USELESS_LINEARFEELEM_RES_DISCARD new ⇒ LABEL_N (N_LABEL new)
213 | USELESS_LINEARFEELEM_RES_DIFF diff ⇒ LABEL_N (N_LABEL (n-diff))
215 | LABEL_END ⇒ LABEL_END
220 [ LABEL_N lbl1 ⇒ match l2 with
221 [ LABEL_N lbl2 ⇒ match lbl1 with
222 [ N_LABEL n1 ⇒ match lbl2 with
223 [ N_LABEL n2 ⇒ eqb n1 n2 ]]
224 | LABEL_END ⇒ false ]
225 | LABEL_END ⇒ match l2 with
226 [ LABEL_N _ ⇒ false | LABEL_END ⇒ true ]
229 lemma eq_to_eqlabel : ∀l1,l2.l1 = l2 → eqLabel l1 l2 = true.
237 rewrite > eq_to_eqb_true;
249 lemma eqlabel_to_eq : ∀l1,l2.eqLabel l1 l2 = true → l1 = l2.
258 rewrite > (eqb_true_to_eq ?? H);
271 let rec useless_linearfeProg_elim fe (prog:linearfe_prog fe) (ul:list (Prod nat nat)) on prog ≝
274 | cons h t ⇒ match h with
275 [ LINEARFE_ELEM lbl lStm jmpB ⇒ match lbl with
276 [ N_LABEL n ⇒ match useless_linearfeElem_elim ul n O with
277 (* intero elemento ridondante *)
278 [ USELESS_LINEARFEELEM_RES_DISCARD _ ⇒ []
279 (* la label e il salto possono necessitare di compattazione *)
280 | USELESS_LINEARFEELEM_RES_DIFF diff ⇒
281 [ LINEARFE_ELEM fe (N_LABEL (n-diff)) lStm (match jmpB with
282 [ JUMPBLOCK_ABS jlbl ⇒ JUMPBLOCK_ABS fe (useless_linearfeProg_elim_aux jlbl ul)
283 | JUMPBLOCK_COND expr jlbl1 jlbl2 ⇒
284 (* NB: il linguaggio non ha effetti collaterali quindi COND expr x x diventa ABS x *)
285 let jlbl1' ≝ useless_linearfeProg_elim_aux jlbl1 ul in
286 let jlbl2' ≝ useless_linearfeProg_elim_aux jlbl2 ul in
287 match eqLabel jlbl1' jlbl2' with
288 [ true ⇒ JUMPBLOCK_ABS fe jlbl1'
289 | false ⇒ JUMPBLOCK_COND fe expr jlbl1' jlbl2'
292 )]]]]@(useless_linearfeProg_elim fe t ul)
295 definition useless_linearfeProg ≝
296 λfe.λmaxProg:Prod nat (linearfe_prog fe).
299 let ul ≝ useless_linearfeElem_closure (get_useless_linearfeElem fe prog []) in
300 pair ?? (max-(len_list ? ul)) (useless_linearfeProg_elim fe prog ul) ].
304 - il livello di annidamento medio non supera mai i 10 livelli
305 - ogni passata puo' rimuovere un "dead" jmp COND x x
306 - per assorbire la trasformazione serve una nuova passata
307 - applichiamo quindi N=10 passate
309 definition useless_linearfeProgMulti ≝
310 λfe.λmaxProg:Prod nat (linearfe_prog fe).
311 let rec aux pMaxProg n on n ≝
314 | S n' ⇒ aux (useless_linearfeProg fe pMaxProg) n'
317 (* ************* TEST ************* *)
321 snd ?? (build_trasfEnv_mapFe O [ tripleT ??? [ ch_A ] false (AST_TYPE_BASE AST_BASE_TYPE_BYTE8) ]
322 (pair ?? empty_map empty_flatEnv)).
324 lemma tid : astfe_id tfe false (AST_TYPE_BASE AST_BASE_TYPE_BYTE8).
325 lapply (ASTFE_ID tfe (STR_ID [ ch_A ] O));
326 [ apply Hletin | apply I ].
331 ASTFE_EXPR_ADD tfe AST_BASE_TYPE_BYTE8
332 (ASTFE_EXPR_ID tfe false (AST_TYPE_BASE AST_BASE_TYPE_BYTE8)
333 (ASTFE_VAR_ID tfe false (AST_TYPE_BASE AST_BASE_TYPE_BYTE8) tid))
334 (ASTFE_EXPR_BYTE8 tfe val).
338 ASTFE_STM_ASG tfe (AST_TYPE_BASE AST_BASE_TYPE_BYTE8)
339 (ASTFE_VAR_ID tfe false (AST_TYPE_BASE AST_BASE_TYPE_BYTE8) tid)
344 LINEARFE_STM_ASG tfe (AST_TYPE_BASE AST_BASE_TYPE_BYTE8)
345 (ASTFE_VAR_ID tfe false (AST_TYPE_BASE AST_BASE_TYPE_BYTE8) tid)
350 ASTFE_BASE_EXPR tfe AST_BASE_TYPE_BYTE8
351 (ASTFE_EXPR_GT tfe AST_BASE_TYPE_BYTE8
352 (ASTFE_EXPR_ID tfe false (AST_TYPE_BASE AST_BASE_TYPE_BYTE8)
353 (ASTFE_VAR_ID tfe false (AST_TYPE_BASE AST_BASE_TYPE_BYTE8) tid))
354 (ASTFE_EXPR_BYTE8 tfe val)).
357 (* senza (SX) e con (DX) ottimizzazione: da 0-24,25new a 0-15,16new
362 { if(tbexp 2) { lasg 2; } }
365 O : [ lasg 0 ; lasg 1 ] : COND (tbexp 0) 2 3 ; * O : [ lasg 0 ; lasg 1 ] : COND (tbexp 0) 2 3 ;
366 2 : [] : COND (tbexp 1) 5 4 ; * 2 : [] : COND (tbexp 1) 5 4 ;
367 5 : [] : COND (tbexp 2) 7 6 ; * 5 : [] : COND (tbexp 2) 7 6 ;
368 7 : [ lasg 2 ] : ABS 6 ; * 7 : [ lasg 2 ] : ABS 6 ;
369 6 : [] : COND (tbexp 1) 5 4 ; * 6 : [] : COND (tbexp 1) 5 4 ;
370 4 : [ lasg 3 ] : ABS 1 ; * 4 : [ lasg 3 ] : ABS 1 ;
377 3 : [] : COND (tbexp 3) 8 9 ; * 3 : [] : COND (tbexp 3) 1 8 ;
378 8 : [] : COND (tbexp 4) 11 12 ; *
380 12 : [] : COND (tbexp 5) 13 10 ; *
390 if(tbexp 8) { lasg 6; }
395 9 : [] : COND (tbexp 6) 14 15 ; * 8 : [] : COND (tbexp 6) 9 10 ;
396 14 : [ lasg 4 ; lasg 5 ] : COND (tbexp 7) 17 16 ; * 9 : [ lasg 4 ; lasg 5 ] : COND (tbexp 7) 12 11 ;
397 17 : [] : COND (tbexp 8) 19 18 ; * 12 : [] : COND (tbexp 8) 14 13 ;
398 19 : [ lasg 6 ] : ABS 18 ; * 14 : [ lasg 6 ] : ABS 13 ;
399 18 : [ lasg 7 ] : ABS 16 ; * 13 : [ lasg 7 ] : ABS 11 ;
400 16 : [ lasg 8 ] : ABS 1 ; * 11 : [ lasg 8 ] : ABS 1 ;
404 if(tbexp 9) { lasg 9; }
407 15 : [] : COND (tbexp 9) 21 22 ; * 10 : [] : COND (tbexp 9) 15 1 ;
408 21 : [ lasg 9 ] : ABS 20 ; * 15 : [ lasg 9 ] : ABS 1 ;
409 22 : [] : COND (tbexp A) 23 24 ; *
414 ... fine dell'if principale ...
415 1 : [] : ABS LABEL_END ] * ... l'ottimizzazione qui si ferma ...
425 (pair ?? (tbexp 〈x0,x0〉)
427 (ASTFE_STM_WHILE tfe (tbexp 〈x0,x1〉) (ASTFE_BODY tfe [
428 (ASTFE_STM_IF tfe («£(pair ?? (tbexp 〈x0,x2〉) (ASTFE_BODY tfe [ tasg 〈x0,x2〉 ]))») (None ?)) ])) ;
430 (pair ?? (tbexp 〈x0,x3〉) (ASTFE_BODY tfe [
431 (ASTFE_STM_IF tfe («(pair ?? (tbexp 〈x0,x4〉) (ASTFE_BODY tfe []))£(pair ?? (tbexp 〈x0,x5〉) (ASTFE_BODY tfe []))») (None ?)) ])) £
432 (pair ?? (tbexp 〈x0,x6〉)
436 (ASTFE_STM_IF tfe («£(pair ?? (tbexp 〈x0,x7〉) (ASTFE_BODY tfe [
437 (ASTFE_STM_IF tfe («£(pair ?? (tbexp 〈x0,x8〉) (ASTFE_BODY tfe [ tasg 〈x0,x6〉 ]))») (None ?)) ;
438 (tasg 〈x0,x7〉) ]))») (None ?)) ;
439 (tasg 〈x0,x8〉) ])) »)
440 (Some ? (ASTFE_BODY tfe [
441 (ASTFE_STM_IF tfe («(pair ?? (tbexp 〈x0,x9〉) (ASTFE_BODY tfe [ tasg 〈x0,x9〉 ]))£
442 (pair ?? (tbexp 〈x0,xA〉) (ASTFE_BODY tfe []))»)
443 (Some ? (ASTFE_BODY tfe [])))])))
446 lemma pippo : ∃b.b=useless_linearfeProgMulti tfe (astfe_to_linearfe tfe tprog).
447 unfold useless_linearfeProgMulti;
449 normalize in ⊢ (? ? (λ_:?.? ? ? (? ? (? ? (? ? (? ? (? ? (? ? (? ? (? ? (? ? %)))))))))));
450 normalize in ⊢ (? ? (λ_:?.? ? ? (? ? (? ? (? ? (? ? (? ? (? ? (? ? (? ? %))))))))));
451 normalize in ⊢ (? ? (λ_:?.? ? ? (? ? (? ? (? ? (? ? (? ? (? ? (? ? %)))))))));
452 normalize in ⊢ (? ? (λ_:?.? ? ? (? ? (? ? (? ? (? ? (? ? (? ? %))))))));
453 normalize in ⊢ (? ? (λ_:?.? ? ? (? ? (? ? (? ? (? ? (? ? %)))))));
454 normalize in ⊢ (? ? (λ_:?.? ? ? (? ? (? ? (? ? (? ? %))))));
455 normalize in ⊢ (? ? (λ_:?.? ? ? (? ? (? ? (? ? %)))));
456 normalize in ⊢ (? ? (λ_:?.? ? ? (? ? (? ? %))));
457 normalize in ⊢ (? ? (λ_:?.? ? ? (? ? %)));
458 normalize in ⊢ (? ? (λ_:?.? ? ? %));
460 fold normalize (lasg 〈x0,x0〉);
461 fold normalize (lasg 〈x0,x1〉);
462 fold normalize (lasg 〈x0,x2〉);
463 fold normalize (lasg 〈x0,x3〉);
464 fold normalize (lasg 〈x0,x4〉);
465 fold normalize (lasg 〈x0,x5〉);
466 fold normalize (lasg 〈x0,x6〉);
467 fold normalize (lasg 〈x0,x7〉);
468 fold normalize (lasg 〈x0,x8〉);
469 fold normalize (lasg 〈x0,x9〉);
470 fold normalize (tbexp 〈x0,x0〉);
471 fold normalize (tbexp 〈x0,x1〉);
472 fold normalize (tbexp 〈x0,x2〉);
473 fold normalize (tbexp 〈x0,x3〉);
474 fold normalize (tbexp 〈x0,x4〉);
475 fold normalize (tbexp 〈x0,x5〉);
476 fold normalize (tbexp 〈x0,x6〉);
477 fold normalize (tbexp 〈x0,x7〉);
478 fold normalize (tbexp 〈x0,x8〉);
479 fold normalize (tbexp 〈x0,x9〉);
480 fold normalize (tbexp 〈x0,xA〉);