Section INLINING.
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).
(** ** Properties of contexts and relocations *)
Remark sreg_below_diff:
forall ctx r r', Plt r' ctx.(dreg) -> sreg ctx r <> r'.
Remark context_below_diff:
forall ctx1 ctx2 r1 r2,
context_below ctx1 ctx2 -> Ple r1 ctx1.(mreg) -> sreg ctx1 r1 <> sreg ctx2 r2.
Remark context_below_lt:
forall ctx1 ctx2 r, context_below ctx1 ctx2 -> Ple r ctx1.(mreg) -> Plt (sreg ctx1 r) ctx2.(dreg).
(* Remark context_below_le: forall ctx1 ctx2 r, context_below ctx1 ctx2 -> Ple r ctx1.(mreg) -> Ple (sreg ctx1 r) ctx2.(dreg). *)
(** ** Agreement between register sets before and after inlining. *)
Definition agree_regs (F: meminj) (ctx: context) (rs rs': regset) :=
(forall r, Ple r ctx.(mreg) -> Val.inject F rs#r rs'#(sreg ctx r))
/\(forall r, Plt ctx.(mreg) r -> rs#r = Vundef).
Definition val_reg_charact (F: meminj) (ctx: context) (rs': regset) (v: val) (r: reg) :=
(Plt ctx.(mreg) r /\ v = Vundef) \/ (Ple r ctx.(mreg) /\ Val.inject F v rs'#(sreg ctx r)).
Remark Plt_Ple_dec:
forall p q, {Plt p q} + {Ple q p}.
Remark agree_regs_init:
forall F ctx rs, agree_regs F ctx (Regmap.init Vundef) rs.
(** ** Executing sequences of moves *)
(** ** Memory invariants *)
(** A stack location is private if it is not the image of a valid location and we have full rights on it. *)
Definition loc_private (F: meminj) (m m': mem) (sp: block) (ofs: Z) : Prop :=
Mem.perm m' sp ofs Cur Freeable /\
(forall b delta, F b = Some(sp, delta) -> ~Mem.perm m b (ofs - delta) Max Nonempty).
(** Likewise, for a range of locations. *)
Definition range_private (F: meminj) (m m': mem) (sp: block) (lo hi: Z) : Prop :=
forall ofs, lo <= ofs < hi -> loc_private F m m' sp ofs.

Lemma range_private_invariant:
forall F m m' sp lo hi F1 m1 m1',
range_private F m m' sp lo hi ->
(forall b delta ofs,
F1 b = Some(sp, delta) ->
Mem.perm m1 b ofs Max Nonempty ->
lo <= ofs + delta < hi ->
F b = Some(sp, delta) /\ Mem.perm m b ofs Max Nonempty) ->
(forall ofs, Mem.perm m' sp ofs Cur Freeable -> Mem.perm m1' sp ofs Cur Freeable) ->
range_private F1 m1 m1' sp lo hi.