(* *********************************************************************)
(*                                                                     *)
(*              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.     *)
(*                                                                     *)
(* *********************************************************************)
(** Correctness proof for RTL generation. *)
(** * Correspondence between Cminor environments and RTL register sets *)
(** A compilation environment (mapping) is well-formed if the following properties hold: - Two distinct Cminor local variables are mapped to distinct pseudo-registers. - A Cminor local variable and a let-bound variable are mapped to distinct pseudo-registers. *)
Record map_wf (m: mapping) : Prop :=
mk_map_wf {
map_wf_inj:
(forall id1 id2 r,
m.(map_vars)!id1 = Some r -> m.(map_vars)!id2 = Some r -> id1 = id2);
map_wf_disj:
(forall id r,
m.(map_vars)!id = Some r -> In r m.(map_letvars) -> False)
}.
(** An RTL register environment matches a CminorSel local environment and let-environment if the value of every local or let-bound variable in the CminorSel environments is identical to the value of the corresponding pseudo-register in the RTL register environment. *)
Record match_env
(map: mapping) (e: env) (le: letenv) (rs: regset) : Prop :=
mk_match_env {
me_vars:
(forall id v,
e!id = Some v -> exists r, map.(map_vars)!id = Some r /\ Val.lessdef v rs#r);
me_letvars:
Val.lessdef_list le rs##(map.(map_letvars))
}.
(** Matching between environments is preserved when an unmapped register (not corresponding to any Cminor variable) is assigned in the RTL execution. *)
Hint Resolve match_env_update_temp: rtlg.
(** Matching between environments is preserved by simultaneous assignment to a Cminor local variable (in the Cminor environments) and to the corresponding RTL pseudo-register (in the RTL register environment). *)
(** A variant of [match_env_update_var] where a variable is optionally assigned to, depending on the [dst] parameter. *)
Hint Resolve match_env_update_dest: rtlg.
(** A variant of [match_env_update_var] corresponding to the assignment of the result of a builtin. *)
(** Matching and [let]-bound variables. *)
(** Matching between initial environments. *)
(** The assignment of function arguments to local variables (on the Cminor side) and pseudo-registers (on the RTL side) preserves matching between environments. *)

Lemma match_init_env_init_reg:
forall params s0 rparams map1 s1 i1 vars rvars map2 s2 i2 vparams tvparams,
add_vars init_mapping params s0 = OK (rparams, map1) s1 i1 ->
add_vars map1 vars s1 = OK (rvars, map2) s2 i2 ->
Val.lessdef_list vparams tvparams ->
match_env map2 (set_locals vars (set_params vparams params))
nil (init_regs tvparams rparams).