(* *********************************************************************)
(*                                                                     *)
(*              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.     *)
(*                                                                     *)
(* *********************************************************************)
(** Abstract domain for neededness analysis *)
(** * Neededness for values *)
Inductive nval : Type :=
| Nothing              (**r value is entirely unused *)
| I (m: int)           (**r only need the bits that are 1 in [m] *)
| All.                 (**r every bit of the value is used *)
Definition eq_nval (x y: nval) : {x=y} + {x<>y}.
Hint Resolve vagree_same vagree_lessdef lessdef_vagree: na.
Inductive vagree_list: list val -> list val -> list nval -> Prop :=
| vagree_list_nil: forall nvl,
vagree_list nil nil nvl
| vagree_list_default: forall v1 vl1 v2 vl2,
vagree v1 v2 All -> vagree_list vl1 vl2 nil ->
vagree_list (v1 :: vl1) (v2 :: vl2) nil
| vagree_list_cons: forall v1 vl1 v2 vl2 nv1 nvl,
vagree v1 v2 nv1 -> vagree_list vl1 vl2 nvl ->
vagree_list (v1 :: vl1) (v2 :: vl2) (nv1 :: nvl).
Hint Resolve lessdef_vagree_list vagree_lessdef_list: na.
(** ** Ordering and least upper bound between value needs *)
Inductive nge: nval -> nval -> Prop :=
| nge_nothing: forall x, nge All x
| nge_all: forall x, nge x Nothing
| nge_int: forall m1 m2,
(forall i, 0 <= i < Int.zwordsize -> Int.testbit m2 i = true -> Int.testbit m1 i = true) ->
nge (I m1) (I m2).
Hint Constructors nge: na.
Hint Resolve nge_refl: na.
Definition nlub (x y: nval) : nval :=
match x, y with
| Nothing, _ => y
| _, Nothing => x
| I m1, I m2 => I (Int.or m1 m2)
| _, _ => All
end.

Lemma nge_lub_l:
forall x y, nge (nlub x y) x.