Section EXPRESSIONS.
Variable cunit: Cminor.program.
Variable hf: helper_functions.
Hypothesis LINK: linkorder cunit prog.
Hypothesis HF: helper_functions_declared cunit hf.
(** If-conversion *)
End EXPRESSIONS.
(** Semantic preservation for functions and statements. *)
Inductive match_cont: Cminor.program -> helper_functions -> known_idents -> typenv -> Cminor.cont -> CminorSel.cont -> Prop :=
| match_cont_seq: forall cunit hf ki env s s' k k',
sel_stmt (prog_defmap cunit) ki env s = OK s' ->
match_cont cunit hf ki env k k' ->
match_cont cunit hf ki env (Cminor.Kseq s k) (Kseq s' k')
| match_cont_block: forall cunit hf ki env k k',
match_cont cunit hf ki env k k' ->
match_cont cunit hf ki env (Cminor.Kblock k) (Kblock k')
| match_cont_other: forall cunit hf ki env k k',
match_call_cont k k' ->
match_cont cunit hf ki env k k'
with match_call_cont: Cminor.cont -> CminorSel.cont -> Prop :=
| match_cont_stop:
match_call_cont Cminor.Kstop Kstop
| match_cont_call: forall cunit hf env id f sp e k f' e' k',
linkorder cunit prog ->
helper_functions_declared cunit hf ->
sel_function (prog_defmap cunit) hf f = OK f' ->
type_function f = OK env ->
match_cont cunit hf (known_id f) env k k' ->
env_lessdef e e' ->
match_call_cont (Cminor.Kcall id f sp e k) (Kcall id f' sp e' k').
Inductive match_states: Cminor.state -> CminorSel.state -> Prop :=
| match_state: forall cunit hf f f' s k s' k' sp e m e' m' env
(LINK: linkorder cunit prog)
(HF: helper_functions_declared cunit hf)
(TF: sel_function (prog_defmap cunit) hf f = OK f')
(TYF: type_function f = OK env)
(TS: sel_stmt (prog_defmap cunit) (known_id f) env s = OK s')
(MC: match_cont cunit hf (known_id f) env k k')
(LD: env_lessdef e e')
(ME: Mem.extends m m'),
match_states
(Cminor.State f s k sp e m)
(State f' s' k' sp e' m')
| match_callstate: forall cunit f f' args args' k k' m m'
(LINK: linkorder cunit prog)
(TF: match_fundef cunit f f')
(MC: match_call_cont k k')
(LD: Val.lessdef_list args args')
(ME: Mem.extends m m'),
match_states
(Cminor.Callstate f args k m)
(Callstate f' args' k' m')
| match_returnstate: forall v v' k k' m m'
(MC: match_call_cont k k')
(LD: Val.lessdef v v')
(ME: Mem.extends m m'),
match_states
(Cminor.Returnstate v k m)
(Returnstate v' k' m')
| match_builtin_1: forall cunit hf ef args optid f sp e k m al f' e' k' m' env
(LINK: linkorder cunit prog)
(HF: helper_functions_declared cunit hf)
(TF: sel_function (prog_defmap cunit) hf f = OK f')
(TYF: type_function f = OK env)
(MC: match_cont cunit hf (known_id f) env k k')
(EA: Cminor.eval_exprlist ge sp e m al args)
(LDE: env_lessdef e e')
(ME: Mem.extends m m'),
match_states
(Cminor.Callstate (External ef) args (Cminor.Kcall optid f sp e k) m)
(State f' (sel_builtin optid ef al) k' sp e' m')
| match_builtin_2: forall cunit hf v v' optid f sp e k m f' e' m' k' env
(LINK: linkorder cunit prog)
(HF: helper_functions_declared cunit hf)
(TF: sel_function (prog_defmap cunit) hf f = OK f')
(TYF: type_function f = OK env)
(MC: match_cont cunit hf (known_id f) env k k')
(LDV: Val.lessdef v v')
(LDE: env_lessdef (set_optvar optid v e) e')
(ME: Mem.extends m m'),
match_states
(Cminor.Returnstate v (Cminor.Kcall optid f sp e k) m)
(State f' Sskip k' sp e' m').
Remark call_cont_commut:
forall cunit hf ki env k k',
match_cont cunit hf ki env k k' -> match_call_cont (Cminor.call_cont k) (call_cont k').
Remark match_is_call_cont:
forall cunit hf ki env k k',
match_cont cunit ki env hf k k' -> Cminor.is_call_cont k ->
match_call_cont k k' /\ is_call_cont k'.
(* Remark match_call_cont_cont: forall k k', match_call_cont k k' -> exists cunit hf ki env, match_cont cunit hf ki env k k'. *)
Definition nolabel (s: Cminor.stmt) : Prop :=
forall lbl k, Cminor.find_label lbl s k = None.
Definition nolabel' (s: stmt) : Prop :=
forall lbl k, find_label lbl s k = None.

Lemma if_conversion_nolabel: forall (hf: helper_functions) ki env a s1 s2 s,
if_conversion ki env a s1 s2 = Some s ->
nolabel s1 /\ nolabel s2 /\ nolabel' s.