Postorder renumbering of RTL control-flow graphs.
Require Import Coqlib Maps Postorder.
Require Import AST Linking.
Require Import Values Memory Globalenvs Events Smallstep.
Require Import Op Registers RTL Renumber.
Definition match_prog (
p tp:
RTL.program) :=
match_program (
fun ctx f tf =>
tf =
transf_fundef f)
eq p tp.
Lemma transf_program_match:
forall p,
match_prog p (
transf_program p).
Proof.
Section PRESERVATION.
Variables prog tprog:
program.
Hypothesis TRANSL:
match_prog prog tprog.
Let ge :=
Genv.globalenv prog.
Let tge :=
Genv.globalenv tprog.
Lemma functions_translated:
forall v f,
Genv.find_funct ge v =
Some f ->
Genv.find_funct tge v =
Some (
transf_fundef f).
Proof (
Genv.find_funct_transf TRANSL).
Lemma function_ptr_translated:
forall v f,
Genv.find_funct_ptr ge v =
Some f ->
Genv.find_funct_ptr tge v =
Some (
transf_fundef f).
Proof (
Genv.find_funct_ptr_transf TRANSL).
Lemma symbols_preserved:
forall id,
Genv.find_symbol tge id =
Genv.find_symbol ge id.
Proof (
Genv.find_symbol_transf TRANSL).
Lemma senv_preserved:
Senv.equiv ge tge.
Proof (
Genv.senv_transf TRANSL).
Lemma sig_preserved:
forall f,
funsig (
transf_fundef f) =
funsig f.
Proof.
destruct f; reflexivity.
Qed.
Lemma find_function_translated:
forall ros rs fd,
find_function ge ros rs =
Some fd ->
find_function tge ros rs =
Some (
transf_fundef fd).
Proof.
Effect of an injective renaming of nodes on a CFG.
Section RENUMBER.
Variable f:
PTree.t positive.
Hypothesis f_inj:
forall x1 x2 y,
f!
x1 =
Some y ->
f!
x2 =
Some y ->
x1 =
x2.
Lemma renum_cfg_nodes:
forall c x y i,
c!
x =
Some i ->
f!
x =
Some y -> (
renum_cfg f c)!
y =
Some(
renum_instr f i).
Proof.
End RENUMBER.
Definition pnum (
f:
function) :=
postorder (
successors_map f)
f.(
fn_entrypoint).
Definition reach (
f:
function) (
pc:
node) :=
reachable (
successors_map f)
f.(
fn_entrypoint)
pc.
Lemma transf_function_at:
forall f pc i,
f.(
fn_code)!
pc =
Some i ->
reach f pc ->
(
transf_function f).(
fn_code)!(
renum_pc (
pnum f)
pc) =
Some(
renum_instr (
pnum f)
i).
Proof.
Ltac TR_AT :=
match goal with
| [
A: (
fn_code _)!
_ =
Some _ ,
B:
reach _ _ |-
_ ] =>
generalize (
transf_function_at _ _ _ A B);
simpl renum_instr;
intros
end.
Lemma reach_succ:
forall f pc i s,
f.(
fn_code)!
pc =
Some i ->
In s (
successors_instr i) ->
reach f pc ->
reach f s.
Proof.
Inductive match_frames:
RTL.stackframe ->
RTL.stackframe ->
Prop :=
|
match_frames_intro:
forall res f sp pc rs
(
REACH:
reach f pc),
match_frames (
Stackframe res f sp pc rs)
(
Stackframe res (
transf_function f)
sp (
renum_pc (
pnum f)
pc)
rs).
Inductive match_states:
RTL.state ->
RTL.state ->
Prop :=
|
match_regular_states:
forall stk f sp pc rs m stk'
(
STACKS:
list_forall2 match_frames stk stk')
(
REACH:
reach f pc),
match_states (
State stk f sp pc rs m)
(
State stk' (
transf_function f)
sp (
renum_pc (
pnum f)
pc)
rs m)
|
match_callstates:
forall stk f args m stk'
(
STACKS:
list_forall2 match_frames stk stk'),
match_states (
Callstate stk f args m)
(
Callstate stk' (
transf_fundef f)
args m)
|
match_returnstates:
forall stk v m stk'
(
STACKS:
list_forall2 match_frames stk stk'),
match_states (
Returnstate stk v m)
(
Returnstate stk'
v m).
Lemma step_simulation:
forall S1 t S2,
RTL.step ge S1 t S2 ->
forall S1',
match_states S1 S1' ->
exists S2',
RTL.step tge S1'
t S2' /\
match_states S2 S2'.
Proof.
Lemma transf_initial_states:
forall S1,
RTL.initial_state prog S1 ->
exists S2,
RTL.initial_state tprog S2 /\
match_states S1 S2.
Proof.
Lemma transf_final_states:
forall S1 S2 r,
match_states S1 S2 ->
RTL.final_state S1 r ->
RTL.final_state S2 r.
Proof.
intros. inv H0. inv H. inv STACKS. constructor.
Qed.
Theorem transf_program_correct:
forward_simulation (
RTL.semantics prog) (
RTL.semantics tprog).
Proof.
End PRESERVATION.