Skip to content
Snippets Groups Projects
Commit bea4906b authored by Jan Rochel's avatar Jan Rochel
Browse files

[e-acsl] Logic_normalizer: rework memoization

Render the memoization tables for predicates and terms bidirectional.
This will help improve user feedback messages in the subsequent commits.
We do not want to confront to the user with feedback messages that
contain transformed code, so we need bidirectional memoization tables in
order to determine the original code that we then can show to the user.
parent 2fdff794
No related branches found
No related tags found
No related merge requests found
...@@ -39,46 +39,50 @@ module Id_predicate = ...@@ -39,46 +39,50 @@ module Id_predicate =
let mem_project = Datatype.never_any_project let mem_project = Datatype.never_any_project
end) end)
(* Memoization module which retrieves the preprocessed form of predicates *) module BiMap (H : Hashtbl.S) = struct
module Memo: sig let from_tbl = H.create 7
val memo_pred: (predicate -> predicate option) -> predicate -> unit let dest_tbl = H.create 7
val get_pred: predicate -> predicate
val memo_term : (term -> term option) -> term -> unit
val get_term : term -> term
val clear: unit -> unit
end = struct
let tbl_term = Misc.Id_term.Hashtbl.create 97
let tbl_pred = Id_predicate.Hashtbl.create 97
let get_pred p =
try Id_predicate.Hashtbl.find tbl_pred p
with Not_found -> p
let memo_pred process p =
try ignore (Id_predicate.Hashtbl.find tbl_pred p) with
| Not_found ->
match process p with
| Some pot -> Id_predicate.Hashtbl.add tbl_pred p pot
| None -> ()
let get_term t = let clear () =
try Misc.Id_term.Hashtbl.find tbl_term t H.clear from_tbl;
with Not_found -> t H.clear dest_tbl
let memo_term process t = let add from dest =
try ignore (Misc.Id_term.Hashtbl.find tbl_term t) with H.add from_tbl from dest;
| Not_found -> H.add dest_tbl dest from
match process t with
| Some term -> Misc.Id_term.Hashtbl.add tbl_term t term
| None -> ()
let clear () = let dest from = H.find from_tbl from
Misc.Id_term.Hashtbl.clear tbl_term; let dest_opt from = H.find_opt from_tbl from
Id_predicate.Hashtbl.clear tbl_pred let from dest = H.find dest_tbl dest
let from_opt dest = H.find_opt dest_tbl dest
let dest_or_self from = try dest from with Not_found -> from
let from_or_self dest = try from dest with Not_found -> dest
end
(* Memoization modules for retrieving the preprocessed and original form of
predicates and terms *)
module Memo (H : Hashtbl.S) = struct
module M = BiMap (H)
let clear = M.clear
let normalized x = M.dest_or_self x
let normalized_opt x = M.dest_opt x
let original x = M.from_or_self x
let original_opt x = M.from_opt x
let memoize process x =
try Some (M.dest x) with
| Not_found ->
match process x with
| Some y -> M.add x y; Some y
| None -> None
end end
module Predicates = Memo (Id_predicate.Hashtbl)
module Terms = Memo (Misc.Id_term.Hashtbl)
let preprocess_pred ~loc p = let preprocess_pred ~loc p =
match p.pred_content with match p.pred_content with
| Pvalid_read(BuiltinLabel Here as llabel, t) | Pvalid_read(BuiltinLabel Here as llabel, t)
...@@ -134,12 +138,12 @@ let preprocessor = object ...@@ -134,12 +138,12 @@ let preprocessor = object
method !vpredicate p = method !vpredicate p =
let loc = p.pred_loc in let loc = p.pred_loc in
Memo.memo_pred (preprocess_pred ~loc) p; ignore @@ Predicates.memoize (preprocess_pred ~loc) p;
Cil.DoChildren Cil.DoChildren
method !vterm t = method !vterm t =
let loc = t.term_loc in let loc = t.term_loc in
Memo.memo_term (preprocess_term ~loc) t; ignore @@ Terms.memoize (preprocess_term ~loc) t;
Cil.DoChildren Cil.DoChildren
end end
...@@ -152,6 +156,11 @@ let preprocess_annot annot = ...@@ -152,6 +156,11 @@ let preprocess_annot annot =
let preprocess_predicate p = let preprocess_predicate p =
ignore @@ preprocessor#visit_predicate p ignore @@ preprocessor#visit_predicate p
let get_pred = Memo.get_pred let get_pred = Predicates.normalized
let get_term = Memo.get_term let get_orig_pred = Predicates.original
let clear = Memo.clear let get_term = Terms.normalized
let get_orig_term = Terms.original
let clear () =
Terms.clear ();
Predicates.clear ()
...@@ -44,8 +44,14 @@ val preprocess_predicate : predicate -> unit ...@@ -44,8 +44,14 @@ val preprocess_predicate : predicate -> unit
val get_pred : predicate -> predicate val get_pred : predicate -> predicate
(** Retrieve the preprocessed form of a predicate *) (** Retrieve the preprocessed form of a predicate *)
val get_orig_pred : predicate -> predicate
(** Retrieve the original form of the given predicate *)
val get_term : term -> term val get_term : term -> term
(** Retrieve the preprocessed form of a term *) (** Retrieve the preprocessed form of a term *)
val get_orig_term : term -> term
(** Retrieve the original form of the given term *)
val clear: unit -> unit val clear: unit -> unit
(** clear the table of normalized predicates *) (** clear the table of normalized predicates *)
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment