source: src/Cminor/initialisation.ma @ 2737

Last change on this file since 2737 was 2624, checked in by campbell, 8 years ago

Properly evict unused and axiomatised Floats.

File size: 4.8 KB
RevLine 
[758]1
2(* Replace initialisation of global variables with equivalent Cminor code. *)
3
[2601]4include "Cminor/Cminor_syntax.ma".
[758]5include "common/Globalenvs.ma".
6
[880]7(* XXX having to specify the return type in the match is annoying. *)
[1872]8definition init_expr : init_data → option (𝚺t:typ. expr t) ≝
[758]9λinit.
[1872]10match init return λ_.option (𝚺t:typ. expr t) with
[1878]11[ Init_int8 i          ⇒ Some ? (mk_DPair ?? (ASTint I8 Unsigned) (Cst ? (Ointconst I8 Unsigned i)))
12| Init_int16 i         ⇒ Some ? (mk_DPair ?? (ASTint I16 Unsigned) (Cst ? (Ointconst I16 Unsigned i)))
13| Init_int32 i         ⇒ Some ? (mk_DPair ?? (ASTint I32 Unsigned) (Cst ? (Ointconst I32 Unsigned i)))
[2624]14(*| Init_float32 f       ⇒ None ? (*Some ? (mk_DPair ?? (ASTfloat F32) (Cst ? (Ofloatconst F32 f)))*)
15| Init_float64 f       ⇒ None ? (*Some ? (mk_DPair ?? (ASTfloat F64) (Cst ? (Ofloatconst F64 f)))*)*)
[758]16| Init_space n         ⇒ None ?
[2176]17| Init_null            ⇒ Some ? (mk_DPair ?? ASTptr (Op1 (ASTint I8 Unsigned) ? (Optrofint ??) (Cst ? (Ointconst I8 Unsigned (zero ?)))))
18| Init_addrof   id off ⇒ Some ? (mk_DPair ?? ASTptr (Cst ? (Oaddrsymbol id off)))
[758]19].
20
[2251]21(* None of the additional code introduces locals, labels or returns. *)
[1316]22definition stmt_inv : stmt → Prop ≝
[2251]23  stmt_P (λs. stmt_vars (λ_.λ_.False) s ∧ stmt_labels (λ_.False) s ∧ match s with [ St_return _ ⇒ False | _ ⇒ True ]).
[1401]24 
25discriminator option.
[1605]26discriminator DPair.
[1316]27
[758]28(* Produces a few extra skips - hopefully the compiler will optimise these
29   away. *)
30
[1316]31definition init_datum : ident → region → init_data → nat (*offset*) → Σs:stmt. stmt_inv s ≝
[881]32λid,r,init,off.
[758]33match init_expr init with
34[ None ⇒ St_skip
35| Some x ⇒
[1872]36    match x with [ mk_DPair t e ⇒
[2176]37      St_store t (Cst ? (Oaddrsymbol id off)) e
[880]38    ]
[758]39].
[2252]40% /3/
[2624]41cases init in p; [ 5: | 6: #a #b | *: #a ] #p normalize in p;
[2252]42destruct;/4 by stmt_labels_mp, conj/
[1316]43qed.
[758]44
[1316]45definition init_var : ident → region → list init_data → Σs:stmt. stmt_inv s ≝
[881]46λid,r,init.
[758]47\snd (foldr ??
48  (λdatum,os.
49   let 〈off,s〉 ≝ os in
[961]50     〈off + (size_init_data datum), St_seq (init_datum id r datum off) s〉)
[1605]51  〈0, mk_Sig ? (λx.stmt_inv x) St_skip ?〉 init).
[2252]52[ % /3/
[1316]53| elim init
[2252]54  [ % /3/
55  | #h #t #IH whd in ⊢ (?(???%)); @breakup_pair
56    %
57    [ /3/
58    | % [ @(pi2 … (init_datum …)) | @IH ]
59    ]
[1316]60] qed.
[758]61
[1316]62definition init_vars : list (ident × region × (list init_data)) → Σs:stmt. stmt_inv s ≝
63λvars. foldr ? (Σs:stmt. stmt_inv s)
[2252]64  (λvar,s. mk_Sig ? (λx.stmt_inv x ) (St_seq s (init_var (\fst (\fst var)) (\snd (\fst var)) (\snd var))) ?) (mk_Sig ? (λx.stmt_inv x ) St_skip ?) vars.
65[ % [ /3/ | % [ @(pi2 … s) | @(pi2 … (init_var …)) ] ]
66| /4/
67] qed.
[758]68
[1316]69lemma no_labels : ∀s. stmt_inv s → labels_of s = [ ].
70#s elim s //
[2252]71[ #s1 #s2 #IH1 #IH2 * #_ * #H1 #H2 whd in ⊢ (??%?);
[1316]72  >(IH1 H1) >(IH2 H2) @refl
[2252]73| #sz #sg #e #s1 #s2 #IH1 #IH2 * #_ * #H1 #H2 whd in ⊢ (??%?);
[1316]74  >(IH1 H1) >(IH2 H2) @refl
[2251]75| #l #s #IH * * * #_ *
[2252]76| #l #s #IH * #_ #H @(IH H)
[1316]77] qed.
78
[2319]79(* FIXME: we need to add a new initialisation function instead of augmenting
80   main, because this currently breaks a recursive main function. *)
81
82definition add_statement : costlabel → ident → (Σs:stmt. stmt_inv s) →
[758]83                              list (ident × (fundef internal_function)) →
84                              list (ident × (fundef internal_function)) ≝
[2319]85λcost,id,s. match s with [ mk_Sig s H ⇒
[758]86  map ??
87    (λidf.
88      let 〈id',f'〉 ≝ idf in
89      match ident_eq id id' with
90      [ inl _ ⇒
91          match f' with
92          [ Internal f ⇒ 〈id, Internal ? (mk_internal_function
[887]93                                           (f_return f)
[758]94                                           (f_params f)
95                                           (f_vars f)
[1631]96                                           (f_distinct f)
[758]97                                           (f_stacksize f)
[2319]98                                           (St_cost cost (St_seq s (f_body f)))
[1316]99                                           ?)〉
[758]100          | External f ⇒ 〈id, External ? f〉 (* Error ? *)
101          ]
[1316]102      | inr _ ⇒ 〈id',f'〉 ]) ].
103%
[2252]104[ % //
105| %
[2319]106 [ % //
107 | % [ @(stmt_P_mp … H) #s * * #V #L #R %
[2252]108    [ @(stmt_vars_mp … V) #i #t *
109    | @(stmt_labels_mp … L) #l *
110    | cases s in R ⊢ %; // #x *
111    ]
112  | whd in match (labels_of ?); >(no_labels … H) @(f_inv f)
[1316]113  ]
[2319]114 ]
[1316]115] qed.
[758]116
[1139]117definition empty_vars : list (ident × region × (list init_data)) →
118                        list (ident × region × nat) ≝
119map ?? (λv. 〈〈\fst (\fst v), \snd (\fst v)〉,
120              size_init_data_list (\snd v)〉).
[758]121
[2319]122definition replace_init : costlabel → Cminor_program → Cminor_noinit_program ≝
123λcost,p.
[758]124  mk_program ??
[1224]125    (empty_vars (prog_vars ?? p))
[2319]126    (add_statement cost (prog_main ?? p) (init_vars (prog_vars ?? p)) (prog_funct ?? p))
[1599]127    (prog_main ?? p).
Note: See TracBrowser for help on using the repository browser.