Module CleanupLabelsproof


Correctness proof for clean-up of labels

From Coq Require Import FSets .
Require Import Coqlib Ordered Integers .
Require Import AST Linking .
Require Import Values Memory Events Globalenvs Smallstep .
Require Import Op Locations Linear .
Require Import CleanupLabels .

Module LabelsetFacts := FSetFacts.Facts (Labelset ).

Definition match_prog (p tp: Linear.program ) :=
match_program (fun ctx f tf => tf = transf_fundef f) eq p tp.

Lemma transf_program_match :
forall p, match_prog p (transf_program p).
Proof.
intros. eapply match_transform_program ; eauto.
Qed.

Section CLEANUP .

Variables prog tprog : program .
Hypothesis TRANSL : match_prog prog tprog .
Let ge := Genv.globalenv prog .
Let tge := Genv.globalenv tprog .

Lemma symbols_preserved :
forall id,
Genv.find_symbol tge id = Genv.find_symbol ge id.
Proof (Genv.find_symbol_transf TRANSL ).

Lemma senv_preserved :
Senv.equiv ge tge .
Proof (Genv.senv_transf TRANSL ).

Lemma functions_translated :
forall v f,
Genv.find_funct ge v = Some f ->
Genv.find_funct tge v = Some (transf_fundef f).
Proof (Genv.find_funct_transf TRANSL ).

Lemma function_ptr_translated :
forall v f,
Genv.find_funct_ptr ge v = Some f ->
Genv.find_funct_ptr tge v = Some (transf_fundef f).
Proof (Genv.find_funct_ptr_transf TRANSL ).

Lemma sig_function_translated :
forall f,
funsig (transf_fundef f) = funsig f.
Proof.
intros. destruct f; reflexivity.
Qed.

Lemma find_function_translated :
forall ros ls f,
find_function ge ros ls = Some f ->
find_function tge ros ls = Some (transf_fundef f).
Proof.
unfold find_function ; intros; destruct ros; simpl.
apply functions_translated ; auto.
rewrite symbols_preserved . destruct (Genv.find_symbol ge i).
apply function_ptr_translated ; auto.
congruence.
Qed.

Correctness of labels_branched_to.

Definition instr_branches_to (i: instruction ) (lbl: label ) : Prop :=
match i with
| Lgoto lbl' => lbl = lbl'
| Lcond cond args lbl' => lbl = lbl'
| Ljumptable arg tbl => In lbl tbl
| _ => False
end.

Remark add_label_branched_to_incr :
forall ls i, Labelset.Subset ls (add_label_branched_to ls i).
Proof.
intros; red; intros; destruct i; simpl; auto.
apply Labelset.add_2 ; auto.
apply Labelset.add_2 ; auto.
revert H; induction l; simpl. auto. intros; apply Labelset.add_2 ; auto.
Qed.

Remark add_label_branched_to_contains :
forall ls i lbl,
instr_branches_to i lbl ->
Labelset.In lbl (add_label_branched_to ls i).
Proof.
destruct i; simpl; intros; try contradiction.
apply Labelset.add_1 ; auto.
apply Labelset.add_1 ; auto.
revert H. induction l; simpl; intros.
contradiction.
destruct H. apply Labelset.add_1 ; auto. apply Labelset.add_2 ; auto.
Qed.

Lemma labels_branched_to_correct :
forall c i lbl,
In i c -> instr_branches_to i lbl -> Labelset.In lbl (labels_branched_to c).
Proof.
intros.
assert (forall c' bto,
Labelset.Subset bto (fold_left add_label_branched_to c' bto)).
induction c'; intros; simpl; red; intros.
auto.
apply IHc'. apply add_label_branched_to_incr ; auto.

assert (forall c' bto,
In i c' -> Labelset.In lbl (fold_left add_label_branched_to c' bto)).
induction c'; simpl; intros.
contradiction.
destruct H2.
subst a. apply H1. apply add_label_branched_to_contains ; auto.
apply IHc'; auto.

unfold labels_branched_to . auto.
Qed.

Commutation with find_label.

Lemma remove_unused_labels_cons :
forall bto i c,
remove_unused_labels bto (i :: c) =
match i with
| Llabel lbl =>
if Labelset.mem lbl bto then i :: remove_unused_labels bto c else remove_unused_labels bto c
| _ =>
i :: remove_unused_labels bto c
end.
Proof.
unfold remove_unused_labels ; intros. rewrite list_fold_right_eq . auto.
Qed.


Lemma find_label_commut :
forall lbl bto,
Labelset.In lbl bto ->
forall c c',
find_label lbl c = Some c' ->
find_label lbl (remove_unused_labels bto c) = Some (remove_unused_labels bto c').
Proof.
induction c; simpl; intros.
congruence.
rewrite remove_unused_labels_cons .
unfold is_label in H0. destruct a; simpl; auto.
destruct (peq lbl l). subst l. inv H0.
rewrite Labelset.mem_1 ; auto.
simpl. rewrite peq_true . auto.
destruct (Labelset.mem l bto); auto. simpl. rewrite peq_false ; auto.
Qed.

Corollary find_label_translated :
forall f i c' lbl c,
incl (i :: c') (fn_code f) ->
find_label lbl (fn_code f) = Some c ->
instr_branches_to i lbl ->
find_label lbl (fn_code (transf_function f)) =
Some (remove_unused_labels (labels_branched_to (fn_code f)) c).
Proof.
intros. unfold transf_function ; unfold cleanup_labels ; simpl.
apply find_label_commut . eapply labels_branched_to_correct ; eauto.
apply H; auto with coqlib.
auto.
Qed.

Lemma find_label_incl :
forall lbl c c', find_label lbl c = Some c' -> incl c' c.
Proof.
induction c; simpl; intros.
discriminate.
destruct (is_label lbl a). inv H; auto with coqlib. auto with coqlib.
Qed.

Correctness of clean-up

Inductive match_stackframes : stackframe -> stackframe -> Prop :=
| match_stackframe_intro :
forall f sp ls c,
incl c f.(fn_code ) ->
match_stackframes
(Stackframe f sp ls c)
(Stackframe (transf_function f) sp ls
(remove_unused_labels (labels_branched_to f.(fn_code )) c)).

Inductive match_states : state -> state -> Prop :=
| match_states_intro :
forall s f sp c ls m ts
(STACKS: list_forall2 match_stackframes s ts)
(INCL: incl c f.(fn_code )),
match_states (State s f sp c ls m)
(State ts (transf_function f) sp (remove_unused_labels (labels_branched_to f.(fn_code )) c) ls m)
| match_states_call :
forall s f ls m ts,
list_forall2 match_stackframes s ts ->
match_states (Callstate s f ls m)
(Callstate ts (transf_fundef f) ls m)
| match_states_return :
forall s ls m ts,
list_forall2 match_stackframes s ts ->
match_states (Returnstate s ls m)
(Returnstate ts ls m).

Definition measure (st: state ) : nat :=
match st with
| State s f sp c ls m => List.length c
| _ => O
end.

Lemma match_parent_locset :
forall s ts,
list_forall2 match_stackframes s ts ->
parent_locset ts = parent_locset s.
Proof.
induction 1; simpl. auto. inv H; auto.
Qed.

Theorem transf_step_correct :
forall s1 t s2, step ge s1 t s2 ->
forall s1' (MS: match_states s1 s1'),
(exists s2', step tge s1' t s2' /\ match_states s2 s2')
\/ (measure s2 < measure s1 /\ t = E0 /\ match_states s2 s1')%nat.
Proof.
induction 1; intros; inv MS; try rewrite remove_unused_labels_cons .
(* Lgetstack *)
left; econstructor; split.
econstructor; eauto.
econstructor; eauto with coqlib.
(* Lsetstack *)
left; econstructor; split.
econstructor; eauto.
econstructor; eauto with coqlib.
(* Lop *)
left; econstructor; split.
econstructor; eauto. instantiate (1 := v). rewrite <- H.
apply eval_operation_preserved . exact symbols_preserved .
econstructor; eauto with coqlib.
(* Lload *)
assert (eval_addressing tge sp addr (LTL.reglist rs args) = Some a).
rewrite <- H. apply eval_addressing_preserved . exact symbols_preserved .
left; econstructor; split.
econstructor; eauto.
econstructor; eauto with coqlib.
(* Lstore *)
assert (eval_addressing tge sp addr (LTL.reglist rs args) = Some a).
rewrite <- H. apply eval_addressing_preserved . exact symbols_preserved .
left; econstructor; split.
econstructor; eauto.
econstructor; eauto with coqlib.
(* Lcall *)
left; econstructor; split.
econstructor. eapply find_function_translated ; eauto.
symmetry; apply sig_function_translated .
econstructor; eauto. constructor; auto. constructor; eauto with coqlib.
(* Ltailcall *)
left; econstructor; split.
econstructor. erewrite match_parent_locset ; eauto. eapply find_function_translated ; eauto.
symmetry; apply sig_function_translated .
simpl. eauto.
econstructor; eauto.
(* Lbuiltin *)
left; econstructor; split.
econstructor.
eapply eval_builtin_args_preserved with (ge1 := ge ); eauto. exact symbols_preserved .
eapply external_call_symbols_preserved ; eauto. apply senv_preserved .
eauto.
econstructor; eauto with coqlib.
(* Llabel *)
case_eq (Labelset.mem lbl (labels_branched_to (fn_code f))); intros.
(* not eliminated *)
left; econstructor; split.
constructor.
econstructor; eauto with coqlib.
(* eliminated *)
right. split. simpl. lia. split. auto. econstructor; eauto with coqlib.
(* Lgoto *)
left; econstructor; split.
econstructor. eapply find_label_translated ; eauto. red; auto.
econstructor; eauto. eapply find_label_incl ; eauto.
(* Lcond taken *)
left; econstructor; split.
econstructor. auto. eauto. eapply find_label_translated ; eauto. red; auto.
econstructor; eauto. eapply find_label_incl ; eauto.
(* Lcond not taken *)
left; econstructor; split.
eapply exec_Lcond_false ; eauto.
econstructor; eauto with coqlib.
(* Ljumptable *)
left; econstructor; split.
econstructor. eauto. eauto. eapply find_label_translated ; eauto.
red. eapply list_nth_z_in ; eauto. eauto.
econstructor; eauto. eapply find_label_incl ; eauto.
(* Lreturn *)
left; econstructor; split.
econstructor; eauto.
erewrite <- match_parent_locset ; eauto.
econstructor; eauto with coqlib.
(* internal function *)
left; econstructor; split.
econstructor; simpl; eauto.
econstructor; eauto with coqlib.
(* external function *)
left; econstructor; split.
econstructor; eauto. eapply external_call_symbols_preserved ; eauto. apply senv_preserved .
econstructor; eauto with coqlib.
(* return *)
inv H3. inv H1. left; econstructor; split.
econstructor; eauto.
econstructor; eauto.
Qed.

Lemma transf_initial_states :
forall st1, initial_state prog st1 ->
exists st2, initial_state tprog st2 /\ match_states st1 st2.
Proof.
intros. inv H.
econstructor; split.
eapply initial_state_intro with (f := transf_fundef f).
eapply (Genv.init_mem_transf TRANSL ); eauto.
rewrite (match_program_main TRANSL ), symbols_preserved ; eauto.
apply function_ptr_translated ; auto.
rewrite sig_function_translated . auto.
constructor; auto. constructor.
Qed.

Lemma transf_final_states :
forall st1 st2 r,
match_states st1 st2 -> final_state st1 r -> final_state st2 r.
Proof.
intros. inv H0. inv H. inv H5. econstructor; eauto.
Qed.

Theorem transf_program_correct :
forward_simulation (Linear.semantics prog ) (Linear.semantics tprog ).
Proof.

End CLEANUP .


Generated by coq2html

AltStyle によって変換されたページ (->オリジナル) /