You can not select more than 25 topics
Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
74 lines
2.0 KiB
74 lines
2.0 KiB
(*
|
|
* Copyright (c) 2016 - present Facebook, Inc.
|
|
* All rights reserved.
|
|
*
|
|
* This source code is licensed under the BSD style license found in the
|
|
* LICENSE file in the root directory of this source tree. An additional grant
|
|
* of patent rights can be found in the PATENTS file in the same directory.
|
|
*)
|
|
|
|
open! IStd
|
|
module F = Format
|
|
|
|
module Set = struct
|
|
module APSet = PrettyPrintable.MakePPSet (AccessPath.Abs)
|
|
|
|
(** TODO (12086310): best-case behavior of some operations can be improved by adding "abstracted"
|
|
bool recording whether an abstracted access path has been introduced *)
|
|
type astate = APSet.t
|
|
|
|
let pp = APSet.pp
|
|
|
|
let empty = APSet.empty
|
|
|
|
let is_empty = APSet.is_empty
|
|
|
|
let normalize aps =
|
|
APSet.filter
|
|
(fun lhs ->
|
|
not
|
|
(APSet.exists
|
|
(fun rhs -> not (phys_equal lhs rhs) && AccessPath.Abs.( <= ) ~lhs ~rhs)
|
|
aps) )
|
|
aps
|
|
|
|
|
|
let add = APSet.add
|
|
|
|
let of_list = APSet.of_list
|
|
|
|
let mem ap aps =
|
|
APSet.mem ap aps
|
|
|| APSet.exists (fun other_ap -> AccessPath.Abs.( <= ) ~lhs:ap ~rhs:other_ap) aps
|
|
|
|
|
|
let mem_fuzzy ap aps =
|
|
let has_overlap ap1 ap2 =
|
|
AccessPath.Abs.( <= ) ~lhs:ap1 ~rhs:ap2 || AccessPath.Abs.( <= ) ~lhs:ap2 ~rhs:ap1
|
|
in
|
|
APSet.mem ap aps || APSet.exists (has_overlap ap) aps
|
|
|
|
|
|
let ( <= ) ~lhs ~rhs =
|
|
if phys_equal lhs rhs then true
|
|
else
|
|
let rhs_contains lhs_ap = mem lhs_ap rhs in
|
|
APSet.subset lhs rhs || APSet.for_all rhs_contains lhs
|
|
|
|
|
|
let join aps1 aps2 = if phys_equal aps1 aps2 then aps1 else APSet.union aps1 aps2
|
|
|
|
let widen ~prev ~next ~num_iters:_ =
|
|
if phys_equal prev next then prev
|
|
else
|
|
let abstract_access_path ap aps =
|
|
match ap with
|
|
| AccessPath.Abs.Exact exact_ap ->
|
|
APSet.add (AccessPath.Abs.Abstracted exact_ap) aps
|
|
| AccessPath.Abs.Abstracted _ ->
|
|
APSet.add ap aps
|
|
in
|
|
let diff_aps = APSet.diff next prev in
|
|
APSet.fold abstract_access_path diff_aps APSet.empty |> join prev
|
|
end
|