Some properties satisfied by well-typed functions with structural
invariants. These are requirements for wf_ssa_functions
Require Import Classical.
Require Import Coqlib.
Require Import Maps.
Require Import AST.
Require Import Registers.
Require Import Floats.
Require Import Utils.
Require Import RTLdfs.
Require Import RTLutils.
Require Import Dom.
Require Import SSA.
Require Import SSAutils.
Require Import Conventions1.
Require Import SSAvalidspec.
Require Import Utilsvalidproof.
Require Import Kildall.
Require Import KildallComp.
Require Import Relation_Operators.
Require Import LightLive.
Require DomCompute.
Require Import Bijection.
Unset Allow StrictProp.
Notation path_step := (
fun f =>
path_step (
cfg f) (
exit f) (
fn_entrypoint f)).
Section WT_FUNCTION.
Variable size:
nat.
Variable f_rtl :
RTLdfs.function.
Variable f :
function.
Variable G :
SSAvalid.tgamma.
Variable live:
PMap.t Regset.t.
Hypothesis fn_wt :
wt_function size f_rtl f live G.
Hypothesis fn_wfi :
wf_init size f G.
Hypothesis fn_erased :
check_erased_spec size f_rtl f.
Hypothesis fn_wfl :
wf_live f_rtl (
Lout live).
Hypothesis fn_ssa :
unique_def_spec f.
Hypothesis fn_ssa_params1 :
forall x pc,
In x (
fn_params f) -> ~
assigned_code_spec (
fn_code f)
pc x.
Hypothesis fn_ssa_params2 :
forall x pc,
In x (
fn_params f) -> ~
assigned_phi_spec (
fn_phicode f)
pc x.
Hypothesis fn_reached :
forall pc ins, (
fn_code f) !
pc =
Some ins ->
reached f pc.
Hypothesis fn_entry :
exists s, (
fn_code f) ! (
fn_entrypoint f) =
Some (
Inop s).
Hypothesis fn_phicode_code :
forall pc block,
(
fn_phicode f) !
pc =
Some block ->
exists ins, (
fn_code f) !
pc =
Some ins.
Hypothesis fn_code_closed:
forall pc pc'
instr,
f.(
fn_code) !
pc =
Some instr ->
In pc' (
successors_instr instr) ->
exists instr',
f.(
fn_code) !
pc' =
Some instr'.
Hypothesis fn_entrypoint_inv:
(
exists i, (
f.(
fn_code) ! (
f.(
fn_entrypoint)) =
Some i)) /\
~
join_point f.(
fn_entrypoint)
f.
Hypothesis fn_code_inv2:
forall jp pc i, (
join_point jp f) ->
In jp ((
successors f) !!!
pc) ->
f.(
fn_code) !
jp =
Some i ->
f.(
fn_code) !
pc =
Some (
Inop jp).
Hypothesis fn_phicode_inv1:
forall phib jp i,
f.(
fn_code) !
jp =
Some i ->
f.(
fn_phicode) !
jp =
Some phib ->
join_point jp f.
Hypothesis fn_phicode_inv2:
forall jp i,
join_point jp f ->
f.(
fn_code) !
jp =
Some i ->
exists phib,
f.(
fn_phicode) !
jp =
Some phib.
Notation ui := (
erase_reg size).
Notation gi := (
get_index size).
Notation entry :=
fn_entrypoint.
Utility lemmas about indexed registers.
Lemma rmap_uigi :
forall x,
Bij.rmap size x = (
ui x,
gi x).
Proof.
Hint Resolve rmap_uigi :
bij.
Utility lemmas on the erasure function
Lemma elim_structural :
forall pc pc'
instr instr'
block,
(
fn_code f) !
pc =
Some instr ->
(
fn_code f) !
pc' =
Some instr' ->
(
fn_phicode f) !
pc' =
Some block ->
In pc' (
successors_instr instr) ->
instr =
Inop pc'.
Proof.
Lemma erased_funct_erased_instr_2:
forall size pc f tf rinstr,
check_erased_spec size f tf ->
(
SSA.fn_code tf)!
pc =
Some rinstr ->
exists pinstr,
(
RTLdfs.fn_code f) !
pc =
Some pinstr
/\
pinstr = (
erase_instr size rinstr).
Proof.
Lemma erased_assigned_code_spec :
forall pc x,
RTLutils.assigned_code_spec (
RTLdfs.fn_code f_rtl)
pc (
ui x) ->
exists rix idx,
Bij.rmap size rix = ((
ui x),
idx) /\
assigned_code_spec (
fn_code f)
pc rix.
Proof.
Lemma use_code_spec :
forall pc x,
use_code f x pc ->
use_rtl_code f_rtl (
ui x)
pc.
Proof.
intros.
inv H ;
(
exploit erased_funct_erased_instr_2 ;
eauto);
(
intros [
pinstr [
Hcode Hins]];
inv Hins);
(
unfold erase_instr in * ;
simpl in *).
-
econstructor 1 ;
eauto; (
eapply in_map ;
eauto).
-
econstructor 2 ;
eauto; (
eapply in_map ;
eauto).
-
econstructor 3 ;
eauto; (
eapply in_map ;
eauto).
-
econstructor 4 ;
eauto.
generalize H1.
clear.
revert x.
induction args;
intros;
auto.
simpl in *.
apply in_app_or in H1.
inv H1.
+
apply in_or_app.
left.
revert H.
clear.
induction a ;
simpl;
intros ;
auto.
*
intuition;
subst;
auto.
*
apply in_app_or in H.
inv H;
apply in_or_app;
auto.
*
apply in_app_or in H.
inv H;
apply in_or_app;
auto.
+
apply in_or_app;
eauto.
-
econstructor 5 ;
eauto.
inv H1;
eauto.
econstructor 2 ;
eauto. (
eapply in_map ;
eauto).
-
econstructor 6 ;
eauto.
inv H1;
eauto.
econstructor 2 ;
eauto. (
eapply in_map ;
eauto).
-
econstructor 8 ;
eauto.
inv H1;
eauto.
econstructor 2 ;
eauto. (
eapply in_map ;
eauto).
-
econstructor 7 ;
eauto. (
eapply in_map ;
eauto).
-
econstructor 9 ;
eauto. (
eapply in_map ;
eauto).
-
econstructor 10 ;
eauto.
-
econstructor 11 ;
eauto.
Qed.
Lemma use_ins_code :
forall pc x,
use f x pc ->
exists ins, (
fn_code f) !
pc =
Some ins.
Proof.
Utility lemmas about cfg edge, and path
Hint Constructors rtl_cfg:
core.
Lemma cfg_rtl_cfg :
forall size f tf pc1 pc2,
check_erased_spec size f tf ->
cfg tf pc1 pc2 ->
rtl_cfg f pc1 pc2.
Proof.
clear.
intros.
inv H0.
exploit erased_funct_erased_instr_2 ;
eauto.
intros [
pinstr [
Hcode Hins]].
inv Hins.
destruct ins;
simpl in * ;
eauto.
(
destruct s0;
allinv; (
inv HCFG_in;
eauto)).
econstructor;
eauto;
simpl;
auto.
intuition.
econstructor;
eauto;
simpl;
auto.
intuition.
econstructor;
eauto;
simpl;
auto.
intuition.
econstructor;
eauto;
simpl;
auto.
intuition.
Qed.
Import DLib.
Notation path := (
fun f =>
path (
cfg f) (
exit f) (
entry f)).
Lemma path_first :
forall p pc pc',
path f (
PState pc)
p (
PState pc') ->
pc <>
pc' ->
exists pc'',
exists p',
exists p'',
path f (
PState pc)
p' (
PState pc'') /\
~
In pc'
p' /\
pc'' <>
pc' /\
path_step f (
PState pc'')
pc'' (
PState pc') /\
p =
p'++(
pc''::
p'').
Proof.
clear.
induction p ;
intros;
inv H.
congruence.
assert (
a =
pc)
by (
inv STEP;
auto).
inv H.
destruct s2.
destruct (
peq pc0 pc').
inv e.
exists pc.
exists nil.
exists p.
split;
eauto.
econstructor ;
eauto.
exploit IHp ;
eauto.
intros [
pc'' [
p' [
p'' [
Hp' [
Hpc'' [
Hdiff [
Hnotin Happ]]]]]]].
exists pc''.
exists (
pc::
p').
exists p''.
split ;
auto.
econstructor ;
eauto.
split ;
auto.
intro Hcont.
inv Hcont.
congruence.
elim Hpc'' ;
auto.
split.
intro Hcont.
inv Hcont.
congruence.
split ;
eauto.
simpl.
rewrite Happ ;
auto.
exploit (@
path_from_ret_nil node);
eauto.
intros Heq ;
subst.
inv PATH.
Qed.
Lemma use_reached :
forall pc x,
use f x pc ->
reached f pc.
Proof.
Tactics
Ltac error_struct tf pc pc' :=
(
match goal with
| [
H1 : (
fn_code tf) !
pc =
Some _ ,
H2 : (
fn_phicode tf) !
pc' =
Some _
|-
_ ] =>
let Hcont :=
fresh "
Hcont"
in
let HHcont :=
fresh "
Hcont"
in
(
exploit (
fn_code_closed pc pc') ;
eauto) ;
(
allinv ;
simpl ;
auto) ;
(
intros [
ins'
Hins'] ; (
exploit (
elim_structural pc pc');
eauto);
[
allinv ; (
simpl) ;
auto | (
intros HHcont;
inv HHcont)])
| [
H1 : (
fn_code tf) !
pc =
Some _ ,
H2 : (
fn_phicode tf) !
pc' =
Some _
|-
_ ] =>
let HHcont :=
fresh "
Hcont"
in
(
exploit (
fn_code_closed pc pc') ;
eauto);
(
intros [
ins'
Hins'] ; (
exploit (
elim_structural pc pc');
eauto)) ;
(
intro HHcont ;
inv HHcont)
end).
Ltac well_typed :=
match goal with
| [
Hwt :
wt_instr _ _ _ _ |-
_ ] =>
inv Hwt
end.
Lemma use_code_valid_reg :
forall x pc,
use_code f x pc ->
Bij.valid_reg_ssa size x =
true.
Proof.
inv fn_wt.
induction 1 ;
intros;
try (
assert (
He:
is_edge f pc s)
by go;
(
exploit WTE;
eauto); (
intros Hwte;
inv Hwte;
allinv);
[
well_typed;
eauto
|
error_struct f pc s]
).
-
assert (
He:
is_out_node f pc)
by go.
exploit WTO;
eauto.
intros Hwte.
inv Hwte;
allinv.
well_typed;
eauto.
-
assert (
He:
is_out_node f pc)
by go.
exploit WTO;
eauto.
intros Hwte.
inv Hwte;
allinv.
well_typed;
eauto.
-
destruct tbl.
+
assert (
He:
is_out_node f pc)
by go.
exploit WTO;
eauto.
intros Hwte.
inv Hwte;
allinv.
well_typed;
eauto.
+
assert (
He:
is_edge f pc n)
by go.
exploit WTE;
eauto.
intros Hwte.
inv Hwte;
allinv.
*
well_typed;
eauto.
*
error_struct f pc n.
-
assert (
He:
is_out_node f pc)
by go.
exploit WTO;
eauto.
intros Hwte.
inv Hwte;
allinv.
well_typed;
eauto.
Qed.
Lemma use_phicode_valid_reg:
forall x pc,
use_phicode f x pc ->
Bij.valid_reg_ssa size x =
true.
Proof.
Lemma def_code_valid_reg :
forall x pc,
assigned_code_spec (
fn_code f)
pc x ->
Bij.valid_reg_ssa size x =
true.
Proof.
inv fn_wt.
induction 1 ;
intros.
-
assert (
He:
is_edge f pc succ)
by go.
(
exploit WTE;
eauto); (
intros Hwte;
inv Hwte;
allinv).
+
well_typed;
eauto.
+
error_struct f pc succ.
-
assert (
He:
is_edge f pc succ)
by go.
(
exploit WTE;
eauto); (
intros Hwte;
inv Hwte;
allinv).
+
well_typed;
eauto.
+
error_struct f pc succ.
-
assert (
He:
is_edge f pc succ)
by go.
(
exploit WTE;
eauto); (
intros Hwte;
inv Hwte;
allinv).
+
well_typed;
eauto.
+
error_struct f pc succ.
-
assert (
He:
is_edge f pc succ)
by go.
(
exploit WTE;
eauto); (
intros Hwte;
inv Hwte;
allinv).
+
well_typed;
eauto.
eelim H6;
eauto.
+
error_struct f pc succ.
Qed.
Lemma def_phicode_valid_reg:
forall x pc,
assigned_phi_spec (
fn_phicode f)
pc x ->
Bij.valid_reg_ssa size x =
true.
Proof.
Lemma def_valid_reg :
forall x pc,
def f x pc ->
Bij.valid_reg_ssa size x =
true.
Proof.
Properties required for wf_ssa_function
Lemma unique_def_spec_def :
forall x d1 d2,
def f x d1 ->
def f x d2 ->
d1 <>
d2 ->
False.
Proof.
intros.
destruct fn_ssa as [
Hssa1 Hssa2].
destruct fn_entry as [
succ Hentry].
inv H ;
inv H0 ;
inv H ;
inv H2;
try congruence;
try solve [
exploit fn_ssa_params1 ;
eauto
|
exploit fn_ssa_params2 ;
eauto
|
exploit H3 ;
eauto
|
exploit H4 ;
eauto;
intuition
| (
eelim (
Hssa1 x d1 d2) ;
eauto;
intuition subst;
eauto)].
Qed.
Lemma use_code_gamma :
forall u x
(
USE :
use_code f x u),
G u (
ui x) = (
gi x).
Proof.
intros.
destruct (
Bij.rmap size x)
as (
rx,
ridx)
eqn:
EQ;
simpl in *.
inv USE;
match goal with
| [
Hins : (
fn_code f) !
u =
Some (
Icall _ _ _ _ _) |-
_ ] =>
inv H0
| [
Hins : (
fn_code f) !
u =
Some (
Itailcall _ _ _) |-
_ ] =>
inv H0
| [
Hins : (
fn_code f) !
u =
Some (
Ijumptable _ _) |-
_ ] =>
destruct tbl as [ |
s succ]; [
idtac |]
|
_ =>
idtac
end ;
let tac := ((
inv fn_wt);
((
assert (
Ho :
is_out_node f u)
by (
solve [
econstructor 2 ;
eauto |
econstructor 1 ;
eauto])) ;
(
exploit (
WTO u) ;
eauto ;
intro Hwto) ;
(
inv Hwto;
allinv;
try error_struct f u s);
(
well_typed ;
eauto using rmap_uigi)))
in
(
match goal with
| [
Hins : (
fn_code f) !
u =
Some (
Ireturn _) |-
_ ] =>
tac
| [
Hins : (
fn_code f) !
u =
Some (
Itailcall _ _ _) |-
_] =>
tac
|
_ =>
try ((
inv fn_wt);
((
assert (
He :
is_edge f u s)
by (
econstructor ;
eauto ;
simpl ;
auto)) ;
(
exploit (
WTE u s) ;
eauto ;
intro Hwte);
(
inv Hwte;
allinv;
try error_struct f u s);
(
well_typed ;
eauto using rmap_uigi)))
end).
((
inv fn_wt);
((
assert (
Ho :
is_out_node f u)
by (
solve [
econstructor 3 ;
eauto |
econstructor 1 ;
eauto])) ;
(
exploit (
WTO u) ;
eauto ;
intro Hwto) ;
(
inv Hwto;
allinv;
try error_struct f u s);
(
well_typed ;
eauto using rmap_uigi))).
Qed.
Lemma use_phicode_gamma :
forall u x
(
USE :
use_phicode f x u),
G u (
ui x) = (
gi x).
Proof.
Lemma use_gamma :
forall x u,
use f x u ->
G u (
ui x) =
gi x.
Proof.
Lemma wt_use_isdef :
forall x u,
use f x u ->
exists d,
def f x d.
Proof.
Lemma gamma_entry_param :
forall x d,
G (
entry f) (
ui x) =
gi x ->
def f x d ->
d = (
entry f).
Proof.
Lemma gamma_path_def :
forall p s,
DomCompute.path f p s ->
match s with
|
PStop =>
True
|
PState pc =>
forall xi x d i,
Bij.rmap size xi = (
x,
i) ->
def f xi d ->
G pc x =
i ->
Regset.In x (
Lin f_rtl pc (
Lout live)) ->
(
In d p
\/ (
d =
pc /\
~ (
use_code f xi pc /\
assigned_code_spec (
fn_code f)
pc xi)))
end.
Proof.
induction 1 ;
intros ;
auto.
-
right.
exploit gamma_entry_param ;
eauto.
+
unfold erase_reg,
get_index.
rewrite H.
simpl;
auto.
+
intro Heq;
subst ;
split ;
auto.
intros [
_ Hcont2].
destruct fn_entry as [
se Hentry].
inv Hcont2 ;
allinv.
-
assert (
is_edge f pc pc')
by (
econstructor ;
eauto).
generalize fn_wt;
intros WELL_TYPED.
inv WELL_TYPED.
destruct (
classic (
Regset.In x (
Lin f_rtl pc (
Lout live)))).
+
exploit WTE ;
eauto.
intros Hwte.
inv Hwte;
allinv.
destruct ins.
*
inv WTI.
rewrite <-
H8 in *.
exploit IHpath ;
eauto.
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21.
left ;
eauto.
*
inv WTI.
destruct (
p2eq (
x,
G pc'
x) (
r0,
i)).
--
inv e.
left.
left.
destruct (
peq d pc);
auto.
exploit (
unique_def_spec_def xi d pc) ;
eauto.
assert (
r =
xi).
{
eapply Bij.INJ;
eauto; [|
congruence].
eapply def_valid_reg;
eauto.
}
subst.
repeat econstructor;
eauto.
intuition.
--
exploit (
IHpath xi) ;
eauto.
++
rewrite <-
H10.
unfold update.
destruct (
peq x r0).
**
inv e.
elim n0.
rewrite <-
H10.
unfold update ;
unfold erase_reg.
rewrite peq_true;
auto.
**
auto.
++
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21 ;
eauto.
*
inv WTI.
destruct (
p2eq (
x,
G pc'
x) (
r0,
i)).
inv e.
left ;
left.
destruct (
peq d pc);
auto.
assert (
r =
xi).
{
eapply Bij.INJ;
eauto; [|
congruence].
eapply def_valid_reg;
eauto.
}
subst.
exploit (
unique_def_spec_def xi d pc) ;
eauto.
intuition.
exploit (
IHpath xi) ;
eauto.
rewrite <-
H12.
unfold update.
destruct (
peq x r0).
inv e.
elim n0.
rewrite <-
H12.
unfold update,
erase_reg.
rewrite peq_true.
auto.
auto.
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21 ;
eauto.
*
inv WTI ;
rewrite <-
H12 in * ;
eauto.
exploit IHpath ;
eauto.
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21 ;
eauto.
*
inv WTI.
destruct (
p2eq (
x,
G pc'
x) (
r0,
i)).
inv e.
unfold erase_reg,
get_index in * ;
simpl in *.
left ;
left.
destruct (
peq d pc);
auto.
assert (
r =
xi).
{
eapply Bij.INJ;
eauto; [|
congruence].
eapply def_valid_reg;
eauto.
}
subst.
exploit (
unique_def_spec_def xi d pc) ;
eauto.
intuition.
exploit (
IHpath xi) ;
eauto.
rewrite <-
H12.
unfold update.
destruct (
peq x r0).
inv e.
elim n0.
rewrite <-
H12.
unfold update,
erase_reg.
rewrite peq_true.
auto.
auto.
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21 ;
eauto.
destruct (
p2eq (
x,
G pc'
x) (
r0,
i)).
inv e.
unfold erase_reg,
get_index in * ;
simpl in *.
left ;
left.
destruct (
peq d pc);
auto.
assert (
r =
xi).
{
eapply Bij.INJ;
eauto; [|
congruence].
eapply def_valid_reg;
eauto.
}
subst.
exploit (
unique_def_spec_def xi d pc) ;
eauto.
intuition.
exploit (
IHpath xi) ;
eauto.
rewrite <-
H12.
unfold update.
destruct (
peq x r0).
inv e.
elim n0.
rewrite <-
H12.
unfold update,
erase_reg.
rewrite peq_true.
auto.
auto.
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21 ;
eauto.
*
inv WTI.
rewrite <-
H9 in * ;
eauto.
exploit IHpath ;
eauto.
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21 ;
eauto.
rewrite <-
H9 in * ;
eauto.
exploit IHpath ;
eauto.
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21 ;
eauto.
*
{
inv WTI.
-
destruct (
p2eq (
x,
G pc'
x) (
r,
i)).
+
inv e0.
left ;
left.
destruct (
peq d pc);
auto.
assert (
x0 =
xi).
{
eapply Bij.INJ;
eauto; [|
congruence].
eapply def_valid_reg;
eauto.
}
subst.
exploit (
unique_def_spec_def xi d pc) ;
eauto.
intuition.
+
exploit (
IHpath xi) ;
eauto.
rewrite <-
H10.
unfold update.
destruct (
peq x r).
subst.
elim n0.
rewrite <-
H10.
unfold update;
rewrite peq_true ;
auto.
auto.
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21 ;
eauto.
-
exploit IHpath;
eauto.
rewrite H10;
auto.
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21 ;
eauto.
}
*
inv WTI.
rewrite <-
H11 in * ;
eauto.
exploit IHpath ;
eauto.
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21 ;
eauto.
*
inv WTI.
rewrite <-
H7 in * ;
eauto.
exploit IHpath ;
eauto.
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21 ;
eauto.
*
inv WTI.
rewrite <-
H6 in * ;
eauto.
exploit IHpath ;
eauto.
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21 ;
eauto.
rewrite <-
H8 in * ;
eauto.
exploit IHpath ;
eauto.
intros [
HH1 | [
HH21 HH22]].
left ;
eauto.
inv HH21 ;
eauto.
*
inv WTPHID.
destruct (
classic (
assigned xi block)).
--
right.
assert (
d =
pc').
destruct (
peq d pc');
auto.
exploit (
unique_def_spec_def xi d pc') ;
eauto.
intuition.
split ;
auto.
intros [
Hcont1 Hcont2].
inv H5.
inv fn_ssa.
destruct (
H5 xi pc'
pc')
as [
_ [
_ [
Hcont _]]].
exploit Hcont ;
eauto.
--
destruct (
classic (
erased_reg_assigned size x block)).
++
inv H6.
inv H7.
destruct (
Bij.rmap size x0)
as (
r,
p0)
eqn:
Hx0;
simpl in *.
exploit (
ASSIG x0);
eauto.
right.
unfold ui in *.
rewrite Hx0 in *.
simpl in *.
rewrite H7 in *.
assert (
x0 =
xi).
{
eapply Bij.INJ;
eauto.
eapply def_valid_reg;
eauto.
congruence.
}
subst.
assert (
d =
pc').
{
destruct (
peq d pc') ;
auto.
intuition.
}
intuition.
++
exploit (
NASSIG x) ;
eauto.
intros.
intros Hcont.
elim H6.
exists ri.
split ;
auto.
unfold ui.
rewrite H7 ;
auto.
intros [
HH1 |
HH2].
rewrite HH1 in * ;
eauto.
exploit IHpath ;
eauto.
intros [
HH1' | [
HH21'
HH22']].
left ;
eauto.
inv HH21' ;
eauto.
intuition.
+
exploit (
wf_live_incl f_rtl (
Lout live)
fn_wfl pc pc') ;
eauto.
eapply cfg_rtl_cfg ;
eauto.
econstructor ;
eauto.
intros [
HH1 |
HH2];
auto.
intuition.
exploit (
erased_assigned_code_spec pc xi) ;
eauto.
unfold ui;
rewrite H0;
auto.
intros [
rix [
idx [
Hrmap Hass]]].
inv Hass ;
allinv.
*
exploit WTE ;
eauto.
intros Hwte.
inv Hwte ;
allinv ;
try (
error_struct f pc pc').
inv WTI.
rewrite <-
H10 in *.
assert (
HEQ: (
r,
i) = (
ui xi,
idx))
by congruence.
inv HEQ.
unfold ui in *.
rewrite H0 in *.
simpl fst in *.
assert (
HEQ:
fst (
Bij.rmap size xi) =
x).
{
rewrite H0;
auto. }
rewrite HEQ in *.
unfold update in * ;
rewrite peq_true in *.
assert (
d =
pc).
destruct (
peq d pc);
auto.
assert (
rix =
xi).
{
eapply Bij.INJ;
eauto; [|
congruence].
eapply def_valid_reg;
eauto.
}
subst.
exploit (
unique_def_spec_def xi d pc) ;
eauto.
intuition.
inv H5.
eauto.
*
exploit WTE ;
eauto.
intros Hwte.
inv Hwte ;
allinv ;
try (
error_struct f pc pc').
inv WTI.
rewrite <-
H12 in *.
assert (
HEQ: (
r,
i) = (
ui xi,
idx))
by congruence.
inv HEQ.
unfold ui in *.
rewrite H0 in *.
simpl fst in *.
assert (
HEQ:
fst (
Bij.rmap size xi) =
x).
{
rewrite H0;
auto. }
rewrite HEQ in *.
unfold update in * ;
rewrite peq_true in *.
assert (
d =
pc).
destruct (
peq d pc);
auto.
assert (
rix =
xi).
{
eapply Bij.INJ;
eauto; [|
congruence].
eapply def_valid_reg;
eauto.
}
subst.
exploit (
unique_def_spec_def xi d pc) ;
eauto.
intuition.
inv H5.
auto.
*
exploit WTE ;
eauto.
intros Hwte.
inv Hwte ;
allinv ;
try (
error_struct f pc pc').
inv WTI.
rewrite <-
H12 in *.
assert (
HEQ: (
r,
i) = (
ui xi,
idx))
by congruence.
inv HEQ.
unfold ui in *.
rewrite H0 in *.
simpl fst in *.
assert (
HEQ:
fst (
Bij.rmap size xi) =
x).
{
rewrite H0;
auto. }
rewrite HEQ in *.
unfold update in * ;
rewrite peq_true in *.
assert (
d =
pc).
destruct (
peq d pc);
auto.
assert (
rix =
xi).
{
eapply Bij.INJ;
eauto; [|
congruence].
eapply def_valid_reg;
eauto.
}
subst.
exploit (
unique_def_spec_def xi d pc) ;
eauto.
intuition.
inv H5.
auto.
rewrite <-
H12 in *.
assert (
HEQ: (
r,
i) = (
ui xi,
idx))
by congruence.
inv HEQ.
unfold ui in *.
rewrite H0 in *.
simpl fst in *.
assert (
HEQ:
fst (
Bij.rmap size xi) =
x).
{
rewrite H0;
auto. }
rewrite HEQ in *.
unfold update in * ;
rewrite peq_true in *.
assert (
d =
pc).
destruct (
peq d pc);
auto.
assert (
rix =
xi).
{
eapply Bij.INJ;
eauto; [|
congruence].
eapply def_valid_reg;
eauto.
}
subst.
exploit (
unique_def_spec_def xi d pc) ;
eauto.
intuition.
inv H5.
auto.
*
exploit WTE ;
eauto.
intros Hwte.
inv Hwte ;
allinv ;
try (
error_struct f pc pc').
inv WTI.
--
rewrite <-
H10 in *.
assert (
HEQ: (
r,
i) = (
ui xi,
idx))
by congruence.
inv HEQ.
unfold ui in *.
rewrite H0 in *.
simpl fst in *.
assert (
HEQ:
fst (
Bij.rmap size xi) =
x).
{
rewrite H0;
auto. }
rewrite HEQ in *.
unfold update in * ;
rewrite peq_true in *.
assert (
d =
pc).
destruct (
peq d pc);
auto.
assert (
rix =
xi).
{
eapply Bij.INJ;
eauto; [|
congruence].
eapply def_valid_reg;
eauto.
}
subst.
exploit (
unique_def_spec_def xi d pc) ;
eauto.
intuition.
inv H5.
auto.
--
eelim H11;
eauto.
Qed.
Lemma gamma_def_path :
forall p pc xi x i d,
Bij.rmap size xi = (
x,
i) ->
def f xi d ->
G pc x =
i ->
DomCompute.path f p (
PState pc) ->
Regset.In x (
Lin f_rtl pc (
Lout live)) ->
In d (
pc::
p).
Proof.
intros.
exploit gamma_path_def ;
eauto.
simpl.
intros.
exploit H4 ;
eauto.
intros [
HH1 | [
HH21 HH22]].
right ;
auto.
inv HH21.
left ;
auto.
Qed.
Lemma phiu_same_length :
forall r args gammas,
phiu size r args gammas ->
length args =
length gammas.
Proof.
induction 1 ; intros ; eauto.
simpl. eauto.
Qed.
Lemma wt_phiu_args_dst :
forall pc phib args dst k xi x i,
(
fn_phicode f) !
pc =
Some phib ->
In (
Iphi args dst)
phib ->
nth_error args k =
Some xi ->
Bij.rmap size xi = (
x,
i) ->
wt_phiu size (
make_predecessors (
fn_code f)
successors_instr) !!!
pc phib G ->
exists idx,
Bij.rmap size dst = (
x,
idx).
Proof.
Lemma wt_pdom :
forall x u d
(
USE:
use f x u)
(
DEF:
def f x d),
dom f d u.
Proof.
Lemma wt_def_use_code_false :
forall x pc
(
USE:
use_code f x pc)
(
DEF:
assigned_code_spec (
fn_code f)
pc x),
False.
Proof.
End WT_FUNCTION.