Library AndersenSound
Require
Import
Arith List Omega TheoryList.
Require
Import
ListUtil Maps Tactics.
Require
Import
Machine AndersenModel Pointer.
Set Implicit
Arguments.
Inductive
followPath : var -> nat -> state -> nat -> Prop :=
| Path_Done : forall v s,
followPath v 0 s (VarMap.sel (vars s) v)
| Path_Step : forall v n s v',
followPath v n s v'
-> v' <> 0
-> followPath v (S n) s (NatMap.sel (heap s) v').
Inductive
abstract_followPath
: var -> nat -> abstract_state -> allocation_site -> Prop :=
| APath_Done : forall v s a,
AllocSet.In a (VarMap.sel (avars s) v) = true
-> abstract_followPath v 0 s a
| APath_Step : forall v n s v' a,
abstract_followPath v n s v'
-> AllocSet.In a (AllocMap.sel (aheap s) v') = true
-> abstract_followPath v (S n) s a.
Hint
Constructors followPath abstract_followPath.
Definition
pathCompatible (conc : state) (abs : abstract_state)
v1 n1 v2 n2 :=
forall r, followPath v1 n1 conc r
-> r <> 0
-> followPath v2 n2 conc r
-> exists r',
abstract_followPath v1 n1 abs r'
/\ abstract_followPath v2 n2 abs r'.
Definition
allPaths conc abs :=
forall v1 n1 v2 n2, pathCompatible conc abs v1 n1 v2 n2.
Record
compatible (conc : state) (abs : abstract_state) : Prop := {
compatInitial : NatMap.sel (heap conc) 0 = 0;
compatInBounds : forall v n v', followPath v n conc v' -> v' <= limit conc;
compatZeroed : forall a, a > limit conc -> NatMap.sel (heap conc) a = 0;
compatPaths : allPaths conc abs
}.
Hint
Constructors reachable_flowInsensitive.
Lemma
abstractAllocate' : forall v program next,
In (Allocate v) program
-> exists site, In (AbsAllocate v site) (abstractProgram' next program).
Lemma
abstractAllocate : forall v program,
In (Allocate v) program
-> exists site, In (AbsAllocate v site) (abstractProgram program).
Ltac
VarMap_split :=
match goal with
| [ |- context[VarMap.sel (VarMap.upd ?M ?A ?V) ?A'] ] =>
let Haddr := fresh "Haddr" with Heq := fresh "Heq" in
(destruct (VarMap.sel_upd M A V A') as [[Haddr Heq] | [Haddr Heq]];
rewrite Heq; simplify)
end.
Ltac
nat_split :=
match goal with
| [ |- context[match ?N with O => _ | S _ => _ end] ] => destruct N; simplify
end.
Hint
Rewrite VarMap.sel_upd_eq : Maps.
Hint
Rewrite VarMap.sel_upd_neq using (intuition; fail) : Maps.
Ltac
mySimplify := repeat progress (simplify;
autorewrite with Maps;
try match goal with
| [ H : _ |- _ ] =>
rewrite VarMap.sel_upd_eq in H
|| (rewrite VarMap.sel_upd_eq in H; [idtac | intuition; fail])
end).
Hint
Resolve AllocSet.In_add_eq.
Lemma
pathCompatible_symm : forall conc abs v1 n1 v2 n2,
pathCompatible conc abs v1 n1 v2 n2
-> pathCompatible conc abs v2 n2 v1 n1.
Hint
Resolve pathCompatible_symm.
Lemma
followPath_write_var : forall v v' conc' n r,
v <> v'
-> followPath v' n conc' r
-> forall conc pc addr lim, conc' = Build_state pc (VarMap.upd (vars conc) v addr) (heap conc) lim
-> followPath v' n conc r.
Hint
Resolve followPath_write_var.
Lemma
abstract_followPath_write_var : forall v v' n abs r,
v <> v'
-> abstract_followPath v' n abs r
-> forall site, abstract_followPath v' n
(Build_abstract_state (VarMap.upd (avars abs) v site) (aheap abs)) r.
Hint
Resolve abstract_followPath_write_var.
Lemma
compatible_write_var : forall conc abs v addr site pc lim,
let conc' := Build_state
pc
(VarMap.upd (vars conc) v addr)
(heap conc)
lim in
let abs' := Build_abstract_state
(VarMap.upd (avars abs) v site)
(aheap abs) in
allPaths conc abs
-> (forall n1 n2, pathCompatible conc' abs' v n1 v n2)
-> (forall v' n n', v <> v' -> pathCompatible conc' abs' v n v' n')
-> allPaths conc' abs'.
unfold allPaths; mySimplify.
destruct (VarMap.sel_upd (vars conc) v (limit conc) v1);
destruct (VarMap.sel_upd (vars conc) v (limit conc) v2);
mySimplify.
generalize (H v1 n1 v2 n2); unfold pathCompatible; mySimplify.
assert (followPath v1 n1 conc r); eauto.
assert (followPath v2 n2 conc r); eauto.
destruct (H3 _ H10 H8 H11) as [r' Hr'].
mySimplify.
Qed
.
Lemma
followPath_SO : forall s v n r,
NatMap.sel (heap s) (VarMap.sel (vars s) v) = 0
-> followPath v n s r
-> r = VarMap.sel (vars s) v \/ r = 0.
Hint
Resolve followPath_SO.
Lemma
followPath_SO' : forall s v n r,
NatMap.sel (heap s) (VarMap.sel (vars s) v) = 0
-> followPath v n s r
-> (n = 0 /\ r = VarMap.sel (vars s) v)
\/ (n = 1 /\ r = 0).
Lemma
followPath_S : forall s v n r,
NatMap.sel (heap s) (VarMap.sel (vars s) v) = 0
-> followPath v (S n) s r
-> r = 0.
Lemma
step_Allocate : forall v program conc abs,
In (Allocate v) program
-> compatible conc abs
-> exists ins', In ins' (abstractProgram program)
/\ compatible (exec (Allocate v) conc) (abstract_exec ins' abs).
Lemma
abstractCopy' : forall src dst program next,
In (Copy src dst) program
-> In (AbsCopy src dst) (abstractProgram' next program).
Lemma
abstractCopy : forall src dst program,
In (Copy src dst) program
-> In (AbsCopy src dst) (abstractProgram program).
Hint
Resolve abstractCopy.
Lemma
followPath_swap_var : forall v1 n conc1 r,
followPath v1 n conc1 r
-> forall conc2 v2, VarMap.sel (vars conc1) v1 = VarMap.sel (vars conc2) v2
-> heap conc2 = heap conc1
-> followPath v2 n conc2 r.
Hint
Resolve AllocSet.incl_In.
Lemma
abstract_followPath_incl : forall v1 abs1 abs2 v2 n r,
AllocSet.incl (VarMap.sel (avars abs1) v1) (VarMap.sel (avars abs2) v2) = true
-> aheap abs1 = aheap abs2
-> abstract_followPath v1 n abs1 r
-> abstract_followPath v2 n abs2 r.
Hint
Resolve AllocSet.incl_union_right AllocSet.incl_refl.
Lemma
step_Copy : forall dst src program conc abs,
In (Copy dst src) program
-> compatible conc abs
-> exists ins', In ins' (abstractProgram program)
/\ compatible (exec (Copy dst src) conc) (abstract_exec ins' abs).
Lemma
abstractRead' : forall src dst program next,
In (Read src dst) program
-> In (AbsRead src dst) (abstractProgram' next program).
Lemma
abstractRead : forall src dst program,
In (Read src dst) program
-> In (AbsRead src dst) (abstractProgram program).
Hint
Resolve abstractRead.
Lemma
followPath_read : forall v1 n conc1 r,
followPath v1 n conc1 r
-> forall conc2, heap conc1 = heap conc2
-> forall v2, VarMap.sel (vars conc2) v2 <> 0
-> VarMap.sel (vars conc1) v1
= NatMap.sel (heap conc2) (VarMap.sel (vars conc2) v2)
-> followPath v2 (S n) conc2 r.
Lemma
abstract_followPath_expand : forall v n abs r,
abstract_followPath v n abs r
-> forall abs', aheap abs = aheap abs'
-> (forall v', AllocSet.incl (VarMap.sel (avars abs) v')
(VarMap.sel (avars abs') v') = true)
-> abstract_followPath v n abs' r.
Lemma
incl_fold_union' : forall ls s s' f,
AllocSet.incl s s' = true
-> AllocSet.incl s
(fold_left
(fun known (site : allocation_site) => AllocSet.union known (f site))
ls
s') = true.
Lemma
incl_fold_union : forall ls s f,
AllocSet.incl s
(fold_left
(fun known (site : allocation_site) => AllocSet.union known (f site))
ls
s) = true.
Lemma
abstract_followPath_read : forall v1 abs1 n' r,
abstract_followPath v1 n' abs1 r
-> forall n, n' = S n
-> forall abs2, aheap abs1 = aheap abs2
-> forall v2, (forall a, AllocSet.In a (VarMap.sel (avars abs1) v1) = true
-> AllocSet.incl (AllocMap.sel (aheap abs1) a)
(VarMap.sel (avars abs2) v2) = true)
-> abstract_followPath v2 n abs2 r.
Lemma
incl_fold_union_read : forall a f ls s i,
ls = AllocSet.elems s
-> AllocSet.In a s = true
-> AllocSet.incl (f a)
(fold_left
(fun known (site : allocation_site) =>
AllocSet.union known (f site))
ls
i)
= true.
Lemma
step_Read : forall dst src program conc abs,
In (Read dst src) program
-> compatible conc abs
-> exists ins', In ins' (abstractProgram program)
/\ compatible (exec (Read dst src) conc) (abstract_exec ins' abs).
Lemma
abstractWrite' : forall src dst program next,
In (Write src dst) program
-> In (AbsWrite src dst) (abstractProgram' next program).
Lemma
abstractWrite : forall src dst program,
In (Write src dst) program
-> In (AbsWrite src dst) (abstractProgram program).
Hint
Resolve abstractWrite.
Lemma
abstract_followPath_write_preserve : forall v n abs1 r,
abstract_followPath v n abs1 r
-> forall abs2, avars abs1 = avars abs2
-> (forall addr, AllocSet.incl
(AllocMap.sel (aheap abs1) addr)
(AllocMap.sel (aheap abs2) addr) = true)
-> abstract_followPath v n abs2 r.
Ltac
AllocMap_split :=
match goal with
| [ |- context[AllocMap.sel (AllocMap.upd ?M ?A ?V) ?A'] ] =>
let Haddr := fresh "Haddr" with Heq := fresh "Heq" in
(destruct (AllocMap.sel_upd M A V A') as [[Haddr Heq] | [Haddr Heq]];
rewrite Heq; simplify)
end.
Hint
Resolve AllocSet.incl_union_left.
Lemma
incl_write_bonanza' : forall addr h s ls i,
(forall addr', AllocSet.incl (AllocMap.sel h addr') (AllocMap.sel i addr') = true)
-> AllocSet.incl (AllocMap.sel h addr)
(AllocMap.sel
(fold_left
(fun known (site : allocation_site) =>
AllocMap.upd known site (AllocSet.union (AllocMap.sel h site) s))
ls
i) addr) = true.
Lemma
incl_write_bonanza : forall addr h s ls,
AllocSet.incl (AllocMap.sel h addr)
(AllocMap.sel
(fold_left
(fun known (site : allocation_site) =>
AllocMap.upd known site (AllocSet.union (AllocMap.sel h site) s))
ls
h) addr) = true.
Ltac
NatMap_split :=
match goal with
| [ |- context[NatMap.sel (NatMap.upd ?M ?A ?V) ?A'] ] =>
let Haddr := fresh "Haddr" with Heq := fresh "Heq" in
(destruct (NatMap.sel_upd M A V A') as [[Haddr Heq] | [Haddr Heq]];
rewrite Heq; simplify)
end.
Lemma
fold_left_sum : forall ns n1 n2,
fold_left (fun x y => S (x + y)) ns (n1 + n2)
= n1 + fold_left (fun x y => S (x + y)) ns n2.
Lemma
followPath_case : forall v n conc' r conc a src,
vars conc' = vars conc
-> heap conc' = NatMap.upd (heap conc) a (VarMap.sel (vars conc) src)
-> followPath v n conc' r
-> followPath v n conc r
\/ exists n', followPath src n' conc r.
Lemma
followPath_nothing_new : forall v n conc' r conc a src,
vars conc' = vars conc
-> heap conc' = NatMap.upd (heap conc) a (VarMap.sel (vars conc) src)
-> followPath v n conc' r
-> exists v', exists n', followPath v' n' conc r.
Lemma
allPaths_step : forall conc' conc a src v n r,
vars conc' = vars conc
-> heap conc' = NatMap.upd (heap conc) a (VarMap.sel (vars conc) src)
-> followPath v n conc' r
-> followPath v n conc r
\/ exists n1, exists n2,
n = S (n1 + n2)
/\ followPath v n1 conc a
/\ followPath src n2 conc' r.
Lemma
follow_conjoin : forall v1 n1 conc v2 n2 r,
followPath v1 n1 conc (VarMap.sel (vars conc) v2)
-> followPath v2 n2 conc r
-> followPath v1 (n1 + n2) conc r.
Lemma
abstract_follow_conjoin : forall conc abs abs' v n1 a dst src n2 r',
allPaths conc abs
-> avars abs' = avars abs
-> (forall addr,
AllocSet.incl (AllocMap.sel (aheap abs) addr)
(AllocMap.sel (aheap abs') addr) = true)
-> (forall r, AllocSet.In r (VarMap.sel (avars abs) dst) = true
-> AllocSet.incl (VarMap.sel (avars abs) src) (AllocMap.sel (aheap abs') r) = true)
-> a = VarMap.sel (vars conc) dst
-> a <> 0
-> followPath v n1 conc a
-> abstract_followPath src n2 abs' r'
-> abstract_followPath v (S (n1 + n2)) abs' r'.
Lemma
allPaths_write : forall conc' conc src abs abs' dst,
vars conc' = vars conc
-> heap conc' = NatMap.upd (heap conc) (VarMap.sel (vars conc) dst) (VarMap.sel (vars conc) src)
-> VarMap.sel (vars conc) dst <> 0
-> avars abs' = avars abs
-> (forall addr,
AllocSet.incl (AllocMap.sel (aheap abs) addr)
(AllocMap.sel (aheap abs') addr) = true)
-> (forall r, AllocSet.In r (VarMap.sel (avars abs) dst) = true
-> AllocSet.incl (VarMap.sel (avars abs) src) (AllocMap.sel (aheap abs') r) = true)
-> allPaths conc abs
-> forall n v1 n1 r, r <> 0
-> followPath v1 n1 conc' r
-> forall v2 n2, followPath v2 n2 conc' r
-> n1 + n2 <= n
-> exists r',
abstract_followPath v1 n1 abs' r'
/\ abstract_followPath v2 n2 abs' r'.
Lemma
sel_bonanza' : forall addr (f : allocation_site -> AllocSet.set) ls h,
AllocMap.sel h addr = f addr
-> AllocMap.sel
(fold_left
(fun known site =>
AllocMap.upd known site (f site))
ls h)
addr = f addr.
Lemma
sel_bonanza : forall addr (f : allocation_site -> AllocSet.set) ls h,
In addr ls
-> AllocMap.sel
(fold_left
(fun known site =>
AllocMap.upd known site (f site))
ls h)
addr = f addr.
Lemma
sel_updated' : forall r (f : allocation_site -> AllocSet.set) ls h,
AllocMap.sel h r = f r
-> AllocMap.sel
(fold_left
(fun known site => AllocMap.upd known site (f site)) ls h) r = f r.
Lemma
sel_updated : forall r src f ls dst h,
ls = AllocSet.elems dst
-> AllocSet.In r dst = true
-> AllocSet.incl src
(AllocMap.sel
(fold_left
(fun known (site : allocation_site) =>
AllocMap.upd known site
(AllocSet.union (f site) src))
ls h) r) = true.
Lemma
step_Write : forall dst src program conc abs,
In (Write dst src) program
-> compatible conc abs
-> exists ins', In ins' (abstractProgram program)
/\ compatible (exec (Write dst src) conc) (abstract_exec ins' abs).
Lemma
followPath_goto : forall conc conc' v n r,
vars conc' = vars conc
-> heap conc' = heap conc
-> followPath v n conc r
-> followPath v n conc' r.
Lemma
step_Goto : forall n conc abs,
compatible conc abs
-> compatible (exec (Goto n) conc) abs.
Section
allocation_site_model_is_conservative.
Variable
program : list instruction.
Lemma
allocation_site_step :
forall conc abs, compatible conc abs
-> forall program ins, In ins program
-> compatible (exec ins conc) abs
\/ exists ins', In ins' (abstractProgram program)
/\ compatible (exec ins conc) (abstract_exec ins' abs).
Theorem
allocation_site_model_is_conservative :
forall conc conc', reachable_flowInsensitive program exec conc conc'
-> forall abs, compatible conc abs
-> exists abs', reachable_flowInsensitive (abstractProgram program)
abstract_exec abs abs'
/\ compatible conc' abs'.
Definition
abstract_initState :=
Build_abstract_state
(VarMap.init AllocSet.empty)
(AllocMap.init AllocSet.empty).
Lemma
andersen_start :
forall conc, reachable_flowInsensitive program exec initState conc
-> exists abs, reachable_flowInsensitive (abstractProgram program)
abstract_exec abstract_initState abs
/\ compatible conc abs.
Theorem
andersen_sound : forall v1 v2,
(forall abs, reachable_flowInsensitive (abstractProgram program)
abstract_exec abstract_initState abs
-> forall site, AllocSet.In site
(AllocSet.intersect (VarMap.sel (avars abs) v1) (VarMap.sel (avars abs) v2))
= false)
-> mustNotAlias program v1 v2.
End
allocation_site_model_is_conservative.
Index
This page has been generated by coqdoc