(** * Neededness for memory locations *)
Inductive nmem : Type :=
| NMemDead
| NMem (stk: ISet.t) (gl: PTree.t ISet.t).
(** Interpretation of [nmem]: - [NMemDead]: all memory locations are unused (dead).  Acts as bottom. - [NMem stk gl]: all memory locations are used, except: - the stack locations whose offset is in the interval [stk] - the global locations whose offset is in the corresponding entry of [gl]. *)
Section LOCATIONS.
Variable ge: genv.
Variable sp: block.
Inductive nlive: nmem -> block -> Z -> Prop :=
| nlive_intro: forall stk gl b ofs
(STK: b = sp -> ~ISet.In ofs stk)
(GL: forall id iv,
Genv.find_symbol ge id = Some b ->
gl!id = Some iv ->
~ISet.In ofs iv),
nlive (NMem stk gl) b ofs.
(** All locations are live *)
Definition nmem_all := NMem ISet.empty (PTree.empty _).

Lemma nlive_all: forall b ofs, nlive nmem_all b ofs.
Definition nmem_add (nm: nmem) (p: aptr) (sz: Z) : nmem :=
match nm with
| NMemDead => nmem_all       (**r very conservative, should never happen *)
| NMem stk gl =>
match p with
| Gl id ofs =>
match gl!id with
| Some iv => NMem stk (PTree.set id (ISet.remove (Ptrofs.unsigned ofs) (Ptrofs.unsigned ofs + sz) iv) gl)
| None => nm
end
| Glo id =>
NMem stk (PTree.remove id gl)
| Stk ofs =>
NMem (ISet.remove (Ptrofs.unsigned ofs) (Ptrofs.unsigned ofs + sz) stk) gl
| Stack =>
NMem ISet.empty gl
| _ => nmem_all
end
end.