Skip to content

Commit a7ce040

Browse files
committed
Refactor MCP.query'
1 parent 4a87a71 commit a7ce040

File tree

1 file changed

+41
-39
lines changed

1 file changed

+41
-39
lines changed

src/analyses/mCP.ml

Lines changed: 41 additions & 39 deletions
Original file line numberDiff line numberDiff line change
@@ -264,46 +264,48 @@ struct
264264

265265
(* Explicitly polymorphic type required here for recursive GADT call in ask. *)
266266
and query': type a. querycache:Obj.t QueryHash.t -> QuerySet.t -> (D.t, G.t, C.t, V.t) ctx -> a Queries.t -> a Queries.result = fun ~querycache asked ctx q ->
267-
let module Result = (val Queries.Result.lattice q) in
268-
if QuerySet.mem (Any q) asked then
269-
Result.top () (* query cycle *)
270-
else if QueryHash.mem querycache (Any q) then
271-
Obj.obj (QueryHash.find querycache (Any q))
272-
else
273-
let asked' = QuerySet.add (Any q) asked in
274-
let sides = ref [] in
275-
let ctx'' = outer_ctx "query" ~sides ctx in
276-
let f ~q a (n,(module S:MCPSpec),d) =
277-
let ctx' : (S.D.t, S.G.t, S.C.t, S.V.t) ctx = inner_ctx "query" ctx'' n d in
278-
(* sideg is discouraged in query, because they would bypass sides grouping in other transfer functions.
279-
See https://github.com/goblint/analyzer/pull/214. *)
280-
let ctx' : (S.D.t, S.G.t, S.C.t, S.V.t) ctx =
281-
{ ctx' with
282-
ask = (fun (type b) (q: b Queries.t) -> query' ~querycache asked' ctx q)
283-
}
267+
let anyq = Queries.Any q in
268+
match QueryHash.find_option querycache anyq with
269+
| Some r -> Obj.obj r
270+
| None ->
271+
let module Result = (val Queries.Result.lattice q) in
272+
if QuerySet.mem anyq asked then
273+
Result.top () (* query cycle *)
274+
else
275+
let asked' = QuerySet.add anyq asked in
276+
let sides = ref [] in
277+
let ctx'' = outer_ctx "query" ~sides ctx in
278+
let f ~q a (n,(module S:MCPSpec),d) =
279+
let ctx' : (S.D.t, S.G.t, S.C.t, S.V.t) ctx = inner_ctx "query" ctx'' n d in
280+
(* sideg is discouraged in query, because they would bypass sides grouping in other transfer functions.
281+
See https://github.com/goblint/analyzer/pull/214. *)
282+
let ctx' : (S.D.t, S.G.t, S.C.t, S.V.t) ctx =
283+
{ ctx' with
284+
ask = (fun (type b) (q: b Queries.t) -> query' ~querycache asked' ctx q)
285+
}
286+
in
287+
(* meet results so that precision from all analyses is combined *)
288+
Result.meet a @@ S.query ctx' q
284289
in
285-
(* meet results so that precision from all analyses is combined *)
286-
Result.meet a @@ S.query ctx' q
287-
in
288-
match q with
289-
| Queries.PrintFullState ->
290-
ignore (Pretty.printf "Current State:\n%a\n\n" D.pretty ctx.local);
291-
()
292-
| Queries.WarnGlobal g ->
293-
(* WarnGlobal is special: it only goes to corresponding analysis and the argument variant is unlifted for it *)
294-
let (n, g): V.t = Obj.obj g in
295-
f ~q:(WarnGlobal (Obj.repr g)) (Result.top ()) (n, spec n, assoc n ctx.local)
296-
| Queries.PartAccess {exp; var_opt; write} ->
297-
Obj.repr (access ctx exp var_opt write)
298-
(* | EvalInt e ->
299-
(* TODO: only query others that actually respond to EvalInt *)
300-
(* 2x speed difference on SV-COMP nla-digbench-scaling/ps6-ll_valuebound5.c *)
301-
f (Result.top ()) (!base_id, spec !base_id, assoc !base_id ctx.local) *)
302-
| _ ->
303-
let r = fold_left (f ~q) (Result.top ()) @@ spec_list ctx.local in
304-
do_sideg ctx !sides;
305-
QueryHash.replace querycache (Any q) (Obj.repr r);
306-
r
290+
match q with
291+
| Queries.PrintFullState ->
292+
ignore (Pretty.printf "Current State:\n%a\n\n" D.pretty ctx.local);
293+
()
294+
| Queries.WarnGlobal g ->
295+
(* WarnGlobal is special: it only goes to corresponding analysis and the argument variant is unlifted for it *)
296+
let (n, g): V.t = Obj.obj g in
297+
f ~q:(WarnGlobal (Obj.repr g)) (Result.top ()) (n, spec n, assoc n ctx.local)
298+
| Queries.PartAccess {exp; var_opt; write} ->
299+
Obj.repr (access ctx exp var_opt write)
300+
(* | EvalInt e ->
301+
(* TODO: only query others that actually respond to EvalInt *)
302+
(* 2x speed difference on SV-COMP nla-digbench-scaling/ps6-ll_valuebound5.c *)
303+
f (Result.top ()) (!base_id, spec !base_id, assoc !base_id ctx.local) *)
304+
| _ ->
305+
let r = fold_left (f ~q) (Result.top ()) @@ spec_list ctx.local in
306+
do_sideg ctx !sides;
307+
QueryHash.replace querycache anyq (Obj.repr r);
308+
r
307309

308310
and query: type a. (D.t, G.t, C.t, V.t) ctx -> a Queries.t -> a Queries.result = fun ctx q ->
309311
let querycache = QueryHash.create 13 in

0 commit comments

Comments
 (0)