From 255cee09b71255051c2b40eae0c88bffce1f6f32 Mon Sep 17 00:00:00 2001 From: xleroy Date: Sat, 20 Apr 2013 07:54:52 +0000 Subject: Big merge of the newregalloc-int64 branch. Lots of changes in two directions: 1- new register allocator (+ live range splitting, spilling&reloading, etc) based on a posteriori validation using the Rideau-Leroy algorithm 2- support for 64-bit integer arithmetic (type "long long"). git-svn-id: https://yquem.inria.fr/compcert/svn/compcert/trunk@2200 fca1b0fc-160b-0410-b1d3-a4f43f01ea2e --- backend/Linearizeproof.v | 462 +++++++++++++++++++++++------------------------ 1 file changed, 223 insertions(+), 239 deletions(-) (limited to 'backend/Linearizeproof.v') diff --git a/backend/Linearizeproof.v b/backend/Linearizeproof.v index d3683110..25485802 100644 --- a/backend/Linearizeproof.v +++ b/backend/Linearizeproof.v @@ -12,10 +12,11 @@ (** Correctness proof for code linearization *) +Require Import FSets. Require Import Coqlib. Require Import Maps. Require Import Ordered. -Require Import FSets. +Require Import Lattice. Require Import AST. Require Import Integers. Require Import Values. @@ -27,17 +28,15 @@ Require Import Smallstep. Require Import Op. Require Import Locations. Require Import LTL. -Require Import LTLtyping. -Require Import LTLin. +Require Import Linear. Require Import Linearize. -Require Import Lattice. Module NodesetFacts := FSetFacts.Facts(Nodeset). Section LINEARIZATION. Variable prog: LTL.program. -Variable tprog: LTLin.program. +Variable tprog: Linear.program. Hypothesis TRANSF: transf_program prog = OK tprog. @@ -70,7 +69,7 @@ Proof (Genv.find_var_info_transf_partial transf_fundef _ TRANSF). Lemma sig_preserved: forall f tf, transf_fundef f = OK tf -> - LTLin.funsig tf = LTL.funsig f. + Linear.funsig tf = LTL.funsig f. Proof. unfold transf_fundef, transf_partial_fundef; intros. destruct f. monadInv H. monadInv EQ. reflexivity. @@ -80,7 +79,7 @@ Qed. Lemma stacksize_preserved: forall f tf, transf_function f = OK tf -> - LTLin.fn_stacksize tf = LTL.fn_stacksize f. + Linear.fn_stacksize tf = LTL.fn_stacksize f. Proof. intros. monadInv H. auto. Qed. @@ -117,8 +116,8 @@ Qed. (** The successors of a reachable instruction are reachable. *) Lemma reachable_successors: - forall f pc pc' i, - f.(LTL.fn_code)!pc = Some i -> In pc' (successors_instr i) -> + forall f pc pc' b, + f.(LTL.fn_code)!pc = Some b -> In pc' (successors_block b) -> (reachable f)!!pc = true -> (reachable f)!!pc' = true. Proof. @@ -222,7 +221,7 @@ Qed. (** * Properties related to labels *) -(** If labels are globally unique and the LTLin code [c] contains +(** If labels are globally unique and the Linear code [c] contains a subsequence [Llabel lbl :: c1], then [find_label lbl c] returns [c1]. *) @@ -284,13 +283,13 @@ Proof. intros. unfold add_branch. destruct (starts_with s k); auto. Qed. -Lemma find_label_lin_instr: +Lemma find_label_lin_block: forall lbl k b, - find_label lbl (linearize_instr b k) = find_label lbl k. + find_label lbl (linearize_block b k) = find_label lbl k. Proof. intros lbl k. generalize (find_label_add_branch lbl k); intro. - induction b; simpl; auto. - case (starts_with n k); simpl; auto. + induction b; simpl; auto. destruct a; simpl; auto. + case (starts_with s1 k); simpl; auto. Qed. Remark linearize_body_cons: @@ -298,7 +297,7 @@ Remark linearize_body_cons: linearize_body f (pc :: enum) = match f.(LTL.fn_code)!pc with | None => linearize_body f enum - | Some b => Llabel pc :: linearize_instr b (linearize_body f enum) + | Some b => Llabel pc :: linearize_block b (linearize_body f enum) end. Proof. intros. unfold linearize_body. rewrite list_fold_right_eq. @@ -309,7 +308,7 @@ Lemma find_label_lin_rec: forall f enum pc b, In pc enum -> f.(LTL.fn_code)!pc = Some b -> - exists k, find_label pc (linearize_body f enum) = Some (linearize_instr b k). + exists k, find_label pc (linearize_body f enum) = Some (linearize_block b k). Proof. induction enum; intros. elim H. @@ -320,7 +319,7 @@ Proof. assert (In pc enum). simpl in H. tauto. destruct (IHenum pc b H1 H0) as [k FIND]. exists k. destruct (LTL.fn_code f)!a. - simpl. rewrite peq_false. rewrite find_label_lin_instr. auto. auto. + simpl. rewrite peq_false. rewrite find_label_lin_block. auto. auto. auto. Qed. @@ -330,7 +329,7 @@ Lemma find_label_lin: f.(LTL.fn_code)!pc = Some b -> (reachable f)!!pc = true -> exists k, - find_label pc (fn_code tf) = Some (linearize_instr b k). + find_label pc (fn_code tf) = Some (linearize_block b k). Proof. intros. monadInv H. simpl. rewrite find_label_add_branch. apply find_label_lin_rec. @@ -343,25 +342,12 @@ Lemma find_label_lin_inv: f.(LTL.fn_code)!pc = Some b -> (reachable f)!!pc = true -> find_label pc (fn_code tf) = Some k -> - exists k', k = linearize_instr b k'. + exists k', k = linearize_block b k'. Proof. intros. exploit find_label_lin; eauto. intros [k' FIND]. exists k'. congruence. Qed. -Lemma find_label_lin_succ: - forall f tf s, - transf_function f = OK tf -> - valid_successor f s -> - (reachable f)!!s = true -> - exists k, - find_label s (fn_code tf) = Some k. -Proof. - intros. destruct H0 as [i AT]. - exploit find_label_lin; eauto. intros [k FIND]. - exists (linearize_instr i k); auto. -Qed. - (** Unique label property for linearized code. *) Lemma label_in_add_branch: @@ -372,16 +358,16 @@ Proof. destruct (starts_with s k); simpl; intuition congruence. Qed. -Lemma label_in_lin_instr: +Lemma label_in_lin_block: forall lbl k b, - In (Llabel lbl) (linearize_instr b k) -> In (Llabel lbl) k. + In (Llabel lbl) (linearize_block b k) -> In (Llabel lbl) k. Proof. - induction b; simpl; intros; - try (apply label_in_add_branch with n; intuition congruence); - try (intuition congruence). - destruct (starts_with n k); simpl in H. - apply label_in_add_branch with n; intuition congruence. - apply label_in_add_branch with n0; intuition congruence. + induction b; simpl; intros. auto. + destruct a; simpl in H; try (intuition congruence). + apply label_in_add_branch with s; intuition congruence. + destruct (starts_with s1 k); simpl in H. + apply label_in_add_branch with s1; intuition congruence. + apply label_in_add_branch with s2; intuition congruence. Qed. Lemma label_in_lin_rec: @@ -392,7 +378,7 @@ Proof. simpl; auto. rewrite linearize_body_cons. destruct (LTL.fn_code f)!a. simpl. intros [A|B]. left; congruence. - right. apply IHenum. eapply label_in_lin_instr; eauto. + right. apply IHenum. eapply label_in_lin_block; eauto. intro; right; auto. Qed. @@ -404,12 +390,13 @@ Proof. destruct (starts_with lbl k); simpl; intuition. Qed. -Lemma unique_labels_lin_instr: +Lemma unique_labels_lin_block: forall k b, - unique_labels k -> unique_labels (linearize_instr b k). + unique_labels k -> unique_labels (linearize_block b k). Proof. - induction b; intro; simpl; auto; try (apply unique_labels_add_branch; auto). - case (starts_with n k); simpl; apply unique_labels_add_branch; auto. + induction b; intros; simpl. auto. + destruct a; auto; try (apply unique_labels_add_branch; auto). + case (starts_with s1 k); simpl; apply unique_labels_add_branch; auto. Qed. Lemma unique_labels_lin_rec: @@ -423,8 +410,8 @@ Proof. intro. destruct (LTL.fn_code f)!a. simpl. split. red. intro. inversion H. elim H3. apply label_in_lin_rec with f. - apply label_in_lin_instr with i. auto. - apply unique_labels_lin_instr. apply IHenum. inversion H; auto. + apply label_in_lin_block with b. auto. + apply unique_labels_lin_block. apply IHenum. inversion H; auto. apply IHenum. inversion H; auto. Qed. @@ -458,6 +445,17 @@ Proof. auto. eauto with coqlib. Qed. +Lemma is_tail_lin_block: + forall b c1 c2, + is_tail (linearize_block b c1) c2 -> is_tail c1 c2. +Proof. + induction b; simpl; intros. + auto. + destruct a; eauto with coqlib. + eapply is_tail_add_branch; eauto. + destruct (starts_with s1 c1); eapply is_tail_add_branch; eauto with coqlib. +Qed. + Lemma add_branch_correct: forall lbl c k s f tf sp ls m, transf_function f = OK tf -> @@ -475,12 +473,11 @@ Qed. (** * Correctness of linearization *) -(** The proof of semantic preservation is a simulation argument - based on diagrams of the following form: +(** The proof of semantic preservation is a simulation argument of the "star" kind: << st1 --------------- st2 | | - t| +|t + t| t| + or ( 0 \/ |st1'| < |st1| ) | | v v st1'--------------- st2' @@ -492,273 +489,260 @@ Qed. control-flow graph, the transformed state is at a code sequence [c] that starts with the label [pc]. *) -Inductive match_stackframes: LTL.stackframe -> LTLin.stackframe -> Prop := +Inductive match_stackframes: LTL.stackframe -> Linear.stackframe -> Prop := | match_stackframe_intro: - forall res f sp pc ls tf c, + forall f sp bb ls tf c, transf_function f = OK tf -> - (reachable f)!!pc = true -> - valid_successor f pc -> - is_tail c (fn_code tf) -> - wt_function f -> + (forall pc, In pc (successors_block bb) -> (reachable f)!!pc = true) -> + is_tail c tf.(fn_code) -> match_stackframes - (LTL.Stackframe res f sp ls pc) - (LTLin.Stackframe res tf sp ls (add_branch pc c)). + (LTL.Stackframe f sp ls bb) + (Linear.Stackframe tf sp ls (linearize_block bb c)). -Inductive match_states: LTL.state -> LTLin.state -> Prop := - | match_states_intro: +Inductive match_states: LTL.state -> Linear.state -> Prop := + | match_states_add_branch: forall s f sp pc ls m tf ts c (STACKS: list_forall2 match_stackframes s ts) (TRF: transf_function f = OK tf) (REACH: (reachable f)!!pc = true) - (AT: find_label pc (fn_code tf) = Some c) - (WTF: wt_function f), + (TAIL: is_tail c tf.(fn_code)), match_states (LTL.State s f sp pc ls m) - (LTLin.State ts tf sp c ls m) + (Linear.State ts tf sp (add_branch pc c) ls m) + | match_states_cond_taken: + forall s f sp pc ls m tf ts cond args c + (STACKS: list_forall2 match_stackframes s ts) + (TRF: transf_function f = OK tf) + (REACH: (reachable f)!!pc = true) + (JUMP: eval_condition cond (reglist ls args) m = Some true), + match_states (LTL.State s f sp pc (undef_regs (destroyed_by_cond cond) ls) m) + (Linear.State ts tf sp (Lcond cond args pc :: c) ls m) + | match_states_jumptable: + forall s f sp pc ls m tf ts arg tbl c n + (STACKS: list_forall2 match_stackframes s ts) + (TRF: transf_function f = OK tf) + (REACH: (reachable f)!!pc = true) + (ARG: ls (R arg) = Vint n) + (JUMP: list_nth_z tbl (Int.unsigned n) = Some pc), + match_states (LTL.State s f sp pc (undef_regs destroyed_by_jumptable ls) m) + (Linear.State ts tf sp (Ljumptable arg tbl :: c) ls m) + | match_states_block: + forall s f sp bb ls m tf ts c + (STACKS: list_forall2 match_stackframes s ts) + (TRF: transf_function f = OK tf) + (REACH: forall pc, In pc (successors_block bb) -> (reachable f)!!pc = true) + (TAIL: is_tail c tf.(fn_code)), + match_states (LTL.Block s f sp bb ls m) + (Linear.State ts tf sp (linearize_block bb c) ls m) | match_states_call: forall s f ls m tf ts, list_forall2 match_stackframes s ts -> transf_fundef f = OK tf -> - wt_fundef f -> match_states (LTL.Callstate s f ls m) - (LTLin.Callstate ts tf ls m) + (Linear.Callstate ts tf ls m) | match_states_return: forall s ls m ts, list_forall2 match_stackframes s ts -> match_states (LTL.Returnstate s ls m) - (LTLin.Returnstate ts ls m). + (Linear.Returnstate ts ls m). -Hypothesis wt_prog: wt_program prog. +Definition measure (S: LTL.state) : nat := + match S with + | LTL.State s f sp pc ls m => 0%nat + | LTL.Block s f sp bb ls m => 1%nat + | _ => 0%nat + end. + +Remark match_parent_locset: + forall s ts, list_forall2 match_stackframes s ts -> parent_locset ts = LTL.parent_locset s. +Proof. + induction 1; simpl. auto. inv H; auto. +Qed. Theorem transf_step_correct: forall s1 t s2, LTL.step ge s1 t s2 -> forall s1' (MS: match_states s1 s1'), - exists s2', plus LTLin.step tge s1' t s2' /\ match_states s2 s2'. -Proof. - induction 1; intros; try (inv MS); - try (generalize (wt_instrs _ WTF _ _ H); intro WTI). - (* Lnop *) - destruct (find_label_lin_inv _ _ _ _ _ TRF H REACH AT) as [c' EQ]. - simpl in EQ. subst c. - assert (REACH': (reachable f)!!pc' = true). - eapply reachable_successors; eauto. simpl; auto. - exploit find_label_lin_succ; eauto. inv WTI; auto. intros [c'' AT']. - econstructor; split. - eapply add_branch_correct; eauto. - eapply is_tail_add_branch. eapply is_tail_find_label. eauto. + (exists s2', plus Linear.step tge s1' t s2' /\ match_states s2 s2') + \/ (measure s2 < measure s1 /\ t = E0 /\ match_states s2 s1')%nat. +Proof. + induction 1; intros; try (inv MS). + + (* start of block, at an [add_branch] *) + exploit find_label_lin; eauto. intros [k F]. + left; econstructor; split. + eapply add_branch_correct; eauto. + econstructor; eauto. + intros; eapply reachable_successors; eauto. + eapply is_tail_lin_block; eauto. eapply is_tail_find_label; eauto. + + (* start of block, target of an [Lcond] *) + exploit find_label_lin; eauto. intros [k F]. + left; econstructor; split. + apply plus_one. eapply exec_Lcond_true; eauto. + econstructor; eauto. + intros; eapply reachable_successors; eauto. + eapply is_tail_lin_block; eauto. eapply is_tail_find_label; eauto. + + (* start of block, target of an [Ljumptable] *) + exploit find_label_lin; eauto. intros [k F]. + left; econstructor; split. + apply plus_one. eapply exec_Ljumptable; eauto. econstructor; eauto. + intros; eapply reachable_successors; eauto. + eapply is_tail_lin_block; eauto. eapply is_tail_find_label; eauto. + (* Lop *) - destruct (find_label_lin_inv _ _ _ _ _ TRF H REACH AT) as [c' EQ]. - simpl in EQ. subst c. - assert (REACH': (reachable f)!!pc' = true). - eapply reachable_successors; eauto. simpl; auto. - exploit find_label_lin_succ; eauto. inv WTI; auto. intros [c'' AT']. - econstructor; split. - eapply plus_left'. - eapply exec_Lop with (v := v); eauto. - rewrite <- H0. apply eval_operation_preserved. exact symbols_preserved. - eapply add_branch_correct; eauto. - eapply is_tail_add_branch. eapply is_tail_cons_left. - eapply is_tail_find_label. eauto. - traceEq. - econstructor; eauto. + left; econstructor; split. simpl. + apply plus_one. econstructor; eauto. + instantiate (1 := v); rewrite <- H; apply eval_operation_preserved. + exact symbols_preserved. + econstructor; eauto. + (* Lload *) - destruct (find_label_lin_inv _ _ _ _ _ TRF H REACH AT) as [c' EQ]. - simpl in EQ. subst c. - assert (REACH': (reachable f)!!pc' = true). - eapply reachable_successors; eauto. simpl; auto. - exploit find_label_lin_succ; eauto. inv WTI; auto. intros [c'' AT']. - econstructor; split. - eapply plus_left'. - apply exec_Lload with a. - rewrite <- H0. apply eval_addressing_preserved. exact symbols_preserved. - eauto. - eapply add_branch_correct; eauto. - eapply is_tail_add_branch. eapply is_tail_cons_left. - eapply is_tail_find_label. eauto. - traceEq. + left; econstructor; split. simpl. + apply plus_one. econstructor. + instantiate (1 := a). rewrite <- H; apply eval_addressing_preserved. + exact symbols_preserved. eauto. eauto. + econstructor; eauto. + + (* Lgetstack *) + left; econstructor; split. simpl. + apply plus_one. econstructor; eauto. + econstructor; eauto. + + (* Lsetstack *) + left; econstructor; split. simpl. + apply plus_one. econstructor; eauto. econstructor; eauto. + (* Lstore *) - destruct (find_label_lin_inv _ _ _ _ _ TRF H REACH AT) as [c' EQ]. - simpl in EQ. subst c. - assert (REACH': (reachable f)!!pc' = true). - eapply reachable_successors; eauto. simpl; auto. - exploit find_label_lin_succ; eauto. inv WTI; auto. intros [c'' AT']. - econstructor; split. - eapply plus_left'. - apply exec_Lstore with a. - rewrite <- H0. apply eval_addressing_preserved. exact symbols_preserved. - eauto. - eapply add_branch_correct; eauto. - eapply is_tail_add_branch. eapply is_tail_cons_left. - eapply is_tail_find_label. eauto. - traceEq. + left; econstructor; split. simpl. + apply plus_one. econstructor. + instantiate (1 := a). rewrite <- H; apply eval_addressing_preserved. + exact symbols_preserved. eauto. eauto. econstructor; eauto. + (* Lcall *) - destruct (find_label_lin_inv _ _ _ _ _ TRF H REACH AT) as [c' EQ]. - simpl in EQ. subst c. - assert (REACH': (reachable f)!!pc' = true). - eapply reachable_successors; eauto. simpl; auto. - assert (VALID: valid_successor f pc'). inv WTI; auto. - exploit find_function_translated; eauto. intros [tf' [A B]]. - econstructor; split. - apply plus_one. eapply exec_Lcall with (f' := tf'); eauto. - symmetry; apply sig_preserved; auto. - econstructor; eauto. - constructor; auto. econstructor; eauto. - eapply is_tail_add_branch. eapply is_tail_cons_left. - eapply is_tail_find_label. eauto. - destruct ros; simpl in H0. - eapply Genv.find_funct_prop; eauto. - destruct (Genv.find_symbol ge i); try discriminate. - eapply Genv.find_funct_ptr_prop; eauto. + exploit find_function_translated; eauto. intros [tfd [A B]]. + left; econstructor; split. simpl. + apply plus_one. econstructor; eauto. + symmetry; eapply sig_preserved; eauto. + econstructor; eauto. constructor; auto. econstructor; eauto. (* Ltailcall *) - destruct (find_label_lin_inv _ _ _ _ _ TRF H REACH AT) as [c' EQ]. - simpl in EQ. subst c. - exploit find_function_translated; eauto. intros [tf' [A B]]. - econstructor; split. - apply plus_one. eapply exec_Ltailcall with (f' := tf'); eauto. - symmetry; apply sig_preserved; auto. - rewrite (stacksize_preserved _ _ TRF). eauto. + exploit find_function_translated; eauto. intros [tfd [A B]]. + left; econstructor; split. simpl. + apply plus_one. econstructor; eauto. + rewrite (match_parent_locset _ _ STACKS). eauto. + symmetry; eapply sig_preserved; eauto. + rewrite (stacksize_preserved _ _ TRF); eauto. + rewrite (match_parent_locset _ _ STACKS). econstructor; eauto. - destruct ros; simpl in H0. - eapply Genv.find_funct_prop; eauto. - destruct (Genv.find_symbol ge i); try discriminate. - eapply Genv.find_funct_ptr_prop; eauto. (* Lbuiltin *) - destruct (find_label_lin_inv _ _ _ _ _ TRF H REACH AT) as [c' EQ]. - simpl in EQ. subst c. - assert (REACH': (reachable f)!!pc' = true). - eapply reachable_successors; eauto. simpl; auto. - exploit find_label_lin_succ; eauto. inv WTI; auto. intros [c'' AT']. - econstructor; split. - eapply plus_left'. - eapply exec_Lbuiltin. - eapply external_call_symbols_preserved; eauto. + left; econstructor; split. simpl. + apply plus_one. eapply exec_Lbuiltin; eauto. + eapply external_call_symbols_preserved'; eauto. + exact symbols_preserved. exact varinfo_preserved. + econstructor; eauto. + + (* Lannot *) + left; econstructor; split. simpl. + apply plus_one. eapply exec_Lannot; eauto. + eapply external_call_symbols_preserved'; eauto. exact symbols_preserved. exact varinfo_preserved. - eapply add_branch_correct; eauto. - eapply is_tail_add_branch. eapply is_tail_cons_left. - eapply is_tail_find_label. eauto. - traceEq. econstructor; eauto. + (* Lbranch *) + assert ((reachable f)!!pc = true). apply REACH; simpl; auto. + right; split. simpl; omega. split. auto. simpl. econstructor; eauto. + (* Lcond *) - destruct (find_label_lin_inv _ _ _ _ _ TRF H REACH AT) as [c' EQ]. - simpl in EQ. subst c. + assert (REACH1: (reachable f)!!pc1 = true) by (apply REACH; simpl; auto). + assert (REACH2: (reachable f)!!pc2 = true) by (apply REACH; simpl; auto). + simpl linearize_block. + destruct (starts_with pc1 c). + (* branch if cond is false *) + assert (DC: destroyed_by_cond (negate_condition cond) = destroyed_by_cond cond). + destruct cond; reflexivity. destruct b. - (* true *) - assert (REACH': (reachable f)!!ifso = true). - eapply reachable_successors; eauto. simpl; auto. - exploit find_label_lin_succ; eauto. inv WTI; eauto. intros [c'' AT']. - destruct (starts_with ifso c'). - econstructor; split. - eapply plus_left'. - eapply exec_Lcond_false; eauto. - rewrite eval_negate_condition; rewrite H0; auto. - eapply add_branch_correct; eauto. - eapply is_tail_add_branch. eapply is_tail_cons_left. - eapply is_tail_find_label. eauto. - traceEq. - econstructor; eauto. - econstructor; split. - apply plus_one. eapply exec_Lcond_true; eauto. - econstructor; eauto. - (* false *) - assert (REACH': (reachable f)!!ifnot = true). - eapply reachable_successors; eauto. simpl; auto. - exploit find_label_lin_succ; eauto. inv WTI; auto. intros [c'' AT']. - destruct (starts_with ifso c'). - econstructor; split. - apply plus_one. eapply exec_Lcond_true; eauto. - rewrite eval_negate_condition; rewrite H0; auto. - econstructor; eauto. - econstructor; split. - eapply plus_left'. - eapply exec_Lcond_false; eauto. - eapply add_branch_correct; eauto. - eapply is_tail_add_branch. eapply is_tail_cons_left. - eapply is_tail_find_label. eauto. - traceEq. + (* cond is true: no branch *) + left; econstructor; split. + apply plus_one. eapply exec_Lcond_false. + rewrite eval_negate_condition. rewrite H. auto. eauto. + rewrite DC. econstructor; eauto. + (* cond is false: branch is taken *) + right; split. simpl; omega. split. auto. rewrite <- DC. econstructor; eauto. + rewrite eval_negate_condition. rewrite H. auto. + (* branch if cond is true *) + destruct b. + (* cond is true: branch is taken *) + right; split. simpl; omega. split. auto. econstructor; eauto. + (* cond is false: no branch *) + left; econstructor; split. + apply plus_one. eapply exec_Lcond_false. eauto. eauto. econstructor; eauto. (* Ljumptable *) - destruct (find_label_lin_inv _ _ _ _ _ TRF H REACH AT) as [c' EQ]. - simpl in EQ. subst c. - assert (REACH': (reachable f)!!pc' = true). - eapply reachable_successors; eauto. simpl. eapply list_nth_z_in; eauto. - exploit find_label_lin_succ; eauto. - inv WTI. apply H6. eapply list_nth_z_in; eauto. - intros [c'' AT']. - econstructor; split. - apply plus_one. eapply exec_Ljumptable; eauto. - econstructor; eauto. + assert (REACH': (reachable f)!!pc = true). + apply REACH. simpl. eapply list_nth_z_in; eauto. + right; split. simpl; omega. split. auto. econstructor; eauto. (* Lreturn *) - destruct (find_label_lin_inv _ _ _ _ _ TRF H REACH AT) as [c' EQ]. - simpl in EQ. subst c. - econstructor; split. - apply plus_one. eapply exec_Lreturn; eauto. + left; econstructor; split. + simpl. apply plus_one. econstructor; eauto. rewrite (stacksize_preserved _ _ TRF). eauto. - econstructor; eauto. - - (* internal function *) + rewrite (match_parent_locset _ _ STACKS). econstructor; eauto. + + (* internal functions *) assert (REACH: (reachable f)!!(LTL.fn_entrypoint f) = true). apply reachable_entrypoint. - inv H7. monadInv H6. - exploit find_label_lin_succ; eauto. inv H1; auto. intros [c'' AT']. - generalize EQ; intro. monadInv EQ0. econstructor; simpl; split. - eapply plus_left'. - eapply exec_function_internal; eauto. - simpl. eapply add_branch_correct. eauto. - simpl. eapply is_tail_add_branch. constructor. eauto. - traceEq. - econstructor; eauto. + monadInv H7. + left; econstructor; split. + apply plus_one. eapply exec_function_internal; eauto. + rewrite (stacksize_preserved _ _ EQ). eauto. + generalize EQ; intro EQ'; monadInv EQ'. simpl. + econstructor; eauto. simpl. eapply is_tail_add_branch. constructor. (* external function *) - monadInv H6. econstructor; split. + monadInv H8. left; econstructor; split. apply plus_one. eapply exec_function_external; eauto. - eapply external_call_symbols_preserved; eauto. + eapply external_call_symbols_preserved'; eauto. exact symbols_preserved. exact varinfo_preserved. econstructor; eauto. (* return *) inv H3. inv H1. - exploit find_label_lin_succ; eauto. intros [c' AT]. - econstructor; split. - eapply plus_left'. - eapply exec_return; eauto. - eapply add_branch_correct; eauto. traceEq. - econstructor; eauto. + left; econstructor; split. + apply plus_one. econstructor. + econstructor; eauto. Qed. Lemma transf_initial_states: forall st1, LTL.initial_state prog st1 -> - exists st2, LTLin.initial_state tprog st2 /\ match_states st1 st2. + exists st2, Linear.initial_state tprog st2 /\ match_states st1 st2. Proof. intros. inversion H. exploit function_ptr_translated; eauto. intros [tf [A B]]. - exists (Callstate nil tf nil m0); split. + exists (Callstate nil tf (Locmap.init Vundef) m0); split. econstructor; eauto. eapply Genv.init_mem_transf_partial; eauto. replace (prog_main tprog) with (prog_main prog). rewrite symbols_preserved. eauto. symmetry. apply (transform_partial_program_main transf_fundef _ TRANSF). rewrite <- H3. apply sig_preserved. auto. constructor. constructor. auto. - eapply Genv.find_funct_ptr_prop; eauto. Qed. Lemma transf_final_states: forall st1 st2 r, - match_states st1 st2 -> LTL.final_state st1 r -> LTLin.final_state st2 r. + match_states st1 st2 -> LTL.final_state st1 r -> Linear.final_state st2 r. Proof. - intros. inv H0. inv H. inv H4. constructor. + intros. inv H0. inv H. inv H6. econstructor; eauto. Qed. Theorem transf_program_correct: - forward_simulation (LTL.semantics prog) (LTLin.semantics tprog). + forward_simulation (LTL.semantics prog) (Linear.semantics tprog). Proof. - eapply forward_simulation_plus. + eapply forward_simulation_star. eexact symbols_preserved. eexact transf_initial_states. eexact transf_final_states. -- cgit