Section CLEANUP.
Variables prog tprog: program.
Hypothesis TRANSL: match_prog prog tprog.
Let ge := Genv.globalenv prog.
Let tge := Genv.globalenv tprog.
Proof (Genv.find_symbol_transf TRANSL).
Proof (Genv.senv_transf TRANSL).
Proof (Genv.find_funct_transf TRANSL).
Proof (Genv.find_funct_ptr_transf TRANSL).
(** Correctness of [labels_branched_to]. *)
Definition instr_branches_to (i: instruction) (lbl: label) : Prop :=
match i with
| Lgoto lbl' => lbl = lbl'
| Lcond cond args lbl' => lbl = lbl'
| Ljumptable arg tbl => In lbl tbl
| _ => False
end.
Remark add_label_branched_to_incr:
forall ls i, Labelset.Subset ls (add_label_branched_to ls i).
Remark add_label_branched_to_contains:
forall ls i lbl,
instr_branches_to i lbl ->
Labelset.In lbl (add_label_branched_to ls i).
(** Commutation with [find_label]. *)
(** Correctness of clean-up *)
Inductive match_stackframes: stackframe -> stackframe -> Prop :=
| match_stackframe_intro:
forall f sp ls c,
incl c f.(fn_code) ->
match_stackframes
(Stackframe f sp ls c)
(Stackframe (transf_function f) sp ls
(remove_unused_labels (labels_branched_to f.(fn_code)) c)).
Inductive match_states: state -> state -> Prop :=
| match_states_intro:
forall s f sp c ls m ts
(STACKS: list_forall2 match_stackframes s ts)
(INCL: incl c f.(fn_code)),
match_states (State s f sp c ls m)
(State ts (transf_function f) sp (remove_unused_labels (labels_branched_to f.(fn_code)) c) ls m)
| match_states_call:
forall s f ls m ts,
list_forall2 match_stackframes s ts ->
match_states (Callstate s f ls m)
(Callstate ts (transf_fundef f) ls m)
| match_states_return:
forall s ls m ts,
list_forall2 match_stackframes s ts ->
match_states (Returnstate s ls m)
(Returnstate ts ls m).
Definition measure (st: state) : nat :=
match st with
| State s f sp c ls m => List.length c
| _ => O
end.

Theorem transf_program_correct:
forward_simulation (Linear.semantics prog) (Linear.semantics tprog).