This file contain the equational lemmas that are enabled by the
well-formed SSA functions (see end of file).
Require Import Coqlib.
Require Import Maps.
Require Import AST.
Require Import Integers.
Require Import Values.
Require Import Memory.
Require Import Globalenvs.
Require Import Smallstep.
Require Import Op.
Require Import Registers.
Require Import Floats.
Require Import Utils.
Require Import RTL.
Require Import SSAutils.
Require Import Utilsvalidproof.
Require Import Dom.
Require Import SSA.
Require Import Conventions1.
Require Import Kildall.
Require Import KildallComp.
Require Import Relation_Operators.
Require Import Events.
Unset Allow StrictProp.
The rhs (right hand side) predicate, and equational invariant
Variant rhs (
f:
function) (
x :
reg) :
instruction ->
Prop :=
|
rhs_iop :
forall op args pc succ
(
RHS: (
fn_code f) !
pc =
Some (
Iop op args x succ))
(
MIND:
op_depends_on_memory op =
false),
rhs f x (
Iop op args x succ).
Global Hint Constructors rhs:
core.
Variant eval :
genv ->
val ->
regset ->
instruction ->
val ->
Prop :=
|
eval_Iop :
forall ge sp rs m op args res pc'
v
(
EVAL:
eval_operation ge sp op rs##
args m =
Some v)
(
MIND:
op_depends_on_memory op =
false),
eval ge sp rs (
Iop op args res pc')
v.
Global Hint Constructors eval:
core.
Variant models :
function ->
genv ->
val ->
regset ->
reg ->
instruction ->
Prop :=
|
models_state :
forall f ge x x'
i sp rs v,
rs #
x =
v ->
rhs f x'
i ->
eval ge sp rs i v ->
models f ge sp rs x i.
Global Hint Constructors models:
core.
Notation "[
a ,
b ,
c ,
d ] |=
x ==
i" := (
models a b c d x i) (
at level 1,
b at next level).
Variant sf_inv (
ge:
genv) :
stackframe ->
Prop :=
|
sf_inv_intro:
forall res f sp pc rs
(
WFF:
wf_ssa_function f)
(
SFINV:
forall x d i,
def f x d ->
rhs f x i ->
sdom f d pc -> [
f,
ge ,
sp ,
rs] |=
x ==
i)
(
SINS:
exists pred sig ros args, (
fn_code f) !
pred =
Some (
Icall sig ros args res pc)),
sf_inv ge (
Stackframe res f sp pc rs).
Global Hint Constructors sf_inv:
core.
Inductive sfl_inv (
ge:
genv) :
list stackframe ->
Prop :=
|
sfl_nil :
sfl_inv ge nil
|
sfl_cons :
forall s sl,
sf_inv ge s ->
sfl_inv ge sl ->
sfl_inv ge (
s::
sl).
Variant s_inv (
ge:
genv) :
state ->
Prop :=
|
si_State :
forall s f sp pc rs m
(
WFF:
wf_ssa_function f)
(
SINV:
forall x d i,
def f x d ->
rhs f x i ->
sdom f d pc -> [
f,
ge,
sp ,
rs] |=
x ==
i)
(
SFINV:
sfl_inv ge s),
s_inv ge (
State s f sp pc rs m)
|
si_Callstate :
forall s f args m
(
WFF:
wf_ssa_fundef f)
(
SFINV:
sfl_inv ge s),
s_inv ge (
Callstate s f args m)
|
si_Returnstate:
forall s v m
(
SFINV:
sfl_inv ge s),
s_inv ge (
Returnstate s v m).
Global Hint Constructors s_inv:
core.
Useful tactics
Ltac ssa_f f :=
match goal with
| [
Hwf:
wf_ssa_function f |-
_] =>
inv Hwf ;
solve [
eelim (
unique_def_elim1 f) ;
eauto]
end.
Ltac wf_ssa f :=
try (
solve [
eapply (
fn_ssa f) ;
eauto
|
eapply (
fn_code_reached f) ;
eauto
|
eapply (
fn_phicode_code f) ;
eauto
|
eapply (
fn_entry f) ;
eauto]).
Ltac def_def f x pc pc' :=
match goal with
| [
HWF:
wf_ssa_function f |-
_ ] =>
(
exploit (
def_def_eq f x pc pc'
HWF);
eauto);
try (
econstructor ;
eauto);
try (
solve [
econstructor ;
eauto])
end.
Lemma ssa_rhs_exists_def :
forall f x i,
wf_ssa_function f ->
rhs f x i ->
exists d,
def f x d.
Proof.
intros.
inv H0.
exists pc ; auto.
econstructor ; eauto.
Qed.
Ltac simpl_ext_params :=
match goal with
| [
h :
ext_params ?
f ?
x |-
_ ] =>
inv h ;
[ (
exploit fn_ssa_params ;
eauto);
(
intros [
HH HH'];
exploit HH ;
eauto ;
intuition)
|
match goal with
| [
h2 :
forall pc :
node, ~
assigned_phi_spec (
fn_phicode ?
f)
_ _,
h3 :
forall pc :
node, ~
assigned_code_spec (
fn_code ?
f)
_ _ |-
_ ] =>
solve [
exploit h2 ;
eauto ;
intuition |
exploit h3 ;
eauto ;
intuition ]
end]
end.
Lemma map_gso :
forall (
rs:
PMap.t val)
args x v,
(
forall arg,
In arg args ->
arg <>
x) ->
(
rs #
x <-
v)##
args =
rs ##
args.
Proof.
induction args ;
intros.
simpl ;
auto.
simpl.
rewrite PMap.gso ;
eauto.
rewrite IHargs;
eauto.
Qed.
Proof of the equational lemma
Section INV.
Variable prog :
program.
Hypothesis HWF:
wf_ssa_program prog.
Let ge_prog :=
Genv.globalenv prog.
Lemma find_function_prop:
forall ros rs fd,
find_function ge_prog ros rs =
Some fd ->
wf_ssa_fundef fd.
Proof.
Lemma subj_red :
forall s s'
t,
s_inv ge_prog s ->
step ge_prog s t s' ->
s_inv ge_prog s'.
Proof.
intros s s'
t HINV STEP.
inv HINV.
-
inv STEP;
econstructor ;
eauto ;
intros.
+
destruct (
peq d pc).
*
subst.
inv H;
try (
inv H2;
congruence).
inv H0.
simpl_ext_params.
inv H0.
inv WFF;
eelim (
unique_def_elim1 f);
eauto.
*
exploit (@
sdom_dom_pred node peq) ;
eauto;
wf_ssa f.
econstructor ;
eauto.
simpl ;
auto.
intros Hdom.
assert (
sdom f d pc)
by (
econstructor ;
eauto).
exploit SINV ;
eauto.
+
destruct (
peq d pc).
*
inv e.
inv H;
try (
inv H2;
congruence).
inv H0.
simpl_ext_params.
inv H0.
assert (
assigned_code_spec (
fn_code f)
pc0 x)
by (
econstructor ;
eauto).
inv WFF;
eelim (
unique_def_elim1 f);
eauto.
*
exploit (@
sdom_dom_pred node peq) ;
eauto;
wf_ssa f.
econstructor ;
eauto.
simpl ;
auto.
intros Hdom.
assert (
sdom f d pc)
by (
econstructor ;
eauto).
exploit SINV ;
eauto.
intros Hrs.
{
econstructor ;
eauto.
inv Hrs.
inv H5.
eapply eval_Iop with (
m:=
m0);
eauto.
rewrite phi_store_notin_preserved.
-
rewrite phi_store_notin_preserved_map;
auto.
inv H0.
intros.
intro Hcont.
assert (
def f dst pc').
econstructor 3 ;
eauto.
assert (
use f dst pc0).
econstructor ;
eauto.
econstructor ;
eauto.
exploit fn_strict ;
eauto;
wf_ssa f.
intros Hdom'.
assert (
pc0 =
d)
by (
destruct (
peq pc0 d);
auto;
def_def f res pc0 d).
subst.
eapply (@
sdom_not_dom node peq)
in H1 ;
eauto.
-
inv H0.
intros.
intro Hcont.
assert (
assigned_phi_spec (
fn_phicode f)
pc'
res).
econstructor ;
eauto.
assert (
assigned_code_spec (
fn_code f)
pc0 res).
econstructor ;
eauto.
ssa_f f.
}
+ {
assert (
HDOM:
dom f d pc).
{
eapply (@
sdom_dom_pred node peq) ;
eauto;
wf_ssa f.
econstructor ;
eauto ;
simpl ;
auto.
}
edestruct (
dom_eq_sdom peq _ _ _ d pc HDOM).
symmetry in H2.
inv H2.
assert (
res =
x).
clear HDOM.
inv H0.
inv H.
simpl_ext_params.
inv H0;
allinv.
auto.
eelim (
unique_def_elim1 f pc d x);
eauto;
wf_ssa f.
econstructor ;
eauto.
inv H2.
inv H0.
assert (
pc =
d)
by (
def_def f x d pc).
inv H0.
unfold fn_code in *;
allinv.
eapply eval_Iop with (
m:=
m) ;
eauto.
rewrite PMap.gss.
rewrite map_gso ;
eauto.
intros.
intro Hcont.
inv Hcont.
assert (
use_code f x d).
econstructor ;
eauto.
eelim fn_use_def_code ;
eauto;
wf_ssa f.
econstructor ;
eauto.
exploit SINV ;
eauto.
intros.
inv H3.
inv H6.
eapply eval_Iop with (
m:=
m0);
auto.
assert (
x <>
res)
by (
intro Hcont;
inv Hcont;
def_def f res pc d; (
intros Heq;
inv Heq ;
inv H2 ;
auto)).
rewrite PMap.gso ;
eauto.
rewrite map_gso ;
eauto.
intros.
intro Hcont.
inv Hcont.
assert (
use f res d).
inv H0.
assert (
d =
pc0).
destruct (
peq d pc0) ;
auto.
def_def f res0 d pc0;
eauto.
inv H0;
eauto.
econstructor ;
eauto.
econstructor ;
eauto.
assert (
def f res pc);
eauto.
exploit fn_strict ;
eauto;
wf_ssa f.
intro Hdom.
eapply (@
sdom_not_dom node peq)
in H2;
eauto.
}
+
assert (
HDOM:
dom f d pc).
eapply (@
sdom_dom_pred node peq) ;
eauto;
wf_ssa f.
econstructor ;
eauto ;
simpl ;
auto.
destruct (
peq pc d).
inv e.
inv H0.
assert (
pc =
d)
by (
def_def f x d pc).
inv H0.
congruence.
exploit SINV ;
eauto.
econstructor ;
eauto.
intros.
inv H2.
inv H5.
econstructor ;
eauto.
eapply eval_Iop with (
m:=
m0);
auto.
assert (
x <>
dst). (
intro Hcont;
inv Hcont;
def_def f dst pc d).
rewrite PMap.gso ;
eauto.
rewrite map_gso ;
eauto.
intros.
intro Hcont.
inv Hcont.
assert (
use f dst d).
inv H0.
assert (
d =
pc0).
destruct (
peq d pc0) ;
auto.
def_def f res d pc0.
inv H0.
econstructor ;
eauto.
econstructor ;
eauto.
assert (
def f dst pc).
econstructor ;
eauto.
exploit fn_strict ;
eauto;
wf_ssa f.
intro Hdom.
eapply (@
sdom_not_dom node peq)
in Hdom ;
eauto.
econstructor ;
eauto.
+
eapply SINV ;
eauto.
exploit (@
sdom_dom_pred node peq) ;
eauto;
wf_ssa f.
econstructor ;
eauto.
simpl ;
auto.
intros.
destruct (
peq d pc).
inv e.
inv H0.
def_def f x pc0 pc.
congruence.
econstructor ;
eauto.
+
eapply find_function_prop;
eauto.
+
{
econstructor ;
eauto.
econstructor;
eauto.
intros.
eapply SINV ;
eauto.
exploit (@
sdom_dom_pred node peq) ;
eauto;
wf_ssa f.
econstructor ;
eauto.
simpl ;
auto.
intros.
destruct (
peq d pc).
inv e.
inv H0.
def_def f x pc0 pc.
inv H0.
congruence.
econstructor ;
eauto.
}
+
eapply find_function_prop;
eauto.
+
assert (
HDOM:
dom f d pc).
eapply (@
sdom_dom_pred node peq) ;
eauto;
wf_ssa f.
econstructor ;
eauto ;
simpl ;
auto.
destruct (
peq pc d).
inv e.
inv H0.
assert (
pc =
d)
by (
def_def f x d pc).
inv H0.
congruence.
exploit SINV ;
eauto.
econstructor ;
eauto.
intros.
inv H2.
inv H5.
econstructor ;
eauto.
eapply eval_Iop with (
m:=
m0);
auto.
assert (
BR x <>
res)
by (
intro Hcont;
inv Hcont;
def_def f x pc d).
unfold regmap_setres.
destruct res ;
auto.
rewrite PMap.gso ;
eauto;
try congruence.
rewrite map_gso ;
eauto.
intros.
intro Hcont.
inv Hcont.
assert (
use f x0 d).
inv H0.
assert (
d =
pc0).
destruct (
peq d pc0) ;
auto.
def_def f res0 d pc0.
inv H0.
econstructor ;
eauto.
econstructor ;
eauto.
assert (
def f x0 pc).
econstructor ;
eauto.
exploit fn_strict ;
eauto;
wf_ssa f.
intro Hdom.
eapply (@
sdom_not_dom node peq)
in Hdom ;
eauto.
econstructor ;
eauto.
+
eapply SINV ;
eauto.
exploit (@
sdom_dom_pred node peq) ;
eauto;
wf_ssa f.
econstructor ;
eauto.
simpl ;
auto.
intros.
destruct (
peq d pc).
inv e.
inv H0.
def_def f x pc0 pc.
congruence.
econstructor ;
eauto.
+
eapply SINV ;
eauto.
exploit (@
sdom_dom_pred node peq) ;
eauto;
wf_ssa f.
econstructor ;
eauto.
simpl ;
auto.
intros.
destruct (
peq d pc).
inv e.
inv H0.
def_def f x pc0 pc.
congruence.
econstructor ;
eauto.
+
eapply SINV ;
eauto.
exploit (@
sdom_dom_pred node peq) ;
eauto;
wf_ssa f.
econstructor ;
eauto.
simpl.
eapply list_nth_z_in ;
eauto.
intros.
destruct (
peq d pc).
inv e.
inv H0.
def_def f x pc0 pc.
congruence.
econstructor ;
eauto.
-
inv STEP;
eauto.
econstructor ;
eauto.
inv WFF ;
auto.
intros ;
eelim (@
entry_sdom node peq) ;
eauto.
-
generalize STEP ;
inv STEP ;
intros STEP.
assert (
WFF:
wf_ssa_function f)
by (
inv SFINV;
inv H1;
auto).
inv SFINV.
inv H1.
econstructor ;
eauto.
intros.
exploit SFINV;
eauto.
intros.
inv H3.
destruct SINS as [
pred [
sig [
ros [
args Hpred]]]].
inv H6.
econstructor ;
eauto.
eapply eval_Iop with (
m:=
m0) ;
eauto.
assert (
x <>
res).
intro Hcont.
inv Hcont.
inv H0.
def_def f res0 pred pc0.
congruence.
rewrite PMap.gso ;
eauto.
rewrite map_gso;
auto.
intros.
intro Hcont.
inv Hcont.
inv H0.
def_def f res0 pc0 d.
intros Heq.
inv Heq.
assert (
def f res pred).
econstructor ;
eauto.
assert (
use f res d).
econstructor ;
eauto.
econstructor ;
eauto.
exploit fn_strict ;
eauto;
wf_ssa f.
intros Hdom'.
assert (
dom f d pred).
eapply (@
sdom_dom_pred node peq) ;
eauto;
wf_ssa f.
econstructor ;
eauto ;
simpl ;
auto.
exploit (@
dom_antisym node peq) ;
eauto.
congruence.
Qed.
Lemma s_inv_initial :
forall s,
initial_state prog s ->
s_inv ge_prog s.
Proof.
Lemma ssa_inv1_aux :
forall s s'
t,
s_inv ge_prog s ->
star step ge_prog s t s' ->
s_inv ge_prog s'.
Proof.
induction 2 ;
intros.
auto.
eapply IHstar ;
eauto.
eapply subj_red ;
eauto.
Qed.
Theorem ssa_inv1 :
forall s s'
t,
initial_state prog s ->
star step ge_prog s t s' ->
s_inv ge_prog s'.
Proof.
Main results
Definition reachable (
prog:
program) (
s:
state) :=
exists s0,
exists t,
initial_state prog s0
/\
star step (
Genv.globalenv prog)
s0 t s.
Theorem equation_lemma :
forall d op args x succ f m rs sp pc s,
(
fn_code f) !
d =
Some (
Iop op args x succ) ->
op_depends_on_memory op =
false ->
sdom f d pc ->
reachable prog (
State s f sp pc rs m) ->
eval_operation ge_prog sp op (
rs##
args)
m =
Some (
rs #
x).
Proof.
intros.
unfold reachable in H2.
destruct H2 as [
s0 [
t [
Hinit Hstar]]].
exploit ssa_inv1;
eauto.
intro Hinv.
inv Hinv ;
auto.
exploit (
SINV x d (
Iop op args x succ)) ;
eauto.
intros Hmodels.
inv Hmodels ;
eauto.
inv H4 ;
auto.
rewrite <-
EVAL.
eapply op_depends_on_memory_correct ;
eauto.
Qed.
Theorem equation_corollary :
forall d op args x succ f m rs sp pc s,
wf_ssa_program prog ->
(
fn_code f) !
d =
Some (
Iop op args x succ) ->
op_depends_on_memory op =
false ->
use f x pc ->
reachable prog (
State s f sp pc rs m) ->
eval_operation (
Genv.globalenv prog)
sp op (
rs##
args)
m =
Some (
rs #
x).
Proof.
End INV.