aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
-rw-r--r--backend/Tunnelingproof.v276
1 files changed, 210 insertions, 66 deletions
diff --git a/backend/Tunnelingproof.v b/backend/Tunnelingproof.v
index 602c018c..6acf2bbd 100644
--- a/backend/Tunnelingproof.v
+++ b/backend/Tunnelingproof.v
@@ -171,18 +171,6 @@ Proof.
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 (tunnel_fundef f).
-Proof.
- intros until f. destruct ros; simpl.
- intro. apply functions_translated; auto.
- rewrite symbols_preserved. destruct (Genv.find_symbol ge i).
- apply function_ptr_translated; auto.
- congruence.
-Qed.
-
(** The proof of semantic preservation is a simulation argument
based on diagrams of the following form:
<<
@@ -200,10 +188,11 @@ Qed.
"zero transition" case occurs when executing a [Lgoto] instruction
in the source code that has been removed by tunneling.
- In the definition of [match_states], note that only the control-flow
- (in particular, the current program point [pc]) is changed:
- the values of locations and the memory states are identical in the
- original and transformed codes. *)
+ In the definition of [match_states], what changes between the original and
+ transformed codes is mainly the control-flow
+ (in particular, the current program point [pc]), but also some values
+ and memory states, since some [Vundef] values can become more defined
+ as a consequence of eliminating useless [Lcond] instructions. *)
Definition tunneled_block (f: function) (b: bblock) :=
tunnel_block (record_gotos f) b.
@@ -211,39 +200,171 @@ Definition tunneled_block (f: function) (b: bblock) :=
Definition tunneled_code (f: function) :=
PTree.map1 (tunneled_block f) (fn_code f).
+Definition locmap_lessdef (ls1 ls2: locset) : Prop :=
+ forall l, Val.lessdef (ls1 l) (ls2 l).
+
Inductive match_stackframes: stackframe -> stackframe -> Prop :=
| match_stackframes_intro:
- forall f sp ls0 bb,
+ forall f sp ls0 bb tls0,
+ locmap_lessdef ls0 tls0 ->
match_stackframes
(Stackframe f sp ls0 bb)
- (Stackframe (tunnel_function f) sp ls0 (tunneled_block f bb)).
+ (Stackframe (tunnel_function f) sp tls0 (tunneled_block f bb)).
Inductive match_states: state -> state -> Prop :=
| match_states_intro:
- forall s f sp pc ls m ts,
- list_forall2 match_stackframes s ts ->
+ forall s f sp pc ls m ts tls tm
+ (STK: list_forall2 match_stackframes s ts)
+ (LS: locmap_lessdef ls tls)
+ (MEM: Mem.extends m tm),
match_states (State s f sp pc ls m)
- (State ts (tunnel_function f) sp (branch_target f pc) ls m)
+ (State ts (tunnel_function f) sp (branch_target f pc) tls tm)
| match_states_block:
- forall s f sp bb ls m ts,
- list_forall2 match_stackframes s ts ->
+ forall s f sp bb ls m ts tls tm
+ (STK: list_forall2 match_stackframes s ts)
+ (LS: locmap_lessdef ls tls)
+ (MEM: Mem.extends m tm),
match_states (Block s f sp bb ls m)
- (Block ts (tunnel_function f) sp (tunneled_block f bb) ls m)
+ (Block ts (tunnel_function f) sp (tunneled_block f bb) tls tm)
| match_states_interm:
- forall s f sp pc bb ls m ts,
- list_forall2 match_stackframes s ts ->
+ forall s f sp pc bb ls m ts tls tm
+ (STK: list_forall2 match_stackframes s ts)
+ (LS: locmap_lessdef ls tls)
+ (MEM: Mem.extends m tm),
match_states (Block s f sp (Lbranch pc :: bb) ls m)
- (State ts (tunnel_function f) sp (branch_target f pc) ls m)
+ (State ts (tunnel_function f) sp (branch_target f pc) tls tm)
| match_states_call:
- forall s f ls m ts,
- list_forall2 match_stackframes s ts ->
+ forall s f ls m ts tls tm
+ (STK: list_forall2 match_stackframes s ts)
+ (LS: locmap_lessdef ls tls)
+ (MEM: Mem.extends m tm),
match_states (Callstate s f ls m)
- (Callstate ts (tunnel_fundef f) ls m)
+ (Callstate ts (tunnel_fundef f) tls tm)
| match_states_return:
- forall s ls m ts,
- list_forall2 match_stackframes s ts ->
+ forall s ls m ts tls tm
+ (STK: list_forall2 match_stackframes s ts)
+ (LS: locmap_lessdef ls tls)
+ (MEM: Mem.extends m tm),
match_states (Returnstate s ls m)
- (Returnstate ts ls m).
+ (Returnstate ts tls tm).
+
+(** Properties of [locmap_lessdef] *)
+
+Lemma reglist_lessdef:
+ forall rl ls1 ls2,
+ locmap_lessdef ls1 ls2 -> Val.lessdef_list (reglist ls1 rl) (reglist ls2 rl).
+Proof.
+ induction rl; simpl; intros; auto.
+Qed.
+
+Lemma locmap_set_lessdef:
+ forall ls1 ls2 v1 v2 l,
+ locmap_lessdef ls1 ls2 -> Val.lessdef v1 v2 -> locmap_lessdef (Locmap.set l v1 ls1) (Locmap.set l v2 ls2).
+Proof.
+ intros; red; intros l'. unfold Locmap.set. destruct (Loc.eq l l').
+- destruct l; auto using Val.load_result_lessdef.
+- destruct (Loc.diff_dec l l'); auto.
+Qed.
+
+Lemma locmap_set_undef_lessdef:
+ forall ls1 ls2 l,
+ locmap_lessdef ls1 ls2 -> locmap_lessdef (Locmap.set l Vundef ls1) ls2.
+Proof.
+ intros; red; intros l'. unfold Locmap.set. destruct (Loc.eq l l').
+- destruct l; auto. destruct ty; auto.
+- destruct (Loc.diff_dec l l'); auto.
+Qed.
+
+Lemma locmap_undef_regs_lessdef:
+ forall rl ls1 ls2,
+ locmap_lessdef ls1 ls2 -> locmap_lessdef (undef_regs rl ls1) (undef_regs rl ls2).
+Proof.
+ induction rl as [ | r rl]; intros; simpl. auto. apply locmap_set_lessdef; auto.
+Qed.
+
+Lemma locmap_undef_regs_lessdef_1:
+ forall rl ls1 ls2,
+ locmap_lessdef ls1 ls2 -> locmap_lessdef (undef_regs rl ls1) ls2.
+Proof.
+ induction rl as [ | r rl]; intros; simpl. auto. apply locmap_set_undef_lessdef; auto.
+Qed.
+
+(*
+Lemma locmap_undef_lessdef:
+ forall ll ls1 ls2,
+ locmap_lessdef ls1 ls2 -> locmap_lessdef (Locmap.undef ll ls1) (Locmap.undef ll ls2).
+Proof.
+ induction ll as [ | l ll]; intros; simpl. auto. apply IHll. apply locmap_set_lessdef; auto.
+Qed.
+
+Lemma locmap_undef_lessdef_1:
+ forall ll ls1 ls2,
+ locmap_lessdef ls1 ls2 -> locmap_lessdef (Locmap.undef ll ls1) ls2.
+Proof.
+ induction ll as [ | l ll]; intros; simpl. auto. apply IHll. apply locmap_set_undef_lessdef; auto.
+Qed.
+*)
+
+Lemma locmap_getpair_lessdef:
+ forall p ls1 ls2,
+ locmap_lessdef ls1 ls2 -> Val.lessdef (Locmap.getpair p ls1) (Locmap.getpair p ls2).
+Proof.
+ intros; destruct p; simpl; auto using Val.longofwords_lessdef.
+Qed.
+
+Lemma locmap_getpairs_lessdef:
+ forall pl ls1 ls2,
+ locmap_lessdef ls1 ls2 ->
+ Val.lessdef_list (map (fun p => Locmap.getpair p ls1) pl) (map (fun p => Locmap.getpair p ls2) pl).
+Proof.
+ intros. induction pl; simpl; auto using locmap_getpair_lessdef.
+Qed.
+
+Lemma locmap_setpair_lessdef:
+ forall p ls1 ls2 v1 v2,
+ locmap_lessdef ls1 ls2 -> Val.lessdef v1 v2 -> locmap_lessdef (Locmap.setpair p v1 ls1) (Locmap.setpair p v2 ls2).
+Proof.
+ intros; destruct p; simpl; auto using locmap_set_lessdef, Val.loword_lessdef, Val.hiword_lessdef.
+Qed.
+
+Lemma locmap_setres_lessdef:
+ forall res ls1 ls2 v1 v2,
+ locmap_lessdef ls1 ls2 -> Val.lessdef v1 v2 -> locmap_lessdef (Locmap.setres res v1 ls1) (Locmap.setres res v2 ls2).
+Proof.
+ induction res; intros; simpl; auto using locmap_set_lessdef, Val.loword_lessdef, Val.hiword_lessdef.
+Qed.
+
+Lemma find_function_translated:
+ forall ros ls tls fd,
+ locmap_lessdef ls tls ->
+ find_function ge ros ls = Some fd ->
+ find_function tge ros tls = Some (tunnel_fundef fd).
+Proof.
+ intros. destruct ros; simpl in *.
+- assert (E: tls (R m) = ls (R m)).
+ { exploit Genv.find_funct_inv; eauto. intros (b & EQ).
+ generalize (H (R m)). rewrite EQ. intros LD; inv LD. auto. }
+ rewrite E. apply functions_translated; auto.
+- rewrite symbols_preserved. destruct (Genv.find_symbol ge i); inv H0.
+ apply function_ptr_translated; auto.
+Qed.
+
+Lemma call_regs_lessdef:
+ forall ls1 ls2, locmap_lessdef ls1 ls2 -> locmap_lessdef (call_regs ls1) (call_regs ls2).
+Proof.
+ intros; red; intros. destruct l as [r | [] ofs ty]; simpl; auto.
+Qed.
+
+Lemma return_regs_lessdef:
+ forall caller1 callee1 caller2 callee2,
+ locmap_lessdef caller1 caller2 ->
+ locmap_lessdef callee1 callee2 ->
+ locmap_lessdef (return_regs caller1 callee1) (return_regs caller2 callee2).
+Proof.
+ intros; red; intros. destruct l; simpl.
+- destruct (Conventions1.is_callee_save r); auto.
+- auto.
+Qed.
(** To preserve non-terminating behaviours, we show that the transformed
code cannot take an infinity of "zero transition" cases.
@@ -262,9 +383,11 @@ Definition measure (st: state) : nat :=
Lemma match_parent_locset:
forall s ts,
list_forall2 match_stackframes s ts ->
- parent_locset ts = parent_locset s.
+ locmap_lessdef (parent_locset s) (parent_locset ts).
Proof.
- induction 1; simpl. auto. inv H; auto.
+ induction 1; simpl.
+- red; auto.
+- inv H; auto.
Qed.
Lemma tunnel_step_correct:
@@ -278,7 +401,7 @@ Proof.
- (* entering a block *)
assert (DEFAULT: branch_target f pc = pc ->
(exists st2' : state,
- step tge (State ts (tunnel_function f) sp (branch_target f pc) rs m) E0 st2'
+ step tge (State ts (tunnel_function f) sp (branch_target f pc) tls tm) E0 st2'
/\ match_states (Block s f sp bb rs m) st2')).
{ intros. rewrite H0. econstructor; split.
econstructor. simpl. rewrite PTree.gmap1. rewrite H. simpl. eauto.
@@ -292,53 +415,63 @@ Proof.
rewrite B. econstructor; eauto.
- (* Lop *)
+ exploit eval_operation_lessdef. apply reglist_lessdef; eauto. eauto. eauto.
+ intros (tv & EV & LD).
left; simpl; econstructor; split.
- eapply exec_Lop with (v := v); eauto.
- rewrite <- H. apply eval_operation_preserved. exact symbols_preserved.
- econstructor; eauto.
+ eapply exec_Lop with (v := tv); eauto.
+ rewrite <- EV. apply eval_operation_preserved. exact symbols_preserved.
+ econstructor; eauto using locmap_set_lessdef, locmap_undef_regs_lessdef.
- (* Lload *)
+ exploit eval_addressing_lessdef. apply reglist_lessdef; eauto. eauto.
+ intros (ta & EV & LD).
+ exploit Mem.loadv_extends. eauto. eauto. eexact LD.
+ intros (tv & LOAD & LD').
left; simpl; econstructor; split.
- eapply exec_Lload with (a := a).
- rewrite <- H. apply eval_addressing_preserved. exact symbols_preserved.
+ eapply exec_Lload with (a := ta).
+ rewrite <- EV. apply eval_addressing_preserved. exact symbols_preserved.
eauto. eauto.
- econstructor; eauto.
+ econstructor; eauto using locmap_set_lessdef, locmap_undef_regs_lessdef.
- (* Lgetstack *)
left; simpl; econstructor; split.
econstructor; eauto.
- econstructor; eauto.
+ econstructor; eauto using locmap_set_lessdef, locmap_undef_regs_lessdef.
- (* Lsetstack *)
left; simpl; econstructor; split.
econstructor; eauto.
- econstructor; eauto.
+ econstructor; eauto using locmap_set_lessdef, locmap_undef_regs_lessdef.
- (* Lstore *)
+ exploit eval_addressing_lessdef. apply reglist_lessdef; eauto. eauto.
+ intros (ta & EV & LD).
+ exploit Mem.storev_extends. eauto. eauto. eexact LD. apply LS.
+ intros (tm' & STORE & MEM').
left; simpl; econstructor; split.
- eapply exec_Lstore with (a := a).
- rewrite <- H. apply eval_addressing_preserved. exact symbols_preserved.
+ eapply exec_Lstore with (a := ta).
+ rewrite <- EV. apply eval_addressing_preserved. exact symbols_preserved.
eauto. eauto.
- econstructor; eauto.
+ econstructor; eauto using locmap_undef_regs_lessdef.
- (* Lcall *)
left; simpl; econstructor; split.
eapply exec_Lcall with (fd := tunnel_fundef fd); eauto.
- apply find_function_translated; auto.
+ eapply find_function_translated; eauto.
rewrite sig_preserved. auto.
econstructor; eauto.
constructor; auto.
constructor; auto.
- (* Ltailcall *)
+ exploit Mem.free_parallel_extends. eauto. eauto. intros (tm' & FREE & MEM').
left; simpl; econstructor; split.
eapply exec_Ltailcall with (fd := tunnel_fundef fd); eauto.
- erewrite match_parent_locset; eauto.
- apply find_function_translated; auto.
+ eapply find_function_translated; eauto using return_regs_lessdef, match_parent_locset.
apply sig_preserved.
- erewrite <- match_parent_locset; eauto.
- econstructor; eauto.
+ econstructor; eauto using return_regs_lessdef, match_parent_locset.
- (* Lbuiltin *)
+ exploit eval_builtin_args_lessdef. eexact LS. eauto. eauto. intros (tvargs & EVA & LDA).
+ exploit external_call_mem_extends; eauto. intros (tvres & tm' & A & B & C & D).
left; simpl; econstructor; split.
eapply exec_Lbuiltin; eauto.
- eapply eval_builtin_args_preserved with (ge1 := ge); eauto. exact symbols_preserved.
+ eapply eval_builtin_args_preserved with (ge1 := ge); eauto. exact symbols_preserved.
eapply external_call_symbols_preserved. apply senv_preserved. eauto.
- econstructor; eauto.
-
+ econstructor; eauto using locmap_setres_lessdef, locmap_undef_regs_lessdef.
- (* Lbranch (preserved) *)
left; simpl; econstructor; split.
eapply exec_Lbranch; eauto.
@@ -352,32 +485,40 @@ Proof.
destruct (peq s1 s2).
+ left; econstructor; split.
eapply exec_Lbranch.
- destruct b. constructor; auto. rewrite e. constructor; auto.
+ destruct b.
+* constructor; eauto using locmap_undef_regs_lessdef_1.
+* rewrite e. constructor; eauto using locmap_undef_regs_lessdef_1.
+ left; econstructor; split.
- eapply exec_Lcond; eauto.
- destruct b; econstructor; eauto.
+ eapply exec_Lcond; eauto. eapply eval_condition_lessdef; eauto using reglist_lessdef.
+ destruct b; econstructor; eauto using locmap_undef_regs_lessdef.
- (* Ljumptable *)
+ assert (tls (R arg) = Vint n).
+ { generalize (LS (R arg)); rewrite H; intros LD; inv LD; auto. }
left; simpl; econstructor; split.
eapply exec_Ljumptable.
eauto. rewrite list_nth_z_map. change U.elt with node. rewrite H0. reflexivity. eauto.
- econstructor; eauto.
+ econstructor; eauto using locmap_undef_regs_lessdef.
- (* Lreturn *)
+ exploit Mem.free_parallel_extends. eauto. eauto. intros (tm' & FREE & MEM').
left; simpl; econstructor; split.
eapply exec_Lreturn; eauto.
- erewrite <- match_parent_locset; eauto.
- constructor; auto.
+ constructor; eauto using return_regs_lessdef, match_parent_locset.
- (* internal function *)
+ exploit Mem.alloc_extends. eauto. eauto. apply Zle_refl. apply Zle_refl.
+ intros (tm' & ALLOC & MEM').
left; simpl; econstructor; split.
eapply exec_function_internal; eauto.
- simpl. econstructor; eauto.
+ simpl. econstructor; eauto using locmap_undef_regs_lessdef, call_regs_lessdef.
- (* external function *)
+ exploit external_call_mem_extends; eauto using locmap_getpairs_lessdef.
+ intros (tvres & tm' & A & B & C & D).
left; simpl; econstructor; split.
eapply exec_function_external; eauto.
eapply external_call_symbols_preserved; eauto. apply senv_preserved.
- simpl. econstructor; eauto.
+ simpl. econstructor; eauto using locmap_setpair_lessdef.
- (* return *)
- inv H3. inv H1.
+ inv STK. inv H1.
left; econstructor; split.
eapply exec_return; eauto.
constructor; auto.
@@ -395,14 +536,17 @@ Proof.
rewrite symbols_preserved. eauto.
apply function_ptr_translated; auto.
rewrite <- H3. apply sig_preserved.
- constructor. constructor.
+ constructor. constructor. red; simpl; auto. apply Mem.extends_refl.
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.
+ intros. inv H0. inv H. inv STK.
+ set (p := map_rpair R (Conventions1.loc_result signature_main)) in *.
+ generalize (locmap_getpair_lessdef p _ _ LS). rewrite H1; intros LD; inv LD.
+ econstructor; eauto.
Qed.
Theorem transf_program_correct: