diff --git a/_oasis b/_oasis index 3946d6f287adf2d62705cedd2cb6cf20d658a2e8..5caff6e6175c65c6d3d0aa5a099e731ab4dc924d 100644 --- a/_oasis +++ b/_oasis @@ -1,6 +1,6 @@ OASISFormat: 0.4 Name: lustre-v6 -Version: 1.706 +Version: 1.707 Synopsis: The Lustre V6 Verimag compiler Description: This package contains: (1) lus2lic: the (current) name of the compiler (and interpreter via -exec). diff --git a/src/action.mli b/src/action.mli index 5afb88de026833a5a4be8e1ad23f7f451def8081..9b453691a0e9e9075bc8475ae1b2ab4c2fb888ec 100644 --- a/src/action.mli +++ b/src/action.mli @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 24/11/2016 (at 16:34) by Erwan Jahier> *) +(** Time-stamp: <modified the 10/07/2017 (at 15:57) by Erwan Jahier> *) (** An action is an intermediary data type that is used to translate expressions into [Soc.gao]. It is basically a clocked Soc.atomic_operation with arguments. @@ -8,7 +8,7 @@ translated into a gao. A more natural Module to define that type in would have been Soc, but that - module is meant to be shared with other front-ends (e.g., lucid-synchrone), + module could be shared with other front-ends (e.g., heptagon or lucid), and I prefer that module not to depend on - such a cutting (expr -> action -> gao) - The [Eff.clock] name (could have been a module parameter though). diff --git a/src/actionsDeps.ml b/src/actionsDeps.ml index cbe44bbfb6e1928cea524e3be5b429142e9b9719..c384cc12e62c0df731c43986fbec0bd72be0b873 100644 --- a/src/actionsDeps.ml +++ b/src/actionsDeps.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 14/01/2016 (at 10:37) by Erwan Jahier> *) +(** Time-stamp: <modified the 12/07/2017 (at 10:29) by Erwan Jahier> *) let dbg = (Lv6Verbose.get_flag "deps") @@ -42,19 +42,20 @@ let rec (depends_on : t -> Action.t -> Action.t -> bool) = 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 *) + (* XXX should I 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. *) -let add_deps: t -> action -> action list -> t = fun m a -> function - | [] -> m - | al -> - let actions = try MapAction.find a m with Not_found -> Actions.empty in - let actions = List.fold_left (fun set a -> Actions.add a set) actions al in - MapAction.add a actions m +let add_deps: t -> action -> action list -> t = + fun m a -> function + | [] -> m + | al -> + let actions = try MapAction.find a m with Not_found -> Actions.empty in + let actions = List.fold_left (fun set a -> Actions.add a set) actions al in + MapAction.add a actions m (* exported *) let (concat: t -> t -> t) = @@ -66,8 +67,7 @@ let (concat: t -> t -> t) = let (generate_deps_from_step_policy: Soc.precedence list -> (string * action) list -> t) = fun precedences actions -> - let generate_deps_for_action: - (t -> string * string list -> t) = + let generate_deps_for_action: (t -> string * string list -> t) = fun ad (action_name, actions_needed) -> let main_action = snd (List.find (fun (n, _) -> n = action_name) actions) in let deps = @@ -88,21 +88,28 @@ end module VarMap = Map.Make(OrderedSocVar) (** A Data structure that maps a Soc.var_expr to all the - actions that use that variable in lhs. + actions that needed to compute it. + + It is used to know which actions impact which Soc.var_expr. + +nb : you can have several actions associated to the same var_expr +when defining arrays or structures parts by parts. For instance + x[0]=42; + x[1]=1; + are two actions that define the var_expr "x" - It is used to know which actions impact which lhs. *) type var2actions_tbl = Actions.t VarMap.t -let var2actions = VarMap.find +let var2actions k tbl = try VarMap.find k tbl with Not_found -> Actions.empty -let rec (get_parents : Soc.var_expr -> Soc.var_expr list) = +let rec (gen_parents : Soc.var_expr -> Soc.var_expr list) = fun var -> -(* if var = t.[2].field, then it returns (also) t.[2] and t *) +(* if var = t.[2].field, then it returns [t.[2].field; t.[2] ; t] *) match var with | Soc.Slice(ve,_,_,_,_,_) | Soc.Field(ve,_,_) - | Soc.Index(ve,_,_) -> ve::(get_parents ve) + | Soc.Index(ve,_,_) -> ve::(gen_parents ve) | Soc.Var(_,vt) | Soc.Const(_,vt) -> [var] @@ -116,66 +123,110 @@ let rec (get_top_var : Soc.var_expr -> Soc.var_expr) = | Soc.Var(_,vt) | Soc.Const(_,vt) -> var +(** If x is a int^2, then + then actions such as a="x = y" + should produce the following dependancies : + x -> a + x[0] -> a + x[1] -> a + Hence, gen_children "x" produces "x[0]", and "x[1]" + *) +let rec (gen_children: Soc.var_expr -> Soc.var_expr list) = + fun v -> + match Soc.data_type_of_var_expr v with + | Data.Alpha _ | Data.Extern _ | Data.Enum _ | Data.Bool | Data.Int | Data.Real -> [v] + | Data.Struct(ident, ident_t_list) -> + List.fold_left + (fun acc (id,t) -> + let new_ve = Soc.Field(v,id,t) in + new_ve::((gen_children new_ve) @ acc) + ) + [] + ident_t_list + | Data.Array(t,size) -> + let new_ve_list = ref [] in + for i=0 to size - 1 do + let new_ve = Soc.Index(v, i, t) in + new_ve_list := new_ve::((gen_children new_ve) @ !new_ve_list); + done; + !new_ve_list + | Data.Alias(_,t) -> assert false (* sno ? *) -(** TODO jb: On a peut-être pas besoin de stocker les actions dans des set, il - devrait n'y avoir qu'une seule action pour chaque sortie en théorie (?) -*) +let nodupl l = + List.fold_left (fun acc x -> if List.mem x acc then acc else x::acc) [] l + + let (get_var2actions_tbl : action list -> var2actions_tbl) = fun al -> - let (tabulate_action : var2actions_tbl -> action -> var2actions_tbl) = - fun tbl action -> + let (tabulate_action : var2actions_tbl -> action -> var2actions_tbl) = + fun tbl action -> let _, _, lhs, _, lxm = action in let (tabulate_output:var2actions_tbl -> Soc.var_expr -> var2actions_tbl) = fun tbl output -> - let v = get_top_var output in - let tabulate_action = try var2actions v tbl - with Not_found -> Actions.empty - in - VarMap.add v (Actions.add action tabulate_action) tbl + let v = (* get_top_var *) output in (* for x of type t^2^2 *) + let children = gen_children v in (* children(x[0]) = [x[0][0];x[0][1]] *) + let parents = gen_parents v in (* and parents(x[0]) = [x] *) + let all = nodupl ((v::children)@parents) in + let tbl = + (* add the current action as a dep of v and its children and its parents *) + List.fold_left + (fun tbl cv -> + let cv_actions = var2actions cv tbl in + VarMap.add cv (Actions.add action cv_actions) tbl) + tbl all + in + tbl in List.fold_left tabulate_output tbl lhs in List.fold_left tabulate_action VarMap.empty al -(** Returns the actions that depends on a set of vars. +(** Returns the actions that depend on a set of vars, according to the content + of a table compute before [actions_of_vars input_vars al] trouve toutes les actions de [al] qui ont besoin d'être effectuées avant de pouvoir se servir de [input_vars] comme entrée d'une autre action. TODO: gérer les dépendances entre des filtres plus complexes, - comme par ex., l'utilisation d'un champ d'une structure nécessite - d'avoir initialisé la structure parente. + comme par ex., l'utilisation d'un champ d'une structure. *) - +let rec (actions_of_vars_old: Soc.var_expr list -> var2actions_tbl -> action list) = + fun vars tbl -> + let find_deps var = Actions.elements (var2actions var tbl) in + (* let vars = List.flatten (List.map gen_parents vars) in *) + (* let vars = List.fold_left (* remove duplicates *) *) + (* (fun acc x -> if List.mem x acc then acc else x::acc) [] vars *) + (* in *) + List.flatten (List.map find_deps vars) let rec (actions_of_vars: Soc.var_expr list -> var2actions_tbl -> action list) = fun vars tbl -> - let find_deps var = - try Actions.elements (var2actions var tbl) - with Not_found -> [] - in - let vars = List.flatten (List.map get_parents vars) in - let vars = List.fold_left (fun acc x -> if List.mem x acc then acc else x::acc) [] vars in - List.flatten (List.map find_deps vars) - + let actions = + List.fold_left + (fun acc v -> Actions.union acc (var2actions v tbl)) + Actions.empty + vars + in + Actions.elements actions + (*********************************************************************************) (* Some Printers to ease the debugging *) -(** Printer pour [Actions.t] *) let string_of_actions: Actions.t -> string = fun s -> let to_string a acc = - acc ^ (Action.to_string a) ^ " ; " + acc ^ "\n\t + '"^ (Action.to_string a) ^ "'" in - "Actions(" ^ (Actions.fold to_string s "") ^ ")" + "" ^ (Actions.fold to_string s "") ^ "" let string_of_var2actions_tbl: var2actions_tbl -> string = fun s -> let to_string key value acc = - let entry = Format.sprintf "%s => %s" (SocUtils.string_of_filter key) - (string_of_actions value) + let entry = Format.sprintf "%s depends on the following actions: %s" + (SocUtils.string_of_filter key) + (string_of_actions value) in acc ^ entry ^ "\n" in @@ -184,49 +235,85 @@ let string_of_var2actions_tbl: var2actions_tbl -> string = let to_string: t -> string = fun m -> let to_string key value acc = let entry = - Format.sprintf "%s \n depends on \" %s \"" + Format.sprintf "- '%s' depends on:%s" (Action.to_string key) (string_of_actions value) in acc ^ entry ^ "\n" in - "ActionsDeps{\n" ^ (MapAction.fold to_string m "") ^ "}" + "dependencies between equations are: \n" ^ (MapAction.fold to_string m "") ^ "" + +(* +let (add_parents : var2actions_tbl -> var2actions_tbl) = + fun tbl -> + let f var actions acc = + let pvars = gen_parents var in + List.folf_left + (fun acc pvar -> + let pactions = try var2actions pvar acc with Not_found -> Actions.empty in + + ) + acc pvars + in + VarMap.fold f tbl tbl + *) +(* It's useless to close this ; toposort will do it +let rec close : t -> t = + fun deps -> + let f action actions acc = + Actions.fold + (fun a acc -> + let a_actions = MapAction.find a acc in + let new_actions = Actions.union actions a_actions in + MapAction.add action new_actions acc + ) + actions acc + in + let new_deps = MapAction.fold f deps deps in + if deps = new_deps (* use MapAction.equal ? *) + then deps else close new_deps + *) (*********************************************************************************) (* exported *) let build_data_deps_from_actions: (Lic.type_ -> Data.t) -> t -> action list -> t = fun lic_to_data_type deps al -> - let tbl = get_var2actions_tbl al in + let tbl = get_var2actions_tbl al in + (* let tbl = add_parents tbl in *) + let pp_dbg () = + let al_str = List.map Action.to_string al in + print_string "\n ====> List of actions to be sorted:\n"; + print_string (String.concat "\n " al_str); + print_string "\n ====> List of computed dependencies:\n"; + print_string (string_of_var2actions_tbl tbl); + flush stdout + in let deps = - List.fold_left - (fun acc_deps action -> - let (clk, rhs, _, _,_) = action in - let dep_vars = match clk with - | Lic.BaseLic -> rhs - | Lic.ClockVar int -> rhs - | Lic.On ((cc,cv,ct),_) -> (Soc.Var(cv, lic_to_data_type ct))::rhs - in - let deps = actions_of_vars dep_vars tbl in - (* The guard should be computed before the guarded expression *) - if deps = [] then ( - Lv6Verbose.exe ~flag:dbg (fun () -> print_string ( - "\n====> No deps for " ^ - (String.concat "," (List.map SocUtils.string_of_filter rhs)))); - acc_deps - ) - else - add_deps acc_deps action deps - ) - deps - al - in - Lv6Verbose.exe ~flag:dbg (fun () -> - let al_str = List.map Action.to_string al in - print_string "\n ====> List of actions to be sorted:\n"; - print_string (String.concat "\n " al_str); - print_string "\n ====> List of computed dependencies:\n"; - print_string (string_of_var2actions_tbl tbl); - flush stdout); - deps + Lv6Verbose.exe ~flag:dbg pp_dbg; + List.fold_left + (fun acc_deps action -> + let (clk, rhs, _, _,_) = action in + let dep_vars = match clk with + | Lic.BaseLic -> rhs + | Lic.ClockVar int -> rhs + | Lic.On ((cc,cv,ct),_) -> + (* The guard should be computed before the guarded expression *) + (Soc.Var(cv, lic_to_data_type ct))::rhs + in + let deps = actions_of_vars dep_vars tbl in + if deps = [] then ( + let rhs_str = String.concat "," (List.map SocUtils.string_of_filter rhs) in + Lv6Verbose.exe + ~flag:dbg (fun () -> print_string ("\n====> No deps for " ^ rhs_str)); + acc_deps + ) + else + add_deps acc_deps action deps + ) + deps + al + in + (* let deps = close deps in *) + deps diff --git a/src/actionsDeps.mli b/src/actionsDeps.mli index b1cecd489e610c1df2de61b2fb33ce2d4c7e6922..8c819a3deeb7c4ea2b8ce19a3c06237ae9864352 100644 --- a/src/actionsDeps.mli +++ b/src/actionsDeps.mli @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 17/03/2015 (at 17:48) by Erwan Jahier> *) +(** Time-stamp: <modified the 11/07/2017 (at 14:37) by Erwan Jahier> *) (** Compute dependencies between actions *) @@ -11,7 +11,7 @@ val empty : t val concat: t -> t -> t -(** Compute the action dependencies that comes from the I/O. +(** Compute the action dependencies that comes from the equations I/O. Construit des dépendances entre les actions en reliant les entrées et les sorties de ces actions. diff --git a/src/l2lCheckLoops.ml b/src/l2lCheckLoops.ml index 0171777c453c8e2d09e6850b73e719d243a9f1e5..c2269e2287ef6dbc4e242798be2de2c10d58711c 100644 --- a/src/l2lCheckLoops.ml +++ b/src/l2lCheckLoops.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 20/10/2015 (at 17:44) by Erwan Jahier> *) +(* Time-stamp: <modified the 11/07/2017 (at 11:52) by Erwan Jahier> *) open Lxm open Lv6errors @@ -13,35 +13,37 @@ type dependencies = (Lxm.t * IdSet.t) IdMap.t (*********************************************************************************) (* Compute the set of vars appearing in an expression *) -let rec (vars_of_exp : IdSet.t -> Lic.val_exp -> IdSet.t) = - fun s ve -> +let rec (vars_of_exp : Lic.val_exp -> IdSet.t) = + fun ve -> + let rec aux s ve = vars_of_val_exp_core s ve.ve_core -and - vars_of_val_exp_core s = function + and + vars_of_val_exp_core s = function | CallByPosLic ({ it=FBY }, _) | CallByPosLic ({ it=PRE }, _) -> s (* pre is not a dependance! *) | CallByPosLic (by_pos_op, vel) -> - let s = vars_of_by_pos_op s by_pos_op.it in - List.fold_left vars_of_exp s vel + let s = vars_of_by_pos_op s by_pos_op.it in + List.fold_left aux s vel | Merge(ce, l) -> - let s = vars_of_exp s ce in - List.fold_left (fun s (_,ve) -> vars_of_exp s ve) s l + let s = aux s ce in + List.fold_left (fun s (_,ve) -> aux s ve) s l | CallByNameLic(_, _) -> s -and - vars_of_by_pos_op s = function + and + vars_of_by_pos_op s = function | VAR_REF id -> IdSet.add id s | PREDEF_CALL(_) | ARRAY_SLICE _ | ARRAY_ACCES _ | ARROW | FBY | CURRENT _ | WHEN _ | ARRAY | HAT(_) | STRUCT_ACCESS _ | TUPLE | CONCAT | CONST_REF _ | CALL _ | CONST _ -> s | PRE -> assert false -and - vars_of_static_arg s = function + and + vars_of_static_arg s = function | ConstStaticArgLic(id,_) | TypeStaticArgLic(id,_) | NodeStaticArgLic(id,_) -> IdSet.add id s - + in + aux IdSet.empty ve (*********************************************************************************) exception DepLoop of (Lxm.t * string) @@ -91,7 +93,7 @@ let rec (visit : dependencies -> visit_info -> Lv6Id.t -> Lv6Id.t list -> visit_ let (update_dependencies : dependencies -> Lic.eq_info srcflagged -> dependencies) = fun deps { it = (ll,exp) ; src = lxm } -> let lvars = List.map (fun l -> (Lic.var_info_of_left l).var_name_eff) ll in - let rvars = vars_of_exp IdSet.empty exp in + let rvars = vars_of_exp exp in let deps = List.fold_left (fun deps v -> diff --git a/src/l2lCheckLoops.mli b/src/l2lCheckLoops.mli index 256c3372e4e26e5d5d9a33828e0207399093c79a..ae919c353717d03b41fd722973e72e835c906751 100644 --- a/src/l2lCheckLoops.mli +++ b/src/l2lCheckLoops.mli @@ -1,6 +1,15 @@ -(* Time-stamp: <modified the 22/01/2013 (at 13:56) by Erwan Jahier> *) +(* Time-stamp: <modified the 11/07/2017 (at 10:31) by Erwan Jahier> *) -(** Check that there is no dependancy loops. *) +(** Check that there is no dependancy loop between equations. + +This check is also done during the lic2soc translation, when ordering +equations. But in the ec mode, no soc is generated, and no such check +is done by ec tools either (exexe, ec2c, etc.). + +Hence it is necessary to duplicate the work (done in ActionsDeps) +here. Note that in ec mode, structs and arrays have been expanded, +which makes things easier. + *) exception Error of (Lxm.t * string * LicPrg.t) diff --git a/src/l2lCheckOutputs.ml b/src/l2lCheckOutputs.ml index 7b2db23a9c1d442bf3272698fc50bb4fc82bc0da..9c74a0088c855145f04a55dc56cba43c0a218c5c 100644 --- a/src/l2lCheckOutputs.ml +++ b/src/l2lCheckOutputs.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 20/06/2017 (at 17:59) by Erwan Jahier> *) +(* Time-stamp: <modified the 11/07/2017 (at 10:49) by Erwan Jahier> *) open Lxm open Lv6errors @@ -45,7 +45,7 @@ let (vds_to_defined_vars : string -> var_def_state -> string list) = aux vds v [] (*********************************************************************************) -(** This is main function: it computes a new [var_def_state] from an +(** This is the main function: it computes a new [var_def_state] from an [var_def_state] and a [filtered_left]. *) let (update_var_def_state : var_def_state -> filtered_left -> var_def_state) = fun vds (v, lxm, filters) -> @@ -70,19 +70,19 @@ let (update_var_def_state : var_def_state -> filtered_left -> var_def_state) = (match vds with | VDS_array(a) -> a | VDS_undef -> undef_array_of_type te - | _ -> assert false (* by type checking *) + | _ -> assert false (* sno, by type checking *) ) | Aaccess(i,te)::tail -> update_array_access v i tail (match vds with | VDS_array(a) -> a | VDS_undef -> undef_array_of_type te - | _ -> assert false (* by type checking *) + | _ -> assert false (* sno, by type checking *) ) | Faccess(id,te)::tail -> update_field_access v id tail (match vds with | VDS_struct(fl) -> fl | VDS_undef -> undef_struct_of_type te - | _ -> assert false (* by type checking *) + | _ -> assert false (* sno, by type checking *) ) and undef_array_of_type = function diff --git a/src/lv6MainArgs.ml b/src/lv6MainArgs.ml index b40b38bf64cfc3c6a12e0af253255678fdbb33ad..608d2ca4e52ee220469663cec201215d824defc0 100644 --- a/src/lv6MainArgs.ml +++ b/src/lv6MainArgs.ml @@ -1,4 +1,4 @@ -(* Time-stamp: <modified the 05/07/2017 (at 15:37) by Erwan Jahier> *) +(* Time-stamp: <modified the 10/07/2017 (at 13:36) 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, @@ -368,7 +368,7 @@ let mkoptab (opt:t) : unit = ( "knows about basic the types int/bool/real)" ] ; mkopt opt ~doc_level:Advanced - ["-enc"; "---expand-node-call"] + ["-enc"; "--expand-node-call"] ~arg:" <string> " (Arg.String (fun str -> opt.expand_node_call <- str::opt.expand_node_call diff --git a/src/lv6Misc.ml b/src/lv6Misc.ml index 1b24c63fce59e35356bf3e78b3b385d4e5c632f4..764a9e8aa3ffbf6086f1c0a2d701e316296f82ed 100644 --- a/src/lv6Misc.ml +++ b/src/lv6Misc.ml @@ -1,8 +1,8 @@ -(* Time-stamp: <modified the 26/02/2015 (at 13:46) by Erwan Jahier> *) +(* Time-stamp: <modified the 11/07/2017 (at 10:48) by Erwan Jahier> *) open Lic open Lxm -(** [left_eff] is a kind of list, but which is in a « bad » order for +(** [left_eff] is a kind of list, but which is in the « reverse » order for easy checking; [filtered_left] contains just the same information, but the list is made explicit and the information (struct or array accesses) is ordered in the « good » way. @@ -27,10 +27,10 @@ let rec (left_eff_to_filtered_left: Lic.left Lxm.srcflagged -> filtered_left) = let te_top = (Lic.var_info_of_left le.it).var_type_eff in let (v,lxm,f) = aux te_top [] le.it in let (_,f) = - (* we don't want to associate to each accessors the type of the - « accessed elements », but its own type. E.g., if "t" is an - array of bool, we want to associate 't[0]' and an array of - bool, and not to a bool. *) + (* It's more useful want to associate to each accessors the + type of the « accessed elements », but its own type. E.g., + if "t" is an array of bool, we want to associate 't[0]' and + an array of bool, and not to a bool. *) List.fold_left (fun (te_top,acc) el -> match el with diff --git a/src/lv6version.ml b/src/lv6version.ml index 6c4f5c5c7dd3c9a9f56dc4e334b688407bf24ba0..3530ba32bfce760e52fec21427390c27ed88d313 100644 --- a/src/lv6version.ml +++ b/src/lv6version.ml @@ -1,7 +1,7 @@ (** Automatically generated from Makefile *) let tool = "lus2lic" let branch = "master" -let commit = "706" -let sha_1 = "ff567b8a3b0197116b5582764af9bba04cf70391" +let commit = "707" +let sha_1 = "a0197e0ca6c1adedc26192caacb2dbd8c8c6ef5e" let str = (branch ^ "." ^ commit ^ " (" ^ sha_1 ^ ")") let maintainer = "jahier@imag.fr" diff --git a/src/socUtils.ml b/src/socUtils.ml index 578c558f06691a8a95154aee7d8cd4283db4e4ce..033edf0be263b204e6d5e7d8ced69ad0e1fe5e2b 100644 --- a/src/socUtils.ml +++ b/src/socUtils.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 03/07/2017 (at 10:27) by Erwan Jahier> *) +(** Time-stamp: <modified the 11/07/2017 (at 17:02) by Erwan Jahier> *) open Soc @@ -57,8 +57,6 @@ let string_of_instance_ff: (instance -> Format.formatter -> unit) = let string_of_instance: (instance -> string) = fun (name,sk) -> name - - (* Filtre d'accès *) let rec string_of_filter_ff: (Soc.var_expr -> Format.formatter -> unit) = fun v ff -> match v with @@ -66,8 +64,9 @@ let rec string_of_filter_ff: (Soc.var_expr -> Format.formatter -> unit) = | Var (id,_) -> fprintf ff "%s" id | Field(f, id,_) -> string_of_filter_ff f ff; fprintf ff ".%s" id | Index(f, index,_) -> string_of_filter_ff f ff; fprintf ff "[%d]" index - | Slice(f,fi,la,st,wi,vt) -> string_of_filter_ff f ff; fprintf ff "[%d..%d step %d]" fi la st - + | Slice(f,fi,la,st,wi,vt) -> + string_of_filter_ff f ff; fprintf ff "[%d..%d step %d]" fi la st + let string_of_filter: (Soc.var_expr -> string) = fun v -> call_fun_ff (string_of_filter_ff v) diff --git a/src/sortActions.ml b/src/sortActions.ml index ded7f456df59fe30fd308c7b31f470e518cf084e..fdfaa39ef41539d9ad85527839b4584889ed3ed2 100644 --- a/src/sortActions.ml +++ b/src/sortActions.ml @@ -1,4 +1,4 @@ -(** Time-stamp: <modified the 22/11/2016 (at 14:57) by Erwan Jahier> *) +(** Time-stamp: <modified the 12/07/2017 (at 10:41) by Erwan Jahier> *) (** topological sort of actions (that may optimize test openning) *) @@ -110,6 +110,7 @@ let (f : Action.t list -> ActionsDeps.t -> Lxm.t -> Soc.gao list) = 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" + "\n "^(String.concat "\n " l) ^ + "\n\nHint: \n\t- try to use --expand-nodes or --expand-node-call; sometimes it works. \n\t- -knc migth ease to see where the cycle is.\n\t - -dbg deps will dump more (too much?) information\n" ^ (ActionsDeps.to_string deps) ^ "\n" in raise (Lv6errors.Global_error msg) diff --git a/test/lus2lic.sum b/test/lus2lic.sum index 88630ab675214da7d4c432f108d8c1efcde02d20..374e21d66f989e5e6bbe01d6935a549390e22d2f 100644 --- a/test/lus2lic.sum +++ b/test/lus2lic.sum @@ -1,5 +1,5 @@ ==> lus2lic0.sum <== -Test Run By jahier on Mon Jul 10 13:16:38 +Test Run By jahier on Wed Jul 12 11:27:39 Native configuration is x86_64-unknown-linux-gnu === lus2lic0 tests === @@ -10,6 +10,7 @@ Schedule of variations: Running target unix Running ./lus2lic.tests/test0.exp ... PASS: ./lus2lic -unit +XFAIL: Test bad programs (syntax): test_lus2lic_no_node should_fail/syntax/carligths.lus XFAIL: Test bad programs (syntax): test_lus2lic_no_node should_fail/syntax/old_style_and_pack.lus XFAIL: Test bad programs (syntax): test_lus2lic_no_node should_fail/syntax/record.lus XFAIL: Test bad programs (type): test_lus2lic_no_node should_fail/type/Gyro.lus @@ -43,6 +44,7 @@ XFAIL: Test bad programs (semantics): test_lus2lic_no_node should_fail/semantics XFAIL: Test bad programs (semantics): test_lus2lic_no_node should_fail/semantics/bad_call01.lus XFAIL: Test bad programs (semantics): test_lus2lic_no_node should_fail/semantics/const2.lus XFAIL: Test bad programs (semantics): test_lus2lic_no_node should_fail/semantics/const3.lus +XFAIL: Test bad programs (semantics): test_lus2lic_no_node should_fail/semantics/depend.lus XFAIL: Test bad programs (semantics): test_lus2lic_no_node should_fail/semantics/deploop.lus XFAIL: Test bad programs (semantics): test_lus2lic_no_node should_fail/semantics/import2.lus XFAIL: Test bad programs (semantics): test_lus2lic_no_node should_fail/semantics/m.lus @@ -64,7 +66,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 Mon Jul 10 13:16:39 +Test Run By jahier on Wed Jul 12 11:27:40 Native configuration is x86_64-unknown-linux-gnu === lus2lic1 tests === @@ -181,7 +183,9 @@ PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c call07.lus {} PASS: ./lus2lic {-2c carV2.lus -n carV2} PASS: sh carV2.sh PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c carV2.lus {} -FAIL: Generate c code : ./lus2lic {-2c carligths.lus -n carligths} +PASS: ./lus2lic {-2c carligths.lus -n carligths} +PASS: sh carligths.sh +PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c carligths.lus {} PASS: ./lus2lic {-2c ck2.lus -n ck2} PASS: sh ck2.sh PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c ck2.lus {} @@ -241,6 +245,7 @@ PASS: ./lus2lic {-2c deconne.lus -n deconne} PASS: ./lus2lic {-2c dep.lus -n dep} PASS: sh dep.sh PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c dep.lus {} +FAIL: Generate c code : ./lus2lic {-2c depend.lus -n depend} PASS: ./lus2lic {-2c dependeur.lus -n dependeur} PASS: sh dependeur.sh PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c dependeur.lus {} @@ -403,7 +408,7 @@ PASS: sh multipar.sh PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c multipar.lus {} ==> lus2lic2.sum <== -Test Run By jahier on Mon Jul 10 13:17:34 +Test Run By jahier on Wed Jul 12 11:28:36 Native configuration is x86_64-unknown-linux-gnu === lus2lic2 tests === @@ -537,7 +542,7 @@ PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c param_node4.lus {} PASS: ./lus2lic {-2c param_struct.lus -n param_struct} PASS: sh param_struct.sh PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c param_struct.lus {} -FAIL: Generate c code : ./lus2lic --expand-nodes {-2c pilote.lus -n pilote} +PASS: ./lus2lic --expand-nodes {-2c pilote.lus -n pilote} PASS: ./lus2lic {-2c pipeline.lus -n pipeline} PASS: sh pipeline.sh PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c pipeline.lus {} @@ -740,10 +745,9 @@ PASS: sh zzz.sh PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c zzz.lus {} PASS: ./lus2lic {-2c zzz2.lus -n zzz2} PASS: sh zzz2.sh -PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c zzz2.lus {} ==> lus2lic3.sum <== -Test Run By jahier on Mon Jul 10 13:18:49 +Test Run By jahier on Wed Jul 12 11:29:50 Native configuration is x86_64-unknown-linux-gnu === lus2lic3 tests === @@ -911,7 +915,7 @@ PASS: ./myec2c {-o carV2.c carV2.ec} PASS: ./lus2lic {-o carligths.lic carligths.lus} PASS: ./lus2lic {-ec -o carligths.ec carligths.lus} PASS: ./myec2c {-o carligths.c carligths.ec} -FAIL: Try to compare lus2lic -exec and ecexe: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node carligths.lus {} +UNRESOLVED: Time out: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node carligths.lus {} PASS: ./lus2lic {-o ck2.lic ck2.lus} PASS: ./lus2lic {-ec -o ck2.ec ck2.lus} PASS: ./myec2c {-o ck2.c ck2.ec} @@ -971,7 +975,7 @@ PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node contractForElement PASS: ./lus2lic {-o convert.lic convert.lus} PASS: ./lus2lic {-ec -o convert.ec convert.lus} PASS: ./myec2c {-o convert.c convert.ec} -PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node convert.lus {} +FAIL: Try to compare lus2lic -exec and ecexe: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node convert.lus {} PASS: ./lus2lic {-o count.lic count.lus} PASS: ./lus2lic {-ec -o count.ec count.lus} PASS: ./myec2c {-o count.c count.ec} @@ -1004,6 +1008,10 @@ PASS: ./lus2lic {-o dep.lic dep.lus} PASS: ./lus2lic {-ec -o dep.ec dep.lus} PASS: ./myec2c {-o dep.c dep.ec} PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node dep.lus {} +PASS: ./lus2lic {-o depend.lic depend.lus} +PASS: ./lus2lic {-ec -o depend.ec depend.lus} +PASS: ./myec2c {-o depend.c depend.ec} +FAIL: Try to compare lus2lic -exec and ecexe: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node depend.lus {} PASS: ./lus2lic {-o dependeur.lic dependeur.lus} PASS: ./lus2lic {-ec -o dependeur.ec dependeur.lus} PASS: ./myec2c {-o dependeur.c dependeur.ec} @@ -1253,7 +1261,7 @@ PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node multipar.lus {} ==> lus2lic4.sum <== -Test Run By jahier on Mon Jul 10 13:21:10 +Test Run By jahier on Wed Jul 12 11:32:38 Native configuration is x86_64-unknown-linux-gnu === lus2lic4 tests === @@ -1739,28 +1747,28 @@ PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node zzz2.lus {} === lus2lic0 Summary === # of expected passes 1 -# of expected failures 52 +# of expected failures 54 ==> lus2lic1.sum <== === lus2lic1 Summary === -# of expected passes 324 +# of expected passes 327 # of unexpected failures 3 ==> lus2lic2.sum <== +PASS: /home/jahier/lus2lic/test/../utils/compare_exec_and_2c zzz2.lus 37907 {} === lus2lic2 Summary === -# of expected passes 327 -# of unexpected failures 1 +# of expected passes 328 ==> lus2lic3.sum <== === lus2lic3 Summary === -# of expected passes 485 -# of unexpected failures 9 -# of unresolved testcases 3 +# of expected passes 487 +# of unexpected failures 10 +# of unresolved testcases 4 ==> lus2lic4.sum <== @@ -1770,14 +1778,14 @@ PASS: /home/jahier/lus2lic/test/../utils/test_lus2lic_no_node zzz2.lus {} # of unexpected failures 6 =============================== # Total number of failures: 19 -lus2lic0.log:testcase ./lus2lic.tests/test0.exp completed in 1 seconds -lus2lic1.log:testcase ./lus2lic.tests/test1.exp completed in 55 seconds -lus2lic2.log:testcase ./lus2lic.tests/test2.exp completed in 75 seconds -lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 141 seconds +lus2lic0.log:testcase ./lus2lic.tests/test0.exp completed in 0 seconds +lus2lic1.log:testcase ./lus2lic.tests/test1.exp completed in 56 seconds +lus2lic2.log:testcase ./lus2lic.tests/test2.exp completed in 74 seconds +lus2lic3.log:testcase ./lus2lic.tests/test3.exp completed in 168 seconds lus2lic4.log:testcase ./lus2lic.tests/test4.exp completed in 68 seconds * Ref time: -0.05user 0.02system 5:40.63elapsed 0%CPU (0avgtext+0avgdata 5656maxresident)k -64inputs+0outputs (0major+6170minor)pagefaults 0swaps +0.05user 0.02system 6:06.52elapsed 0%CPU (0avgtext+0avgdata 5648maxresident)k +160inputs+0outputs (0major+6211minor)pagefaults 0swaps * Quick time (-j 4): -0.05user 0.02system 2:31.81elapsed 0%CPU (0avgtext+0avgdata 5664maxresident)k -96inputs+0outputs (0major+6184minor)pagefaults 0swaps +0.06user 0.01system 2:51.96elapsed 0%CPU (0avgtext+0avgdata 5652maxresident)k +96inputs+0outputs (0major+6190minor)pagefaults 0swaps diff --git a/test/should_fail/semantics/depend.lus b/test/should_fail/semantics/depend.lus new file mode 100644 index 0000000000000000000000000000000000000000..f051eaf70924fda478ed063e115b825d0f780ddc --- /dev/null +++ b/test/should_fail/semantics/depend.lus @@ -0,0 +1,41 @@ +-- to test complex dependencies with struct and arrays + +type complex = struct { + re : real = 0.; + im : real = 0. +}; --- + +type bizzare = { + a : complex ^ 2; + b : complex ^ 2; +}; + +function depend(x,y: real) returns (res:bizzare^2); +var + a,b:complex ^ 2; + c:complex; + biz1,biz2:bizzare; + +let + biz1 = bizzare { a = a ; b = b}; + biz2 = bizzare { a = biz1.b ; b = biz1.a}; + res[0] = biz1; + + res[1].b = b; + res[1].a[0] = a[1]; + + res[1].a[1] = biz2.b[0]; + + a[0] = opp(b[1]); + a[1] = opp(b[0]); + b[0] = complex { re = x; im = res[1].a[1].im }; + b[1] = c; + c = complex { re = x; im = y }; +tel + -- end of depend + +function opp(x:complex) returns (res:complex); +let + res = complex { re = x.im ; im = x.re} ; +tel + -- end of opp \ No newline at end of file diff --git a/test/should_fail/semantics/tranche.lus b/test/should_fail/semantics/tranche.lus index 62a9abc92cb0e18d51b9582516988d2bd730b040..bc122917f37fe136bbecd0cc4a206b1884278e98 100644 --- a/test/should_fail/semantics/tranche.lus +++ b/test/should_fail/semantics/tranche.lus @@ -3,13 +3,13 @@ type t2 = bool^7^8^9^10; const - n : t; + n = [[1,2,3],[1,2,3],[1,2,3],[1,2,3]] ; m = n[3][2]; - s : t2; + s = 2^7^8^9^10; o = s[9][8][7][6]; -node tranche(a: bool^3) returns (res: bool); +function tranche(a: bool^3) returns (res: bool); var x: bool^3; y: real; @@ -18,7 +18,7 @@ var let y = 1.; - x[if(1>2) then -2 else 0] = true; +-- x[if(1>2) then -2 else 0] = true; x[1..2] = a[1..2]; res = if x[1] then x[0] else x[2]; z[0][0] = true; @@ -29,5 +29,6 @@ let z[2..3]= x1; x1[0] = x; x1[1] = x; - --x[0] = x1[0][0]; + x[0] = x1[1][0]; -- there is a self dep hidden here +-- x[0] = x1[0][0]; -- already defined tel diff --git a/test/should_fail/struct_incomplete.lus b/test/should_fail/struct_incomplete.lus index 2acb7d8f2061ca1b16f57ead4989f79d83c1560a..911247c6dbd82be229d8d23058e652d3a45b6848 100644 --- a/test/should_fail/struct_incomplete.lus +++ b/test/should_fail/struct_incomplete.lus @@ -3,7 +3,7 @@ type Toto = struct { y : int }; -node bibi (dummy : int) returns (z : Toto); +node struct_incomplete (dummy : int) returns (z : Toto); let z = Toto { x = 3 }; tel diff --git a/test/should_fail/syntax/carligths.lus b/test/should_fail/syntax/carligths.lus new file mode 100644 index 0000000000000000000000000000000000000000..3d570f35037253b93bb2be37497f5d609a6bee68 --- /dev/null +++ b/test/should_fail/syntax/carligths.lus @@ -0,0 +1,20 @@ +node carligths(TL, TR, LH, FL, LRL:bool) returns (side, low, high, fog, long:bool); +var fog_select, long_select :bool; +let + assert(not ((LH and TL) or (LH and TR))); + fog_select = FL; + long_select = LRL; + side = false -> (not(pre(side) or pre(low) or pre(high)) and TL) or + ( (pre(high) or pre(low) ) and (TL or TR)) or + (if not(TL or TR or LH) then pre(side) else false); + low = false -> (pre(side) and TL) or + (pre(high) and LH) or + (if not(TL or TR or LH) then pre(low) else false); + high = false -> (pre(low) and LH ) or + (if not(TL or TR or LH) then pre(high) else false); + fog = pre(low) and fog_select; + long = pre(high) and long_select; + + + +tel diff --git a/test/should_work/carligths.lus b/test/should_work/carligths.lus index 1a51ea455beed87ba5e38779b1a1e876f9805c5c..59650e9349eb6d1c7980c1a2e576f142e812e4b1 100644 --- a/test/should_work/carligths.lus +++ b/test/should_work/carligths.lus @@ -1,4 +1,4 @@ -node carlights(TL, TR, LH, FL, LRL:bool) returns (side, low, high, fog, long:bool); +node carligths(TL, TR, LH, FL, LRL:bool) returns (side, low, high, fog, long_:bool); var fog_select, long_select :bool; let assert(not ((LH and TL) or (LH and TR))); @@ -13,7 +13,7 @@ let high = false -> (pre(low) and LH ) or (if not(TL or TR or LH) then pre(high) else false); fog = pre(low) and fog_select; - long = pre(high) and long_select; + long_ = pre(high) and long_select; diff --git a/test/should_work/depend.lus b/test/should_work/depend.lus new file mode 100644 index 0000000000000000000000000000000000000000..ffd3fed875e06a939cb6396bc496588a9f6c9ecc --- /dev/null +++ b/test/should_work/depend.lus @@ -0,0 +1,40 @@ +-- to test complex dependencies with struct and arrays + +type complex = struct { + re : real = 0.; + im : real = 0. +}; --- + +type bizzare = { + a : complex ^ 2; + b : complex ^ 2; +}; + +function depend(x,y: real) returns (res:bizzare^2); +var + a,b:complex ^ 2; + c:complex; + biz1,biz2:bizzare; + +let + biz1 = bizzare { a = a ; b = b}; + biz2 = bizzare { a = biz1.b ; b = biz1.a}; + res[0] = biz1; + + res[1].b = b; + res[1].a[0] = a[1]; + + res[1].a[1] = res[1].a[0]; -- such expr is rejected because of the splitting! + + a[0] = opp(b[1]); + a[1] = opp(b[0]); + b = c^2; + c = complex { re = x; im = y }; +tel + -- end of depend + +function opp(x:complex) returns (res:complex); +let + res = complex { re = x.im ; im = x.re} ; +tel + -- end of opp \ No newline at end of file