From 59c7ec9ae11312b4abb27bf24c9b46d31948b733 Mon Sep 17 00:00:00 2001
From: Virgile Prevosto <virgile.prevosto@m4x.org>
Date: Mon, 10 Jan 2022 15:27:38 +0100
Subject: [PATCH] [kernel] diff-ast: do not propagate rec env when not needed

---
 src/kernel_services/ast_queries/ast_diff.ml | 198 +++++++++-----------
 1 file changed, 90 insertions(+), 108 deletions(-)

diff --git a/src/kernel_services/ast_queries/ast_diff.ml b/src/kernel_services/ast_queries/ast_diff.ml
index fd7fad581de..75c9ca2fa4b 100644
--- a/src/kernel_services/ast_queries/ast_diff.ml
+++ b/src/kernel_services/ast_queries/ast_diff.ml
@@ -182,7 +182,6 @@ module Info(I: sig val name: string end) =
    types, and function (both C and ACSL). Other symbols must be
    correctly ordered in a well-formed AST
 *)
-[@@@ ocaml.warning "-69"] (* WIP: currently not all fields are used *)
 type is_same_env =
   {
     compinfo: compinfo Cil_datatype.Compinfo.Map.t;
@@ -191,16 +190,9 @@ type is_same_env =
     logic_type_info: logic_type_info Cil_datatype.Logic_type_info.Map.t;
   }
 
-module Build(H:Datatype.S_with_collections)(D:Datatype.S) = struct
-  include
-    State_builder.Hashtbl(H.Hashtbl)(D)
-      (Info(struct let name = "Ast_diff." ^ D.name end))
-
-  let memo_env mk_val key env =
-    if mem key then find key, env
-    else let (data, _) as res = mk_val key env in
-      add key data; res
-end
+module Build(H:Datatype.S_with_collections)(D:Datatype.S) =
+  State_builder.Hashtbl(H.Hashtbl)(D)
+    (Info(struct let name = "Ast_diff." ^ D.name end))
 
 module Build_correspondance(H:Datatype.S_with_collections) =
   Build(H)(Correspondance.Make(H))
@@ -287,98 +279,91 @@ let find_candidate_logic_type ?loc:_loc ti =
     Some (Logic_env.find_logic_type ti.lt_name)
   with Not_found -> None
 
-let (&&>) (res,env) f = if res then f env else false, env
-let (&&|) env f = f env
-let (&&&) (res,env) b = res && b, env
-
 let is_same_opt f o o' env =
   match o, o' with
-  | None, None -> true, env
+  | None, None -> true
   | Some v, Some v' -> f v v' env
-  | _ -> false, env
+  | _ -> false
 
 let rec is_same_list f l l' env =
   match l, l' with
-  | [], [] -> true, env
+  | [], [] -> true
   | h::t, h'::t' ->
-    env &&| f h h' &&> is_same_list f t t'
-  | _ -> false, env
+    f h h' env && is_same_list f t t' env
+  | _ -> false
 
 let rec is_same_type t t' env =
   match t, t' with
   | (TVoid _ | TInt _ | TFloat _ | TBuiltin_va_list _), _ ->
-    Cil_datatype.TypByName.equal t t', env
+    Cil_datatype.TypByName.equal t t'
   | TPtr(t,a), TPtr(t',a') ->
-    env &&| is_same_type t t' &&& Cil_datatype.Attributes.equal a a'
+    is_same_type t t' env && Cil_datatype.Attributes.equal a a'
   | TArray(t,s,a), TArray(t',s',a') ->
-    env &&|
-    is_same_type t t' &&>
-    is_same_opt is_same_exp s s' &&&
+    is_same_type t t' env &&
+    is_same_opt is_same_exp s s' env &&
     Cil_datatype.Attributes.equal a a'
   | TFun(rt,l,var,a), TFun(rt', l', var', a') ->
-    env &&|
-    is_same_type rt rt' &&>
-    is_same_opt (is_same_list is_same_formal) l l' &&&
-    (var = var') &&&
+    is_same_type rt rt' env &&
+    is_same_opt (is_same_list is_same_formal) l l' env &&
+    (var = var') &&
     Cil_datatype.Attributes.equal a a'
   | TNamed(t,a), TNamed(t',a') ->
-    let correspondance, env = typeinfo_correspondance t env in
+    let correspondance = typeinfo_correspondance t env in
     (match correspondance with
-     | `Not_present -> false, env
-     | `Same t'' -> Cil_datatype.Typeinfo.equal t' t'',env) &&&
+     | `Not_present -> false
+     | `Same t'' -> Cil_datatype.Typeinfo.equal t' t'') &&
     Cil_datatype.Attributes.equal a a'
   | TComp(c,a), TComp(c', a') ->
-    let correspondance, env = compinfo_correspondance c env in
+    let correspondance = compinfo_correspondance c env in
     (match correspondance with
-     | `Not_present -> false, env
-     | `Same c'' -> Cil_datatype.Compinfo.equal c' c'', env) &&&
+     | `Not_present -> false
+     | `Same c'' -> Cil_datatype.Compinfo.equal c' c'') &&
     Cil_datatype.Attributes.equal a a'
   | TEnum(e,a), TEnum(e',a') ->
-    let correspondance, env = enuminfo_correspondance e env in
+    let correspondance = enuminfo_correspondance e env in
     (match correspondance with
-     | `Not_present -> false, env
-     | `Same e'' -> Cil_datatype.Enuminfo.equal e' e'', env) &&&
+     | `Not_present -> false
+     | `Same e'' -> Cil_datatype.Enuminfo.equal e' e'') &&
     Cil_datatype.Attributes.equal a a'
-  | (TPtr _ | TArray _ | TFun _ | TNamed _ | TComp _ | TEnum _), _ -> false, env
+  | (TPtr _ | TArray _ | TFun _ | TNamed _ | TComp _ | TEnum _), _ -> false
 
-and is_same_compinfo _ci _ci' env = false, env
+and is_same_compinfo _ci _ci' _env = false
 
-and is_same_enuminfo _ei _ei' env = false, env
+and is_same_enuminfo _ei _ei' _env = false
 
 and is_same_formal (_,t,a) (_,t',a') env =
-  is_same_type t t' env &&& Cil_datatype.Attributes.equal a a'
+  is_same_type t t' env && Cil_datatype.Attributes.equal a a'
 
 and is_same_compound_init (o,i) (o',i') env =
-  is_same_offset o o' env &&> is_same_init i i'
+  is_same_offset o o' env && is_same_init i i' env
 
 and is_same_init i i' env =
   match i, i' with
   | SingleInit e, SingleInit e' -> is_same_exp e e' env
   | CompoundInit (t,l), CompoundInit (t', l') ->
-    is_same_type t t' env &&>
-    (is_same_list is_same_compound_init) l l'
-  | (SingleInit _ | CompoundInit _), _ -> false, env
+    is_same_type t t' env &&
+    (is_same_list is_same_compound_init) l l' env
+  | (SingleInit _ | CompoundInit _), _ -> false
 
-and is_same_initinfo i i' = is_same_opt is_same_init i.init i'.init
+and is_same_initinfo i i' env = is_same_opt is_same_init i.init i'.init env
 
-and is_same_exp _e _e' env = false, env
+and is_same_exp _e _e' _env = false
 
-and is_same_offset _o _o' env = false, env
+and is_same_offset _o _o' _env = false
 
-and is_same_funspec _s _s' env = false, env
+and is_same_funspec _s _s' _env = false
 
-and is_same_fundec _f _f' env: body_correspondance*is_same_env =
-  `Body_changed, env
+and is_same_fundec _f _f' _env: body_correspondance = `Body_changed
 
-and is_same_logic_type _t _t' env = false, env
+and is_same_logic_type _t _t' _env = false
 
-and is_same_logic_param _lv _lv' env = false, env
+and is_same_logic_param _lv _lv' _env = false
 
-and is_same_logic_info _li _li' env = false, env
+and is_same_logic_info _li _li' _env = false
 
-and is_same_logic_type_info _ti _ti' env = false, env
+and is_same_logic_type_info _ti _ti' _env = false
 
-and is_same_model_info _mi _mi' env = false, env
+and is_same_model_info _mi _mi' _env = false
 
 (* because of overloading, we have to check for a corresponding profile,
    leading to potentially recursive calls to is_same_* functions. *)
@@ -390,20 +375,18 @@ and find_candidate_logic_info ?loc:_loc li env =
   let rec extract l =
     match l with
     | [] -> None
-    | li' :: tl ->
-      let (res,_) = find_one li' in
-      if res then Some li' else extract tl
+    | li' :: tl -> if find_one li' then Some li' else extract tl
   in
   match extract candidates with
   | None -> None
   | Some li' ->
-    let (res,_) = is_same_opt is_same_logic_type li.l_type li'.l_type env in
+    let res = is_same_opt is_same_logic_type li.l_type li'.l_type env in
     if res then Some li' else None
 
 and find_candidate_model_info ?loc:_loc mi env =
   let candidates = Logic_env.find_all_model_fields mi.mi_name in
   let find_one mi' =
-    fst (is_same_type mi.mi_base_type mi'.mi_base_type env)
+    is_same_type mi.mi_base_type mi'.mi_base_type env
   in
   let rec aux = function
     | [] -> None
@@ -412,39 +395,38 @@ and find_candidate_model_info ?loc:_loc mi env =
   aux candidates
 
 and typeinfo_correspondance ?loc ti env =
-  let add ti env =
+  let add ti =
     match find_candidate_type ?loc ti with
-    | None -> `Not_present, env
+    | None -> `Not_present
     | Some ti' ->
-      let res, env = is_same_type ti.ttype ti'.ttype env in
-      (if res then `Same ti' else `Not_present), env
+      let res = is_same_type ti.ttype ti'.ttype env in
+      if res then `Same ti' else `Not_present
   in
-  Typeinfo.memo_env add ti env
+  Typeinfo.memo add ti
 
 and compinfo_correspondance ?loc ci env =
-  let add ci env =
+  let add ci =
     match find_candidate_compinfo ?loc ci with
-    | None -> `Not_present, env
+    | None -> `Not_present
     | Some ci' ->
-      let env =
+      let env' =
         {env with compinfo = Cil_datatype.Compinfo.Map.add ci ci' env.compinfo}
       in
-      let res, env = is_same_compinfo ci ci' env in
-      (if res then `Same ci' else `Not_present), env
+      let res = is_same_compinfo ci ci' env' in
+      if res then `Same ci' else `Not_present
   in
   match Cil_datatype.Compinfo.Map.find_opt ci env.compinfo with
-  | Some ci' -> `Same ci', env
-  | None -> Compinfo.memo_env add ci env
+  | Some ci' -> `Same ci'
+  | None -> Compinfo.memo add ci
 
 and enuminfo_correspondance ?loc ei env =
-  let add ei env =
+  let add ei =
     match find_candidate_enuminfo ?loc ei with
-    | None -> `Not_present, env
+    | None -> `Not_present
     | Some ei' ->
-      let res, env = is_same_enuminfo ei ei' env in
-      (if res then `Same ei' else `Not_present),env
+      if is_same_enuminfo ei ei' env then `Same ei' else `Not_present
   in
-  Enuminfo.memo_env add ei env
+  Enuminfo.memo add ei
 
 and gfun_correspondance ?loc vi env =
   let selection =
@@ -458,64 +440,64 @@ and gfun_correspondance ?loc vi env =
   let kf =
     Project.on ~selection (Orig_project.get()) Globals.Functions.get vi
   in
-  let add kf env =
+  let add kf =
     match find_candidate_func ?loc kf with
-    | None -> `Not_present, env
+    | None -> `Not_present
     | Some kf' ->
-      let env =
+      let env' =
         { env with kernel_function = Kf.Map.add kf kf' env.kernel_function }
       in
-      let same_spec, env = is_same_funspec kf.spec kf'.spec env in
-      let same_body, env =
+      let same_spec = is_same_funspec kf.spec kf'.spec env' in
+      let same_body =
         match (Kf.has_definition kf, Kf.has_definition kf') with
-        | false, false -> `Same_body, env
-        | false, true | true, false -> `Body_changed, env
+        | false, false -> `Same_body
+        | false, true | true, false -> `Body_changed
         | true, true ->
-          is_same_fundec (Kf.get_definition kf) (Kf.get_definition kf') env
+          is_same_fundec (Kf.get_definition kf) (Kf.get_definition kf') env'
       in
       match same_spec, same_body with
-      | false, `Body_changed -> `Not_present, env
-      | false, `Callees_changed -> `Partial(kf',`Callees_spec_changed), env
-      | false, `Same_body -> `Partial(kf', `Spec_changed), env
-      | true, `Same_body -> `Same kf', env
-      | true, ((`Body_changed|`Callees_changed) as c) -> `Partial(kf', c), env
+      | false, `Body_changed -> `Not_present
+      | false, `Callees_changed -> `Partial(kf',`Callees_spec_changed)
+      | false, `Same_body -> `Partial(kf', `Spec_changed)
+      | true, `Same_body -> `Same kf'
+      | true, ((`Body_changed|`Callees_changed) as c) -> `Partial(kf', c)
   in
   match Kf.Map.find_opt kf env.kernel_function with
-  | Some kf' -> `Same kf', env
-  | None -> Kernel_function.memo_env add kf env
+  | Some kf' -> `Same kf'
+  | None -> Kernel_function.memo add kf
 
 and logic_info_correspondance ?loc li env =
-  let add li env =
+  let add li =
     match find_candidate_logic_info ?loc li env with
-    | None -> `Not_present, env
+    | None -> `Not_present
     | Some li' ->
       let env =
         { env with
           logic_info = Cil_datatype.Logic_info.Map.add li li' env.logic_info }
       in
-      let res, env = is_same_logic_info li li' env in
-      (if res then `Same li' else `Not_present), env
+      let res = is_same_logic_info li li' env in
+      if res then `Same li' else `Not_present
   in
   match Cil_datatype.Logic_info.Map.find_opt li env.logic_info with
-  | Some li' -> `Same li', env
-  | None -> Logic_info.memo_env add li env
+  | Some li' -> `Same li'
+  | None -> Logic_info.memo add li
 
 and logic_type_correspondance ?loc ti env =
-  let add ti env =
+  let add ti =
     match find_candidate_logic_type ?loc ti with
-    | None -> `Not_present, env
+    | None -> `Not_present
     | Some ti' ->
       let env =
         { env with
           logic_type_info =
             Cil_datatype.Logic_type_info.Map.add ti ti' env.logic_type_info }
       in
-      let res, env = is_same_logic_type_info ti ti' env in
-      (if res then `Same ti' else `Not_present), env
+      let res = is_same_logic_type_info ti ti' env in
+      if res then `Same ti' else `Not_present
   in
   match Cil_datatype.Logic_type_info.Map.find_opt ti env.logic_type_info with
-  | Some ti' -> `Same ti', env
-  | None -> Logic_type_info.memo_env add ti env
+  | Some ti' -> `Same ti'
+  | None -> Logic_type_info.memo add ti
 
 let gvar_correspondance ?loc vi =
   let add vi =
@@ -527,7 +509,7 @@ let gvar_correspondance ?loc vi =
         Project.on ~selection (Orig_project.get()) Globals.Vars.find vi
       in
       let init' = Globals.Vars.find vi' in
-      let res,_ = is_same_initinfo init init' empty_env in
+      let res = is_same_initinfo init init' empty_env in
       if res then `Same vi' else `Not_present
   in
   Varinfo.memo add vi
@@ -537,7 +519,7 @@ let model_info_correspondance ?loc mi =
     match find_candidate_model_info ?loc mi empty_env with
     | None -> `Not_present
     | Some mi' ->
-      let res,_ = is_same_model_info mi mi' empty_env in
+      let res = is_same_model_info mi mi' empty_env in
       if res then `Same mi' else `Not_present
   in
   Model_info.memo add mi
-- 
GitLab