Require Import Coqlib Integers Maps Values AST Globalenvs.
Require Import CUAST InteractionSemantics Footprint.
Require Import IS_local.
Require Import Memory Blockset Op_fp Linear Linear_local val_casted.
Require Import InjRels LDSimDefs_local LDSim_local.
Require Import Errors CleanupLabels cleanuplabels.
Local Notation empfp:=
FP.emp.
Local Notation footprint:=
FP.t.
Definition match_cu (
su tu:
Linear_comp_unit):=
match_comp_unit_gen (
fun f tf =>
OK (
transf_fundef f) =
OK tf)
eq su tu.
Lemma transf_program_match:
forall p tp,
transf_program p =
OK tp ->
match_cu p tp.
Proof.
Section PRESERVATION.
Variable scu tcu:
Linear_comp_unit.
Variable sge tge:
Linear.genv.
Hypothesis SGEINIT:
globalenv_generic scu sge.
Hypothesis TGEINIT:
globalenv_generic tcu tge.
Hypothesis S_EQ:
sge.(
Genv.genv_next) =
tge.(
Genv.genv_next).
Hypothesis TRANSF:
match_cu scu tcu.
Lemma ge_match:
ge_match_strict sge tge.
Proof.
Lemma genv_match:
Genv.match_genvs (
match_globdef (
fun f tf =>
OK (
transf_fundef f) =
OK tf)
eq)
sge tge.
Proof.
Lemma symbols_preserved:
forall (
s:
ident),
Genv.find_symbol tge s =
Genv.find_symbol sge s.
Proof.
Lemma funct_ptr_translated:
forall (
b:
block) (
f:
Linear.fundef),
Genv.find_funct_ptr sge b =
Some f ->
Genv.find_funct_ptr tge b =
Some (
transf_fundef f).
Proof.
Lemma functions_translated:
forall (
v:
val) (
f:
Linear.fundef),
Genv.find_funct sge v =
Some f ->
Genv.find_funct tge v =
Some (
transf_fundef f).
Proof.
Lemma senv_preserved:
Senv.equiv sge tge.
Proof.
Lemma sig_preserved:
forall f,
funsig (
transf_fundef f) =
funsig f.
Proof.
destruct f; auto.
Qed.
Lemma stacksize_preserved:
forall f,
fn_stacksize (
transf_function f) =
fn_stacksize f.
Proof.
unfold transf_function.
intros.
destruct (
zeq (
fn_stacksize f) 0);
auto.
Qed.
Lemma find_function_translated:
forall ros rs f,
find_function sge ros rs =
Some f ->
find_function tge ros rs =
Some (
transf_fundef f).
Proof.
Definition match_locset(
l1 l2:
locset):
Prop:=
forall loc,
Val.lessdef (
l1 loc)(
l2 loc).
Inductive match_stackframes:
stackframe ->
stackframe ->
Prop :=
|
match_stackframe_intro:
forall f sp rs ls0 c,
match_locset rs ls0->
incl c f.(
fn_code) ->
match_stackframes (
Stackframe f sp rs c)
(
Stackframe (
transf_function f)
sp ls0
(
remove_unused_labels (
labels_branched_to (
fn_code f))
c)).
Lemma match_locset_refl:
forall l,
match_locset l l.
Proof.
Definition state:
Type:=
core*
mem.
Inductive match_states:
state ->
state ->
Prop :=
|
match_states_intro:
forall s f sp c ls m ts ls0 m'
ls2 f'
ls3,
list_forall2 match_stackframes s ts ->
match_locset ls ls0->
Mem.extends m m'->
incl c f.(
fn_code) ->
match_locset ls2 ls3 ->
match_states (
Core_State s f sp c ls (
mk_load_frame ls2 f'),
m)
(
Core_State ts (
transf_function f)
sp (
remove_unused_labels (
labels_branched_to f.(
fn_code))
c)
ls0
(
mk_load_frame ls3 (
transf_function f')),
m')
|
match_states_in:
forall s ls m ts ls0 m'
f,
list_forall2 match_stackframes s ts ->
match_locset ls ls0->
Mem.extends m m'->
match_states (
Core_CallstateIn s (
Internal f)
ls (
mk_load_frame ls f),
m)
(
Core_CallstateIn ts (
transf_fundef (
Internal f))
ls0 (
mk_load_frame ls0 (
transf_function f)),
m')
|
match_states_call:
forall s ls m ts ls0 m'
fd f0 ls2 ls3,
list_forall2 match_stackframes s ts ->
match_locset ls ls0->
Mem.extends m m'->
match_locset ls2 ls3 ->
match_states (
Core_Callstate s fd ls (
mk_load_frame ls2 f0),
m)
(
Core_Callstate ts (
transf_fundef fd)
ls0 (
mk_load_frame ls3 (
transf_function f0)),
m')
|
match_states_return:
forall s ls m ts ls0 m'
f ls2 ls3,
list_forall2 match_stackframes s ts ->
match_locset ls ls0 ->
Mem.extends m m' ->
match_locset ls2 ls3 ->
match_states (
Core_Returnstate s ls (
mk_load_frame ls2 f),
m)
(
Core_Returnstate ts ls0 (
mk_load_frame ls3 (
transf_function f)),
m').
Definition measure (
st:
core) :
nat :=
match st with
|
Core_State s f sp c ls m =>
List.length c
|
_ =>
O
end.
Definition MS (
_ :
bool)
n mu fp fp'
cm cm':
Prop :=
match_states cm cm' /\
Injections.FPMatch'
mu fp fp' /\
let (
c,
m) :=
cm in
let (
c',
m') :=
cm'
in
(
forall b,
Bset.belongsto (
Injections.SharedSrc mu)
b ->
Mem.valid_block m b) /\
(
forall b,
Bset.belongsto (
Injections.SharedTgt mu)
b ->
Mem.valid_block m'
b) /\
(
proper_mu sge tge inject_id mu) /\
(
MemClosures_local.unmapped_closed mu m m') /\
n =
measure c /\
true =
true.
Ltac invMS :=
match goal with
|
H:
MS _ _ _ _ _ ?
cm1 ?
cm2 |-
_ =>
destruct cm1 as [
sc Hm];
destruct cm2 as [
tc Lm];
unfold MS in H;
simpl in H;
destruct H as [
MS [
FPMATCH [
SVALID [
TVALID [
AGMU [
RCPRESV [
INDEX FLAG]]]]]]]
|
H:
MS _ _ _ _ _ ?
cm1 ?
cm2 |-
_ =>
unfold MS in H;
simpl in H;
destruct H as [
MS [
FPMATCH [
SVALID [
TVALID [
AGMU [
RCPRESV [
INDEX FLAG]]]]]]]
end.
Lemma match_parent_locset:
forall s ts,
list_forall2 match_stackframes s ts ->
match_locset (
parent_locset s) (
parent_locset ts).
Proof.
clear.
intros.
inv H.
constructor.
destruct a1,
b1;
auto.
simpl.
unfold match_locset.
intros.
inv H0.
auto.
Qed.
Lemma val_lessdef_list_refl:
forall s,
Val.lessdef_list s s.
Proof.
induction s;auto. Qed.
Lemma v_v0_inj_refl:
forall mu v v0,
Val.inject (
Bset.inj_to_meminj (
Injections.inj mu))
v v0 ->
LDSimDefs.G_arg (
Injections.SharedSrc mu)
v ->
inject_incr (
Bset.inj_to_meminj (
Injections.inj mu))
inject_id ->
v =
v0.
Proof.
intros.
inv H;
auto;
try contradiction.
eapply H1 in H2.
unfold inject_id in H2.
inv H2.
rewrite Ptrofs.add_zero;
auto.
Qed.
Lemma same_val_from_matchlocset :
forall mu rp rs rs1,
LDSimDefs.G_arg (
Injections.SharedSrc mu) (
get_result rp rs) ->
match_locset rs rs1 ->
Some (
get_result rp rs1) =
Some (
get_result rp rs).
Proof.
intros.
unfold match_locset in H0.
unfold LDSimDefs.G_arg in H.
unfold get_result.
destruct rp.
specialize (
H0 (
Locations.R r))
as ?.
inv H1;
try discriminate.
rewrite H4;
auto.
unfold get_result in H.
rewrite <-
H3 in H;
try contradiction.
unfold get_result in H.
specialize (
H0 (
Locations.R rhi))
as ?.
inv H1.
specialize (
H0 (
Locations.R rlo))
as ?.
inv H1.
auto.
destruct (
rs (
Locations.R rhi));
simpl in *;
auto.
rewrite <-
H3 in H;
try contradiction.
rewrite <-
H3 in H.
simpl in *.
contradiction.
Qed.
Lemma set_locset_lessdef:
forall ls ls'
v v'
l,
match_locset ls ls' ->
Val.lessdef v v' ->
match_locset (
Locations.Locmap.set l v ls) (
Locations.Locmap.set l v'
ls').
Proof.
Lemma setpair_locset_lessdef:
forall ls ls'
v v'
l,
match_locset ls ls' ->
Val.lessdef v v' ->
match_locset (
Locations.Locmap.setpair l v ls) (
Locations.Locmap.setpair l v'
ls').
Proof.
Lemma undef_locset_lessdef:
forall ls ls'
rl,
match_locset ls ls' ->
match_locset (
LTL.undef_regs rl ls) (
LTL.undef_regs rl ls').
Proof.
clear.
induction rl;
intros;
auto.
apply IHrl in H.
simpl.
eapply set_locset_lessdef.
auto.
auto.
Qed.
Lemma call_locset_lessdef:
forall ls ls',
match_locset ls ls' ->
match_locset (
LTL.call_regs ls) (
LTL.call_regs ls').
Proof.
clear.
intros.
unfold LTL.call_regs.
intro l.
destruct l;
auto.
destruct sl;
auto.
Qed.
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.
Lemma lessdef_list :
forall rs ls0 args,
match_locset rs ls0 ->
Val.lessdef_list (
LTL.reglist rs args) (
LTL.reglist ls0 args).
Proof.
intros.
unfold match_locset in H.
induction args.
simpl.
auto.
constructor.
apply H.
auto.
Qed.
Lemma find_function_lessdef:
forall ros ls tfd ls',
find_function sge ros ls =
Some tfd ->
match_locset ls ls' ->
find_function sge ros ls' =
Some tfd.
Proof.
Lemma return_locset_lessdef:
forall ls ls0 ls'
ls0',
match_locset ls ls' ->
match_locset ls0 ls0' ->
match_locset (
LTL.return_regs ls0 ls) (
LTL.return_regs ls0'
ls').
Proof.
Lemma setres_locset_lessdef:
forall res ls ls'
vres vres',
match_locset ls ls' ->
Val.lessdef vres vres' ->
match_locset (
Locations.Locmap.setres res vres ls)
(
Locations.Locmap.setres res vres'
ls').
Proof.
Lemma match_locset0:
forall s ts rs0,
list_forall2 match_stackframes s ts ->
match_locset (
parent_locset0 rs0 s) (
parent_locset0 rs0 ts).
Proof.
intros.
inv H.
constructor.
unfold parent_locset0.
destruct a1,
b1.
inv H0.
auto.
Qed.
Lemma match_locset0_match_ld :
forall locset_inv1 locset_inv2 s ts,
match_locset locset_inv1 locset_inv2 ->
list_forall2 match_stackframes s ts ->
match_locset (
parent_locset0 locset_inv1 s) (
parent_locset0 locset_inv2 ts).
Proof.
intros.
unfold parent_locset0.
destruct s,
ts.
auto.
inv H0.
inv H0.
destruct s,
s1.
inv H0.
inv H4.
auto.
Qed.
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.
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.
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.
Lemma find_function_temp :
forall locset_inv1 locset_inv2 f'
loc,
match_locset locset_inv1 locset_inv2 ->
Genv.find_funct sge (
locset_inv1 loc) =
Some f' ->
Genv.find_funct tge (
locset_inv2 loc) =
Some (
transf_fundef f').
Proof.
intros.
assert (
locset_inv1 loc =
locset_inv2 loc).
unfold match_locset in H.
specialize (
H loc)
as ?.
inv H1;
auto.
rewrite <-
H3 in H0.
inv H0.
rewrite <-
H1.
eapply functions_translated;
auto.
Qed.
Lemma find_function_matchlocset :
forall locset_inv1 locset_inv2 locset_src locset_tgt s ts ros f',
match_locset locset_inv1 locset_inv2 ->
match_locset locset_src locset_tgt ->
list_forall2 match_stackframes s ts ->
find_function sge ros (
LTL.return_regs (
parent_locset0 locset_inv1 s)
locset_src) =
Some f' ->
(
find_function tge ros (
LTL.return_regs (
parent_locset0 locset_inv2 ts)
locset_tgt) =
Some (
transf_fundef f')).
Proof.
Lemma incl_less :
forall a b f,
incl (
a::
b)
f.(
fn_code) ->
incl b f.(
fn_code).
Proof.
clear.
intros.
unfold incl in *.
intros.
specialize (
H a0)
as ?.
apply H1.
clear H1.
eapply in_cns.
right.
auto.
Qed.
Lemma incl_rel :
forall a,
incl a.(
fn_code)
a.(
fn_code).
Proof.
intros.
unfold incl.
intros.
auto.
Qed.
Lemma locset_lessdef_args:
forall ls ls'
args,
match_locset ls ls' ->
Val.lessdef_list (
map (
fun p :
rpair Locations.loc =>
Locations.Locmap.getpair p ls)
args)
(
map (
fun p :
rpair Locations.loc =>
Locations.Locmap.getpair p ls')
args).
Proof.
Lemma fp_matchemp :
forall mu Hfp Lfp,
Injections.FPMatch'
mu Hfp Lfp ->
Injections.FPMatch'
mu (
FP.union Hfp empfp) (
FP.union Lfp empfp).
Proof.
Lemma valid_block_sm' :
forall mu sm tm sm'
tm',
mem_init_inj mu sm tm ->
LDefs.HLRely mu sm sm'
tm tm' ->
forall b0 :
block,
Bset.belongsto (
Injections.SharedSrc mu)
b0 ->
Mem.valid_block sm'
b0 /\
forall b0 :
block,
Bset.belongsto (
Injections.SharedTgt mu)
b0 ->
Mem.valid_block tm'
b0.
Proof.
split. intros. inv H. eapply dom_eq_src in H1. red. inv H0. inv H. rewrite EQNEXT;eauto.
intros. inv H. eapply dom_eq_tgt in H2. red. inv H0. inv H3. rewrite EQNEXT;eauto.
Qed.
Ltac resolvfp:=
match goal with
| |-
context[
FP.union _ empfp] =>
rewrite FP.fp_union_emp;
resolvfp
| |-
context[
FP.union empfp _] =>
rewrite FP.emp_union_fp;
resolvfp
|
H:
Some _ =
Some _ |-
_ =>
inv H;
resolvfp
|
H:
FP.subset ?
fp1' ?
fp1 |-
Injections.FPMatch' ?
mu (
FP.union ?
fp1 _) (
FP.union ?
fp1'
_) =>
eapply Injections.fp_match_union';
resolvfp
|
H:
Injections.FPMatch'
_ ?
fp1 ?
fp1' |-
Injections.FPMatch' ?
mu (
FP.union ?
fp1 _) (
FP.union ?
fp1'
_) =>
eapply Injections.fp_match_union';
auto;
resolvfp
|
H:
Injections.FPMatch'
_ ?
fp1 ?
fp1' |-
Injections.FPMatch' ?
mu (
FP.union ?
fp1 _) ?
fp1' =>
eapply Injections.fp_match_union_S';
auto;
resolvfp
|
H:
FP.subset ?
fp1' ?
fp1 |-
FP.subset (
FP.union ?
fp1'
_) (
FP.union ?
fp1 _) =>
eapply FP.subset_parallel_union;
resolvfp
|
H:
FP.subset ?
fp1' ?
fp1 |-
FP.subset (
FP.union ?
fp1'
_) (
FP.union (
FP.union ?
fp1 _)
_) =>
eapply FP.subset_parallel_union;
resolvfp
|
H:
FP.subset ?
fp1' ?
fp1 |-
FP.subset (
FP.union (
FP.union ?
fp1'
_)
_) (
FP.union (
FP.union ?
fp1 _)
_)=>
eapply FP.subset_parallel_union;
resolvfp
|
H:
FP.subset ?
fp ?
fp' |-
FP.subset ?
fp (
FP.union ?
fp1 ?
fp') =>
rewrite FP.union_comm_eq;
resolvfp
|
H:
FP.subset ?
fp ?
fp' |-
FP.subset ?
fp (
FP.union ?
fp'
_) =>
apply FP.subset_union_subset;
auto
| |-
Injections.FPMatch'
_ _ empfp =>
apply Injections.fp_match_emp'
|
H:
FP.subset ?
fp1 ?
fp2 |-
Injections.FPMatch'
_ ?
fp2 ?
fp1 =>
apply Injections.fp_match_subset_T'
with fp2;
try exact H;
resolvfp
|
H:
FP.subset ?
fp2 ?
fp1 |-
Injections.FPMatch'
_ (
FP.union ?
fp1 _) ?
fp2 =>
apply Injections.fp_match_union_S';
resolvfp
|
H:
FP.subset ?
fp2 ?
fp1 |-
Injections.FPMatch'
_ ?
fp1 (
FP.union ?
fp2 _) =>
apply Injections.fp_match_union_T';
resolvfp
|
H:
FP.subset ?
fp2 ?
fp1 |-
Injections.FPMatch'
_ ?
fp1 (
FP.union (
FP.union ?
fp2 _)
_) =>
apply Injections.fp_match_union_T';
resolvfp
|
H:
FP.subset ?
fp2 ?
fp1 |-
Injections.FPMatch'
_ (
FP.union ?
fp1 _) (
FP.union (
FP.union ?
fp2 _)
_) =>
apply Injections.fp_match_union';
resolvfp
|
H: (
forall b,
Bset.belongsto (
FP.blocks ?
fp2)
_ -> ~
Injections.SharedTgt ?
mu _)
|-
Injections.FPMatch'
_ _ ?
fp2 =>
apply Injections.fp_match_local_block;
auto
| |-
FP.subset ?
fp ?
fp =>
apply FP.subset_refl
|
H:
fp_inject _ ?
fp ?
fp',
H':
proper_mu _ _ _ _ |-
Injections.FPMatch'
_ ?
fp ?
fp' =>
eapply fp_inject_fp_match;
inv H';
eauto
|
H:
fp_inject inject_id ?
fp ?
fp'|-
FP.subset ?
fp' ?
fp =>
apply fp_inject_id_fp_subset
|
H:
proper_mu _ _ _ _ |-
Injections.FPMatch'
_ ?
fp ?
fp =>
inv H;
eapply fp_match_id;
eauto
|
_ =>
idtac
end.
Ltac eresolvfp:=
resolvfp;
eauto.
Ltac resvalid:=
match goal with
valid blocks
|
H: (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m1 x),
H':
Mem.free ?
m1 _ _ _ =
Some ?
m2
|- (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m2 x)
=>
let X :=
fresh in
intros ?
X;
apply H in X;
eapply Mem.valid_block_free_1;
eauto
|
H: (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m1 x),
H':
Mem.alloc ?
m1 _ _ = (?
m2,
_)
|- (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m2 x)
=>
let X :=
fresh in
intros ?
X;
apply H in X;
eapply Mem.valid_block_alloc;
eauto
|
H: (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m1 x),
H':
Mem.store _ ?
m1 _ _ _ =
Some ?
m2
|- (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m2 x)
=>
let X :=
fresh in
intros ?
X;
apply H in X;
eapply Mem.store_valid_block_1;
eauto
|
H: (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m1 x),
H1:
LDefs.Rely ?
S ?
m1 ?
m2
|- (
forall x,
Bset.belongsto ?
S x ->
Mem.valid_block ?
m2 x)
=>
intros ?
X;
unfold Mem.valid_block in *;
apply H in X;
inversion H1 as [
EQNEXT ? ?];
rewrite EQNEXT;
auto
Mem inv
|
H1:
Mem.store _ ?
m1 _ _ _ =
Some ?
m2,
H2:
Mem.store _ ?
m1'
_ _ _ =
Some ?
m2',
H3:
proper_mu _ _ _ _
|-
MemClosures_local.unmapped_closed _ ?
m2 ?
m2'
=>
inv H3;
eapply MemClosures_local.store_val_inject_unmapped_closed_preserved;
try (
rewrite Z.add_0_r);
try eassumption;
try (
compute;
eauto;
fail);
try omega
|
H1:
Mem.free ?
m1 _ _ _ =
Some ?
m2,
H2:
Mem.free ?
m1'
_ _ _ =
Some ?
m2',
H3:
proper_mu _ _ _ _
|-
MemClosures_local.unmapped_closed _ ?
m2 ?
m2'
=>
inv H3;
eapply MemClosures_local.free_inject_unmapped_closed_preserved;
eauto;
try (
rewrite Z.add_0_r);
try eassumption;
try (
compute;
eauto;
fail);
try omega
|
H1:
Mem.alloc ?
m1 _ _ = (?
m2,
_),
H2:
Mem.alloc ?
m1'
_ _ = (?
m2',
_),
H3:
proper_mu _ _ _ _
|-
MemClosures_local.unmapped_closed _ ?
m2 ?
m2'
=>
inv H3;
eapply MemClosures_local.unchanged_on_unmapped_closed_preserved;
eauto;
try (
eapply Mem.alloc_unchanged_on;
eauto;
fail)
|
_ =>
idtac
end.
Ltac Ex_index :=
match goal with
| |-
context[
Core_State ?
s ?
f ?
sp ?
pc ?
rs] =>
exists (
measure (
Core_State s f sp pc rs))
| |-
context[
Core_Callstate] =>
exists 0%
nat
| |-
context[
Core_Returnstate ?
s ?
v] =>
exists (
measure (
Core_Returnstate s v))
end.
Ltac Right :=
right;
do 4
eexists;
split; [
apply plus_one|
resolvfp].
Ltac FP:=
match goal with |- ?
P /\
_ =>
assert P; [
eresolvfp|
try (
split;[
auto;
fail|])]
end.
Ltac Left :=
left;
Ex_index;
split; [
auto|
eresolvfp].
Ltac splitMS :=
split;
[
econstructor;
eresolvfp |
split; [
eresolvfp|
split; [
try resvalid;
auto |
split; [
try resvalid;
auto
|
split; [
auto|
split; [
try resvalid;
eauto|
split;
eauto]]]]]].
Ltac inv_eq:=
repeat match goal with
|
H:?
P ,
H1: ?
P |-
_ =>
clear H
|
H:
context[
match ?
x with _ =>
_ end] |-
_ =>
destruct x eqn:?;
inversion H ;
subst
|
H:?
P = ?
Q,
H1:
context [ ?
P ] |-
_ =>
rewrite H in H1
|
H:?
P = ?
Q |-
context [ ?
P ] =>
rewrite H
end;
simpl in *;
subst;
try contradiction;
try discriminate.
Ltac Hsimpl:=
repeat match goal with
|
H1:?
a,
H2:?
a->?
b|-
_=>
specialize (
H2 H1)
|
H:
_/\
_|-
_=>
destruct H
|
H:
exists _,
_|-
_=>
destruct H
end.
Ltac Esimpl:=
repeat match goal with
|
H:
_|-
_/\
_=>
split
|
H:
_|-
exists _,
_=>
eexists
end.
Ltac resolv_ls :=
match goal with
| |-
match_locset (
Locations.Locmap.set _ _ _) (
Locations.Locmap.set _ _ _) =>
apply set_locset_lessdef;
auto;
resolv_ls
| |-
match_locset (
LTL.undef_regs _ _) (
LTL.undef_regs _ _) =>
apply undef_locset_lessdef;
auto;
resolv_ls
| |-
match_locset (
LTL.return_regs _ _) (
LTL.return_regs _ _) =>
apply return_locset_lessdef;
auto;
resolv_ls
| |-
match_locset (
LTL.call_regs _ _) (
LTL.return_regs _ _) =>
apply call_locset_lessdef;
auto;
resolv_ls
| |-
match_locset (
Locations.Locmap.setres _ _ _) (
Locations.Locmap.setres _ _ _) =>
apply setres_locset_lessdef;
auto;
resolv_ls
| |-
match_locset (
Locations.Locmap.setpair _ _ _) (
Locations.Locmap.setpair _ _ _) =>
apply setpair_locset_lessdef;
auto;
resolv_ls
|
_ =>
idtac
end.
Lemma val_inject_proper_mu :
forall mu l,
proper_mu sge tge inject_id mu ->
LDSimDefs.G_arg (
Injections.SharedSrc mu)
l->
Val.inject (
Bset.inj_to_meminj (
Injections.inj mu))
l l.
Proof.
Lemma match_loc_inject_list:
forall mu l1 l2,
proper_mu sge tge inject_id mu ->
LDSimDefs.G_args (
Injections.SharedSrc mu)
l1 ->
Val.lessdef_list l1 l2 ->
Val.inject_list (
Bset.inj_to_meminj (
Injections.inj mu))
l1 l2.
Proof.
intros.
induction H1.
constructor.
constructor.
inv H0.
destruct v1,
v2;
try auto;
try inv H1;
try auto.
eapply val_inject_proper_mu;
eauto.
eapply IHlessdef_list;
eauto.
inv H0.
auto. Qed.
Lemma cleanuplabels_local_ldsim:
@
local_ldsim_properties Linear_IS Linear_IS nat lt sge tge sge tge MS.
Proof.
End PRESERVATION.
Theorem transf_local_ldsim:
forall su tu,
cleanuplabels.transf_program su =
OK tu->
forall sge sG tge tG,
init_genv_local Linear_IS su sge sG->
init_genv_local Linear_IS tu tge tG->
Genv.genv_next sge =
Genv.genv_next tge->
local_ldsim sG tG sge tge.
Proof.