(* *********************************************************************)
(*                                                                     *)
(*              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.     *)
(*                                                                     *)
(* *********************************************************************)
(** Translation from CminorSel to RTL. *)
Require Errors.
Local Open Scope string_scope.
(** * Translation environments and state *)
(** The translation functions are parameterized by the following compile-time environment, which maps CminorSel local variables and let-bound variables to RTL registers.   The mapping for local variables is computed from the CminorSel variable declarations at the beginning of the translation of a function, and does not change afterwards. The mapping for let-bound variables is initially empty and updated during translation of expressions, when crossing a [Elet] binding. *)
Record mapping: Type := mkmapping {
map_vars: PTree.t reg;
map_letvars: list reg
}.
(** The translation functions modify a global state, comprising the current state of the control-flow graph for the function being translated, as well as sources of fresh RTL registers and fresh CFG nodes. *)
Record state: Type := mkstate {
st_nextreg: positive;
st_nextnode: positive;
st_code: code;
st_wf: forall (pc: positive), Plt pc st_nextnode \/ st_code!pc = None
}.
(** Operations over the global state satisfy a crucial monotonicity property: nodes are only added to the CFG, but are never removed nor their instructions are changed; similarly, fresh nodes and fresh registers are only consumed, but never reused.  This property is captured by the following predicate over states, which we show is a partial order. *)
Inductive state_incr: state -> state -> Prop :=
state_incr_intro:
forall (s1 s2: state),
Ple s1.(st_nextnode) s2.(st_nextnode) ->
Ple s1.(st_nextreg) s2.(st_nextreg) ->
(forall pc,
s1.(st_code)!pc = None \/ s2.(st_code)!pc = s1.(st_code)!pc) ->
state_incr s1 s2.

Lemma state_incr_trans:
forall s1 s2 s3, state_incr s1 s2 -> state_incr s2 s3 -> state_incr s1 s3.