11open Goblint_constraint.ConstrSys
22
33
4- let gas_default = ref (10 ,3 )
4+ let gas_default = (10 ,3 )
5+ (* TODO make these config options *)
6+ let do_local_gc = false
7+ let do_global_gc = false
58
69(* * Manage warrowing
710
@@ -13,8 +16,6 @@ module Warrow (L : Lattice.S) = struct
1316 Narrowing flag denotes if the last update lead
1417 to a narrowing. This is required to maintain delay/gas values.
1518 *)
16- type state = L .t * int * int * bool
17-
1819 type contribution = {
1920 value : L .t ;
2021 delay : int ;
@@ -23,10 +24,10 @@ module Warrow (L : Lattice.S) = struct
2324 }
2425
2526 let default () =
26- let (delay,gas) = ! gas_default in { value = L. bot () ; delay; gas; last_was_narrow= false }
27+ let (delay,gas) = gas_default in { value = L. bot () ; delay; gas; last_was_narrow= false }
2728
2829 let warrowc contribution new_value =
29- let (delay0, _) = ! gas_default in
30+ let (delay0, _) = gas_default in
3031
3132 let narrow () =
3233 if contribution.last_was_narrow then
@@ -67,7 +68,7 @@ module Warrow (L : Lattice.S) = struct
6768 (* Legacy warrow with tuples instead of contribution types *)
6869 (* remove once all solvers are migrated *)
6970 let warrow (current , delay , gas , narrow_flag ) newval =
70- let (delay0, _) = ! gas_default in
71+ let (delay0, _) = gas_default in
7172 if L. equal current newval then (current, delay, gas, narrow_flag)
7273
7374 else if L. leq newval current then (
@@ -83,12 +84,16 @@ module Warrow (L : Lattice.S) = struct
8384 )
8485end
8586
86- module SolverLocals (Sys : FwdGlobConstrSys ) (LM : Hashtbl.S with type key=Sys.LVar.t ) = struct
87+ module SolverLocals (Sys : FwdGlobConstrSys )
88+ (LM : Hashtbl.S with type key=Sys.LVar.t )
89+ (GS : Set.S with type elt=Sys.GVar.t )
90+ = struct
8791
8892 module System = Sys
8993 module D = Sys. D
9094 module LWarrow = Warrow (D )
9195 module LM = LM
96+ module GS = GS
9297
9398 type lt = System.LVar .t
9499
@@ -99,15 +104,18 @@ module SolverLocals (Sys: FwdGlobConstrSys) (LM: Hashtbl.S with type key=Sys.LVa
99104 loc_init : D .t ;
100105 mutable called : bool ;
101106 mutable aborted : bool ;
102- loc_from : contribution LM .t }
107+ loc_from : contribution LM .t ;
108+ (* * Globals that take contributions from this local, needed for GC *)
109+ mutable contribs : GS .t ;
110+ }
103111
104112 let loc: t LM. t = LM. create 100
105113
106114 let get x =
107115 let add_default () =
108116 let default = {loc_value = D. bot () ; loc_init = D. bot () ;
109117 called = false ; aborted = false ;
110- loc_from = LM. create 10 } in
118+ loc_from = LM. create 10 ; contribs = GS. empty } in
111119 LM. add loc x default;
112120 default in
113121 BatOption. default_delayed add_default (LM. find_opt loc x)
@@ -118,7 +126,8 @@ module SolverLocals (Sys: FwdGlobConstrSys) (LM: Hashtbl.S with type key=Sys.LVa
118126 loc_init = d;
119127 called = false ;
120128 aborted = false ;
121- loc_from = LM. create 10
129+ loc_from = LM. create 10 ;
130+ contribs = GS. empty;
122131 }
123132
124133 let construct_value data =
@@ -209,7 +218,7 @@ module SolverGlobals (Sys: FwdGlobConstrSys) (LS: Set.S with type elt = Sys.LVar
209218 }
210219
211220 let default_contribution () =
212- let (delay,gas) = ! gas_default in
221+ let (delay,gas) = gas_default in
213222 { value = G. bot () ; delay; gas; last_was_narrow= false ; set= LS. empty}
214223
215224 (* * Values for globals
293302module type SolverLocalsSig = sig
294303 module System : FwdGlobConstrSys
295304 module LM : Hashtbl .S with type key = System.LVar. t
305+ module GS : Set .S with type elt = System.GVar. t
296306
297307 type contribution
298308
@@ -301,7 +311,9 @@ module type SolverLocalsSig = sig
301311 loc_init : System .D .t;
302312 mutable called : bool ;
303313 mutable aborted : bool ;
304- loc_from : contribution LM .t }
314+ loc_from : contribution LM .t ;
315+ mutable contribs : GS .t ;
316+ }
305317
306318 val get : System.LVar .t -> t
307319end
@@ -358,7 +370,7 @@ module Checker (System: FwdGlobConstrSys)
358370 let get_local x = try (Lcl. get x).loc_value with _ -> D. bot () in
359371
360372 let check_local x d = if D. leq d (D. bot () ) then ()
361- else let {loc_value :D .t ; loc_init;called;aborted;loc_from}: Lcl. t = Lcl. get x in
373+ else let {loc_value :D .t ; loc_init;called;aborted;loc_from; contribs }: Lcl. t = Lcl. get x in
362374 if D. leq d loc_value then
363375 if LM. mem sigma_out x then ()
364376 else (
@@ -458,21 +470,25 @@ module BaseFwdSolver (System: FwdGlobConstrSys) = struct
458470 module G = System. G
459471
460472 module LS = Set. Make (System. LVar )
473+ module GS = Set. Make (System. GVar )
461474 module GM = Hashtbl. Make (System. GVar )
462475 module LM = Hashtbl. Make (System. LVar )
463476
464477
465478 module Gbl = SolverGlobals (System )(LS )(LM )(GM )
466- module Lcl = SolverLocals (System )(LM )
479+ module Lcl = SolverLocals (System )(LM )( GS )
467480
468481 (* *
469482 wrapper around propagation function to collect multiple contributions to same unknowns;
470483 contributions are delayed until the very end
471484 *)
472- let wrap get_local get_global set_local set_global rhs x d =
485+ let wrap get_local get_global set_local set_global rhs x =
473486 let local_updates = LM. create 10 in
474487 let global_updates = GM. create 10 in
475488
489+ let x_record = Lcl. get x in
490+ let d = x_record.loc_value in
491+
476492 let collect_local y d =
477493 let d = LM. find_opt local_updates y |> BatOption. map_default (D. join d) d in
478494 LM. replace local_updates y d in
@@ -483,8 +499,18 @@ module BaseFwdSolver (System: FwdGlobConstrSys) = struct
483499
484500 (* Use the collect functions for set, so that we can delay and re-order the
485501 contributions *)
486- rhs d get_local collect_local (get_global x) collect_global;
487- GM. iter (set_global x) global_updates;
502+ if do_global_gc then (
503+ let old_contribs = x_record.contribs in
504+ rhs d get_local collect_local (get_global x) collect_global;
505+ let new_contribs = GM. fold (fun g _ s -> GS. add g s) global_updates GS. empty in
506+ x_record.contribs < - new_contribs;
507+ GM. iter (set_global x) global_updates;
508+ let removed_contribs = GS. filter (fun g -> not @@ GS. mem g new_contribs) old_contribs in
509+ GS. iter (fun g -> set_global x g (G. bot () )) removed_contribs
510+ ) else (
511+ rhs d get_local collect_local (get_global x) collect_global;
512+ GM. iter (set_global x) global_updates
513+ );
488514 LM. iter (set_local x) local_updates;
489515 (* possibly better with reversed ordering *)
490516end
0 commit comments