From 0850d5349ba30e255220b15525434727a70eead2 Mon Sep 17 00:00:00 2001
From: =?UTF-8?q?David=20B=C3=BChler?= <david.buhler@cea.fr>
Date: Fri, 5 Apr 2019 22:42:33 +0200
Subject: [PATCH] [Eva] Partition: do not export split_monitor, simplifies the
 split/merge actions.

split_monitors are created and internally used by partition.
New type split_kind to distinguish between static and dynamic splits, instead
of using different constructors in the action type.
---
 src/plugins/value/engine/partition.ml         | 39 +++++++++----------
 src/plugins/value/engine/partition.mli        | 18 ++-------
 .../value/engine/partitioning_parameters.ml   | 14 ++++---
 .../value/engine/state_partitioning.mli       |  1 -
 4 files changed, 30 insertions(+), 42 deletions(-)

diff --git a/src/plugins/value/engine/partition.ml b/src/plugins/value/engine/partition.ml
index 8c555ff0a8d..83a988cfd11 100644
--- a/src/plugins/value/engine/partition.ml
+++ b/src/plugins/value/engine/partition.ml
@@ -134,6 +134,8 @@ type unroll_limit =
   | ExpLimit of Cil_types.exp
   | IntLimit of int
 
+type split_kind = Static | Dynamic
+
 type action =
   | Enter_loop of unroll_limit
   | Leave_loop
@@ -141,10 +143,8 @@ type action =
   | Branch of branch * int
   | Ration of int
   | Ration_merge of (int*int) option
-  | Static_split of (Cil_types.exp * split_monitor)
-  | Dynamic_split of (Cil_types.exp * split_monitor)
-  | Static_merge of Cil_types.exp
-  | Dynamic_merge of Cil_types.exp
+  | Split of Cil_types.exp * split_kind * int
+  | Merge of Cil_types.exp * split_kind
   | Update_dynamic_splits
 
 exception InvalidAction
@@ -295,16 +295,15 @@ struct
 
   (* --- Applying partitioning actions onto flows --------------------------- *)
 
-  let split_state ~monitor ~(static : bool) (exp : Cil_types.exp)
+  let split_state ~monitor (kind : split_kind) (exp : Cil_types.exp)
       (key : key) (state : state) : (key * state) list =
     try
+      let add value map = ExpMap.add exp (value, monitor) map in
       let update_key (v,x) =
         let k =
-          let m = monitor in
-          if static then
-            { key with static_split = ExpMap.add exp (v,m) key.static_split }
-          else
-            { key with dynamic_split = ExpMap.add exp (v,m) key.dynamic_split }
+          match kind with
+          | Static -> { key with static_split = add v key.static_split }
+          | Dynamic -> { key with dynamic_split = add v key.dynamic_split }
         in
         (k,x)
       in
@@ -312,9 +311,10 @@ struct
     with Operation_failed ->
       [(key,state)]
 
-  let split ~monitor ~(static : bool) (p : t) (exp : Cil_types.exp) =
+  let split ~limit (kind : split_kind) (exp : Cil_types.exp) (p : t) =
+    let monitor = new_monitor limit in
     let add_split acc (key,state) =
-      split_state ~monitor ~static exp key state @ acc
+      split_state ~monitor kind exp key state @ acc
     in
     List.fold_left add_split [] p
 
@@ -324,7 +324,7 @@ struct
       (* Split the states in the list l for the given exp *)
       let update_exp exp (_i,monitor) l =
         let resplit acc (k,x) =
-          split_state ~monitor ~static:false exp k x @ acc
+          split_state ~monitor Dynamic exp k x @ acc
         in
         List.fold_left resplit [] l
       in
@@ -337,18 +337,15 @@ struct
     List.map (fun (k,x) -> f k x, x) p
 
   let transfer_keys p = function
-    | Static_split (exp,monitor) ->
-      split ~monitor ~static:true p exp
-
-    | Dynamic_split (exp,monitor) ->
-      split ~monitor ~static:false p exp
+    | Split (expr, kind, limit) ->
+      split ~limit kind expr p
 
     | Update_dynamic_splits ->
       update_dynamic_splits p
 
     | action -> (* Simple map transfer functions *)
       let transfer = match action with
-        | Static_split _ | Dynamic_split _ | Update_dynamic_splits ->
+        | Split _ | Update_dynamic_splits ->
           assert false (* Handled above *)
 
         | Enter_loop limit_kind -> fun k x ->
@@ -402,10 +399,10 @@ struct
         | Ration_merge ration_stamp  -> fun k _x ->
           { k with ration_stamp }
 
-        | Static_merge exp -> fun k _x ->
+        | Merge (exp, Static) -> fun k _x ->
           { k with static_split = ExpMap.remove exp k.static_split }
 
-        | Dynamic_merge exp -> fun k _x ->
+        | Merge (exp, Dynamic) -> fun k _x ->
           { k with dynamic_split = ExpMap.remove exp k.dynamic_split }
       in
       map_keys transfer p
diff --git a/src/plugins/value/engine/partition.mli b/src/plugins/value/engine/partition.mli
index f5e03e8642f..27f287d438d 100644
--- a/src/plugins/value/engine/partition.mli
+++ b/src/plugins/value/engine/partition.mli
@@ -20,16 +20,6 @@
 (*                                                                        *)
 (**************************************************************************)
 
-(* Split monitor : prevents splits from generating too many states *)
-
-type split_monitor = {
-  split_limit : int;
-  mutable split_values : Datatype.Integer.Set.t;
-}
-
-val new_monitor : split_limit:int -> split_monitor
-
-
 (*  A state partition is a collection of states, each of which is identified
     by a unique key. The key identifies the reason for which we want to keep
     the state separate from the others. The partitioning method will involve
@@ -101,6 +91,8 @@ type unroll_limit =
   | ExpLimit of Cil_types.exp
   | IntLimit of int
 
+type split_kind = Static | Dynamic
+
 type action =
   | Enter_loop of unroll_limit
   | Leave_loop
@@ -108,10 +100,8 @@ type action =
   | Branch of branch * int (* branch taken, max branches in history *)
   | Ration of int (* starting ration stamp *)
   | Ration_merge of (int * int) option (* new ration stamp for the merge state *)
-  | Static_split of (Cil_types.exp * split_monitor)
-  | Dynamic_split of (Cil_types.exp * split_monitor)
-  | Static_merge of Cil_types.exp
-  | Dynamic_merge of Cil_types.exp
+  | Split of Cil_types.exp * split_kind * int
+  | Merge of Cil_types.exp * split_kind
   | Update_dynamic_splits
 
 exception InvalidAction
diff --git a/src/plugins/value/engine/partitioning_parameters.ml b/src/plugins/value/engine/partitioning_parameters.ml
index 60ed14ebdc6..3cd62544005 100644
--- a/src/plugins/value/engine/partitioning_parameters.ml
+++ b/src/plugins/value/engine/partitioning_parameters.ml
@@ -110,8 +110,7 @@ struct
     let add name l =
       try
         let vi = Globals.Vars.find_from_astinfo name VGlobal in
-        let m = Partition.new_monitor split_limit in
-        Partition.Dynamic_split (Cil.evar vi, m) :: l
+        Partition.Split (Cil.evar vi, Partition.Dynamic, split_limit) :: l
       with Not_found ->
         warn ~current:false "cannot find the global variable %s for value \
                              partitioning" name;
@@ -120,12 +119,15 @@ struct
     ValuePartitioning.fold add []
 
   let flow_actions stmt =
+    let kind = Partition.Static in
     let map_annot acc t =
       try
-        let m = Partition.new_monitor split_limit in
-        match t with
-        | FlowSplit t -> Partition.Static_split (term_to_exp t,m) :: acc
-        | FlowMerge t -> Partition.Static_merge (term_to_exp t) :: acc
+        let action =
+          match t with
+          | FlowSplit t -> Partition.Split (term_to_exp t, kind, split_limit)
+          | FlowMerge t -> Partition.Merge (term_to_exp t, kind)
+        in
+        action :: acc
       with
         Db.Properties.Interp.No_conversion ->
         warn "split/merge expressions must be valid expressions";
diff --git a/src/plugins/value/engine/state_partitioning.mli b/src/plugins/value/engine/state_partitioning.mli
index fdaaec4ff31..d5b8df9227e 100644
--- a/src/plugins/value/engine/state_partitioning.mli
+++ b/src/plugins/value/engine/state_partitioning.mli
@@ -38,7 +38,6 @@ sig
   val merge : Cil_types.stmt -> bool
   val unroll : loop -> Partition.unroll_limit
   val history_size : int
-  val split_limit : int
   val universal_splits : Partition.action list
   val flow_actions : Cil_types.stmt -> Partition.action list
 end
-- 
GitLab