(* *********************************************************************)
(*                                                                     *)
(*              The Compcert verified compiler                         *)
(*                                                                     *)
(*      Laurence Rideau, INRIA Sophia-Antipolis-M\u00e9diterran\u00e9e           *)
(*      Bernard Paul Serpette, INRIA Sophia-Antipolis-M\u00e9diterran\u00e9e     *)
(*      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 GNU General Public License as published by  *)
(*  the Free Software Foundation, either version 2 of the License, or  *)
(*  (at your option) any later version.  This file is also distributed *)
(*  under the terms of the INRIA Non-Commercial License Agreement.     *)
(*                                                                     *)
(* *********************************************************************)
(** Translation of parallel moves into sequences of individual moves *)
(** The ``parallel move'' problem, also known as ``parallel assignment'', is the following.  We are given a list of (source, destination) pairs of locations.  The goal is to find a sequence of elementary moves ([loc <- loc] assignments) such that, at the end of the sequence, location [dst] contains the value of location [src] at the beginning of the sequence, for each ([src], [dst]) pairs in the given problem. Moreover, other locations should keep their values, except one register of each type, which can be used as temporaries in the generated sequences.  The parallel move problem is trivial if the sources and destinations do not overlap.  For instance, << (R1, R2) <- (R3, R4)     becomes    R1 <- R3; R2 <- R4 >> However, arbitrary overlap is allowed between sources and destinations. This requires some care in ordering the individual moves, as in << (R1, R2) <- (R3, R1)     becomes    R2 <- R1; R1 <- R3 >> Worse, cycles (permutations) can require the use of temporaries, as in << (R1, R2, R3) <- (R2, R3, R1)   becomes   T <- R1; R1 <- R2; R2 <- R3; R3 <- T; >> An amazing fact is that for any parallel move problem, at most one temporary (or in our case one integer temporary and one float temporary) is needed.  The development in this section was designed by Laurence Rideau and Bernard Serpette.  It is described in the paper ``Tilting at windmills with Coq: Formal verification of a compilation algorithm for parallel moves'', #<A HREF="http://hal.inria.fr/inria-00176007"># http://hal.inria.fr/inria-00176007 #</A># *)
Section PARMOV.
(** * Registers, moves, and their semantics *)
(** The development is parameterized by the type of registers, equipped with a decidable equality. *)
Variable reg: Type.
Variable reg_eq : forall (r1 r2: reg), {r1=r2} + {r1<>r2}.
(** The [temp] function maps every register [r] to the register that should be used to save the value of [r] temporarily while performing a cyclic assignment involving [r].  In the simplest case, there is only one such temporary register [rtemp] and [temp] is the constant function [fun r => rtemp].  In more realistic cases, different temporary registers can be used to hold different values.  In the case of Compcert, we have two temporary registers, one for integer values and the other for floating-point values, and [temp] returns the appropriate temporary depending on the type of its argument. *)
Variable temp: reg -> reg.
Definition is_temp (r: reg): Prop := exists s, r = temp s.
(** A set of moves is a list of pairs of registers, of the form (source, destination). *)
Definition moves := (list (reg * reg))%type.  (* src -> dst *)
Definition srcs (m: moves) := List.map (@fst reg reg) m.
Definition dests (m: moves) := List.map (@snd reg reg) m.
(** ** Semantics of moves *)
(** The dynamic  semantics of moves is given in terms of environments. An environment is a mapping of registers to their current values. *)
Variable val: Type.
Definition env := reg -> val.

(* Specifications: *)
Lemma env_ext:
forall (e1 e2: env),
(forall r, e1 r = e2 r) -> e1 = e2.
Lemma env_ext:
forall (e1 e2: env),
(forall r, e1 r = e2 r) -> e1 = e2.