Section PRESERVATION.
Variable prog: program.
Variable tprog: program.
Hypothesis TRANSF: match_prog prog tprog.
Let ge := Genv.globalenv prog.
Let tge := Genv.globalenv tprog.
Proof (Genv.find_symbol_match TRANSF).
Proof (Genv.senv_match TRANSF).
Proof (Genv.find_funct_match TRANSF).
Proof (Genv.find_funct_ptr_match TRANSF).
Definition vanalyze (cu: program) (f: function) :=
ValueAnalysis.analyze (romem_for cu) f.
Hint Resolve is_dead_sound_1 is_dead_sound_2: na.
(** * Semantic invariant *)
Inductive match_stackframes: stackframe -> stackframe -> Prop :=
| match_stackframes_intro:
forall res f sp pc e tf te cu an
(LINK: linkorder cu prog)
(FUN: transf_function (romem_for cu) f = OK tf)
(ANL: analyze (vanalyze cu f) f = Some an)
(RES: forall v tv,
Val.lessdef v tv ->
eagree (e#res <- v) (te#res<- tv)
(fst (transfer f (vanalyze cu f) pc an!!pc))),
match_stackframes (Stackframe res f (Vptr sp Ptrofs.zero) pc e)
(Stackframe res tf (Vptr sp Ptrofs.zero) pc te).
Inductive match_states: state -> state -> Prop :=
| match_regular_states:
forall s f sp pc e m ts tf te tm cu an
(STACKS: list_forall2 match_stackframes s ts)
(LINK: linkorder cu prog)
(FUN: transf_function (romem_for cu) f = OK tf)
(ANL: analyze (vanalyze cu f) f = Some an)
(ENV: eagree e te (fst (transfer f (vanalyze cu f) pc an!!pc)))
(MEM: magree m tm (nlive ge sp (snd (transfer f (vanalyze cu f) pc an!!pc)))),
match_states (State s f (Vptr sp Ptrofs.zero) pc e m)
(State ts tf (Vptr sp Ptrofs.zero) pc te tm)
| match_call_states:
forall s f args m ts tf targs tm cu
(STACKS: list_forall2 match_stackframes s ts)
(LINK: linkorder cu prog)
(FUN: transf_fundef (romem_for cu) f = OK tf)
(ARGS: Val.lessdef_list args targs)
(MEM: Mem.extends m tm),
match_states (Callstate s f args m)
(Callstate ts tf targs tm)
| match_return_states:
forall s v m ts tv tm
(STACKS: list_forall2 match_stackframes s ts)
(RES: Val.lessdef v tv)
(MEM: Mem.extends m tm),
match_states (Returnstate s v m)
(Returnstate ts tv tm).
(** [match_states] and CFG successors *)
(** Builtin arguments and results *)
(** Properties of volatile memory accesses *)

Lemma transf_volatile_store:
forall v1 v2 v1' v2' m tm chunk sp nm t v m',
volatile_store_sem chunk ge (v1::v2::nil) m t v m' ->
Val.lessdef v1 v1' ->
vagree v2 v2' (store_argument chunk) ->
magree m tm (nlive ge sp nm) ->
v = Vundef /\
exists tm', volatile_store_sem chunk ge (v1'::v2'::nil) tm t Vundef tm'
/\ magree m' tm' (nlive ge sp nm).