@@ -5,20 +5,26 @@ open GoblintCil
55open Analyses
66open GobConfig
77
8+ module type NameLifter =
9+ sig
10+ val lift_name : string -> string
11+ end
812
9- (* * Lifts a [Spec] so that the domain is [Hashcons]d *)
10- module HashconsLifter (S :Spec )
13+ module type LatticeLifter =
14+ functor (L : Lattice.S ) ->
15+ sig
16+ include Lattice. S
17+
18+ val lift : L .t -> t
19+ val unlift : t -> L .t
20+ end
21+
22+ module DomainLifter (N : NameLifter ) (F : LatticeLifter ) (S :Spec )
1123 : Spec with module G = S. G
1224 and module C = S. C
1325=
1426struct
15- module HConsedArg =
16- struct
17- (* We do refine int values on narrow and meet {!IntDomain.IntDomTupleImpl}, which can lead to fixpoint issues if we assume x op x = x *)
18- (* see https://github.com/goblint/analyzer/issues/1005 *)
19- let assume_idempotent = GobConfig. get_string " ana.int.refinement" = " never"
20- end
21- module D = Lattice. HConsed (S. D ) (HConsedArg )
27+ module D = F (S. D )
2228 module G = S. G
2329 module C = S. C
2430 module V = S. V
2834 let of_elt x = of_elt (D. unlift x)
2935 end
3036
31- let name () = S. name () ^ " hashconsed "
37+ let name () = N. lift_name ( S. name () )
3238
33- type marshal = S .marshal (* TODO: should hashcons table be in here to avoid relift altogether? *)
39+ type marshal = S .marshal
3440 let init = S. init
3541 let finalize = S. finalize
3642
@@ -98,104 +104,50 @@ struct
98104 D. lift @@ S. event (conv man) e (conv oman)
99105end
100106
101- (* * Lifts a [Spec] so that the context is [Hashcons]d. *)
102- module HashconsContextLifter (S :Spec )
103- : Spec with module D = S. D
104- and module G = S. G
105- and module C = Printable. HConsed (S. C )
106- =
107+ (* * Lifts a [Spec] so that the domain is [Hashcons]d *)
108+ module HashconsLifter (S : Spec ) = (* keep functor eta-expanded to look up option when lifter is actually used *)
107109struct
108- module D = S. D
109- module G = S. G
110- module C = Printable. HConsed (S. C )
111- module V = S. V
112- module P = S. P
113-
114- let name () = S. name () ^ " context hashconsed"
115-
116- type marshal = S .marshal (* TODO: should hashcons table be in here to avoid relift altogether? *)
117- let init = S. init
118- let finalize = S. finalize
119-
120- let startstate = S. startstate
121- let exitstate = S. exitstate
122- let morphstate = S. morphstate
123-
124- let conv man =
125- { man with context = (fun () -> C. unlift (man.context () )) }
126-
127- let context man fd = C. lift % S. context (conv man) fd
128- let startcontext () = C. lift @@ S. startcontext ()
129-
130- let sync man reason =
131- S. sync (conv man) reason
132-
133- let query man (type a ) (q : a Queries.t ): a Queries.result =
134- match q with
135- | Queries. IterPrevVars f ->
136- let g i (n , c , j ) e = f i (n, Obj. repr (C. lift (Obj. obj c)), j) e in
137- S. query (conv man) (Queries. IterPrevVars g)
138- | _ -> S. query (conv man) q
139-
140- let assign man lv e =
141- S. assign (conv man) lv e
142-
143- let vdecl man v =
144- S. vdecl (conv man) v
145-
146- let branch man e tv =
147- S. branch (conv man) e tv
148-
149- let body man f =
150- S. body (conv man) f
151-
152- let return man r f =
153- S. return (conv man) r f
154-
155- let asm man =
156- S. asm (conv man)
157-
158- let skip man =
159- S. skip (conv man)
160-
161- let enter man r f args =
162- S. enter (conv man) r f args
163-
164- let special man r f args =
165- S. special (conv man) r f args
110+ module NameLifter =
111+ struct
112+ let lift_name x = x ^ " hashconsed"
113+ end
166114
167- let combine_env man r fe f args fc es f_ask =
168- S. combine_env (conv man) r fe f args (Option. map C. unlift fc) es f_ask
115+ module HConsedArg =
116+ struct
117+ (* We do refine int values on narrow and meet {!IntDomain.IntDomTupleImpl}, which can lead to fixpoint issues if we assume x op x = x *)
118+ (* see https://github.com/goblint/analyzer/issues/1005 *)
119+ let assume_idempotent = GobConfig. get_string " ana.int.refinement" = " never"
120+ end
169121
170- let combine_assign man r fe f args fc es f_ask =
171- S. combine_assign (conv man) r fe f args (Option. map C. unlift fc) es f_ask
122+ include DomainLifter (NameLifter ) (Lattice. HConsed (HConsedArg )) (S )
172123
173- let threadenter man ~ multiple lval f args =
174- S. threadenter (conv man) ~multiple lval f args
124+ (* TODO: should marshal hashcons table to avoid relift altogether? *)
125+ end
175126
176- let threadspawn man ~multiple lval f args fman =
177- S. threadspawn (conv man) ~multiple lval f args (conv fman)
127+ module type PrintableLifter =
128+ functor (P : Printable.S ) ->
129+ sig
130+ include Printable. S
178131
179- let paths_as_set man = S. paths_as_set (conv man)
180- let event man e oman = S. event (conv man) e (conv oman)
181- end
132+ val lift : P .t -> t
133+ val unlift : t -> P .t
134+ end
182135
183- (* * Lifts a [Spec] so that the context is [HashCached]. *)
184- module HashCachedContextLifter (S :Spec )
136+ module ContextLifter (N : NameLifter ) (F : PrintableLifter ) (S :Spec )
185137 : Spec with module D = S. D
186138 and module G = S. G
187- and module C = Printable. HashCached (S. C )
139+ and module C = F (S. C )
188140=
189141struct
190142 module D = S. D
191143 module G = S. G
192- module C = Printable. HashCached (S. C )
144+ module C = F (S. C )
193145 module V = S. V
194146 module P = S. P
195147
196- let name () = S. name () ^ " context hashcached "
148+ let name () = N. lift_name ( S. name () )
197149
198- type marshal = S .marshal
150+ type marshal = S .marshal
199151 let init = S. init
200152 let finalize = S. finalize
201153
@@ -262,6 +214,13 @@ struct
262214 let event man e oman = S. event (conv man) e (conv oman)
263215end
264216
217+ (* * Lifts a [Spec] so that the context is [Hashcons]d. *)
218+ module HashconsContextLifter = ContextLifter (struct let lift_name s = s ^ " context hashconsed" end ) (Printable. HConsed )
219+ (* TODO: should marshal hashcons table to avoid relift altogether? *)
220+
221+ (* * Lifts a [Spec] so that the context is [HashCached]. *)
222+ module HashCachedContextLifter = ContextLifter (struct let lift_name s = s ^ " context hashcached" end ) (Printable. HashCached )
223+
265224(* see option ana.opt.equal *)
266225module OptEqual (S : Spec ) = struct
267226 module D = struct include S. D let equal x y = x == y || equal x y end
0 commit comments