diff options
Diffstat (limited to 'backend/Coloringproof.v')
-rw-r--r-- | backend/Coloringproof.v | 957 |
1 files changed, 0 insertions, 957 deletions
diff --git a/backend/Coloringproof.v b/backend/Coloringproof.v deleted file mode 100644 index 8ebc87e..0000000 --- a/backend/Coloringproof.v +++ /dev/null @@ -1,957 +0,0 @@ -(* *********************************************************************) -(* *) -(* The Compcert verified compiler *) -(* *) -(* Xavier Leroy, INRIA Paris-Rocquencourt *) -(* *) -(* Copyright Institut National de Recherche en Informatique et en *) -(* Automatique. All rights reserved. This file is distributed *) -(* under the terms of the INRIA Non-Commercial License Agreement. *) -(* *) -(* *********************************************************************) - -(** Correctness of graph coloring. *) - -Require Import SetoidList. -Require Import Coqlib. -Require Import Maps. -Require Import AST. -Require Import Op. -Require Import Registers. -Require Import RTL. -Require Import RTLtyping. -Require Import Locations. -Require Import Conventions. -Require Import InterfGraph. -Require Import Coloring. - -(** * Correctness of the interference graph *) - -(** We show that the interference graph built by [interf_graph] - is correct in the sense that it contains all conflict edges - that we need. - - Many boring lemmas on the auxiliary functions used to construct - the interference graph follow. The lemmas are of two kinds: - the ``increasing'' lemmas show that the auxiliary functions only add - edges to the interference graph, but do not remove existing edges; - and the ``correct'' lemmas show that the auxiliary functions - correctly add the edges that we'd like them to add. *) - -Lemma graph_incl_refl: - forall g, graph_incl g g. -Proof. - intros; split; auto. -Qed. - -Lemma add_interf_live_incl_aux: - forall (filter: reg -> bool) res live g, - graph_incl g - (List.fold_left - (fun g r => if filter r then add_interf r res g else g) - live g). -Proof. - induction live; simpl; intros. - apply graph_incl_refl. - apply graph_incl_trans with (if filter a then add_interf a res g else g). - case (filter a). - apply add_interf_incl. - apply graph_incl_refl. - apply IHlive. -Qed. - -Lemma add_interf_live_incl: - forall (filter: reg -> bool) res live g, - graph_incl g (add_interf_live filter res live g). -Proof. - intros. unfold add_interf_live. rewrite Regset.fold_1. - apply add_interf_live_incl_aux. -Qed. - -Lemma add_interf_live_correct_aux: - forall filter res r live, - InA Regset.E.eq r live -> filter r = true -> - forall g, - interfere r res - (List.fold_left - (fun g r => if filter r then add_interf r res g else g) - live g). -Proof. - induction 1; simpl; intros. - hnf in H. subst y. rewrite H0. - generalize (add_interf_live_incl_aux filter res l (add_interf r res g)). - intros [A B]. - apply A. apply add_interf_correct. - apply IHInA; auto. -Qed. - -Lemma add_interf_live_correct: - forall filter res live g r, - Regset.In r live -> - filter r = true -> - interfere r res (add_interf_live filter res live g). -Proof. - intros. unfold add_interf_live. rewrite Regset.fold_1. - apply add_interf_live_correct_aux; auto. - apply Regset.elements_1. auto. -Qed. - -Lemma add_interf_op_incl: - forall res live g, - graph_incl g (add_interf_op res live g). -Proof. - intros; unfold add_interf_op. apply add_interf_live_incl. -Qed. - -Lemma add_interf_op_correct: - forall res live g r, - Regset.In r live -> - r <> res -> - interfere r res (add_interf_op res live g). -Proof. - intros. unfold add_interf_op. - apply add_interf_live_correct. - auto. destruct (Reg.eq r res); congruence. -Qed. - -Lemma add_interf_move_incl: - forall arg res live g, - graph_incl g (add_interf_move arg res live g). -Proof. - intros; unfold add_interf_move. apply add_interf_live_incl. -Qed. - -Lemma add_interf_move_correct: - forall arg res live g r, - Regset.In r live -> - r <> arg -> r <> res -> - interfere r res (add_interf_move arg res live g). -Proof. - intros. unfold add_interf_move. - apply add_interf_live_correct. - auto. - rewrite dec_eq_false; auto. rewrite dec_eq_false; auto. -Qed. - -Lemma add_interf_destroyed_incl_aux_1: - forall mr live g, - graph_incl g - (List.fold_left (fun g r => add_interf_mreg r mr g) live g). -Proof. - induction live; simpl; intros. - apply graph_incl_refl. - apply graph_incl_trans with (add_interf_mreg a mr g). - apply add_interf_mreg_incl. - auto. -Qed. - -Lemma add_interf_destroyed_incl_aux_2: - forall mr live g, - graph_incl g - (Regset.fold (fun r g => add_interf_mreg r mr g) live g). -Proof. - intros. rewrite Regset.fold_1. apply add_interf_destroyed_incl_aux_1. -Qed. - -Lemma add_interf_destroyed_incl: - forall live destroyed g, - graph_incl g (add_interf_destroyed live destroyed g). -Proof. - induction destroyed; simpl; intros. - apply graph_incl_refl. - eapply graph_incl_trans; [idtac|apply IHdestroyed]. - apply add_interf_destroyed_incl_aux_2. -Qed. - -Lemma add_interfs_indirect_call_incl: - forall rfun locs g, - graph_incl g (add_interfs_indirect_call rfun locs g). -Proof. - unfold add_interfs_indirect_call. induction locs; simpl; intros. - apply graph_incl_refl. - destruct a. eapply graph_incl_trans; [idtac|eauto]. - apply add_interf_mreg_incl. - auto. -Qed. - -Lemma add_interfs_call_incl: - forall ros locs g, - graph_incl g (add_interf_call ros locs g). -Proof. - intros. unfold add_interf_call. destruct ros. - apply add_interfs_indirect_call_incl. - apply graph_incl_refl. -Qed. - -Lemma interfere_incl: - forall r1 r2 g1 g2, - graph_incl g1 g2 -> - interfere r1 r2 g1 -> - interfere r1 r2 g2. -Proof. - unfold graph_incl; intros. elim H; auto. -Qed. - -Lemma interfere_mreg_incl: - forall r1 r2 g1 g2, - graph_incl g1 g2 -> - interfere_mreg r1 r2 g1 -> - interfere_mreg r1 r2 g2. -Proof. - unfold graph_incl; intros. elim H; auto. -Qed. - -Lemma add_interf_destroyed_correct_aux_1: - forall mr r live, - InA Regset.E.eq r live -> - forall g, - interfere_mreg r mr - (List.fold_left (fun g r => add_interf_mreg r mr g) live g). -Proof. - induction 1; simpl; intros. - hnf in H; subst y. eapply interfere_mreg_incl. - apply add_interf_destroyed_incl_aux_1. - apply add_interf_mreg_correct. - auto. -Qed. - -Lemma add_interf_destroyed_correct_aux_2: - forall mr live g r, - Regset.In r live -> - interfere_mreg r mr - (Regset.fold (fun r g => add_interf_mreg r mr g) live g). -Proof. - intros. rewrite Regset.fold_1. apply add_interf_destroyed_correct_aux_1. - apply Regset.elements_1. auto. -Qed. - -Lemma add_interf_destroyed_correct: - forall live destroyed g r mr, - Regset.In r live -> - In mr destroyed -> - interfere_mreg r mr (add_interf_destroyed live destroyed g). -Proof. - induction destroyed; simpl; intros. - elim H0. - elim H0; intros. - subst a. eapply interfere_mreg_incl. - apply add_interf_destroyed_incl. - apply add_interf_destroyed_correct_aux_2; auto. - apply IHdestroyed; auto. -Qed. - -Lemma add_interfs_indirect_call_correct: - forall rfun mr locs g, - In (R mr) locs -> - interfere_mreg rfun mr (add_interfs_indirect_call rfun locs g). -Proof. - unfold add_interfs_indirect_call. induction locs; simpl; intros. - elim H. - destruct H. subst a. - eapply interfere_mreg_incl. - apply (add_interfs_indirect_call_incl rfun locs (add_interf_mreg rfun mr g)). - apply add_interf_mreg_correct. - auto. -Qed. - -Lemma add_interfs_call_correct: - forall rfun locs g mr, - In (R mr) locs -> - interfere_mreg rfun mr (add_interf_call (inl _ rfun) locs g). -Proof. - intros. unfold add_interf_call. - apply add_interfs_indirect_call_correct. auto. -Qed. - -Lemma add_prefs_call_incl: - forall args locs g, - graph_incl g (add_prefs_call args locs g). -Proof. - induction args; destruct locs; simpl; intros; - try apply graph_incl_refl. - destruct l. - eapply graph_incl_trans; [idtac|eauto]. - apply add_pref_mreg_incl. - auto. -Qed. - -Lemma add_prefs_builtin_incl: - forall ef args res g, - graph_incl g (add_prefs_builtin ef args res g). -Proof. - intros. unfold add_prefs_builtin. - destruct ef; try apply graph_incl_refl. - destruct args; try apply graph_incl_refl. - apply add_pref_incl. -Qed. - -Lemma add_interf_entry_incl: - forall params live g, - graph_incl g (add_interf_entry params live g). -Proof. - unfold add_interf_entry; induction params; simpl; intros. - apply graph_incl_refl. - eapply graph_incl_trans; [idtac|eauto]. - apply add_interf_op_incl. -Qed. - -Lemma add_interf_entry_correct: - forall params live g r1 r2, - In r1 params -> - Regset.In r2 live -> - r1 <> r2 -> - interfere r1 r2 (add_interf_entry params live g). -Proof. - unfold add_interf_entry; induction params; simpl; intros. - elim H. - elim H; intro. - subst a. apply interfere_incl with (add_interf_op r1 live g). - exact (add_interf_entry_incl _ _ _). - apply interfere_sym. apply add_interf_op_correct; auto. - auto. -Qed. - -Lemma add_interf_params_incl_aux: - forall p1 pl g, - graph_incl g - (List.fold_left - (fun g r => if Reg.eq r p1 then g else add_interf r p1 g) - pl g). -Proof. - induction pl; simpl; intros. - apply graph_incl_refl. - eapply graph_incl_trans; [idtac|eauto]. - case (Reg.eq a p1); intro. - apply graph_incl_refl. apply add_interf_incl. -Qed. - -Lemma add_interf_params_incl: - forall pl g, - graph_incl g (add_interf_params pl g). -Proof. - induction pl; simpl; intros. - apply graph_incl_refl. - eapply graph_incl_trans; [idtac|eauto]. - apply add_interf_params_incl_aux. -Qed. - -Lemma add_interf_params_correct_aux: - forall p1 pl g p2, - In p2 pl -> - p1 <> p2 -> - interfere p1 p2 - (List.fold_left - (fun g r => if Reg.eq r p1 then g else add_interf r p1 g) - pl g). -Proof. - induction pl; simpl; intros. - elim H. - elim H; intro; clear H. - subst a. apply interfere_sym. eapply interfere_incl. - apply add_interf_params_incl_aux. - case (Reg.eq p2 p1); intro. - congruence. apply add_interf_correct. - auto. -Qed. - -Lemma add_interf_params_correct: - forall pl g r1 r2, - In r1 pl -> In r2 pl -> r1 <> r2 -> - interfere r1 r2 (add_interf_params pl g). -Proof. - induction pl; simpl; intros. - elim H. - elim H; intro; clear H; elim H0; intro; clear H0. - congruence. - subst a. eapply interfere_incl. apply add_interf_params_incl. - apply add_interf_params_correct_aux; auto. - subst a. apply interfere_sym. - eapply interfere_incl. apply add_interf_params_incl. - apply add_interf_params_correct_aux; auto. - auto. -Qed. - -Lemma add_edges_instr_incl: - forall sig instr live g, - graph_incl g (add_edges_instr sig instr live g). -Proof. - intros. destruct instr; unfold add_edges_instr; - try apply graph_incl_refl. - case (Regset.mem r live). - destruct (is_move_operation o l). - eapply graph_incl_trans; [idtac|apply add_pref_incl]. - apply add_interf_move_incl. - apply add_interf_op_incl. - apply graph_incl_refl. - case (Regset.mem r live). - apply add_interf_op_incl. - apply graph_incl_refl. - eapply graph_incl_trans; [idtac|apply add_prefs_call_incl]. - eapply graph_incl_trans; [idtac|apply add_pref_mreg_incl]. - eapply graph_incl_trans; [idtac|apply add_interf_op_incl]. - eapply graph_incl_trans; [idtac|apply add_interfs_call_incl]. - apply add_interf_destroyed_incl. - eapply graph_incl_trans; [idtac|apply add_prefs_call_incl]. - apply add_interfs_call_incl. - eapply graph_incl_trans. apply add_interf_op_incl. apply add_prefs_builtin_incl. - destruct o. - apply add_pref_mreg_incl. - apply graph_incl_refl. -Qed. - -(** The proposition below states that graph [g] contains - all the conflict edges expected for instruction [instr]. *) - -Definition correct_interf_instr - (live: Regset.t) (instr: instruction) (g: graph) : Prop := - match instr with - | Iop op args res s => - match is_move_operation op args with - | Some arg => - forall r, - Regset.In res live -> - Regset.In r live -> - r <> res -> r <> arg -> interfere r res g - | None => - forall r, - Regset.In res live -> - Regset.In r live -> - r <> res -> interfere r res g - end - | Iload chunk addr args res s => - forall r, - Regset.In res live -> - Regset.In r live -> - r <> res -> interfere r res g - | Icall sig ros args res s => - (forall r mr, - Regset.In r live -> - In mr destroyed_at_call_regs -> - r <> res -> - interfere_mreg r mr g) - /\ (forall r, - Regset.In r live -> - r <> res -> interfere r res g) - /\ (match ros with - | inl rfun => forall mr, In (R mr) (loc_arguments sig) -> - interfere_mreg rfun mr g - | inr idfun => True - end) - | Itailcall sig ros args => - match ros with - | inl rfun => forall mr, In (R mr) (loc_arguments sig) -> - interfere_mreg rfun mr g - | inr idfun => True - end - | Ibuiltin ef args res s => - forall r, - Regset.In r live -> - r <> res -> interfere r res g - | _ => - True - end. - -Lemma correct_interf_instr_incl: - forall live instr g1 g2, - graph_incl g1 g2 -> - correct_interf_instr live instr g1 -> - correct_interf_instr live instr g2. -Proof. - intros until g2. intro. - unfold correct_interf_instr; destruct instr; auto. - destruct (is_move_operation o l). - intros. eapply interfere_incl; eauto. - intros. eapply interfere_incl; eauto. - intros. eapply interfere_incl; eauto. - intros [A [B C]]. - split. intros. eapply interfere_mreg_incl; eauto. - split. intros. eapply interfere_incl; eauto. - destruct s0; auto. intros. eapply interfere_mreg_incl; eauto. - destruct s0; auto. intros. eapply interfere_mreg_incl; eauto. - intros. eapply interfere_incl; eauto. -Qed. - -Lemma add_edges_instr_correct: - forall sig instr live g, - correct_interf_instr live instr (add_edges_instr sig instr live g). -Proof. - intros. - destruct instr; unfold add_edges_instr; unfold correct_interf_instr; auto. - destruct (is_move_operation o l); intros. - rewrite Regset.mem_1; auto. eapply interfere_incl. - apply add_pref_incl. apply add_interf_move_correct; auto. - rewrite Regset.mem_1; auto. apply add_interf_op_correct; auto. - - intros. rewrite Regset.mem_1; auto. apply add_interf_op_correct; auto. - - (* Icall *) - set (largs := loc_arguments s). - set (lres := loc_result s). - split. intros. - apply interfere_mreg_incl with - (add_interf_destroyed (Regset.remove r live) destroyed_at_call_regs g). - eapply graph_incl_trans; [idtac|apply add_prefs_call_incl]. - eapply graph_incl_trans; [idtac|apply add_pref_mreg_incl]. - eapply graph_incl_trans; [idtac|apply add_interf_op_incl]. - apply add_interfs_call_incl. - apply add_interf_destroyed_correct; auto. - apply Regset.remove_2; auto. - - split. intros. - eapply interfere_incl. - eapply graph_incl_trans; [idtac|apply add_prefs_call_incl]. - apply add_pref_mreg_incl. - apply add_interf_op_correct; auto. - - destruct s0; auto; intros. - eapply interfere_mreg_incl. - eapply graph_incl_trans; [idtac|apply add_prefs_call_incl]. - eapply graph_incl_trans; [idtac|apply add_pref_mreg_incl]. - apply add_interf_op_incl. - apply add_interfs_call_correct. auto. - - (* Itailcall *) - destruct s0; auto; intros. - eapply interfere_mreg_incl. - apply add_prefs_call_incl. - apply add_interfs_call_correct. auto. - - (* Ibuiltin *) - intros. eapply interfere_incl. apply add_prefs_builtin_incl. - apply add_interf_op_correct; auto. -Qed. - -Lemma add_edges_instrs_correct: - forall f live pc i, - f.(fn_code)!pc = Some i -> - correct_interf_instr live!!pc i (add_edges_instrs f live). -Proof. - intros f live. - set (P := fun (c: code) g => - forall pc i, c!pc = Some i -> correct_interf_instr live#pc i g). - set (F := (fun (g : graph) (pc0 : positive) (i0 : instruction) => - add_edges_instr (fn_sig f) i0 live # pc0 g)). - change (P f.(fn_code) (PTree.fold F f.(fn_code) empty_graph)). - apply PTree_Properties.fold_rec; unfold P; intros. - apply H0. rewrite H. auto. - rewrite PTree.gempty in H. congruence. - rewrite PTree.gsspec in H2. destruct (peq pc k). - inv H2. unfold F. apply add_edges_instr_correct. - apply correct_interf_instr_incl with a. - unfold F; apply add_edges_instr_incl. - apply H1; auto. -Qed. - -(** Here are the three correctness properties of the generated - inference graph. First, it contains the conflict edges - needed by every instruction of the function. *) - -Lemma interf_graph_correct_1: - forall f live live0 pc i, - f.(fn_code)!pc = Some i -> - correct_interf_instr live!!pc i (interf_graph f live live0). -Proof. - intros. unfold interf_graph. - apply correct_interf_instr_incl with (add_edges_instrs f live). - eapply graph_incl_trans; [idtac|apply add_prefs_call_incl]. - eapply graph_incl_trans; [idtac|apply add_interf_params_incl]. - apply add_interf_entry_incl. - apply add_edges_instrs_correct; auto. -Qed. - -(** Second, function parameters conflict pairwise. *) - -Lemma interf_graph_correct_2: - forall f live live0 r1 r2, - In r1 f.(fn_params) -> - In r2 f.(fn_params) -> - r1 <> r2 -> - interfere r1 r2 (interf_graph f live live0). -Proof. - intros. unfold interf_graph. - eapply interfere_incl. - apply add_prefs_call_incl. - apply add_interf_params_correct; auto. -Qed. - -(** Third, function parameters conflict pairwise with pseudo-registers - live at function entry. If the function never uses a pseudo-register - before it is defined, pseudo-registers live at function entry - are a subset of the function parameters and therefore this condition - is implied by [interf_graph_correct_3]. However, we prefer not - to make this assumption. *) - -Lemma interf_graph_correct_3: - forall f live live0 r1 r2, - In r1 f.(fn_params) -> - Regset.In r2 live0 -> - r1 <> r2 -> - interfere r1 r2 (interf_graph f live live0). -Proof. - intros. unfold interf_graph. - eapply interfere_incl. - eapply graph_incl_trans; [idtac|apply add_prefs_call_incl]. - apply add_interf_params_incl. - apply add_interf_entry_correct; auto. -Qed. - -(** * Correctness of the a priori checks over the result of graph coloring *) - -(** We now show that the checks performed over the candidate coloring - returned by [graph_coloring] are correct: candidate colorings that - pass these checks are indeed correct colorings. *) - -Section CORRECT_COLORING. - -Variable g: graph. -Variable env: regenv. -Variable allregs: Regset.t. -Variable coloring: reg -> loc. - -Lemma check_coloring_1_correct: - forall r1 r2, - check_coloring_1 g coloring = true -> - SetRegReg.In (r1, r2) g.(interf_reg_reg) -> - coloring r1 <> coloring r2. -Proof. - unfold check_coloring_1. intros. - assert (compat_bool OrderedRegReg.eq - (fun r1r2 => if Loc.eq (coloring (fst r1r2)) (coloring (snd r1r2)) - then false else true)). - red. unfold OrderedRegReg.eq. unfold OrderedReg.eq. - intros x y [EQ1 EQ2]. rewrite EQ1; rewrite EQ2; auto. - generalize (SetRegReg.for_all_2 H1 H H0). - simpl. case (Loc.eq (coloring r1) (coloring r2)); intro. - intro; discriminate. auto. -Qed. - -Lemma check_coloring_2_correct: - forall r1 mr2, - check_coloring_2 g coloring = true -> - SetRegMreg.In (r1, mr2) g.(interf_reg_mreg) -> - coloring r1 <> R mr2. -Proof. - unfold check_coloring_2. intros. - assert (compat_bool OrderedRegMreg.eq - (fun r1r2 => if Loc.eq (coloring (fst r1r2)) (R (snd r1r2)) - then false else true)). - red. unfold OrderedRegMreg.eq. unfold OrderedReg.eq. - intros x y [EQ1 EQ2]. rewrite EQ1; rewrite EQ2; auto. - generalize (SetRegMreg.for_all_2 H1 H H0). - simpl. case (Loc.eq (coloring r1) (R mr2)); intro. - intro; discriminate. auto. -Qed. - -Lemma same_typ_correct: - forall t1 t2, same_typ t1 t2 = true -> t1 = t2. -Proof. - destruct t1; destruct t2; simpl; congruence. -Qed. - -Lemma loc_is_acceptable_correct: - forall l, loc_is_acceptable l = true -> loc_acceptable l. -Proof. - destruct l; unfold loc_is_acceptable, loc_acceptable. - case (In_dec Loc.eq (R m) temporaries); intro. - intro; discriminate. auto. - destruct s. - case (zlt z 0); intro. intro; discriminate. auto. - intro; discriminate. - intro; discriminate. -Qed. - -Lemma check_coloring_3_correct: - forall r, - check_coloring_3 allregs env coloring = true -> - Regset.mem r allregs = true -> - loc_acceptable (coloring r) /\ env r = Loc.type (coloring r). -Proof. - unfold check_coloring_3; intros. - exploit Regset.for_all_2; eauto. - red; intros. congruence. - apply Regset.mem_2. eauto. - simpl. intro. elim (andb_prop _ _ H1); intros. - split. apply loc_is_acceptable_correct; auto. - apply same_typ_correct; auto. -Qed. - -End CORRECT_COLORING. - -(** * Correctness of clipping *) - -(** We then show the correctness of the ``clipped'' coloring - returned by [alloc_of_coloring] applied to a candidate coloring - that passes the a posteriori checks. *) - -Section ALLOC_OF_COLORING. - -Variable g: graph. -Variable env: regenv. -Let allregs := all_interf_regs g. -Variable coloring: reg -> loc. -Let alloc := alloc_of_coloring coloring env allregs. - -Lemma alloc_of_coloring_correct_1: - forall r1 r2, - check_coloring g env allregs coloring = true -> - SetRegReg.In (r1, r2) g.(interf_reg_reg) -> - alloc r1 <> alloc r2. -Proof. - unfold check_coloring, alloc, alloc_of_coloring; intros. - elim (andb_prop _ _ H); intros. - generalize (all_interf_regs_correct_1 _ _ _ H0). - intros [A B]. - unfold allregs. rewrite Regset.mem_1; auto. rewrite Regset.mem_1; auto. - eapply check_coloring_1_correct; eauto. -Qed. - -Lemma alloc_of_coloring_correct_2: - forall r1 mr2, - check_coloring g env allregs coloring = true -> - SetRegMreg.In (r1, mr2) g.(interf_reg_mreg) -> - alloc r1 <> R mr2. -Proof. - unfold check_coloring, alloc, alloc_of_coloring; intros. - elim (andb_prop _ _ H); intros. - elim (andb_prop _ _ H2); intros. - generalize (all_interf_regs_correct_2 _ _ _ H0). intros. - unfold allregs. rewrite Regset.mem_1; auto. - eapply check_coloring_2_correct; eauto. -Qed. - -Lemma alloc_of_coloring_correct_3: - forall r, - check_coloring g env allregs coloring = true -> - loc_acceptable (alloc r). -Proof. - unfold check_coloring, alloc, alloc_of_coloring; intros. - elim (andb_prop _ _ H); intros. - elim (andb_prop _ _ H1); intros. - caseEq (Regset.mem r allregs); intro. - generalize (check_coloring_3_correct _ _ _ r H3 H4). tauto. - case (env r); simpl. - unfold dummy_int_reg. intuition congruence. - unfold dummy_float_reg. intuition congruence. -Qed. - -Lemma alloc_of_coloring_correct_4: - forall r, - check_coloring g env allregs coloring = true -> - env r = Loc.type (alloc r). -Proof. - unfold check_coloring, alloc, alloc_of_coloring; intros. - elim (andb_prop _ _ H); intros. - elim (andb_prop _ _ H1); intros. - caseEq (Regset.mem r allregs); intro. - generalize (check_coloring_3_correct _ _ _ r H3 H4). tauto. - case (env r); reflexivity. -Qed. - -End ALLOC_OF_COLORING. - -(** * Correctness of the whole graph coloring algorithm *) - -(** Combining results from the previous sections, we now summarize - the correctness properties of the assignment (of locations to - registers) returned by [regalloc]. *) - -Definition correct_alloc_instr - (live: PMap.t Regset.t) (alloc: reg -> loc) - (pc: node) (instr: instruction) : Prop := - match instr with - | Iop op args res s => - match is_move_operation op args with - | Some arg => - forall r, - Regset.In res live!!pc -> - Regset.In r live!!pc -> - r <> res -> r <> arg -> alloc r <> alloc res - | None => - forall r, - Regset.In res live!!pc -> - Regset.In r live!!pc -> - r <> res -> alloc r <> alloc res - end - | Iload chunk addr args res s => - forall r, - Regset.In res live!!pc -> - Regset.In r live!!pc -> - r <> res -> alloc r <> alloc res - | Icall sig ros args res s => - (forall r, - Regset.In r live!!pc -> - r <> res -> - ~(In (alloc r) destroyed_at_call)) - /\ (forall r, - Regset.In r live!!pc -> - r <> res -> alloc r <> alloc res) - /\ (match ros with - | inl rfun => ~(In (alloc rfun) (loc_arguments sig)) - | inr idfun => True - end) - | Itailcall sig ros args => - (match ros with - | inl rfun => ~(In (alloc rfun) (loc_arguments sig)) - | inr idfun => True - end) - | Ibuiltin ef args res s => - forall r, - Regset.In r live!!pc -> - r <> res -> alloc r <> alloc res - | _ => - True - end. - -Section REGALLOC_PROPERTIES. - -Variable f: function. -Variable env: regenv. -Variable live: PMap.t Regset.t. -Variable live0: Regset.t. -Variable alloc: reg -> loc. - -Let g := interf_graph f live live0. -Let allregs := all_interf_regs g. -Let coloring := graph_coloring f g env allregs. - -Lemma regalloc_ok: - regalloc f live live0 env = Some alloc -> - check_coloring g env allregs coloring = true /\ - alloc = alloc_of_coloring coloring env allregs. -Proof. - unfold regalloc, coloring, allregs, g. - case (check_coloring (interf_graph f live live0) env). - intro EQ; injection EQ; intro; clear EQ. - split. auto. auto. - intro; discriminate. -Qed. - -Lemma regalloc_acceptable: - forall r, - regalloc f live live0 env = Some alloc -> - loc_acceptable (alloc r). -Proof. - intros. elim (regalloc_ok H); intros. - rewrite H1. unfold allregs. apply alloc_of_coloring_correct_3. - exact H0. -Qed. - -Lemma regsalloc_acceptable: - forall rl, - regalloc f live live0 env = Some alloc -> - locs_acceptable (List.map alloc rl). -Proof. - intros; red; intros. - elim (list_in_map_inv _ _ _ H0). intros r [EQ IN]. - subst l. apply regalloc_acceptable. auto. -Qed. - -Lemma regalloc_preserves_types: - forall r, - regalloc f live live0 env = Some alloc -> - Loc.type (alloc r) = env r. -Proof. - intros. elim (regalloc_ok H); intros. - rewrite H1. unfold allregs. symmetry. - apply alloc_of_coloring_correct_4. - exact H0. -Qed. - -Lemma correct_interf_alloc_instr: - forall pc instr, - (forall r1 r2, interfere r1 r2 g -> alloc r1 <> alloc r2) -> - (forall r1 mr2, interfere_mreg r1 mr2 g -> alloc r1 <> R mr2) -> - (forall r, loc_acceptable (alloc r)) -> - correct_interf_instr live!!pc instr g -> - correct_alloc_instr live alloc pc instr. -Proof. - intros pc instr ALL1 ALL2 ALL3. - unfold correct_interf_instr, correct_alloc_instr; - destruct instr; auto. - destruct (is_move_operation o l); auto. - (* Icall *) - intros [A [B C]]. - split. intros; red; intros. - unfold destroyed_at_call in H1. - generalize (list_in_map_inv R _ _ H1). - intros [mr [EQ IN]]. - generalize (A r0 mr H IN H0). intro. - generalize (ALL2 _ _ H2). contradiction. - split. auto. - destruct s0; auto. red; intros. - generalize (ALL3 r0). generalize (loc_arguments_acceptable _ _ H). - unfold loc_argument_acceptable, loc_acceptable. - caseEq (alloc r0). intros. - elim (ALL2 r0 m). apply C; auto. congruence. auto. - destruct s0; auto. - (* Itailcall *) - destruct s0; auto. red; intros. - generalize (ALL3 r). generalize (loc_arguments_acceptable _ _ H0). - unfold loc_argument_acceptable, loc_acceptable. - caseEq (alloc r). intros. - elim (ALL2 r m). apply H; auto. congruence. auto. - destruct s0; auto. -Qed. - -Lemma regalloc_correct_1: - forall pc instr, - regalloc f live live0 env = Some alloc -> - f.(fn_code)!pc = Some instr -> - correct_alloc_instr live alloc pc instr. -Proof. - intros. elim (regalloc_ok H); intros. - apply correct_interf_alloc_instr. - intros. rewrite H2. unfold allregs. red in H3. - elim (ordered_pair_charact r1 r2); intro. - apply alloc_of_coloring_correct_1. auto. rewrite H4 in H3; auto. - apply sym_not_equal. - apply alloc_of_coloring_correct_1. auto. rewrite H4 in H3; auto. - intros. rewrite H2. unfold allregs. - apply alloc_of_coloring_correct_2. auto. exact H3. - intros. eapply regalloc_acceptable; eauto. - unfold g. apply interf_graph_correct_1. auto. -Qed. - -Lemma regalloc_correct_2: - regalloc f live live0 env = Some alloc -> - list_norepet f.(fn_params) -> - list_norepet (List.map alloc f.(fn_params)). -Proof. - intros. elim (regalloc_ok H); intros. - apply list_map_norepet; auto. - intros. rewrite H2. unfold allregs. - elim (ordered_pair_charact x y); intro. - apply alloc_of_coloring_correct_1. auto. - change positive with reg. rewrite <- H6. - change (interfere x y g). unfold g. - apply interf_graph_correct_2; auto. - apply sym_not_equal. - apply alloc_of_coloring_correct_1. auto. - change positive with reg. rewrite <- H6. - change (interfere x y g). unfold g. - apply interf_graph_correct_2; auto. -Qed. - -Lemma regalloc_correct_3: - forall r1 r2, - regalloc f live live0 env = Some alloc -> - In r1 f.(fn_params) -> - Regset.In r2 live0 -> - r1 <> r2 -> - alloc r1 <> alloc r2. -Proof. - intros. elim (regalloc_ok H); intros. - rewrite H4; unfold allregs. - elim (ordered_pair_charact r1 r2); intro. - apply alloc_of_coloring_correct_1. auto. - change positive with reg. rewrite <- H5. - change (interfere r1 r2 g). unfold g. - apply interf_graph_correct_3; auto. - apply sym_not_equal. - apply alloc_of_coloring_correct_1. auto. - change positive with reg. rewrite <- H5. - change (interfere r1 r2 g). unfold g. - apply interf_graph_correct_3; auto. -Qed. - -End REGALLOC_PROPERTIES. |