Correctness proof for interval propagation.
Require Import Coqlib Maps Integers Floats Lattice Kildall.
Require Import AST Linking.
Require Import Values Builtins Events Memory Globalenvs Smallstep.
Require Compopts Machregs.
Require Import Op Registers RTL.
Require Import Liveness ZIntervalDomain ZIntervalAOp RTL_ZIntervalAnalysis.
Require Import IntervalpropOp IntervalpropOpproof Intervalprop.
Definition match_prog (
prog tprog:
program) :=
match_program (
fun cu f tf =>
tf =
transf_fundef f)
eq prog tprog.
Lemma transf_program_match:
forall prog,
match_prog prog (
transf_program prog).
Proof.
Section PRESERVATION.
Variable prog:
program.
Variable tprog:
program.
Hypothesis TRANSL:
match_prog prog tprog.
Let ge :=
Genv.globalenv prog.
Let tge :=
Genv.globalenv tprog.
Correctness of the code transformation
We now show that the transformed code after constant propagation
has the same semantics as the original code.
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; trivial.
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.
Lemma init_regs_lessdef:
forall rl vl1 vl2,
Val.lessdef_list vl1 vl2 ->
regs_lessdef (
init_regs vl1 rl) (
init_regs vl2 rl).
Proof.
Inductive match_stackframes:
stackframe ->
stackframe ->
Prop :=
match_stackframe_intro:
forall res sp pc rs f rs'
(
REGS :
regs_lessdef rs rs'),
match_stackframes
(
Stackframe res f (
Vptr sp Ptrofs.zero)
pc rs)
(
Stackframe res (
transf_function f) (
Vptr sp Ptrofs.zero)
pc rs').
Inductive match_states:
state ->
state ->
Prop :=
|
match_states_intro:
forall s sp pc rs m f s' rs' m'
(
STACKS:
list_forall2 match_stackframes s s')
(
REGS:
regs_lessdef rs rs')
(
MEM:
Mem.extends m m'),
match_states (
State s f (
Vptr sp Ptrofs.zero)
pc rs m)
(
State s' (
transf_function f) (
Vptr sp Ptrofs.zero)
pc rs' m')
|
match_states_call:
forall s f args m s' args' m'
(
STACKS:
list_forall2 match_stackframes s s')
(
ARGS:
Val.lessdef_list args args')
(
MEM:
Mem.extends m m'),
match_states (
Callstate s f args m)
(
Callstate s' (
transf_fundef f)
args' m')
|
match_states_return:
forall s v m s' v' m'
(
STACKS:
list_forall2 match_stackframes s s')
(
RES:
Val.lessdef v v')
(
MEM:
Mem.extends m m'),
match_states (
Returnstate s v m)
(
Returnstate s' v' m').
Lemma transf_instr_at:
forall f pc i,
f.(
fn_code)!
pc =
Some i ->
(
transf_function f).(
fn_code)!
pc =
Some(
transf_instr f (
AA.analyze tt f)
pc i).
Proof.
intros.
simpl.
rewrite PTree.gmap.
rewrite H.
auto.
Qed.
Ltac TransfInstr :=
match goal with
|
H1: (
PTree.get ?
pc (
fn_code ?
f) =
Some ?
instr),
H2: (
AA.analyze ?
pinfo ?
f)#?
pc =
AA.Astate ?
aa |- _ =>
unfold transf_function;
cbn;
unfold transf_instr;
rewrite PTree.gmap;
unfold option_map;
rewrite H1;
change (
option aenv)
with AA.VA.t;
change (
AA.get_prog_info prog)
with tt in H2;
rewrite H2;
try reflexivity
end.
Ltac TransfAnalyze :=
match goal with
|
H1: (
PTree.get ?
pc (
fn_code ?
f) =
Some ?
instr),
H2: (
AA.analyze ?
pinfo ?
f)#?
pc =
AA.Astate ?
ae |- _ =>
exploit AA.analyze_succ; [
exact H2 |
cbn;
rewrite H1;
cbn;
reflexivity |
cbn;
auto |
idtac |
intros (
ae' &
ANALYZE' &
EMATCH')]
end.
The proof of simulation proceeds by case analysis on the transition
taken in the source code.
Definition match_states_full S1 S1' :=
AA.sound_state prog S1 /\
match_states S1 S1'.
Opaque op_strength_reduction.
Lemma find_function_same:
forall ros rs rs' fd
(
LESS_REGS :
regs_lessdef rs rs')
(
FIND :
find_function ge ros rs =
Some fd),
find_function ge ros rs' =
Some fd.
Proof.
intros. destruct ros; cbn in *.
- pose proof (LESS_REGS r) as LESS.
inv LESS.
+ assumption.
+ rewrite <- H0 in FIND. cbn in FIND. discriminate.
- assumption.
Qed.
Lemma step_simulation0:
forall S1 t S2,
RTL.step ge S1 t S2 ->
forall S1',
AA.sound_state prog S1 ->
match_states S1 S1' ->
exists S2',
RTL.step tge S1' t S2' /\
match_states S2 S2'.
Proof.
Lemma step_simulation:
forall S1 t S2,
RTL.step ge S1 t S2 ->
forall S1',
match_states_full S1 S1' ->
exists S2',
RTL.step tge S1' t S2' /\
match_states_full S2 S2'.
Proof.
Lemma transf_initial_states:
forall st1,
initial_state prog st1 ->
exists st2,
initial_state tprog st2 /\
match_states_full st1 st2.
Proof.
Lemma transf_final_states:
forall st1 st2 r,
match_states_full st1 st2 ->
final_state st1 r ->
final_state st2 r.
Proof.
intros until r. intros (SOUND & MATCH). intro FINAL.
inv FINAL. inv MATCH. inv RES. inv STACKS. constructor.
Qed.
The preservation of the observable behavior of the program then
follows.
Theorem transf_program_correct:
forward_simulation (
RTL.semantics prog) (
RTL.semantics tprog).
Proof.
End PRESERVATION.