Correctness proof for the RRE pass.
Require Import Axioms.
Require Import Coqlib.
Require Import Maps.
Require Import AST.
Require Import Values.
Require Import Globalenvs.
Require Import Events.
Require Import Smallstep.
Require Import Op.
Require Import Locations.
Require Import Conventions.
Require Import Linear.
Require Import RRE.
Operations over equations
Lemma find_reg_containing_sound:
forall s r eqs,
find_reg_containing s eqs =
Some r ->
In (
mkeq r s)
eqs.
Proof.
induction eqs;
simpl;
intros.
congruence.
destruct (
slot_eq (
e_slot a)
s).
inv H.
left;
destruct a;
auto.
right;
eauto.
Qed.
Definition equations_hold (
ls:
locset) (
eqs:
equations) :
Prop :=
forall e,
In e eqs ->
ls (
S (
e_slot e)) =
ls (
R (
e_reg e)).
Lemma nil_hold:
forall ls,
equations_hold ls nil.
Proof.
red; intros; contradiction.
Qed.
Lemma In_kill_loc:
forall e l eqs,
In e (
kill_loc l eqs) ->
In e eqs /\
Loc.diff (
S (
e_slot e))
l /\
Loc.diff (
R (
e_reg e))
l.
Proof.
Lemma kill_loc_hold:
forall ls eqs l v,
equations_hold ls eqs ->
equations_hold (
Locmap.set l v ls) (
kill_loc l eqs).
Proof.
Lemma In_kill_locs:
forall e ll eqs,
In e (
kill_locs ll eqs) ->
In e eqs /\
Loc.notin (
S (
e_slot e))
ll /\
Loc.notin (
R (
e_reg e))
ll.
Proof.
Opaque Loc.diff.
induction ll;
simpl;
intros.
tauto.
exploit IHll;
eauto.
intros [
A [
B C]].
exploit In_kill_loc;
eauto.
intros [
D [
E F]].
tauto.
Qed.
Lemma kill_locs_hold:
forall ll ls eqs,
equations_hold ls eqs ->
equations_hold (
Locmap.undef ll ls) (
kill_locs ll eqs).
Proof.
Lemma kill_temps_hold:
forall ls eqs,
equations_hold ls eqs ->
equations_hold (
LTL.undef_temps ls) (
kill_temps eqs).
Proof.
Lemma kill_at_move_hold:
forall ls eqs,
equations_hold ls eqs ->
equations_hold (
undef_setstack ls) (
kill_at_move eqs).
Proof.
Lemma kill_at_op_hold:
forall op ls eqs,
equations_hold ls eqs ->
equations_hold (
undef_op op ls) (
kill_op op eqs).
Proof.
Lemma eqs_getstack_hold:
forall rs r s eqs,
equations_hold rs eqs ->
equations_hold (
Locmap.set (
R r) (
rs (
S s))
rs)
(
mkeq r s ::
kill_loc (
R r)
eqs).
Proof.
Lemma eqs_movestack_hold:
forall rs r s eqs,
equations_hold rs eqs ->
equations_hold (
Locmap.set (
R r) (
rs (
S s)) (
undef_setstack rs))
(
kill_at_move (
mkeq r s ::
kill_loc (
R r)
eqs)).
Proof.
Lemma eqs_setstack_hold:
forall rs r s eqs,
equations_hold rs eqs ->
equations_hold (
Locmap.set (
S s) (
rs (
R r)) (
undef_setstack rs))
(
kill_at_move (
mkeq r s ::
kill_loc (
S s)
eqs)).
Proof.
Lemma locmap_set_reg_same:
forall rs r,
Locmap.set (
R r) (
rs (
R r))
rs =
rs.
Proof.
Agreement between values of locations
Values of locations may differ between the original and transformed
program: after a Lgetstack is optimized to a Lop Omove,
the values of destroyed_at_move temporaries differ. This
can only happen in parts of the code where the safe_move_insertion
function returns true.
Definition agree (
sm:
bool) (
rs rs':
locset) :
Prop :=
forall l,
sm =
false \/
Loc.notin l destroyed_at_move ->
rs'
l =
rs l.
Lemma agree_false:
forall rs rs',
agree false rs rs' <->
rs' =
rs.
Proof.
intros; split; intros.
apply extensionality; intros. auto.
subst rs'. red; auto.
Qed.
Lemma agree_slot:
forall sm rs rs'
s,
agree sm rs rs' ->
rs' (
S s) =
rs (
S s).
Proof.
Transparent Loc.diff.
intros.
apply H.
right.
simpl;
destruct s;
tauto.
Qed.
Lemma agree_reg:
forall sm rs rs'
r,
agree sm rs rs' ->
sm =
false \/ ~
In r destroyed_at_move_regs ->
rs' (
R r) =
rs (
R r).
Proof.
intros. apply H. destruct H0; auto. right.
simpl in H0; simpl; intuition congruence.
Qed.
Lemma agree_regs:
forall sm rs rs'
rl,
agree sm rs rs' ->
sm =
false \/
list_disjoint rl destroyed_at_move_regs ->
reglist rs'
rl =
reglist rs rl.
Proof.
Lemma agree_set:
forall sm rs rs'
l v,
agree sm rs rs' ->
agree sm (
Locmap.set l v rs) (
Locmap.set l v rs').
Proof.
intros;
red;
intros.
unfold Locmap.set.
destruct (
Loc.eq l l0).
auto.
destruct (
Loc.overlap l l0).
auto.
apply H;
auto.
Qed.
Lemma agree_undef_move_1:
forall sm rs rs',
agree sm rs rs' ->
agree true rs (
undef_setstack rs').
Proof.
intros.
unfold undef_setstack.
red;
intros.
destruct H0.
congruence.
rewrite Locmap.guo;
auto.
Qed.
Remark locmap_undef_equal:
forall x ll rs rs',
(
forall l,
Loc.notin l ll ->
rs'
l =
rs l) ->
Locmap.undef ll rs'
x =
Locmap.undef ll rs x.
Proof.
induction ll;
intros;
simpl.
apply H.
simpl.
auto.
apply IHll.
intros.
unfold Locmap.set.
destruct (
Loc.eq a l).
auto.
destruct (
Loc.overlap a l)
as []
_eqn.
auto.
apply H.
simpl.
split;
auto.
apply Loc.diff_sym.
apply Loc.non_overlap_diff;
auto.
Qed.
Lemma agree_undef_move_2:
forall sm rs rs',
agree sm rs rs' ->
agree false (
undef_setstack rs) (
undef_setstack rs').
Proof.
Lemma agree_undef_temps:
forall sm rs rs',
agree sm rs rs' ->
agree false (
LTL.undef_temps rs) (
LTL.undef_temps rs').
Proof.
intros.
rewrite agree_false.
apply extensionality;
intros.
unfold LTL.undef_temps.
apply locmap_undef_equal.
intros.
apply H.
right.
simpl in H0;
simpl;
tauto.
Qed.
Lemma agree_undef_op:
forall op sm rs rs',
agree sm rs rs' ->
agree false (
undef_op op rs) (
undef_op op rs').
Proof.
Lemma transl_find_label:
forall lbl c eqs,
find_label lbl (
transf_code eqs c) =
option_map (
transf_code nil) (
find_label lbl c).
Proof.
Semantic preservation
Section PRESERVATION.
Variable prog:
program.
Let tprog :=
transf_program prog.
Let ge :=
Genv.globalenv prog.
Let tge :=
Genv.globalenv tprog.
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 _ _ _ transf_fundef prog).
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 _ _ _ transf_fundef prog).
Lemma symbols_preserved:
forall id,
Genv.find_symbol tge id =
Genv.find_symbol ge id.
Proof (@
Genv.find_symbol_transf _ _ _ transf_fundef prog).
Lemma varinfo_preserved:
forall b,
Genv.find_var_info tge b =
Genv.find_var_info ge b.
Proof (@
Genv.find_var_info_transf _ _ _ transf_fundef prog).
Lemma sig_preserved:
forall f,
funsig (
transf_fundef f) =
funsig f.
Proof.
destruct f; reflexivity.
Qed.
Lemma find_function_translated:
forall ros rs fd,
find_function ge ros rs =
Some fd ->
find_function tge ros rs =
Some (
transf_fundef fd).
Proof.
Inductive match_frames:
stackframe ->
stackframe ->
Prop :=
|
match_frames_intro:
forall f sp rs c,
match_frames (
Stackframe f sp rs c)
(
Stackframe (
transf_function f)
sp rs (
transf_code nil c)).
Inductive match_states:
state ->
state ->
Prop :=
|
match_states_regular:
forall sm stk f sp c rs m stk'
rs'
eqs
(
STK:
list_forall2 match_frames stk stk')
(
EQH:
equations_hold rs'
eqs)
(
AG:
agree sm rs rs')
(
SAFE:
sm =
false \/
safe_move_insertion c =
true),
match_states (
State stk f sp c rs m)
(
State stk' (
transf_function f)
sp (
transf_code eqs c)
rs'
m)
|
match_states_call:
forall stk f rs m stk'
(
STK:
list_forall2 match_frames stk stk'),
match_states (
Callstate stk f rs m)
(
Callstate stk' (
transf_fundef f)
rs m)
|
match_states_return:
forall stk rs m stk'
(
STK:
list_forall2 match_frames stk stk'),
match_states (
Returnstate stk rs m)
(
Returnstate stk'
rs m).
Definition measure (
S:
state) :
nat :=
match S with
|
State s f sp c rs m =>
List.length c
|
_ => 0%
nat
end.
Remark match_parent_locset:
forall stk stk',
list_forall2 match_frames stk stk' ->
return_regs (
parent_locset stk') =
return_regs (
parent_locset stk).
Proof.
intros. inv H; auto. inv H0; 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.
Lemma transf_initial_states:
forall st1,
initial_state prog st1 ->
exists st2,
initial_state tprog st2 /\
match_states st1 st2.
Proof.
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 STK. econstructor. auto.
Qed.
Theorem transf_program_correct:
forward_simulation (
Linear.semantics prog) (
Linear.semantics tprog).
Proof.
End PRESERVATION.