From 7d0da0b878fcf77c3718b34e09dfa65298d47d42 Mon Sep 17 00:00:00 2001
From: Erwan Jahier <jahier@imag.fr>
Date: Wed, 18 Mar 2015 17:12:29 +0100
Subject: [PATCH] lic2soc: try a few optimisation wrt Soc.gao scheduling and
 test opening.

Indeed, in order to sort Soc.gao, I currently process in 3 stages ;
1. compute a total ordering of Actions.t according to the deps
2. transform Actions.t into Soc.gao (List.map)
3. factorize Soc.gao by looking at consecutive gao that have the same guard

With this change, between steps 1 and 2, I reorder the list of actions
so that group of independent actions are sorted according to their
clock. The idea is of course to provide to step 3 more opportunities
of factorization.

The result is not very convincing yet.

I've also tried to sort the actions wrt their clock before performing
the toposort. Seems not too bad.

I've kept the old behavior by default though.
---
 Makefile               |   2 +-
 _oasis                 |   2 +-
 src/action.ml          |   4 +-
 src/actionsDeps.ml     |  13 ++++-
 src/actionsDeps.mli    |   7 ++-
 src/lv6MainArgs.ml     |  23 +++++++-
 src/lv6MainArgs.mli    |   3 +
 src/lv6util.ml         |   8 +++
 src/sortActions.ml     |  61 ++++++++++++--------
 src/sortActionsExpe.ml | 127 +++++++++++++++++++++++++++++++++++++++++
 test/lus2lic.sum       |  26 ++++-----
 test/lus2lic.time      |  16 +++---
 12 files changed, 238 insertions(+), 54 deletions(-)
 create mode 100644 src/sortActionsExpe.ml

diff --git a/Makefile b/Makefile
index 08b9310d..5e772047 100644
--- a/Makefile
+++ b/Makefile
@@ -132,7 +132,7 @@ tags:
 	$(OTAGS) -v  src/*.ml
 
 ltags:
-	$(OTAGS) -v $(shell ocamlc -where)/*.mli  
+	$(OTAGS) -v  src/*.ml $(shell ocamlc -where)/*.mli 
 
 log:
 	rm -f lv6.log; git log > lv6.log
diff --git a/_oasis b/_oasis
index 82c24bb7..7d558b0b 100644
--- a/_oasis
+++ b/_oasis
@@ -37,5 +37,5 @@ Library "lustre-v6"
   Install:true
   XMETAEnable: true
   XMETADescription: an API to call the Lustre v6 interpreter from ocaml
-  InternalModules: SocExecValue,SocUtils,Lv6util,Lv6version,Lv6errors,Lxm,Lv6MainArgs,Verbose,Soc,SocPredef,Lv6Id,SocExec,SocExecEvalPredef,Compile,AstTab,AstTabSymbol,AstInstanciateModel,Lv6parserUtils,AstV6,FilenameExtras,LicTab,LicDump,AstPredef,Lic,AstCore,FreshName,IdSolver,EvalConst,LicEvalConst,LicEvalType,UnifyType,Ast2lic,AstV6Dump,EvalClock,UnifyClock,LicEvalClock,EvalType,LicPrg,LicMetaOp,L2lCheckOutputs,Misc,L2lRmPoly,L2lExpandMetaOp,L2lSplit,L2lExpandNodes,L2lExpandArrays,L2lCheckLoops,L2lCheckMemSafe,L2lOptimIte,Lv6lexer,Lv6parser,AstRecognizePredef,Lic2soc,Action,ActionsDeps,SocVar,Lus2licRun,SortActions
+  InternalModules: SocExecValue,SocUtils,Lv6util,Lv6version,Lv6errors,Lxm,Lv6MainArgs,Verbose,Soc,SocPredef,Lv6Id,SocExec,SocExecEvalPredef,Compile,AstTab,AstTabSymbol,AstInstanciateModel,Lv6parserUtils,AstV6,FilenameExtras,LicTab,LicDump,AstPredef,Lic,AstCore,FreshName,IdSolver,EvalConst,LicEvalConst,LicEvalType,UnifyType,Ast2lic,AstV6Dump,EvalClock,UnifyClock,LicEvalClock,EvalType,LicPrg,LicMetaOp,L2lCheckOutputs,Misc,L2lRmPoly,L2lExpandMetaOp,L2lSplit,L2lExpandNodes,L2lExpandArrays,L2lCheckLoops,L2lCheckMemSafe,L2lOptimIte,Lv6lexer,Lv6parser,AstRecognizePredef,Lic2soc,Action,ActionsDeps,SocVar,Lus2licRun,SortActions,SortActionsExpe
 # Comment se passer de cette liste à la Prevert ?
diff --git a/src/action.ml b/src/action.ml
index 29dd1618..a6469b62 100644
--- a/src/action.ml
+++ b/src/action.ml
@@ -1,4 +1,4 @@
-(** Time-stamp: <modified the 15/01/2015 (at 10:45) by Erwan Jahier> *)
+(** Time-stamp: <modified the 18/03/2015 (at 16:40) by Erwan Jahier> *)
 
 (* exported *)
 type rhs = Soc.var_expr list
@@ -19,7 +19,7 @@ let to_string_msg: (t -> string) =
     if o = [] then
       Format.sprintf "%s(%s)" (string_of_operation p) (string_of_params i)
     else
-      Format.sprintf "%s = %s(%s) on %s"
+      Format.sprintf "%s = %s(%s) %s"
         (string_of_params o)
         (string_of_operation p) (string_of_params i) (Lic.string_of_clock c)
 
diff --git a/src/actionsDeps.ml b/src/actionsDeps.ml
index 17720cd6..d441f6e2 100644
--- a/src/actionsDeps.ml
+++ b/src/actionsDeps.ml
@@ -1,4 +1,4 @@
-(** Time-stamp: <modified the 15/01/2015 (at 10:51) by Erwan Jahier> *)
+(** Time-stamp: <modified the 13/03/2015 (at 15:36) by Erwan Jahier> *)
   
 let dbg = (Verbose.get_flag "deps")
 
@@ -35,6 +35,17 @@ let (remove_dep :  t -> action -> t) =
 let (find_deps: t -> action -> action list) = 
   fun m a ->
     try Actions.elements (MapAction.find a m) with Not_found -> []
+
+
+let rec (depends_on : t -> Action.t -> Action.t -> bool) =
+  fun m a1 a2 ->
+    try
+      let a1_deps = MapAction.find a1 m in
+      Actions.mem a2 a1_deps || 
+        (* XXX I should compute the closure of the deps once for all *)
+        Actions.exists (fun a1 -> depends_on m a1 a2) a1_deps
+    with 
+        Not_found -> false
     
 (*********************************************************************************)
 (** Ajoute une liste de dépendances à une action. *)
diff --git a/src/actionsDeps.mli b/src/actionsDeps.mli
index b7400dd8..b1cecd48 100644
--- a/src/actionsDeps.mli
+++ b/src/actionsDeps.mli
@@ -1,4 +1,4 @@
-(** Time-stamp: <modified the 15/01/2015 (at 10:43) by Erwan Jahier> *)
+(** Time-stamp: <modified the 17/03/2015 (at 17:48) by Erwan Jahier> *)
 
 (** Compute dependencies between actions  *)
 
@@ -30,5 +30,10 @@ val find_deps: t -> Action.t -> Action.t list
 val have_deps : t -> Action.t -> bool
 val remove_dep :  t -> Action.t -> t
 
+(* Could also be named is_greater because if a1 depends on a2, it
+   means that a2 should be computed before, i.e. that a2 is smaller than
+   a1 *)
+val depends_on : t -> Action.t -> Action.t -> bool
+
 val to_string: t -> string
 
diff --git a/src/lv6MainArgs.ml b/src/lv6MainArgs.ml
index 779d3436..27ddab4a 100644
--- a/src/lv6MainArgs.ml
+++ b/src/lv6MainArgs.ml
@@ -1,4 +1,4 @@
-(* Time-stamp: <modified the 27/02/2015 (at 09:19) by Erwan Jahier> *)
+(* Time-stamp: <modified the 18/03/2015 (at 16:58) by Erwan Jahier> *)
 (*
 Le manager d'argument adapté de celui de lutin, plus joli
 N.B. solution un peu batarde : les options sont stockées, comme avant, dans Global,
@@ -13,6 +13,7 @@ let usage_msg =  "usage: "^tool_name^" [options] <file> | "^tool_name^" -help"
 
 type enum_mode = AsInt | AsConst | AsEnum
 type io_transmit_mode = Stack | Heap | HeapStack
+type schedul_mode = Simple | Sort | Reorder
 
 type t = {
   mutable opts : (string * Arg.spec * string) list; (* classical Arg option tab used by Arg.parse *)
@@ -58,6 +59,7 @@ type global_opt = {
   mutable line_start_pos : int;
   mutable soc2c_no_switch : bool;
   mutable io_transmit_mode : io_transmit_mode;
+  mutable schedul_mode : schedul_mode;
 }
 let (global_opt:global_opt) =
   {
@@ -73,6 +75,7 @@ let (global_opt:global_opt) =
     expand_enums =  AsInt;
     soc2c_no_switch = false;
     io_transmit_mode = Stack;
+    schedul_mode = Simple;
   }
 let (make_opt : unit -> t) = 
   fun () -> 
@@ -287,7 +290,7 @@ let mkoptab (opt:t) : unit = (
       ["Expand all node calls in the main node."]
     ;
     mkopt opt
-      ["-en"; "--expand-io-type"]
+      ["-et"; "--expand-io-type"]
       (Arg.Unit (fun _ -> opt.expand_io_type <- true))
       ["Expand structured types of the main node (impact the simulation only)."]
     ;
@@ -385,6 +388,22 @@ let mkoptab (opt:t) : unit = (
       ["I/O of memoryless soc are transmitted via the stack, and the heap otherwise (forces -2c)"]
     ;
 
+    mkopt opt ~hide:true
+      ["--schedule-simple"]
+      (Arg.Unit (fun i -> global_opt.schedul_mode <- Simple))
+      ["no re-ordering after topological sort"]
+    ;
+    mkopt opt ~hide:true
+      ["--schedule-sort"]
+      (Arg.Unit (fun i -> global_opt.schedul_mode <- Sort))
+      ["sort wrt guard before after topological sort"]
+    ;
+    mkopt opt ~hide:true
+      ["--schedule-reorder"]
+      (Arg.Unit (fun i -> global_opt.schedul_mode <- Reorder))
+      ["re-order Soc.gao after scheduling to increase the clock factorisation"]
+    ;
+
     mkopt opt ~hide:true
       ["--2c-no-switch"]
       (Arg.Unit (fun () -> global_opt.soc2c_no_switch <-true))
diff --git a/src/lv6MainArgs.mli b/src/lv6MainArgs.mli
index 0d18d50e..1d9e2c11 100644
--- a/src/lv6MainArgs.mli
+++ b/src/lv6MainArgs.mli
@@ -14,6 +14,8 @@ type io_transmit_mode =
   | Heap  (* All I/O are in a ctx structure; ctx of memoryless soc are global *)
   | HeapStack  (* I/O of memoryful soc are in a ctx structure; memoryless soc uses step arg *)
 (* *)
+
+type schedul_mode = Simple | Sort | Reorder
       
 type t = {
   mutable opts : (string * Arg.spec * string) list; (* classical Arg option tab used by Arg.parse *)
@@ -58,6 +60,7 @@ type global_opt = {
   mutable line_start_pos : int;
   mutable soc2c_no_switch : bool;
   mutable io_transmit_mode : io_transmit_mode;
+  mutable schedul_mode : schedul_mode;
 }
 val paranoid : Verbose.flag 
 
diff --git a/src/lv6util.ml b/src/lv6util.ml
index 22fb2f24..9ee8922c 100644
--- a/src/lv6util.ml
+++ b/src/lv6util.ml
@@ -49,3 +49,11 @@ let string_ends str1 str2 =
     str2 = String.sub str1 (l1 - l2 ) l2
 
 let _ = assert (string_ends "int []" "[]")
+
+(* [my_assoc x l] returns the elt associated to x in l plus l without (x,elt) *)
+let my_assoc x l = 
+  let rec aux acc = function
+  | [] -> None
+  | (a,b)::l -> if compare a x = 0 then Some(b,List.rev_append acc l) else aux ((a,b)::acc) l
+  in 
+  aux [] l
diff --git a/src/sortActions.ml b/src/sortActions.ml
index 262654fb..2efaf4be 100644
--- a/src/sortActions.ml
+++ b/src/sortActions.ml
@@ -1,4 +1,4 @@
-(** Time-stamp: <modified the 26/02/2015 (at 11:25) by Erwan Jahier> *)
+(** Time-stamp: <modified the 18/03/2015 (at 16:39) by Erwan Jahier> *)
 
 (** topological sort of actions (that may optimize test openning) *)
 
@@ -88,17 +88,14 @@ let rec (gao_of_action: Action.t -> Soc.gao) =
     unpack_clock (Soc.Call (ol, op, il)) ck
 
 (*********************************************************************************)
-(* [my_assoc x l] returns the elt associated to x in l plus l without (x,elt) *)
-let my_assoc x l = 
-  let rec aux acc = function
-  | [] -> None
-  | (a,b)::l -> if compare a x = 0 then Some(b,List.rev_append acc l) else aux ((a,b)::acc) l
-  in 
-  aux [] l
-
-(* Simple optimisation : when 2 consecutive gao holds on the same clock, we
-   try to factorize them out.
+
+(* In order to sort Soc.gao, I process in 3 stages ;
+1. compute a total ordering of Actions.t according to the deps
+2. transform Actions.t into Soc.gao (List.map)
+3. factorize Soc.gao by looking at consecutive gao that have the same guard
+
 *)
+
 let (optimize_test_openning: Soc.gao list -> ActionsDeps.t -> Soc.gao list) =
   fun gaol deps ->
     let rec aux acc gaol = match gaol with 
@@ -117,7 +114,7 @@ let (optimize_test_openning: Soc.gao list -> ActionsDeps.t -> Soc.gao list) =
         match l1 with
           | [] -> if l2 = [] then List.rev acc else List.rev_append acc l2
           | (x1,gaol1)::l1 -> 
-            (match my_assoc x1 l2 with
+            (match Lv6util.my_assoc x1 l2 with
               | None -> merge_gaol l1 l2 ((x1,gaol1)::acc)
               | Some(gaol2,l2) -> 
                 let gaol = aux [] (gaol1@gaol2) in
@@ -127,19 +124,33 @@ let (optimize_test_openning: Soc.gao list -> ActionsDeps.t -> Soc.gao list) =
     aux [] gaol
 
 (*********************************************************************************)
+open Lv6MainArgs
 
 let (f : Action.t list -> ActionsDeps.t -> Lxm.t -> Soc.gao list) = 
   fun actions deps lxm -> 
-    let actions = 
-      try topo_sort actions deps
-      with DependencyCycle(x,l) ->
-        let l = List.map Action.to_string l in
-        let msg = "A combinational cycle been detected "^
-          (Lxm.details lxm)^" on \n  "^(Action.to_string x)^
-          "\n  "^(String.concat "\n  " l) ^ "\n\nHint: try to use --expand-nodes.\n"
-        in
-        raise (Lv6errors.Global_error msg)
-    in
-    let gaol = List.map gao_of_action actions in
-     optimize_test_openning gaol deps 
-(*     gaol *)
+    (* =>  la liste d'actions en entrée contient des doublons !  *)
+    try match global_opt.schedul_mode with
+      | Simple -> (
+        let actions = topo_sort actions deps in
+        let gaol = List.map gao_of_action actions in
+        optimize_test_openning gaol deps 
+      )
+      | Sort -> ( (* experimental scheduling *)
+        let actions = List.sort_uniq SortActionsExpe.compare_actions actions in
+        let actions = topo_sort actions deps in
+        let gaol = List.map gao_of_action actions in
+        optimize_test_openning gaol deps 
+      )
+       | Reorder -> ( (* experimental scheduling *)
+        let actions = topo_sort actions deps in
+        let actions = SortActionsExpe.group actions deps in 
+         let gaol = List.map (List.map gao_of_action) actions in 
+         SortActionsExpe.optimize_test_openning gaol 
+      )
+    with DependencyCycle(x,l) ->
+      let l = List.map Action.to_string l in
+      let msg = "A combinational cycle been detected "^
+        (Lxm.details lxm)^" on \n  "^(Action.to_string x)^
+        "\n  "^(String.concat "\n  " l) ^ "\n\nHint: try to use --expand-nodes.\n"
+      in
+      raise (Lv6errors.Global_error msg)
diff --git a/src/sortActionsExpe.ml b/src/sortActionsExpe.ml
new file mode 100644
index 00000000..223593da
--- /dev/null
+++ b/src/sortActionsExpe.ml
@@ -0,0 +1,127 @@
+(** Time-stamp: <modified the 18/03/2015 (at 17:00) by Erwan Jahier> *)
+
+(** Some experiments on heuristics used in schedule Actions.  Indeed,
+    there are 2 dimensions: 
+
+    - at worst, there exists n! possible topological sorts (total
+    orderings of actions) of a DAG (a partial ordering induced by
+    dependencies). Some orderings are better than others because they
+    makes it possible to factorize test opennings. Indeed, compare 
+
+    "if c then e1; if c then e2;" 
+
+    with 
+    
+    "if c then (e1;e2)"
+
+    - Beside, some more tests can be saved by duplicating code. for ex
+    
+    "if c then e1 ; e2 ; if c then  e3;"
+    
+    can be tranformed into
+    
+    "if c then (e1 ; e2 ; e3) else e2;"
+    
+    which saves 1 test. But of course the code size may blows up, and some trade-offs
+    should be chosen.
+
+
+    Idées d'heuristiques : 
+
+    - Quand on choisit un successeur parmis dep(a), on pourrait prendre
+    celui qui a le moins de dépendances.
+*)
+
+(* split_al [a1;a2;...;an] returns [a1;a2;...;ak],[ak+1;...;an] where k is
+   the greater index such that {ai}_{i in [1,k]} is a set of independant
+   actions. 
+   nb : 
+    - k=>1
+    - the list in input is already sorted wrt deps (i.e., i<j => ai <= aj)
+*)
+let (split_al : ActionsDeps.t -> Action.t list -> Action.t list * Action.t list) =
+  fun deps al ->
+    (* al is (topologically) sorted, i.e.,  i<j => al_i <= al_j 
+       (where a <= b means a depends on b or not)
+    *)
+    let rec aux acc = function
+      | [] -> acc, []
+      | a::al ->
+        if List.for_all (fun acc1 -> not(ActionsDeps.depends_on deps a acc1)) acc then
+          aux (a::acc) al
+        else
+          acc, (a::al)
+    in 
+    aux [] al
+
+(* XXX switch cc and cv in the def of Lic.clock for the "On" variant 
+   to avoid this function
+*)
+let compare_actions a1 a2 = 
+  let (c1,r1,l1,op1,lxm1) = a1 in
+  let (c2,r2,l2,op2,lxm2) = a2 in
+  match c1,c2 with
+    | Lic.On((cc1, cv1, t1),clk1),Lic.On((cc2, cv2, t2),clk2) -> 
+      compare (cv1,cc1,t1,clk1,r1,l1,op1,lxm1) (cv2,cc2,t2,clk2,r2,l2,op2,lxm2)
+    | _,_ -> compare a1 a2
+
+(* In order to sort Soc.gao, I currently process in 3 stages ;
+1. compute a total ordering of Actions.t according to the deps
+2. transform Actions.t into Soc.gao (List.map)
+3. factorize Soc.gao by looking at consecutive gao that have the same guard
+
+   group is meant to work between steps 1 and 2, and reorder the list of
+   actions so that group of independent actions are sorted according to
+   their clock. The idea is of course to provide to step 3 more
+   opportunities of factorization.
+*)
+let (group : Action.t list -> ActionsDeps.t -> Action.t list list) =
+  fun al deps ->
+    let rec aux al acc =
+      let al1, al2 = split_al deps al in 
+      let al1 = List.sort_uniq compare_actions al1 in 
+    (* the clock is the left most element of the Action.t tuple *)
+      match al2 with
+        | [] -> List.rev (al1::acc)
+        | _ -> aux al2 (al1::acc)
+    in 
+    let res = aux al [] in (*
+    List.iter (fun al ->
+      let strl = List.map Action.to_string_msg al in
+      Printf.printf "\n*** actions that are grouped :\n   %s\n" (String.concat "\n   " strl) ;
+      flush stdout
+    ) res;*)
+    res
+
+(* duplicated! *)
+let (optimize_test_openning: Soc.gao list list -> Soc.gao list) =
+  fun gaoll ->
+    let rec merge_consecutive acc gaol = match gaol with
+      | []  -> List.rev acc
+      | [a] -> List.rev (a::acc)
+      | Soc.Call(o,op,i)::tail -> merge_consecutive (Soc.Call(o,op,i)::acc) tail
+      | a1::Soc.Call(o,op,i)::tail ->  merge_consecutive (Soc.Call(o,op,i)::a1::acc) tail 
+      | Soc.Case(v1,l1)::Soc.Case(v2,l2)::tail -> 
+        if v1 <> v2 then merge_consecutive (Soc.Case(v1,l1)::acc) (Soc.Case(v2,l2)::tail) else
+          let l = merge_gaol l1 l2 [] in
+          merge_consecutive acc (Soc.Case(v1,l)::tail) 
+            
+    and (merge_gaol : (string * Soc.gao list) list -> (string * Soc.gao list) list -> 
+         (string * Soc.gao list) list -> (string * Soc.gao list) list) =
+      fun l1 l2 acc -> 
+        match l1 with
+          | [] -> if l2 = [] then acc else List.rev_append acc l2
+          | (x1,gaol1)::l1 -> 
+            (match Lv6util.my_assoc x1 l2 with
+              | None -> merge_gaol l1 l2 ((x1,gaol1)::acc)
+              | Some(gaol2,l2) -> 
+                let gaol = merge_consecutive [] (gaol1@gaol2) in
+                merge_gaol l1 l2 ((x1,gaol)::acc)
+            )
+    in
+    (* inner lists are sorted, hence merge_consecutive should hits some merge *)
+    let gaoll = List.map (merge_consecutive []) gaoll in
+    let gaoll = List.mapi (fun i gaol -> if i mod 2 = 1 then List.rev gaol else gaol) gaoll in 
+    let gaol = List.flatten gaoll in
+     merge_consecutive []  gaol
+(* devrait pouvoir faire mieux !!*)      
diff --git a/test/lus2lic.sum b/test/lus2lic.sum
index 3c29bd3a..a719ceed 100644
--- a/test/lus2lic.sum
+++ b/test/lus2lic.sum
@@ -1,5 +1,5 @@
 ==> lus2lic0.sum <==
-Test Run By jahier on Tue Mar  3 15:17:54 
+Test Run By jahier on Wed Mar 18 17:03:49 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic0 tests ===
@@ -63,7 +63,7 @@ XFAIL: Test bad programs (assert): test_lus2lic_no_node should_fail/assert/lecte
 XFAIL: Test bad programs (assert): test_lus2lic_no_node should_fail/assert/s.lus
 
 ==> lus2lic1.sum <==
-Test Run By jahier on Tue Mar  3 15:17:58 
+Test Run By jahier on Wed Mar 18 17:03:53 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic1 tests ===
@@ -397,7 +397,7 @@ PASS: gcc -o multipar.exec multipar_multipar.c multipar_multipar_loop.c
 PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c multipar.lus  {}
 
 ==> lus2lic2.sum <==
-Test Run By jahier on Tue Mar  3 15:18:34 
+Test Run By jahier on Wed Mar 18 17:04:32 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic2 tests ===
@@ -727,7 +727,7 @@ PASS: gcc -o zzz2.exec zzz2_zzz2.c zzz2_zzz2_loop.c
 PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c zzz2.lus  {}
 
 ==> lus2lic3.sum <==
-Test Run By jahier on Tue Mar  3 15:19:37 
+Test Run By jahier on Wed Mar 18 17:05:38 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic3 tests ===
@@ -1230,7 +1230,7 @@ PASS: ./myec2c {-o multipar.c multipar.ec}
 PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node multipar.lus {}
 
 ==> lus2lic4.sum <==
-Test Run By jahier on Tue Mar  3 15:20:21 
+Test Run By jahier on Wed Mar 18 17:06:15 
 Native configuration is x86_64-unknown-linux-gnu
 
 		=== lus2lic4 tests ===
@@ -1727,13 +1727,13 @@ PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node zzz2.lus {}
 ===============================
 # Total number of failures: 14
 lus2lic0.log:testcase ./lus2lic.tests/test0.exp completed in 4 seconds
-lus2lic1.log:testcase ./lus2lic.tests/test1.exp completed in 36 seconds
-lus2lic2.log:testcase ./lus2lic.tests/test2.exp completed in 62 seconds
-lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 44 seconds
-lus2lic4.log:testcase ./lus2lic.tests/test4.exp completed in 70 seconds
+lus2lic1.log:testcase ./lus2lic.tests/test1.exp completed in 39 seconds
+lus2lic2.log:testcase ./lus2lic.tests/test2.exp completed in 66 seconds
+lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 37 seconds
+lus2lic4.log:testcase ./lus2lic.tests/test4.exp completed in 79 seconds
 * Ref time: 
-0.06user 0.03system 3:37.12elapsed 0%CPU (0avgtext+0avgdata 5076maxresident)k
-160inputs+0outputs (0major+5478minor)pagefaults 0swaps
+0.04user 0.02system 3:45.68elapsed 0%CPU (0avgtext+0avgdata 5120maxresident)k
+160inputs+0outputs (0major+5502minor)pagefaults 0swaps
 * Quick time (-j 4):
-0.04user 0.02system 1:25.72elapsed 0%CPU (0avgtext+0avgdata 5116maxresident)k
-160inputs+0outputs (0major+5521minor)pagefaults 0swaps
+0.03user 0.02system 1:25.43elapsed 0%CPU (0avgtext+0avgdata 5128maxresident)k
+160inputs+0outputs (0major+5564minor)pagefaults 0swaps
diff --git a/test/lus2lic.time b/test/lus2lic.time
index 8ad3950e..aad7425d 100644
--- a/test/lus2lic.time
+++ b/test/lus2lic.time
@@ -1,11 +1,11 @@
 lus2lic0.log:testcase ./lus2lic.tests/test0.exp completed in 4 seconds
-lus2lic1.log:testcase ./lus2lic.tests/test1.exp completed in 36 seconds
-lus2lic2.log:testcase ./lus2lic.tests/test2.exp completed in 62 seconds
-lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 44 seconds
-lus2lic4.log:testcase ./lus2lic.tests/test4.exp completed in 70 seconds
+lus2lic1.log:testcase ./lus2lic.tests/test1.exp completed in 39 seconds
+lus2lic2.log:testcase ./lus2lic.tests/test2.exp completed in 66 seconds
+lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 37 seconds
+lus2lic4.log:testcase ./lus2lic.tests/test4.exp completed in 79 seconds
 * Ref time: 
-0.06user 0.03system 3:37.12elapsed 0%CPU (0avgtext+0avgdata 5076maxresident)k
-160inputs+0outputs (0major+5478minor)pagefaults 0swaps
+0.04user 0.02system 3:45.68elapsed 0%CPU (0avgtext+0avgdata 5120maxresident)k
+160inputs+0outputs (0major+5502minor)pagefaults 0swaps
 * Quick time (-j 4):
-0.04user 0.02system 1:25.72elapsed 0%CPU (0avgtext+0avgdata 5116maxresident)k
-160inputs+0outputs (0major+5521minor)pagefaults 0swaps
+0.03user 0.02system 1:25.43elapsed 0%CPU (0avgtext+0avgdata 5128maxresident)k
+160inputs+0outputs (0major+5564minor)pagefaults 0swaps
-- 
GitLab