source: src/Cminor/initialisation.ma @ 1401

Last change on this file since 1401 was 1401, checked in by ricciott, 8 years ago

Changes concerning the new behavior of destruct.

File size: 4.4 KB
Line 
1
2(* Replace initialisation of global variables with equivalent Cminor code. *)
3
4include "Cminor/syntax.ma".
5include "common/Globalenvs.ma".
6include "utilities/pair.ma".
7include "utilities/deppair.ma".
8
9(* XXX having to specify the return type in the match is annoying. *)
10definition init_expr : init_data → option (Σc:memory_chunk. expr (typ_of_memory_chunk c)) ≝
11λinit.
12match init return λ_.option (Σc:memory_chunk. expr (typ_of_memory_chunk c)) with
13[ Init_int8 i          ⇒ Some ? (dp ?? Mint8unsigned (Cst ? (Ointconst I8 i)))
14| Init_int16 i         ⇒ Some ? (dp ?? Mint16unsigned (Cst ? (Ointconst I16 i)))
15| Init_int32 i         ⇒ Some ? (dp ?? Mint32 (Cst ? (Ointconst I32 i)))
16| Init_float32 f       ⇒ Some ? (dp ?? Mfloat32 (Cst ? (Ofloatconst f)))
17| Init_float64 f       ⇒ Some ? (dp ?? Mfloat64 (Cst ? (Ofloatconst f)))
18| Init_space n         ⇒ None ?
19| Init_null r          ⇒ Some ? (dp ?? (Mpointer r) (Op1 (ASTint I8 Unsigned) ? (Optrofint ?? r) (Cst ? (Ointconst I8 (zero ?)))))
20| Init_addrof r id off ⇒ Some ? (dp ?? (Mpointer r) (Cst ? (Oaddrsymbol id off)))
21].
22
23(* None of the additional code introduces locals or labels. *)
24definition stmt_inv : stmt → Prop ≝
25  stmt_P (λs. stmt_vars (λ_.False) s ∧ stmt_labels (λ_.False) s).
26 
27discriminator option.
28discriminator Sig.
29
30(* Produces a few extra skips - hopefully the compiler will optimise these
31   away. *)
32
33definition init_datum : ident → region → init_data → nat (*offset*) → Σs:stmt. stmt_inv s ≝
34λid,r,init,off.
35match init_expr init with
36[ None ⇒ St_skip
37| Some x ⇒
38    match x with [ dp chunk e ⇒
39      St_store ? r chunk (Cst ? (Oaddrsymbol id off)) e
40    ]
41].
42% //
43cases init in p; [ 8: #a #b ] #c #p normalize in p;
44destruct;/2/
45qed.
46
47definition init_var : ident → region → list init_data → Σs:stmt. stmt_inv s ≝
48λid,r,init.
49\snd (foldr ??
50  (λdatum,os.
51   let 〈off,s〉 ≝ os in
52     〈off + (size_init_data datum), St_seq (init_datum id r datum off) s〉)
53  〈0, dp ? (λx.stmt_inv x) St_skip ?〉 init).
54[ % //
55| elim init
56  [ % //
57  | #h #t #IH whd in ⊢ (?(???%)) @breakup_pair whd in ⊢ (?%) % [ % [ % // | @(use_sig ? stmt_inv) ] | @IH ]
58] qed.
59
60definition init_vars : list (ident × region × (list init_data)) → Σs:stmt. stmt_inv s ≝
61λvars. foldr ? (Σs:stmt. stmt_inv s)
62  (λvar,s. dp ? (λx.stmt_inv x ) (St_seq s (init_var (\fst (\fst var)) (\snd (\fst var)) (\snd var))) ?) (dp ? (λx.stmt_inv x ) St_skip (conj ?? I I)) vars.
63% [ % [ % // | @(use_sig ? stmt_inv) ] | @(use_sig ? stmt_inv) ]
64qed.
65
66lemma no_labels : ∀s. stmt_inv s → labels_of s = [ ].
67#s elim s //
68[ #s1 #s2 #IH1 #IH2 * * * #_ #_ #H1 #H2 whd in ⊢ (??%?)
69  >(IH1 H1) >(IH2 H2) @refl
70| #sz #sg #e #s1 #s2 #IH1 #IH2 * * * #_ #_ #H1 #H2 whd in ⊢ (??%?)
71  >(IH1 H1) >(IH2 H2) @refl
72| #s #IH * * #_ #_ #H @(IH H)
73| #s #IH * * #_ #_ #H @(IH H)
74| #l #s #IH * * #_ *
75| #l #s #IH * * #_ #_ #H @(IH H)
76] qed.
77
78definition add_statement : ident → (Σs:stmt. stmt_inv s) →
79                              list (ident × (fundef internal_function)) →
80                              list (ident × (fundef internal_function)) ≝
81λid,s. match s with [ dp s H ⇒
82  map ??
83    (λidf.
84      let 〈id',f'〉 ≝ idf in
85      match ident_eq id id' with
86      [ inl _ ⇒
87          match f' with
88          [ Internal f ⇒ 〈id, Internal ? (mk_internal_function
89                                           (f_return f)
90                                           (f_params f)
91                                           (f_vars f)
92                                           (f_stacksize f)
93                                           (St_seq s (f_body f))
94                                           ?)〉
95          | External f ⇒ 〈id, External ? f〉 (* Error ? *)
96          ]
97      | inr _ ⇒ 〈id',f'〉 ]) ].
98%
99[ % [ % // |
100  @(stmt_P_mp … H) #s * #V #L %
101  [ @(stmt_vars_mp … V) #i *
102  | @(stmt_labels_mp … L) #l *
103  ]
104  ]
105| whd in ⊢ (?(λ_.??(?(λ_.???%)?))?) >(no_labels … H) @(f_inv f)
106] qed.
107
108definition empty_vars : list (ident × region × (list init_data)) →
109                        list (ident × region × nat) ≝
110map ?? (λv. 〈〈\fst (\fst v), \snd (\fst v)〉,
111              size_init_data_list (\snd v)〉).
112
113definition replace_init : Cminor_program → Cminor_noinit_program ≝
114λp.
115  mk_program ??
116    (empty_vars (prog_vars ?? p))
117    (add_statement (prog_main ?? p) (init_vars (prog_vars ?? p)) (prog_funct ?? p))
118    (prog_main ?? p).
Note: See TracBrowser for help on using the repository browser.