Postorder renumbering of RTL control-flow graphs.
Require Import Coqlib.
Require Import Maps.
Require Import Postorder.
Require Import Events.
Require Import Globalenvs.
Require Import Smallstep.
Require Import Op.
Require Import Registers.
Require Import RTL.
Require Import Renumber.
Require Import Values.
Require Import Values_symbolictype.
Require Import Values_symbolic.
Section PRESERVATION.
Variable prog:
program.
Let tprog :=
transf_program prog.
Let ge :=
Genv.globalenv prog.
Let tge :=
Genv.globalenv tprog.
Lemma functions_translated:
forall m v f,
Genv.find_funct m ge v =
Some f ->
Genv.find_funct m tge v =
Some (
transf_fundef f).
Proof (@
Genv.find_funct_transf _ _ _ transf_fundef prog).
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 _ _ _ transf_fundef prog).
Lemma symbols_preserved:
forall id,
Genv.find_symbol tge id =
Genv.find_symbol ge id.
Proof (@
Genv.find_symbol_transf _ _ _ transf_fundef prog).
Lemma varinfo_preserved:
forall b,
Genv.find_var_info tge b =
Genv.find_var_info ge b.
Proof (@
Genv.find_var_info_transf _ _ _ transf_fundef prog).
Lemma sig_preserved:
forall f,
funsig (
transf_fundef f) =
funsig f.
Proof.
destruct f; reflexivity.
Qed.
Lemma find_function_translated:
forall m ros rs fd,
find_function ge m ros rs =
Some fd ->
find_function tge m 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).
Variable needed_stackspace :
AST.ident ->
nat .
Lemma step_simulation:
forall S1 t S2,
RTL.step ge needed_stackspace S1 t S2 ->
forall S1',
match_states S1 S1' ->
exists S2',
RTL.step tge needed_stackspace S1'
t S2' /\
match_states S2 S2'.
Proof.
Lemma transf_initial_states:
forall sg S1,
RTL.initial_state prog sg S1 ->
exists S2,
RTL.initial_state tprog sg 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. auto.
Qed.
Theorem transf_program_correct:
forall sg,
forward_simulation
(
RTL.semantics prog needed_stackspace sg )
(
RTL.semantics tprog needed_stackspace sg ).
Proof.
End PRESERVATION.