using address equality optimization in all abstract domains

Reviewed By: dkgi

Differential Revision: D3164574

fb-gh-sync-id: 1fab1d2
fbshipit-source-id: 1fab1d2
master
Sam Blackshear 9 years ago committed by Facebook Github Bot 6
parent 378ab69558
commit e468d3d189

@ -30,22 +30,32 @@ module BottomLifted (Domain : S) = struct
let initial = NonBottom Domain.initial let initial = NonBottom Domain.initial
let (<=) ~lhs ~rhs = match lhs, rhs with let (<=) ~lhs ~rhs =
| Bottom, _ -> true if lhs == rhs
| _ , Bottom -> false then true
| NonBottom lhs, NonBottom rhs -> Domain.(<=) ~lhs ~rhs else
match lhs, rhs with
| Bottom, _ -> true
| _ , Bottom -> false
| NonBottom lhs, NonBottom rhs -> Domain.(<=) ~lhs ~rhs
let join astate1 astate2 = let join astate1 astate2 =
match astate1, astate2 with if astate1 == astate2
| Bottom, _ -> astate2 then astate1
| _, Bottom -> astate1 else
| NonBottom a1, NonBottom a2 -> NonBottom (Domain.join a1 a2) match astate1, astate2 with
| Bottom, _ -> astate2
| _, Bottom -> astate1
| NonBottom a1, NonBottom a2 -> NonBottom (Domain.join a1 a2)
let widen ~prev ~next ~num_iters = let widen ~prev ~next ~num_iters =
match prev, next with if prev == next
| Bottom, _ -> next then prev
| _, Bottom -> prev else
| NonBottom prev, NonBottom next -> NonBottom (Domain.widen ~prev ~next ~num_iters) match prev, next with
| Bottom, _ -> next
| _, Bottom -> prev
| NonBottom prev, NonBottom next -> NonBottom (Domain.widen ~prev ~next ~num_iters)
let pp fmt = function let pp fmt = function
| Bottom -> F.fprintf fmt "_|_" | Bottom -> F.fprintf fmt "_|_"
@ -80,9 +90,12 @@ module Pair (Domain1 : S) (Domain2 : S) = struct
| _, true -> astate1 | _, true -> astate1
| _ -> Domain1.join (fst astate1) (fst astate2), Domain2.join (snd astate1) (snd astate2) | _ -> Domain1.join (fst astate1) (fst astate2), Domain2.join (snd astate1) (snd astate2)
let widen ~prev:(astate1_next, astate2_next) ~next:(astate1_prev, astate2_prev) ~num_iters = let widen ~prev ~next ~num_iters =
Domain1.widen ~prev:astate1_next ~next:astate1_prev ~num_iters, if prev == next
Domain2.widen ~prev:astate2_next ~next:astate2_prev ~num_iters then prev
else
Domain1.widen ~prev:(fst prev) ~next:(fst next) ~num_iters,
Domain2.widen ~prev:(snd prev) ~next:(snd next) ~num_iters
let pp fmt (astate1, astate2) = let pp fmt (astate1, astate2) =
F.fprintf fmt "(%a, %a)" Domain1.pp astate1 Domain2.pp astate2 F.fprintf fmt "(%a, %a)" Domain1.pp astate1 Domain2.pp astate2
@ -95,8 +108,19 @@ module FiniteSet (S : PrettyPrintable.PPSet) = struct
type astate = t type astate = t
let initial = empty let initial = empty
let is_bottom _ = false let is_bottom _ = false
let (<=) ~lhs ~rhs = subset lhs rhs
let join = union let (<=) ~lhs ~rhs =
let widen ~prev ~next ~num_iters:_ = union prev next if lhs == rhs
then true
else subset lhs rhs
let join astate1 astate2 =
if astate1 == astate2
then astate1
else union astate1 astate2
let widen ~prev ~next ~num_iters:_ =
join prev next
end end

@ -20,18 +20,24 @@ module Domain = struct
(* return true if the key-value bindings in [rhs] are a subset of the key-value bindings in (* return true if the key-value bindings in [rhs] are a subset of the key-value bindings in
[lhs] *) [lhs] *)
let (<=) ~lhs ~rhs = let (<=) ~lhs ~rhs =
Var.Map.for_all if lhs == rhs
(fun k v -> then true
try Var.var_equal v (Var.Map.find k lhs) else
with Not_found -> false) Var.Map.for_all
rhs (fun k v ->
try Var.var_equal v (Var.Map.find k lhs)
with Not_found -> false)
rhs
let join astate1 astate2 = let join astate1 astate2 =
let keep_if_same _ v1_opt v2_opt = match v1_opt, v2_opt with if astate1 == astate2
| Some v1, Some v2 -> then astate1
if Var.var_equal v1 v2 then Some v1 else None else
| _ -> None in let keep_if_same _ v1_opt v2_opt = match v1_opt, v2_opt with
Var.Map.merge keep_if_same astate1 astate2 | Some v1, Some v2 ->
if Var.var_equal v1 v2 then Some v1 else None
| _ -> None in
Var.Map.merge keep_if_same astate1 astate2
let widen ~prev ~next ~num_iters:_= let widen ~prev ~next ~num_iters:_=
join prev next join prev next

Loading…
Cancel
Save