(* *********************************************************************)
(*                                                                     *)
(*              The Compcert verified compiler                         *)
(*                                                                     *)
(*          Xavier Leroy, INRIA Paris-Rocquencourt                     *)
(*                                                                     *)
(*  Copyright Institut National de Recherche en Informatique et en     *)
(*  Automatique.  All rights reserved.  This file is distributed       *)
(*  under the terms of the INRIA Non-Commercial License Agreement.     *)
(*                                                                     *)
(* *********************************************************************)
(** Elimination of unneeded computations over RTL: correctness proof. *)
Definition match_prog (prog tprog: RTL.program) :=
match_program (fun cu f tf => transf_fundef (romem_for cu) f = OK tf) eq prog tprog.
(** * Relating the memory states *)
(** The [magree] predicate is a variant of [Mem.extends] where we allow the contents of the two memory states to differ arbitrarily on some locations.  The predicate [P] is true on the locations whose contents must be in the [lessdef] relation. *)
Definition locset := block -> Z -> Prop.
Record magree (m1 m2: mem) (P: locset) : Prop := mk_magree {
ma_perm:
forall b ofs k p,
Mem.perm m1 b ofs k p -> Mem.perm m2 b ofs k p;
ma_perm_inv:
forall b ofs k p,
Mem.perm m2 b ofs k p -> Mem.perm m1 b ofs k p \/ ~Mem.perm m1 b ofs Max Nonempty;
ma_memval:
forall b ofs,
Mem.perm m1 b ofs Cur Readable ->
P b ofs ->
memval_lessdef (ZMap.get ofs (PMap.get b (Mem.mem_contents m1)))
(ZMap.get ofs (PMap.get b (Mem.mem_contents m2)));
ma_nextblock:
Mem.nextblock m2 = Mem.nextblock m1
}.
(** * Properties of the need environment *)

Lemma add_need_vagree:
forall e e' r nv ne,
eagree e e' (add_need r nv ne) -> vagree e#r e'#r nv.