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 *)

Lemma transfer_builtin_arg_sound:
forall bc e e' sp m m' a v,
eval_builtin_arg ge (fun r => e#r) (Vptr sp Ptrofs.zero) m a v ->
forall nv ne1 nm1 ne2 nm2,
transfer_builtin_arg nv (ne1, nm1) a = (ne2, nm2) ->
eagree e e' ne2 ->
magree m m' (nlive ge sp nm2) ->
genv_match bc ge ->
bc sp = BCstack ->
exists v',
eval_builtin_arg ge (fun r => e'#r) (Vptr sp Ptrofs.zero) m' a  v'
/\ vagree v v' nv
/\ eagree e e' ne1
/\ magree m m' (nlive ge sp nm1).