diff --git a/src/optimization/ljs_new_env_clean.ml b/src/optimization/ljs_clean_env.ml similarity index 74% rename from src/optimization/ljs_new_env_clean.ml rename to src/optimization/ljs_clean_env.ml index be4ced2c..a1eb9420 100644 --- a/src/optimization/ljs_new_env_clean.ml +++ b/src/optimization/ljs_clean_env.ml @@ -74,12 +74,12 @@ let rec related_ids id (env : env) (curr_used : IdSet.t) : IdSet.t = with _ -> IdSet.add id curr_used (* eliminate unused ids in environment *) -let new_env_clean (exp : exp) : exp = - let rec env_clean_rec (e : exp) (env : env) (used_ids : IdSet.t) : (exp * IdSet.t) = +let clean_env (exp : exp) : exp = + let rec clean_rec (e : exp) (env : env) (used_ids : IdSet.t) : (exp * IdSet.t) = let rec handle_option (opt : exp option) env used_ids : exp option * IdSet.t = match opt with | Some (e) -> - let new_e, used_ids = env_clean_rec e env used_ids in + let new_e, used_ids = clean_rec e env used_ids in Some (new_e), used_ids | None -> None, used_ids in @@ -105,12 +105,12 @@ let new_env_clean (exp : exp) : exp = extensible = attrs.extensible } in let handle_prop (p : 'a) env used_ids : ('a * IdSet.t) = match p with | (s, Data(data, enum, config)) -> - let value, used_ids = env_clean_rec data.value env used_ids in + let value, used_ids = clean_rec data.value env used_ids in (s, Data({value = value; writable = data.writable}, enum, config)), used_ids | (s, Accessor (acc, enum, config)) -> - let getter, used_ids = env_clean_rec acc.getter env used_ids in - let setter, used_ids = env_clean_rec acc.setter env used_ids in + let getter, used_ids = clean_rec acc.getter env used_ids in + let setter, used_ids = clean_rec acc.setter env used_ids in (s, Accessor ({getter = getter; setter = setter}, enum, config)), used_ids in @@ -125,8 +125,8 @@ let new_env_clean (exp : exp) : exp = Object (p, new_attrs, prop_list), used_ids | GetAttr (p, pattr, obj, field) -> - let o, used_ids= env_clean_rec obj env used_ids in - let fld, used_ids = env_clean_rec field env used_ids in + let o, used_ids= clean_rec obj env used_ids in + let fld, used_ids = clean_rec field env used_ids in GetAttr (p, pattr, o, fld), used_ids | SetAttr (p, attr, obj, field, newval) -> @@ -134,24 +134,24 @@ let new_env_clean (exp : exp) : exp = dprint "clean SetAttr: %s\n" (EU.ljs_str e); Undefined Pos.dummy, used_ids end else - let o, used_ids = env_clean_rec obj env used_ids in - let f, used_ids = env_clean_rec field env used_ids in - let v, used_ids = env_clean_rec newval env used_ids in + let o, used_ids = clean_rec obj env used_ids in + let f, used_ids = clean_rec field env used_ids in + let v, used_ids = clean_rec newval env used_ids in SetAttr (p, attr, o, f, v), used_ids | GetObjAttr (p, oattr, obj) -> - let o, used_ids = env_clean_rec obj env used_ids in + let o, used_ids = clean_rec obj env used_ids in GetObjAttr(p, oattr, o), used_ids | SetObjAttr (p, oattr, obj, attre) -> - let o, used_ids = env_clean_rec obj env used_ids in - let attr, used_ids = env_clean_rec attre env used_ids in + let o, used_ids = clean_rec obj env used_ids in + let attr, used_ids = clean_rec attre env used_ids in SetObjAttr (p, oattr, o, attr), used_ids | GetField (p, obj, fld, args) -> - let o, used_ids = env_clean_rec obj env used_ids in - let f, used_ids = env_clean_rec fld env used_ids in - let a, used_ids = env_clean_rec args env used_ids in + let o, used_ids = clean_rec obj env used_ids in + let f, used_ids = clean_rec fld env used_ids in + let a, used_ids = clean_rec args env used_ids in let used_ids = match obj, fld with | Id (_, "%context"), String (_, id) -> (dprint "use point %s\n" id; IdSet.add id used_ids) @@ -165,40 +165,40 @@ let new_env_clean (exp : exp) : exp = Undefined Pos.dummy, used_ids end else - let o, used_ids = env_clean_rec obj env used_ids in - let f, used_ids = env_clean_rec fld env used_ids in - let v, used_ids = env_clean_rec newval env used_ids in - let a, used_ids = env_clean_rec args env used_ids in + let o, used_ids = clean_rec obj env used_ids in + let f, used_ids = clean_rec fld env used_ids in + let v, used_ids = clean_rec newval env used_ids in + let a, used_ids = clean_rec args env used_ids in SetField (p, o, f, v, a), used_ids | DeleteField (p, obj, fld) -> - let o, used_ids = env_clean_rec obj env used_ids in - let f, used_ids = env_clean_rec fld env used_ids in + let o, used_ids = clean_rec obj env used_ids in + let f, used_ids = clean_rec fld env used_ids in DeleteField (p, o, f), used_ids | OwnFieldNames (p, obj) -> - let o, used_ids = env_clean_rec obj env used_ids in + let o, used_ids = clean_rec obj env used_ids in OwnFieldNames (p, o), used_ids | SetBang (p, x, x_v) -> - let x_v, used_ids = env_clean_rec x_v env used_ids in + let x_v, used_ids = clean_rec x_v env used_ids in let used_ids = IdSet.add x used_ids in dprint "find usage point at SetBang %s\n" x; SetBang (p, x, x_v), used_ids | Op1 (p, op, e) -> - let e, used_ids = env_clean_rec e env used_ids in + let e, used_ids = clean_rec e env used_ids in Op1 (p, op, e), used_ids | Op2 (p, op, e1, e2) -> - let e1, used_ids = env_clean_rec e1 env used_ids in - let e2, used_ids = env_clean_rec e2 env used_ids in + let e1, used_ids = clean_rec e1 env used_ids in + let e2, used_ids = clean_rec e2 env used_ids in Op2 (p, op, e1, e2), used_ids | If (p, cond, thn, els) -> (* more optimization in constant folding *) - let cond, used_ids = env_clean_rec cond env used_ids in - let thn, used_ids = env_clean_rec thn env used_ids in - let els, used_ids = env_clean_rec els env used_ids in + let cond, used_ids = clean_rec cond env used_ids in + let thn, used_ids = clean_rec thn env used_ids in + let els, used_ids = clean_rec els env used_ids in If (p, cond, thn, els), used_ids | App (p, f, args) -> @@ -216,11 +216,11 @@ let new_env_clean (exp : exp) : exp = dprint "clean app: %s\n" (EU.ljs_str e); Undefined Pos.dummy, used_ids end else - let f, used_ids = env_clean_rec f env used_ids in + let f, used_ids = clean_rec f env used_ids in let rec handle_args args env used_ids = match args with | [] -> args, used_ids | fst :: rest -> - let v, used_ids = env_clean_rec fst env used_ids in + let v, used_ids = clean_rec fst env used_ids in let rest_v, used_ids = handle_args rest env used_ids in v :: rest_v, used_ids in @@ -228,8 +228,8 @@ let new_env_clean (exp : exp) : exp = App (p, f, args), used_ids | Seq (p, e1, e2) -> - let new_e2, e2_used_ids = env_clean_rec e2 env used_ids in - let new_e1, e1_used_ids = env_clean_rec e1 env e2_used_ids in + let new_e2, e2_used_ids = clean_rec e2 env used_ids in + let new_e1, e1_used_ids = clean_rec e1 env e2_used_ids in let e1_is_lambda = match new_e1 with Lambda (_,_,_) -> true | _ -> false in if e1_is_lambda || not (EU.has_side_effect new_e1) then new_e2, e1_used_ids @@ -238,7 +238,7 @@ let new_env_clean (exp : exp) : exp = | Let (p, x, x_v, body) -> let new_env = IdMap.add x x_v env in - let new_body, used_ids = env_clean_rec body new_env used_ids in + let new_body, used_ids = clean_rec body new_env used_ids in if not (IdSet.mem x used_ids) then begin dprint "Clean Let(%s=..)\n" x; new_body, used_ids @@ -249,7 +249,7 @@ let new_env_clean (exp : exp) : exp = | Rec (p, x, lambda, body) -> let new_env = IdMap.add x lambda env in - let new_body, used_ids = env_clean_rec body new_env used_ids in + let new_body, used_ids = clean_rec body new_env used_ids in if not (IdSet.mem x used_ids) then begin dprint "Clean Rec(%s=..)\n" x; new_body, used_ids @@ -260,39 +260,39 @@ let new_env_clean (exp : exp) : exp = Rec (p, x, lambda, new_body), IdSet.union lambda_ids used_ids | Label (p, l, e) -> - let new_e, used_ids = env_clean_rec e env used_ids in + let new_e, used_ids = clean_rec e env used_ids in Label (p, l, new_e), used_ids | Break (p, l, e) -> - let new_e, used_ids = env_clean_rec e env used_ids in + let new_e, used_ids = clean_rec e env used_ids in Break (p, l, new_e), used_ids | TryCatch (p, body, catch) -> - let b, used_ids = env_clean_rec body env used_ids in - let c, used_ids = env_clean_rec catch env used_ids in + let b, used_ids = clean_rec body env used_ids in + let c, used_ids = clean_rec catch env used_ids in TryCatch (p, b, c), used_ids | TryFinally (p, body, fin) -> - let b, used_ids = env_clean_rec body env used_ids in - let f, used_ids = env_clean_rec fin env used_ids in + let b, used_ids = clean_rec body env used_ids in + let f, used_ids = clean_rec fin env used_ids in TryFinally (p, b, f), used_ids | Throw (p, e) -> - let e, used_ids = env_clean_rec e env used_ids in + let e, used_ids = clean_rec e env used_ids in Throw(p, e), used_ids | Lambda (p, xs, body) -> (* lambda is only for collecting free vars. however, `with` expression will be desugared to fun(e) and the lambda contains variables like %context['TypeError'] *) - let body, used_ids = env_clean_rec body env used_ids in + let body, used_ids = clean_rec body env used_ids in let used_ids = IdSet.diff used_ids (IdSet.from_list xs) in Lambda (p, xs, body), used_ids | Hint (p, id, e) -> - let new_e, used_ids = env_clean_rec e env used_ids in + let new_e, used_ids = clean_rec e env used_ids in Hint (p, id, new_e), used_ids in - let new_exp, new_ids = env_clean_rec exp IdMap.empty IdSet.empty in + let new_exp, new_ids = clean_rec exp IdMap.empty IdSet.empty in new_exp diff --git a/src/optimization/ljs_less_mutation.ml b/src/optimization/ljs_convert_assignment.ml similarity index 83% rename from src/optimization/ljs_less_mutation.ml rename to src/optimization/ljs_convert_assignment.ml index e107c6df..a1e2c36b 100644 --- a/src/optimization/ljs_less_mutation.ml +++ b/src/optimization/ljs_convert_assignment.ml @@ -305,12 +305,12 @@ let rec free_vars_in_lambda exp : IdSet.t = | exp -> List.fold_left IdSet.union IdSet.empty (map free_vars_in_lambda (child_exps exp)) (** new **) -let less_mutation (exp : exp) : exp = - let rec less_rec (e : exp) (env : env) (used_ids : IdSet.t) : (exp * IdSet.t) = +let convert_assignment (exp : exp) : exp = + let rec convert_rec (e : exp) (env : env) (used_ids : IdSet.t) : (exp * IdSet.t) = let rec handle_option (opt : exp option) env used_ids : exp option * IdSet.t = match opt with | Some (e) -> - let new_e, used_ids = less_rec e env used_ids in + let new_e, used_ids = convert_rec e env used_ids in Some (new_e), used_ids | None -> None, used_ids in @@ -331,12 +331,12 @@ let less_mutation (exp : exp) : exp = extensible = attrs.extensible } in let handle_prop (p : 'a) env used_ids : ('a * IdSet.t) = match p with | (s, Data(data, enum, config)) -> - let value, used_ids = less_rec data.value env used_ids in + let value, used_ids = convert_rec data.value env used_ids in (s, Data({value = value; writable = data.writable}, enum, config)), used_ids | (s, Accessor (acc, enum, config)) -> - let getter, used_ids = less_rec acc.getter env used_ids in - let setter, used_ids = less_rec acc.setter env used_ids in + let getter, used_ids = convert_rec acc.getter env used_ids in + let setter, used_ids = convert_rec acc.setter env used_ids in (s, Accessor ({getter = getter; setter = setter}, enum, config)), used_ids in @@ -351,66 +351,66 @@ let less_mutation (exp : exp) : exp = Object (p, new_attrs, prop_list), used_ids | GetAttr (p, pattr, obj, field) -> - let o, used_ids= less_rec obj env used_ids in - let fld, used_ids = less_rec field env used_ids in + let o, used_ids= convert_rec obj env used_ids in + let fld, used_ids = convert_rec field env used_ids in GetAttr (p, pattr, o, fld), used_ids | SetAttr (p, attr, obj, field, newval) -> - let o, used_ids = less_rec obj env used_ids in - let f, used_ids = less_rec field env used_ids in - let v, used_ids = less_rec newval env used_ids in + let o, used_ids = convert_rec obj env used_ids in + let f, used_ids = convert_rec field env used_ids in + let v, used_ids = convert_rec newval env used_ids in SetAttr (p, attr, o, f, v), used_ids | GetObjAttr (p, oattr, obj) -> - let o, used_ids = less_rec obj env used_ids in + let o, used_ids = convert_rec obj env used_ids in GetObjAttr(p, oattr, o), used_ids | SetObjAttr (p, oattr, obj, attre) -> - let o, used_ids = less_rec obj env used_ids in - let attr, used_ids = less_rec attre env used_ids in + let o, used_ids = convert_rec obj env used_ids in + let attr, used_ids = convert_rec attre env used_ids in SetObjAttr (p, oattr, o, attr), used_ids | GetField (p, obj, fld, args) -> - let o, used_ids = less_rec obj env used_ids in - let f, used_ids = less_rec fld env used_ids in - let a, used_ids = less_rec args env used_ids in + let o, used_ids = convert_rec obj env used_ids in + let f, used_ids = convert_rec fld env used_ids in + let a, used_ids = convert_rec args env used_ids in GetField (p, o, f, a), used_ids | SetField (p, obj, fld, newval, args) -> - let o, used_ids = less_rec obj env used_ids in - let f, used_ids = less_rec fld env used_ids in - let v, used_ids = less_rec newval env used_ids in - let a, used_ids = less_rec args env used_ids in + let o, used_ids = convert_rec obj env used_ids in + let f, used_ids = convert_rec fld env used_ids in + let v, used_ids = convert_rec newval env used_ids in + let a, used_ids = convert_rec args env used_ids in SetField (p, o, f, v, a), used_ids | DeleteField (p, obj, fld) -> - let o, used_ids = less_rec obj env used_ids in - let f, used_ids = less_rec fld env used_ids in + let o, used_ids = convert_rec obj env used_ids in + let f, used_ids = convert_rec fld env used_ids in DeleteField (p, o, f), used_ids | OwnFieldNames (p, obj) -> - let o, used_ids = less_rec obj env used_ids in + let o, used_ids = convert_rec obj env used_ids in OwnFieldNames (p, o), used_ids | SetBang (p, x, x_v) -> - let x_v, used_ids = less_rec x_v env used_ids in + let x_v, used_ids = convert_rec x_v env used_ids in let used_ids = IdSet.add x used_ids in dprint "find usage point at SetBang %s\n" x; SetBang (p, x, x_v), used_ids | Op1 (p, op, e) -> - let e, used_ids = less_rec e env used_ids in + let e, used_ids = convert_rec e env used_ids in Op1 (p, op, e), used_ids | Op2 (p, op, e1, e2) -> - let e1, used_ids = less_rec e1 env used_ids in - let e2, used_ids = less_rec e2 env used_ids in + let e1, used_ids = convert_rec e1 env used_ids in + let e2, used_ids = convert_rec e2 env used_ids in Op2 (p, op, e1, e2), used_ids | If (p, cond, thn, els) -> (* more optimization in constant folding *) - let cond, used_ids = less_rec cond env used_ids in - let thn, used_ids = less_rec thn env used_ids in - let els, used_ids = less_rec els env used_ids in + let cond, used_ids = convert_rec cond env used_ids in + let thn, used_ids = convert_rec thn env used_ids in + let els, used_ids = convert_rec els env used_ids in If (p, cond, thn, els), used_ids | App (p, f, args) -> @@ -418,11 +418,11 @@ let less_mutation (exp : exp) : exp = | Id (_, id) -> related_ids id env used_ids | _ -> used_ids in *) - let f, used_ids = less_rec f env used_ids in + let f, used_ids = convert_rec f env used_ids in let rec handle_args args env used_ids = match args with | [] -> args, used_ids | fst :: rest -> - let v, used_ids = less_rec fst env used_ids in + let v, used_ids = convert_rec fst env used_ids in let rest_v, used_ids = handle_args rest env used_ids in v :: rest_v, used_ids in @@ -438,59 +438,59 @@ let less_mutation (exp : exp) : exp = let _ = dprint "%s of setBang is used elsewhere. no change\n" x in (* we haven't visit e2 yet, but used used_ids already contains x. That means x is used outside the execution path. we cannot do the transformation *) - let new_e2, used_ids = less_rec e2 env used_ids in - let new_e1, used_ids = less_rec e1 env used_ids in + let new_e2, used_ids = convert_rec e2 env used_ids in + let new_e1, used_ids = convert_rec e1 env used_ids in Seq (p, e1, new_e2), used_ids | SetBang (p, x, x_v) -> let _ = dprint "transform %s" (ljs_str e1) in (* x may only be used in e2, so transform it! *) - let x_v, used_ids = less_rec x_v env used_ids in - let new_e2, used_ids = less_rec e2 env used_ids in + let x_v, used_ids = convert_rec x_v env used_ids in + let new_e2, used_ids = convert_rec e2 env used_ids in Let (p, x, x_v, new_e2), used_ids | Let (pos, "#strict", v, Let (p, tmp_name, func, SetBang(p1, real_name, Id(p2, tmp_name2)))) when tmp_name = tmp_name2 -> dprint_string "find js function pattern\n"; (* desugared js function *) - let new_func, used_ids = less_rec func env used_ids in + let new_func, used_ids = convert_rec func env used_ids in if IdSet.mem real_name used_ids then (* if the func contains the real_name, this function definition is a recursive function. We cannot do the transformation *) let _ = dprint "recursive function %s. keep it as it was\n" real_name in let new_e1 = Let (pos, "#strict", v, Let(pos, tmp_name, new_func, SetBang(p1, real_name, Id(p2, tmp_name2)))) in - let new_e2, used_ids = less_rec e2 env used_ids in + let new_e2, used_ids = convert_rec e2 env used_ids in Seq (p, new_e1, new_e2), used_ids else let _ = dprint "convert js function def pattern %s to let\n" (ljs_str e1) in - let new_e2, used_ids = less_rec e2 env used_ids in + let new_e2, used_ids = convert_rec e2 env used_ids in Let (pos, "#strict", v, Let(pos, real_name, new_func, new_e2)), IdSet.remove real_name used_ids | Let (pos, tmp_name, func, SetBang(p1, real_name, Id(p2, tmp_name2))) when tmp_name = tmp_name2 -> dprint_string "find js function pattern\n"; (* desugared js function *) - let new_func, used_ids = less_rec func env used_ids in + let new_func, used_ids = convert_rec func env used_ids in if IdSet.mem real_name used_ids then (* if the func contains the real_name, this function definition is a recursive function. We cannot do the transformation *) let _ = dprint "recursive function %s. keep it as it was\n" real_name in let new_e1 = Let(pos, tmp_name, new_func, SetBang(p1, real_name, Id(p2, tmp_name2))) in - let new_e2, used_ids = less_rec e2 env used_ids in + let new_e2, used_ids = convert_rec e2 env used_ids in Seq (p, new_e1, new_e2), used_ids else let _ = dprint "convert js function def pattern %s to let\n" (ljs_str e1) in - let new_e2, used_ids = less_rec e2 env used_ids in + let new_e2, used_ids = convert_rec e2 env used_ids in Let(pos, real_name, new_func, new_e2), IdSet.remove real_name used_ids | _ -> let _ = dprint_string "normal seq\n" in let used_ids = IdSet.union (free_vars_in_lambda e1) used_ids in - let new_e2, used_ids = less_rec e2 env used_ids in - let new_e1, used_ids = less_rec e1 env used_ids in + let new_e2, used_ids = convert_rec e2 env used_ids in + let new_e1, used_ids = convert_rec e1 env used_ids in Seq (p, new_e1, new_e2), used_ids end | Let (pos, tmp_name, func, SetBang(p1, real_name, Id(p2, tmp_name2))) (* this exp is a standalone js function definition *) when tmp_name = tmp_name2 -> - let func, used_ids = less_rec func env used_ids in + let func, used_ids = convert_rec func env used_ids in if IdSet.mem real_name used_ids then (* recursive, leave it as it was *) Let (pos, tmp_name, func, SetBang(p1, real_name, Id(p2, tmp_name2))), @@ -501,53 +501,53 @@ let less_mutation (exp : exp) : exp = | Let (p, x, x_v, body) -> let new_env = IdMap.add x x_v env in let used_ids = IdSet.union used_ids (free_vars_in_lambda x_v) in - let new_body, used_ids = less_rec body new_env used_ids in - let x_v, used_ids = less_rec x_v env used_ids in + let new_body, used_ids = convert_rec body new_env used_ids in + let x_v, used_ids = convert_rec x_v env used_ids in let used_ids = IdSet.remove x used_ids in Let (p, x, x_v, new_body), used_ids | Rec (p, x, lambda, body) -> let new_env = IdMap.add x lambda env in - let new_body, used_ids = less_rec body new_env used_ids in + let new_body, used_ids = convert_rec body new_env used_ids in (* x is recursive function def, so remove x from lambda's env *) - let lambda, used_ids = less_rec lambda env used_ids in + let lambda, used_ids = convert_rec lambda env used_ids in let used_ids = IdSet.remove x used_ids in Rec (p, x, lambda, new_body), used_ids | Label (p, l, e) -> - let new_e, used_ids = less_rec e env used_ids in + let new_e, used_ids = convert_rec e env used_ids in Label (p, l, new_e), used_ids | Break (p, l, e) -> - let new_e, used_ids = less_rec e env used_ids in + let new_e, used_ids = convert_rec e env used_ids in Break (p, l, new_e), used_ids | TryCatch (p, body, catch) -> - let b, used_ids = less_rec body env used_ids in - let c, used_ids = less_rec catch env used_ids in + let b, used_ids = convert_rec body env used_ids in + let c, used_ids = convert_rec catch env used_ids in TryCatch (p, b, c), used_ids | TryFinally (p, body, fin) -> - let b, used_ids = less_rec body env used_ids in - let f, used_ids = less_rec fin env used_ids in + let b, used_ids = convert_rec body env used_ids in + let f, used_ids = convert_rec fin env used_ids in TryFinally (p, b, f), used_ids | Throw (p, e) -> - let e, used_ids = less_rec e env used_ids in + let e, used_ids = convert_rec e env used_ids in Throw(p, e), used_ids | Lambda (p, xs, body) -> (* lambda is only for collecting free vars. however, `with` expression will be desugared to fun(e) and the lambda contains variables like %context['TypeError'] *) - let body, used_ids = less_rec body env used_ids in + let body, used_ids = convert_rec body env used_ids in let used_ids = IdSet.diff used_ids (IdSet.from_list xs) in Lambda (p, xs, body), used_ids | Hint (p, id, e) -> - let new_e, used_ids = less_rec e env used_ids in + let new_e, used_ids = convert_rec e env used_ids in Hint (p, id, new_e), used_ids in - let new_exp, new_ids = less_rec exp IdMap.empty IdSet.empty in + let new_exp, new_ids = convert_rec exp IdMap.empty IdSet.empty in new_exp diff --git a/src/optimization/ljs_deadcode_elimination.ml b/src/optimization/ljs_eliminate_deadcode.ml similarity index 99% rename from src/optimization/ljs_deadcode_elimination.ml rename to src/optimization/ljs_eliminate_deadcode.ml index b311dc6d..fd733d9a 100644 --- a/src/optimization/ljs_deadcode_elimination.ml +++ b/src/optimization/ljs_eliminate_deadcode.ml @@ -15,7 +15,7 @@ let no_sideeffect_list = [ let no_sideeffect_set = IdSet.from_list no_sideeffect_list (* eliminate unused ids, sequence *) -let deadcode_elimination (exp : exp) : exp = +let eliminate_deadcode (exp : exp) : exp = let rec eliminate_ids_rec (e : exp) (ids : IdSet.t) : (exp * IdSet.t) = let rec handle_option (opt : exp option) ids : exp option * IdSet.t = match opt with diff --git a/src/optimization/ljs_env_clean.ml b/src/optimization/ljs_env_clean.ml deleted file mode 100644 index e4115635..00000000 --- a/src/optimization/ljs_env_clean.ml +++ /dev/null @@ -1,331 +0,0 @@ -open Prelude -open Ljs_syntax -module EU = Exp_util - -type env = exp IdMap.t - -let ljs_str ljs = - Ljs_pretty.exp ljs Format.str_formatter; Format.flush_str_formatter() - -let debug_on = true - -let dprint, dprint_string, dprint_ljs = Debug.make_debug_printer ~on:debug_on "env-clean" -let dprint_set set = - dprint "set {%s}\n" (String.concat ", " (IdSet.to_list set)) - -(* get global accessed ids in user code. user defined ids are excluded *) -let rec user_code_ids (exp : exp) : IdSet.t = - let rec get_global_accessors (exp : exp) : IdSet.t = - match exp with - | App (_, f, args) -> - begin match f, args with - | Id (_, "%defineGlobalAccessors"), [Id(_, "%context"); String(_, global_var)] -> - IdSet.singleton global_var - | _ -> IdSet.empty - end - | _ -> IdSet.unions (List.map get_global_accessors (child_exps exp)) - in - match exp with - | Let (p, "%context", Id(p1, ctx), body) - when ctx = "%strictContext" || ctx = "%nonstrictContext" -> - IdSet.union (free_vars exp) (get_global_accessors exp) - | _ -> IdSet.unions (List.map user_code_ids (child_exps exp)) - -type binding = (id, exp) Hashtbl.t - -let rec collect_env_bindings (exp : exp) (bindings : binding) : binding = match exp with - | Let (_, "%context", Id(_, ctx), body) - when ctx = "%strictContext" || ctx = "%nonstrictContext" -> - (* the body is user code *) - bindings - | Let (_, x, x_v, body) -> - Hashtbl.add bindings x x_v; - collect_env_bindings body bindings - | Rec (_, x, x_v, body) -> - Hashtbl.add bindings x x_v; - collect_env_bindings body bindings - | _ -> List.fold_left (fun b e->collect_env_bindings e b) bindings (child_exps exp) - -(* find id's exp in bindings, get ids from that exp and find ids' exp again - bindings is changing. The result includes id -*) -let rec id_dependencies (id : id) (bindings : binding) : IdSet.t = - let dependencies = - try - let exp = Hashtbl.find bindings id in - let ids = free_vars exp in - (* first, remove this id from the binding *) - Hashtbl.remove bindings id; - (* then get the dependencies for each id in ids *) - IdSet.fold (fun (elm : id) (set : IdSet.t)-> - let subset = id_dependencies elm bindings in - IdSet.union subset set) ids ids - with _ -> IdSet.empty - in - dprint "dependencies of %s:\n" id; - dprint_set dependencies; - IdSet.add id dependencies - -let rec useless_def_point f args ids : bool = - match f, args with - | Id(_, "%defineOwnProperty"), [Id(_, "%global"); String(_, func_name); Object(_,_,_)] - when not (IdSet.mem func_name ids) -> - (* field of %global(global var) is not used *) - true - | Id(_, "%defineNYIProperty"), [Id(_, proto); String(_, func_name)] - when not (IdSet.mem proto ids) -> - (* proto is not used *) - true - | Id(_, "%define15Property"), [Id(_, obj); String(_, func_name);_] - when not (IdSet.mem obj ids) -> - (* obj is not used *) - true - | Id(_, "%defineOwnProperty"), [Id(_, obj); String(_, func_name); _] - when not (IdSet.mem obj ids) -> - (* obj is not used *) - true - | _ -> false - -let useless_obj_set obj field ids : bool = - match obj, field with - | Id(_, "%global"), String(_, fld) - when not (IdSet.mem fld ids) -> - (* always special case the obj field of %global, because it is actually a def point *) - true - | Id (_, o), String(_,_) - when not (IdSet.mem o ids) -> - (* in env, if the object is not used(directly or indirectly) in user code, we can clean it *) - true - | _ -> false - -(* eliminate unused ids in environment *) -(* todo: this function should be applied in preprocess function *) -let env_clean (exp : exp) : exp = - let bindings = collect_env_bindings exp (Hashtbl.create 1000) in - (*Hashtbl.iter (fun k v->dprint_string (sprintf "%s -> %s" k (EU.ljs_str v))) bindings; - dprint_string "--end bindings--\n";*) - let rec env_clean_rec (e : exp) (ids : IdSet.t) : (exp * IdSet.t) = - let rec handle_option (opt : exp option) ids: exp option * IdSet.t = - match opt with - | Some (e) -> - let new_e, new_ids = env_clean_rec e ids in - Some (new_e), new_ids - | None -> None, ids - in - match e with - | Let (p, "%context", Id(p1, ctx), body) - when ctx = "%strictContext" || ctx = "%nonstrictContext" -> - (* below is user code, collect user code ids *) - dprint_string "------- user code ids ------ \n"; - dprint_set (user_code_ids e); - dprint_string "------- end user code ids ----\n"; - e, user_code_ids e - | Null _ - | Undefined _ - | String (_,_) - | Num (_,_) - | True _ - | False _ -> e, ids - | Id (_,id) -> - (* if we are visiting an id like %StringProto, we need to visit the id's value - add ids in that value *) - let more_ids = id_dependencies id bindings in - dprint "visit '%s' related id: \n" id; dprint_set more_ids; - dprint_string "current id set:\n"; dprint_set (IdSet.union more_ids ids); - e, IdSet.union more_ids ids - | Object (p, attrs, strprop) -> - let primval, ids = handle_option attrs.primval ids in - let code, ids = handle_option attrs.code ids in - let proto, ids = handle_option attrs.proto ids in - let new_attrs = { primval = primval; code = code; - proto = proto; klass = attrs.klass; - extensible = attrs.extensible } in - let handle_prop (p : 'a) ids : ('a * IdSet.t) = match p with - | (s, Data(data, enum, config)) -> - let value, ids = env_clean_rec data.value ids in - (s, Data({value = value; writable = data.writable}, - enum, config)), ids - | (s, Accessor (acc, enum, config)) -> - let getter, ids = env_clean_rec acc.getter ids in - let setter, ids = env_clean_rec acc.setter ids in - (s, Accessor ({getter = getter; setter = setter}, - enum, config)), ids - in - let rec handle_prop_list strprops ids = match strprops with - | [] -> strprops, ids - | fst :: rest -> - let p, ids = handle_prop fst ids in - let rest_p, rest_ids = handle_prop_list rest ids in - p :: rest_p, rest_ids - in - let prop_list, ids = handle_prop_list strprop ids in - Object (p, new_attrs, prop_list), ids - | GetAttr (p, pattr, obj, field) -> - let o, ids = env_clean_rec obj ids in - let fld, ids = env_clean_rec field ids in - GetAttr (p, pattr, o, fld), ids - - | SetAttr (p, attr, obj, field, newval) -> - if useless_obj_set obj field ids then begin - dprint "clean SetAttr: %s\n" (EU.ljs_str e); - Undefined Pos.dummy, ids - end else - let o, ids = env_clean_rec obj ids in - let f, ids = env_clean_rec field ids in - let v, ids = env_clean_rec newval ids in - SetAttr (p, attr, o, f, v), ids - - | GetObjAttr (p, oattr, obj) -> - let o, ids = env_clean_rec obj ids in - GetObjAttr(p, oattr, o), ids - - | SetObjAttr (p, oattr, obj, attre) -> - (* todo *) - let o, ids = env_clean_rec obj ids in - let attr, ids = env_clean_rec attre ids in - SetObjAttr (p, oattr, o, attr), ids - - | GetField (p, obj, fld, args) -> - let o, ids = env_clean_rec obj ids in - let f, ids = env_clean_rec fld ids in - let a, ids = env_clean_rec args ids in - let ids = match obj, fld with - | Id (_, "%context"), String (_, id) -> - (dprint "add %s\n" id; IdSet.add id ids) - | _ -> ids - in - GetField (p, o, f, a), ids - - | SetField (p, obj, fld, newval, args) -> - (* %StringProto["slice" = %stringSlice] => check whether slice is used because slice is one field of one prototype - %stringSlice["length" = 2] => check whether %stringSlice is used, it is not a prototype - *) - if useless_obj_set obj fld ids then begin - dprint "clean SetField: %s\n" (EU.ljs_str e); - Undefined Pos.dummy, ids - end - else - let o, ids = env_clean_rec obj ids in - let f, ids = env_clean_rec fld ids in - let v, ids = env_clean_rec newval ids in - let a, ids = env_clean_rec args ids in - SetField (p, o, f, v, a), ids - - | DeleteField (p, obj, fld) -> - let o, ids = env_clean_rec obj ids in - let f, ids = env_clean_rec fld ids in - DeleteField (p, o, f), ids - - | OwnFieldNames (p, obj) -> - let o, ids = env_clean_rec obj ids in - OwnFieldNames (p, o), ids - - | SetBang (p, x, x_v) -> - let x_v, ids = env_clean_rec x_v ids in - let ids = IdSet.add x ids in - dprint "add %s\n" x; - SetBang (p, x, x_v), ids - - | Op1 (p, op, e) -> - let e, ids = env_clean_rec e ids in - Op1 (p, op, e), ids - - | Op2 (p, op, e1, e2) -> - let e1, ids = env_clean_rec e1 ids in - let e2, ids = env_clean_rec e2 ids in - Op2 (p, op, e1, e2), ids - - | If (p, cond, thn, els) -> (* more optimization in constant folding *) - let cond, ids = env_clean_rec cond ids in - let thn, ids = env_clean_rec thn ids in - let els, ids = env_clean_rec els ids in - If (p, cond, thn, els), ids - - | App (p, f, args) -> - if useless_def_point f args ids then begin - dprint "clean app: %s\n" (EU.ljs_str e); - Undefined Pos.dummy, ids - end else - let f, ids = env_clean_rec f ids in - let rec handle_args args ids = match args with - | [] -> args, ids - | fst :: rest -> - let v, new_ids = env_clean_rec fst ids in - let rest_v, rest_ids = handle_args rest new_ids in - v :: rest_v, rest_ids - in - let args, ids = handle_args args ids in - App (p, f, args), ids - - | Seq (p, e1, e2) -> - let new_e2, e2_ids = env_clean_rec e2 ids in - let new_e1, e1_ids = env_clean_rec e1 e2_ids in - let e1_is_lambda = match new_e1 with Lambda (_,_,_) -> true | _ -> false in - if e1_is_lambda || not (EU.has_side_effect new_e1) then - new_e2, e2_ids - else - Seq (p, new_e1, new_e2), IdSet.union e1_ids e2_ids - - | Let (p, x, x_v, body) -> - let new_body, body_ids = env_clean_rec body ids in - if not (IdSet.mem x body_ids) - then begin - (*printf "not include [%s] collect ids:" x; - IdSet.iter (fun s->printf "%s," s) body_ids; print_newline();*) - new_body, body_ids - end else - (*let new_x_v, v_ids = env_clean_rec x_v IdSet.empty in*) - let xv_used_id = free_vars x_v in - let v_ids = IdSet.unions (map (fun i->id_dependencies i bindings) - (IdSet.elements xv_used_id)) in - let new_ids = IdSet.union (IdSet.remove x body_ids) v_ids in - (*printf "include [%s]. collect ids:" x; - IdSet.iter (fun s->printf "%s," s) new_ids; print_newline();*) - Let (p, x, x_v, new_body), new_ids - - | Rec (p, x, lambda, body) -> - let new_body, body_ids = env_clean_rec body ids in - if not (IdSet.mem x body_ids) then - new_body, body_ids - else - (* x is recursive function def, so remove x from lambda's ids *) - let lambda_ids = IdSet.remove x (free_vars lambda) in - let v_ids = IdSet.unions (map (fun i->id_dependencies i bindings) - (IdSet.elements lambda_ids)) in - let new_ids = IdSet.union (IdSet.remove x body_ids) v_ids in - Rec (p, x, lambda, new_body), new_ids - - | Label (p, l, e) -> - let new_e, ids = env_clean_rec e ids in - Label (p, l, new_e), ids - - | Break (p, l, e) -> - let new_e, ids = env_clean_rec e ids in - Break (p, l, new_e), ids - - | TryCatch (p, body, catch) -> - let b, ids = env_clean_rec body ids in - let c, ids = env_clean_rec catch ids in - TryCatch (p, b, c), ids - - | TryFinally (p, body, fin) -> - let b, ids = env_clean_rec body ids in - let f, ids = env_clean_rec fin ids in - TryFinally (p, b, f), ids - - | Throw (p, e) -> - let e, ids = env_clean_rec e ids in - Throw(p, e), ids - - | Lambda (p, xs, body) -> - let freevars = free_vars e in - let new_body, _ = env_clean_rec body ids in - Lambda (p, xs, new_body), IdSet.union freevars ids - - | Hint (p, id, e) -> - let new_e, ids = env_clean_rec e ids in - Hint (p, id, new_e), ids - - in - let new_exp, new_ids = env_clean_rec exp IdSet.empty in - new_exp diff --git a/src/optimization/ljs_const_folding.ml b/src/optimization/ljs_fold_const.ml similarity index 78% rename from src/optimization/ljs_const_folding.ml rename to src/optimization/ljs_fold_const.ml index 5bf53397..d86148d4 100644 --- a/src/optimization/ljs_const_folding.ml +++ b/src/optimization/ljs_fold_const.ml @@ -16,10 +16,10 @@ module EU = Exp_util * return new exp in option on success, None otherwise. * Note: the e should be a simplified exp. *) -let const_folding_op1 (p : Pos.t) (op : string) (e : exp) : exp option = +let fold_const_op1 (p : Pos.t) (op : string) (e : exp) : exp option = EU.apply_op1 p op e -let const_folding_op2 (p : Pos.t) (op : string) (e1 : exp) (e2 : exp) : exp option = +let fold_const_op2 (p : Pos.t) (op : string) (e1 : exp) (e2 : exp) : exp option = EU.apply_op2 p op e1 e2 (* function for extracting property of one field *) @@ -61,7 +61,7 @@ let rec get_obj_field (obj : exp) (name : string) (look_proto: bool) : prop opti will do that. *) -let const_folding_getattr pos pattr obj field : exp = +let fold_const_getattr pos pattr obj field : exp = let exp_bool (b : bool) : exp = match b with | true -> True pos | false -> False pos in @@ -87,7 +87,7 @@ let const_folding_getattr pos pattr obj field : exp = 1. o is Object and 2. TODO: o does not have side effect *) -let const_folding_getobjattr pos (oattr : oattr) o : exp = +let fold_const_getobjattr pos (oattr : oattr) o : exp = match oattr, o with | Klass, Object (_, {klass=klass}, _) -> String (pos, klass) | Code, Object (_, {code=None}, _) -> Null pos @@ -102,7 +102,7 @@ let const_folding_getobjattr pos (oattr : oattr) o : exp = | _ -> GetObjAttr(pos, oattr, o) -let rec const_folding_getfield pos o f a = +let rec fold_const_getfield pos o f a = match o, f with | Object (_, attr, strprop), String (_, fld) -> begin @@ -114,7 +114,7 @@ let rec const_folding_getfield pos o f a = | {proto=Some proto} -> begin match proto with - | Object (_,_,_) -> const_folding_getfield pos proto f a + | Object (_,_,_) -> fold_const_getfield pos proto f a | _ -> Undefined pos end | _ -> Undefined pos @@ -127,10 +127,10 @@ let rec const_folding_getfield pos o f a = type env = exp IdMap.t -let rec const_folding_app pos lambda args = +let rec fold_const_app pos lambda args = Null pos -let rec const_folding (e : exp) : exp = +let rec fold_const (e : exp) : exp = match e with | Undefined _ | Null _ @@ -141,32 +141,32 @@ let rec const_folding (e : exp) : exp = | Id (_, _) -> e | GetAttr (p, pattr, obj, field) -> - let o = const_folding obj in - let f = const_folding field in + let o = fold_const obj in + let f = fold_const field in if EU.valid_for_folding o && EU.valid_for_folding f then - const_folding_getattr p pattr o f + fold_const_getattr p pattr o f else GetAttr (p, pattr, o, f) | GetObjAttr (p, oattr, obj) -> - let o = const_folding obj in + let o = fold_const obj in if EU.valid_for_folding o then - const_folding_getobjattr p oattr o + fold_const_getobjattr p oattr o else GetObjAttr (p, oattr, o) | GetField (pos, obj, fld, args) -> - let o = const_folding obj in - let f = const_folding fld in - let a = const_folding args in + let o = fold_const obj in + let f = fold_const fld in + let a = fold_const args in if EU.valid_for_folding o && EU.valid_for_folding f then - const_folding_getfield pos o f a + fold_const_getfield pos o f a else GetField (pos, o, f, a) | Op1 (p, op, e) -> - let newe = const_folding e in - let v = const_folding_op1 p op newe in + let newe = fold_const e in + let v = fold_const_op1 p op newe in begin try match v with @@ -175,9 +175,9 @@ let rec const_folding (e : exp) : exp = with _ -> Op1 (p, op, newe) end | Op2 (p, op, e1, e2) -> - let newe1 = const_folding e1 in - let newe2 = const_folding e2 in - let v = const_folding_op2 p op newe1 newe2 in + let newe1 = fold_const e1 in + let newe2 = fold_const e2 in + let v = fold_const_op2 p op newe1 newe2 in begin try match v with @@ -186,43 +186,43 @@ let rec const_folding (e : exp) : exp = with _ -> Op2 (p, op, newe1, newe2) end | If (p, cond, thn, els) -> - let c_val = const_folding cond in + let c_val = fold_const cond in begin match c_val with - | True _ -> const_folding thn + | True _ -> fold_const thn | False _ | Null _ | Undefined _ | Num (_,_) | String (_,_) | Lambda (_,_,_) - | Object (_,_,_) -> const_folding els + | Object (_,_,_) -> fold_const els | _ -> begin - let t = const_folding thn in - let e = const_folding els in + let t = fold_const thn in + let e = fold_const els in If (p, c_val, t, e) end end | App (p, func, args) -> - let f = const_folding func in - let args = List.map const_folding args in + let f = fold_const func in + let args = List.map fold_const args in if EU.valid_for_folding f && (List.for_all EU.valid_for_folding args) then - const_folding_app p f args + fold_const_app p f args else App (p, f, args) | Label (p,l,lbody) -> begin match lbody with | Break (_, l', brk) -> - if l = l' then const_folding brk - else Label (p, l, const_folding lbody) - | _ -> Label (p, l, const_folding lbody) + if l = l' then fold_const brk + else Label (p, l, fold_const lbody) + | _ -> Label (p, l, fold_const lbody) end | TryCatch (p,t,c) -> if EU.valid_for_folding t then - const_folding t + fold_const t else - TryCatch (p, const_folding t, const_folding c) + TryCatch (p, fold_const t, fold_const c) | Object (_,_,_) | SetAttr (_,_,_,_,_) | SetObjAttr (_,_,_,_) @@ -238,5 +238,5 @@ let rec const_folding (e : exp) : exp = | TryFinally (_,_,_) | Throw (_,_) | Hint (_,_,_) - -> optimize const_folding e + -> optimize fold_const e diff --git a/src/optimization/ljs_type_infer.ml b/src/optimization/ljs_infer_types.ml similarity index 80% rename from src/optimization/ljs_type_infer.ml rename to src/optimization/ljs_infer_types.ml index 04e90ad5..f2f09aeb 100644 --- a/src/optimization/ljs_type_infer.ml +++ b/src/optimization/ljs_infer_types.ml @@ -55,30 +55,30 @@ let op1 p op arg env : exp = match op with 3. PropAccessorCheck 4. ToObject *) -let type_infer (exp : exp) : exp = - let rec clean_rec (exp : exp) (env : env) : exp = - let clean e = clean_rec e env in +let infer_types (exp : exp) : exp = + let rec infer_rec (exp : exp) (env : env) : exp = + let infer e = infer_rec e env in match exp with | Op1 (p, op, arg) -> - let arg = clean_rec arg env in + let arg = infer_rec arg env in op1 p op arg env | Let (p, x, x_v, body) -> - let x_v = clean_rec x_v env in + let x_v = infer_rec x_v env in if (EU.same_Id x x_v) then - clean_rec body env + infer_rec body env else if (EU.mutate_var x body) then let env = IdMap.remove x env in - Let (p, x, x_v, clean_rec body env) + Let (p, x, x_v, infer_rec body env) else let env = IdMap.add x x_v env in - Let (p, x, x_v, clean_rec body env) + Let (p, x, x_v, infer_rec body env) | Lambda (p, xs, body) -> let env = IdMap.filter (fun k _->not (List.mem k xs)) env in - let body = clean_rec body env in + let body = infer_rec body env in Lambda (p, xs, body) | App (p, f, args) -> - let f = clean_rec f env in - let args = List.map clean args in + let f = infer_rec f env in + let args = List.map infer args in begin match f, args with | Id (_, "%ToObject"), [e] -> begin match get_type e env with @@ -98,19 +98,19 @@ let type_infer (exp : exp) : exp = | Some (String (_, "Undefined")) -> App(p, f, args) | Some (_) -> (* make it a ToObject expression *) let new_app = App (p, Id(p0, "%ToObject"), [e]) in - clean_rec new_app env + infer_rec new_app env | None -> App (p, f, args) end | _ -> App (p, f, args) end | If (p, tst, thn, els) -> - let tst = clean_rec tst env in + let tst = infer_rec tst env in begin match tst with - | True _ -> clean_rec thn env - | False _ -> clean_rec els env + | True _ -> infer_rec thn env + | False _ -> infer_rec els env | _ -> - If (p, tst, clean_rec thn env, clean_rec els env) + If (p, tst, infer_rec thn env, infer_rec els env) end - | _ -> optimize clean exp + | _ -> optimize infer exp in - clean_rec exp IdMap.empty + infer_rec exp IdMap.empty diff --git a/src/optimization/ljs_function_inlining.ml b/src/optimization/ljs_inline_function.ml similarity index 99% rename from src/optimization/ljs_function_inlining.ml rename to src/optimization/ljs_inline_function.ml index ba54967c..224f34b8 100644 --- a/src/optimization/ljs_function_inlining.ml +++ b/src/optimization/ljs_inline_function.ml @@ -91,7 +91,7 @@ inline a function when 1. lambda that has no free variables and has no side effect in the body 2. function application's argument should be constants or `id`. *) -let rec function_inlining (e : exp) : exp = +let rec inline_function (e : exp) : exp = let empty_env = IdMap.empty in let rec inlining_rec e env = match e with diff --git a/src/optimization/ljs_const_propagation.ml b/src/optimization/ljs_propagate_const.ml similarity index 89% rename from src/optimization/ljs_const_propagation.ml rename to src/optimization/ljs_propagate_const.ml index fb174cf7..8a922896 100644 --- a/src/optimization/ljs_const_propagation.ml +++ b/src/optimization/ljs_propagate_const.ml @@ -74,10 +74,10 @@ let get_subst (e : exp) (env : env) : bool = match e with end | _ -> false -let rec const_propagation (e : exp) : exp = +let rec propagate_const (e : exp) : exp = let empty_env = IdMap.empty in - let rec propagation_rec (e : exp) (env : env) : exp = - let propagate exp = propagation_rec exp env in + let rec propagate_rec (e : exp) (env : env) : exp = + let propagate exp = propagate_rec exp env in match e with | Undefined _ | Null _ @@ -93,7 +93,7 @@ let rec const_propagation (e : exp) : exp = with _ -> e end | Let (p, x, x_v, body) -> - let x_v = propagation_rec x_v env in + let x_v = propagate_rec x_v env in let is_const = is_constant x_v env in let rec decide_subst e env : bool = if is_prim_constant e || @@ -112,27 +112,27 @@ let rec const_propagation (e : exp) : exp = (* if x will be mutated or x_v is not constant *) if EU.mutate_var x body || not is_const then let env = IdMap.remove x env in - Let (p,x,x_v, propagation_rec body env) + Let (p,x,x_v, propagate_rec body env) else let substitute = decide_subst x_v env in let env = IdMap.add x (x_v, substitute) env in - Let (p, x, x_v, propagation_rec body env) + Let (p, x, x_v, propagate_rec body env) | Rec (p, x, x_v, body) -> - let x_v = propagation_rec x_v (IdMap.remove x env) in + let x_v = propagate_rec x_v (IdMap.remove x env) in let is_const = is_constant x_v env in (* if x will be mutated or x_v is not constant *) if EU.mutate_var x body || not is_const then let env = IdMap.remove x env in - Rec (p,x,x_v, propagation_rec body env) + Rec (p,x,x_v, propagate_rec body env) else let substitute = not (EU.multiple_usages x body) in let env = IdMap.add x (x_v, substitute) env in - Rec (p, x, x_v, propagation_rec body env) + Rec (p, x, x_v, propagate_rec body env) | Lambda (p, xs, body) -> (* remove each x in xs from env *) let filtered_env = IdMap.filter (fun x _->not (List.mem x xs) ) env in - Lambda (p, xs, propagation_rec body filtered_env) + Lambda (p, xs, propagate_rec body filtered_env) | Object (_, _, _) | GetAttr (_, _, _, _) | SetAttr (_, _, _, _, _) @@ -154,4 +154,4 @@ let rec const_propagation (e : exp) : exp = | TryFinally (_,_,_) | Throw (_,_) | Hint (_,_,_) -> optimize propagate e in - propagation_rec e empty_env + propagate_rec e empty_env diff --git a/src/optimization/ljs_alias_propagation.ml b/src/optimization/ljs_propagate_copy.ml similarity index 80% rename from src/optimization/ljs_alias_propagation.ml rename to src/optimization/ljs_propagate_copy.ml index 17786b4a..d4287167 100644 --- a/src/optimization/ljs_alias_propagation.ml +++ b/src/optimization/ljs_propagate_copy.ml @@ -14,9 +14,9 @@ let remove_id_value (id : id) (env : env) : env = in IdMap.filter (fun _ v->not_the_id id v) env -let alias_propagation (e : exp) : exp = - let rec propagation_rec (e : exp) (env : env) : exp = - let propagate (e : exp) = propagation_rec e env in +let propagate_copy (e : exp) : exp = + let rec propagate_rec (e : exp) (env : env) : exp = + let propagate (e : exp) = propagate_rec e env in match e with | Undefined _ | Null _ @@ -26,7 +26,7 @@ let alias_propagation (e : exp) : exp = | False _ -> e | Id (_, id) -> begin try IdMap.find id env with _ -> e end | Let (p, x, xexp, body) -> - let x_v = propagation_rec xexp env in + let x_v = propagate_rec xexp env in (* env should change: 1. anything maps to x should be removed from env; 2. anything that x maps to in env should be removed. @@ -39,24 +39,24 @@ let alias_propagation (e : exp) : exp = | Id (_, v_id) -> (* if x, or v_id gets mutated in body, x should not be replaced with v_id in body *) if EU.mutate_var x body || EU.mutate_var v_id body then - Let (p, x, x_v, propagation_rec body env) + Let (p, x, x_v, propagate_rec body env) else let env = IdMap.add x x_v env in - Let (p, x, x_v, propagation_rec body env) - | _ -> Let (p, x, x_v, propagation_rec body env) + Let (p, x, x_v, propagate_rec body env) + | _ -> Let (p, x, x_v, propagate_rec body env) end | Rec (p, x, xexp, body) -> let env = IdMap.remove x env in - let x_v = propagation_rec xexp env in + let x_v = propagate_rec xexp env in let env = remove_id_value x env in - Rec (p, x, x_v, propagation_rec body env) + Rec (p, x, x_v, propagate_rec body env) | Lambda (p,xs,body) -> let rec remove_list (lst : id list) env = match lst with | [] -> env | fst :: rest -> remove_list rest (remove_id_value fst env) in let env = remove_list xs env in let env = IdMap.filter (fun var _->not (List.mem var xs)) env in - Lambda (p, xs, propagation_rec body env) + Lambda (p, xs, propagate_rec body env) | Object (_,_,_) | GetAttr (_, _, _, _) | GetObjAttr (_, _, _) @@ -81,4 +81,4 @@ let alias_propagation (e : exp) : exp = -> optimize propagate e in - propagation_rec e IdMap.empty + propagate_rec e IdMap.empty diff --git a/src/optimization/ljs_preprocess.ml b/src/optimization/ljs_restore_id.ml similarity index 93% rename from src/optimization/ljs_preprocess.ml rename to src/optimization/ljs_restore_id.ml index cc4672a0..bb2c1847 100644 --- a/src/optimization/ljs_preprocess.ml +++ b/src/optimization/ljs_restore_id.ml @@ -30,9 +30,9 @@ type env = exp IdMap.t let debug_on = false -let dprint, dprint_string, dprint_ljs = Debug.make_debug_printer ~on:debug_on "preprocess" +let dprint, dprint_string, dprint_ljs = Debug.make_debug_printer ~on:debug_on "restore" -(* only apply the preprocess on code that is in strict mode *) +(* only apply the restore on code that is in strict mode *) let only_strict = false let create_global_bindings () = @@ -274,7 +274,7 @@ let rec window_free ?(toplevel=true) exp : bool = | _ -> List.for_all (fun e -> window_free ~toplevel e) (child_exps exp) *) -let rec eligible_for_preprocess exp : bool = +let rec eligible_for_restore exp : bool = let is_static_field fld = match fld with | String (_, _) -> true | _ -> @@ -402,8 +402,8 @@ let make_writable_error (msg : string) : exp = let msg = msg ^ " not writable" in App (Pos.dummy, Id(Pos.dummy, "%TypeError"), [String (Pos.dummy, msg)]) -let rec preprocess (e : exp) : exp = - let rec preprocess_rec ?(in_lambda=false) (e : exp) (ctx : env) : exp = +let rec restore_id (e : exp) : exp = + let rec restore_rec ?(in_lambda=false) (e : exp) (ctx : env) : exp = match e with | Seq (p, e1, e2) -> (match e1 with @@ -417,22 +417,22 @@ let rec preprocess (e : exp) : exp = IdMap.add id (IdMap.find id global_bindings) ctx else IdMap.add id (Undefined Pos.dummy) ctx in - let newe2 = preprocess_rec ~in_lambda e2 ctx in + let newe2 = restore_rec ~in_lambda e2 ctx in Let (p, id, Undefined Pos.dummy, newe2) | App (_, Id (_, "%defineGlobalAccessors"), [Id(_, "%context"); String (_, id)]) when (IdMap.mem id global_bindings) -> dprint "find defineGlobalAccessor %s in %%global bindings\n" id; let id_v = IdMap.find id global_bindings in let ctx = IdMap.add id id_v ctx in - preprocess_rec ~in_lambda e2 ctx + restore_rec ~in_lambda e2 ctx | _ -> - let newe1 = preprocess_rec ~in_lambda e1 ctx in - let newe2 = preprocess_rec ~in_lambda e2 ctx in + let newe1 = restore_rec ~in_lambda e1 ctx in + let newe2 = restore_rec ~in_lambda e2 ctx in Seq (p, newe1, newe2)) | GetField (pos, obj, fld, args) -> - let o = preprocess_rec ~in_lambda obj ctx in - let f = preprocess_rec ~in_lambda fld ctx in - let a = preprocess_rec ~in_lambda args ctx in + let o = restore_rec ~in_lambda obj ctx in + let f = restore_rec ~in_lambda fld ctx in + let a = restore_rec ~in_lambda args ctx in (match o, f with | Id (_, "%context"), String (_, fldstr) -> (* get fld from context *) (*printf "match context['%s']\n%!" fldstr; @@ -452,10 +452,10 @@ let rec preprocess (e : exp) : exp = | _ -> GetField (pos, o, f, a) ) | SetField (pos, obj, fld, newval, args) -> - let o = preprocess_rec ~in_lambda obj ctx in - let f = preprocess_rec ~in_lambda fld ctx in - let v = preprocess_rec ~in_lambda newval ctx in - let a = preprocess_rec ~in_lambda args ctx in + let o = restore_rec ~in_lambda obj ctx in + let f = restore_rec ~in_lambda fld ctx in + let v = restore_rec ~in_lambda newval ctx in + let a = restore_rec ~in_lambda args ctx in (match o, f with | Id (_, "%context"), String (_, fldstr) -> (try match IdMap.find fldstr ctx with @@ -469,8 +469,8 @@ let rec preprocess (e : exp) : exp = | _ -> SetField (pos, o, f, v, a) ) | App (pos, f, args) -> - let f = preprocess_rec ~in_lambda f ctx in - let args = List.map (fun x->preprocess_rec ~in_lambda x ctx) args in + let f = restore_rec ~in_lambda f ctx in + let args = List.map (fun x->restore_rec ~in_lambda x ctx) args in (match f, args with | Id (_, "%EnvCheckAssign"), [Id (_, "%context"); String (_, id); v; _] -> (try match IdMap.find id ctx with @@ -490,7 +490,7 @@ let rec preprocess (e : exp) : exp = Id (pos, "%context") | Id (p1, "%set-property"), [Id (p2, "%context"); String (p3, id); v] -> let newexp = SetField (p1, Id(p2, "%context"), String(p3,id), v, Null Pos.dummy) in - (match preprocess_rec ~in_lambda newexp ctx with + (match restore_rec ~in_lambda newexp ctx with | SetField(_,_,_,_,_) -> (* cannot translate, use the original set-property exp *) App (pos, f, args) @@ -526,26 +526,26 @@ let rec preprocess (e : exp) : exp = | _ -> App (pos, f, args) ) | Let (p, x, x_v, body) -> - let x_v = preprocess_rec ~in_lambda x_v ctx in + let x_v = restore_rec ~in_lambda x_v ctx in (* first match with context patterns in lambda *) begin match get_localcontext e with | None -> (* not a new context binding in lambda *) (* in the desugared code, there is no place to bind %context to a non-obj *) assert (x <> "%context"); - Let (p, x, x_v, preprocess_rec ~in_lambda body ctx) + Let (p, x, x_v, restore_rec ~in_lambda body ctx) | Some (new_let) -> (* FIXME: 12.14-1 *) dprint "new_let is %s\n" (Exp_util.ljs_str new_let); (try let new_ctx = recognize_new_context x_v ctx in - replace_let_body new_let (preprocess_rec ~in_lambda body new_ctx) + replace_let_body new_let (restore_rec ~in_lambda body new_ctx) with Failure msg -> (printf "oops, pattern error: %s\n%!" msg; - Let (p, x, x_v, preprocess_rec ~in_lambda body ctx) + Let (p, x, x_v, restore_rec ~in_lambda body ctx) ) ) end | Lambda (p, xs, body) -> - let result = preprocess_rec ~in_lambda:true body ctx in + let result = restore_rec ~in_lambda:true body ctx in Lambda (p, xs, result) | Undefined _ | Null _ @@ -572,26 +572,26 @@ let rec preprocess (e : exp) : exp = | TryFinally (_,_,_) | Throw (_,_) | Hint (_,_,_) - -> optimize (fun e->preprocess_rec ~in_lambda e ctx) e + -> optimize (fun e->restore_rec ~in_lambda e ctx) e in let rec jump_env (e : exp) : exp = match e with | Let (p, "%context", Id (p1, c), body) -> if (only_strict && c = "%strictContext") || (not only_strict) then begin - if eligible_for_preprocess e then + if eligible_for_restore e then begin let env = IdMap.empty in - dprint_string "eligible for preprocess, start preprocessing...\n"; - let newbody = preprocess_rec body env in + dprint_string "eligible for restore, start restore...\n"; + let newbody = restore_rec body env in Let (p, "%context", Id (p1, c), newbody) end else - (dprint_string "not eligible for preprocess, return original one\n"; + (dprint_string "not eligible for restore, return original one\n"; e) end else begin - dprint_string "find nonstrict context. not eligible for preprocessing...\n"; + dprint_string "find nonstrict context. not eligible for restore...\n"; e end | _ -> optimize jump_env e diff --git a/src/optimization/test/less_mutation_test.ml b/src/optimization/test/convert_assignment_test.ml similarity index 98% rename from src/optimization/test/less_mutation_test.ml rename to src/optimization/test/convert_assignment_test.ml index 2ea3ef8d..894ecca4 100644 --- a/src/optimization/test/less_mutation_test.ml +++ b/src/optimization/test/convert_assignment_test.ml @@ -1,11 +1,11 @@ open Prelude open Util open OUnit2 -open Ljs_less_mutation +open Ljs_convert_assignment let suite = - let cmp before after = cmp before less_mutation after in - let no_change code = no_change code less_mutation in + let cmp before after = cmp before convert_assignment after in + let no_change code = no_change code convert_assignment in "Test Less Mutation" >::: [ "transform SetBang to Let" >:: diff --git a/src/optimization/test/deadcode_elimination_test.ml b/src/optimization/test/eliminate_deadcode_test.ml similarity index 97% rename from src/optimization/test/deadcode_elimination_test.ml rename to src/optimization/test/eliminate_deadcode_test.ml index 537dabc7..d320841c 100644 --- a/src/optimization/test/deadcode_elimination_test.ml +++ b/src/optimization/test/eliminate_deadcode_test.ml @@ -1,13 +1,13 @@ open Prelude open Util open OUnit2 -open Ljs_deadcode_elimination +open Ljs_eliminate_deadcode module S = Ljs_syntax let unused_id_test = - let cmp before after = cmp before deadcode_elimination after in - let no_change code = no_change code deadcode_elimination in + let cmp before after = cmp before eliminate_deadcode after in + let no_change code = no_change code eliminate_deadcode in "Test Unused Id Elimination" >::: ["unused at all" >:: (cmp "let (x=1) diff --git a/src/optimization/test/const_folding_test.ml b/src/optimization/test/fold_const_test.ml similarity index 96% rename from src/optimization/test/const_folding_test.ml rename to src/optimization/test/fold_const_test.ml index 020a71d6..9e0790ce 100644 --- a/src/optimization/test/const_folding_test.ml +++ b/src/optimization/test/fold_const_test.ml @@ -1,11 +1,11 @@ open Prelude open Util open OUnit2 -open Ljs_const_folding +open Ljs_fold_const let suite = - let cmp before after = cmp before const_folding after in - let no_change code = no_change code const_folding in + let cmp before after = cmp before fold_const after in + let no_change code = no_change code fold_const in let obj = "{[#proto: null, #extensible: false, #class: 'Object'] 'fld1': {#value 1, #writable false}, 'fld2': {#getter func(this, arg) {1}, #setter func(t) {t}}}" diff --git a/src/optimization/test/type_infer_test.ml b/src/optimization/test/infer_types_test.ml similarity index 93% rename from src/optimization/test/type_infer_test.ml rename to src/optimization/test/infer_types_test.ml index 2f9ab910..8215f315 100644 --- a/src/optimization/test/type_infer_test.ml +++ b/src/optimization/test/infer_types_test.ml @@ -1,11 +1,11 @@ open Prelude open Util open OUnit2 -open Ljs_type_infer +open Ljs_infer_types let suite = - let cmp before after = cmp before type_infer after in - let no_change code = no_change code type_infer in + let cmp before after = cmp before infer_types after in + let no_change code = no_change code infer_types in "Test Type Infer" >::: [ "simple number" >:: diff --git a/src/optimization/test/function_inlining_test.ml b/src/optimization/test/inline_function_test.ml similarity index 98% rename from src/optimization/test/function_inlining_test.ml rename to src/optimization/test/inline_function_test.ml index b7a7de56..1e066a46 100644 --- a/src/optimization/test/function_inlining_test.ml +++ b/src/optimization/test/inline_function_test.ml @@ -1,11 +1,11 @@ open Prelude open Util open OUnit2 -open Ljs_function_inlining +open Ljs_inline_function let suite = - let cmp before after = cmp before function_inlining after in - let no_change code = no_change code function_inlining in + let cmp before after = cmp before inline_function after in + let no_change code = no_change code inline_function in "Test Function Inlining Test" >::: [ "inlining for prim arg" >:: diff --git a/src/optimization/test/const_propagation_test.ml b/src/optimization/test/propagate_const_test.ml similarity index 96% rename from src/optimization/test/const_propagation_test.ml rename to src/optimization/test/propagate_const_test.ml index 01170fa9..da687b7d 100644 --- a/src/optimization/test/const_propagation_test.ml +++ b/src/optimization/test/propagate_const_test.ml @@ -1,11 +1,11 @@ open Prelude open Util open OUnit2 -open Ljs_const_propagation +open Ljs_propagate_const let suite = - let cmp before after = cmp before const_propagation after in - let no_change code = no_change code const_propagation in + let cmp before after = cmp before propagate_const after in + let no_change code = no_change code propagate_const in "Test Const Propagation" >::: [ "propagate number" >:: diff --git a/src/optimization/test/alias_propagation_test.ml b/src/optimization/test/propagate_copy_test.ml similarity index 94% rename from src/optimization/test/alias_propagation_test.ml rename to src/optimization/test/propagate_copy_test.ml index faeb7d54..00c52bc3 100644 --- a/src/optimization/test/alias_propagation_test.ml +++ b/src/optimization/test/propagate_copy_test.ml @@ -1,11 +1,11 @@ open Prelude open Util open OUnit2 -open Ljs_alias_propagation +open Ljs_propagate_copy let suite = - let cmp before after = cmp before alias_propagation after in - let no_change code = no_change code alias_propagation in + let cmp before after = cmp before propagate_copy after in + let no_change code = no_change code propagate_copy in "Test Alias Elimination" >::: [ "simple" >:: diff --git a/src/optimization/test/preprocess_test.ml b/src/optimization/test/restore_id_test.ml similarity index 96% rename from src/optimization/test/preprocess_test.ml rename to src/optimization/test/restore_id_test.ml index 0568e964..7f8b4951 100644 --- a/src/optimization/test/preprocess_test.ml +++ b/src/optimization/test/restore_id_test.ml @@ -1,7 +1,7 @@ open Prelude open Util open OUnit2 -open Ljs_preprocess +open Ljs_restore_id open Sys let jsparser_path = "../tests/jsparser.sh" @@ -17,7 +17,7 @@ let suite = let eligible_test (jscode : string) (expected : bool) = fun test_ctx -> let s5code = desugar jscode in - assert_equal expected (eligible_for_preprocess s5code) + assert_equal expected (eligible_for_restore s5code) ~printer: (fun x -> if x then ("eligible:\n" ^ jscode) else ("not eligible:\n" ^ jscode)) in @@ -29,7 +29,7 @@ let suite = ~printer: (fun x -> if x then "window free" else "not window free") in let eq ?(nyi=false) (jscode : string) (expected : string) = - (* this function will first assert the code is eligible for preprocessing. + (* this function will first assert the code is eligible for restoreing. and evaluate the jscode and expected, and compare the result with that of expected *) fun text_ctx -> @@ -38,9 +38,9 @@ let suite = let es5env = Ljs.parse_es5_env (open_in "../envs/es5.env") "../envs/es5.env" in let s5code = desugar jscode in let s5expected = desugar expected in - assert_equal true (eligible_for_preprocess s5code) + assert_equal true (eligible_for_restore s5code) ~printer: (fun x -> if x then "eligible" else "not eligible"); - let s5value = Ljs_eval.eval_expr (es5env (preprocess s5code)) desugar true in + let s5value = Ljs_eval.eval_expr (es5env (restore_id s5code)) desugar true in let expectedv = Ljs_eval.eval_expr (es5env s5expected) desugar true in match s5value, expectedv with | Ljs_eval.Answer(_,value,_,_), Ljs_eval.Answer(_,value2,_,_) -> @@ -59,7 +59,7 @@ let suite = let not_eligible (jscode : string) = eligible_test jscode false in - "Test Preprocess" >::: + "Test Restore" >::: [ (* ------- test window free ------- *) "not window free: window reference" >:: @@ -290,9 +290,9 @@ let suite = "not eligible nonstrict mode is not eligible" >:: (fun ctx -> - skip_if (Ljs_preprocess.only_strict = false) "only strict mode is off"; + skip_if (Ljs_restore_id.only_strict = false) "only strict mode is off"; let s5code = desugar "var bar = 2; bar" in - assert_equal false (eligible_for_preprocess s5code)); + assert_equal false (eligible_for_restore s5code)); "not eligible nonstrict mode is not eligible" >:: (fun ctx -> @@ -300,7 +300,7 @@ let suite = let s5code = desugar "var f = function () {return 1} var o = {'v1' : this['f']()} o.v1" in - assert_equal true (eligible_for_preprocess s5code)); + assert_equal true (eligible_for_restore s5code)); "not eligible: computation string field" >:: @@ -361,7 +361,7 @@ let suite = foo"); (* todo: use arguments keyword *) - (* todo: make preprocess works over environment *) + (* todo: make restore works over environment *) "test this" >:: (eq "'use strict'; diff --git a/src/s5.ml b/src/s5.ml index c9e25d20..c60a51db 100644 --- a/src/s5.ml +++ b/src/s5.ml @@ -6,16 +6,15 @@ open Ljs_cesk open Ljs_syntax open Ljs_pretty_html open Reachability -open Ljs_const_folding -open Ljs_const_propagation -open Ljs_deadcode_elimination -open Ljs_alias_propagation -open Ljs_function_inlining -open Ljs_preprocess -open Ljs_env_clean -open Ljs_new_env_clean -open Ljs_type_infer -open Ljs_less_mutation +open Ljs_fold_const +open Ljs_propagate_const +open Ljs_eliminate_deadcode +open Ljs_propagate_copy +open Ljs_inline_function +open Ljs_restore_id +open Ljs_clean_env +open Ljs_infer_types +open Ljs_convert_assignment open Ljs_no_checks open Ljs_fixed_arity @@ -387,57 +386,52 @@ module S5 = struct (* optimization command *) - let opt_constant_folding cmd () = + let opt_fold_const cmd () = let ljs = pop_ljs cmd in - let new_ljs = const_folding ljs in + let new_ljs = fold_const ljs in push_ljs new_ljs (* print origin one for debug *) (*Ljs_pretty.exp ljs std_formatter; print_newline ()*) - let opt_const_propagation cmd () = + let opt_propagate_const cmd () = let ljs = pop_ljs cmd in - let new_ljs = const_propagation ljs in + let new_ljs = propagate_const ljs in push_ljs new_ljs - let opt_deadcode_elimination cmd () = + let opt_eliminate_deadcode cmd () = let ljs = pop_ljs cmd in - let new_ljs = deadcode_elimination ljs in + let new_ljs = eliminate_deadcode ljs in push_ljs new_ljs - let opt_alias_propagation cmd () = + let opt_propagate_copy cmd () = let ljs = pop_ljs cmd in - let new_ljs = alias_propagation ljs in + let new_ljs = propagate_copy ljs in push_ljs new_ljs - let opt_function_inlining cmd () = + let opt_inline_function cmd () = let ljs = pop_ljs cmd in - let new_ljs = function_inlining ljs in + let new_ljs = inline_function ljs in push_ljs new_ljs - let opt_preprocess cmd () = + let opt_restore_id cmd () = let ljs = pop_ljs cmd in - let new_ljs = preprocess ljs in + let new_ljs = restore_id ljs in push_ljs new_ljs - let opt_env_clean cmd () = + let opt_clean_env cmd () = let ljs = pop_ljs cmd in - let new_ljs = env_clean ljs in + let new_ljs = clean_env ljs in push_ljs new_ljs - let opt_new_env_clean cmd () = + let opt_infer_types cmd () = let ljs = pop_ljs cmd in - let new_ljs = new_env_clean ljs in + let new_ljs = infer_types ljs in push_ljs new_ljs - let opt_type_infer cmd () = + let opt_convert_assignment cmd () = let ljs = pop_ljs cmd in - let new_ljs = type_infer ljs in - push_ljs new_ljs - - let opt_less_mutation cmd () = - let ljs = pop_ljs cmd in - let new_ljs = less_mutation ljs in + let new_ljs = convert_assignment ljs in push_ljs new_ljs let opt_no_checks cmd () = @@ -598,30 +592,28 @@ module S5 = struct "marshal s5 code to file as sequence of bytes"; strCmd "-load-s5" load_s5 "load s5 from marshalled file that created by -save-s5(use -s5 to load text form of s5 code)"; - unitCmd "-opt-preprocess" opt_preprocess - "preprocess s5 code to make it more optimizable."; - unitCmd "-opt-const-folding" opt_constant_folding + unitCmd "-opt-restore-id" opt_restore_id + "restore JavaScript id in desugared S5"; + unitCmd "-opt-fold-const" opt_fold_const "perform constant folding on s5"; - unitCmd "-opt-const-propagation" opt_const_propagation + unitCmd "-opt-propagate-const" opt_propagate_const "perform constant propagation on s5"; - unitCmd "-opt-deadcode-elimination" opt_deadcode_elimination + unitCmd "-opt-eliminate-deadcode" opt_eliminate_deadcode "perform dead code elimination on s5"; - unitCmd "-opt-alias-propagation" opt_alias_propagation - "propagate alias on s5"; - unitCmd "-opt-function-inlining" opt_function_inlining + unitCmd "-opt-propagate-copy" opt_propagate_copy + "propagate copy (let bindings of an id to another id) on s5"; + unitCmd "-opt-inline-function" opt_inline_function "perform function inlining on s5"; - unitCmd "-opt-env-clean" opt_env_clean - "[obsolete] clean unused env expression"; - unitCmd "-opt-new-env-clean" opt_new_env_clean + unitCmd "-opt-clean-env" opt_clean_env "clean unused env expression"; - unitCmd "-opt-type-infer" opt_type_infer - "clean prim('typeof', obj)"; - unitCmd "-opt-less-mutation" opt_less_mutation - "convert mutation x:=1 to let bindings when possible"; + unitCmd "-opt-infer-types" opt_infer_types + "use type inference to safely clean static checks"; + unitCmd "-opt-convert-assignment" opt_convert_assignment + "convert assignment to let bindings when possible"; unitCmd "-opt-no-checks" opt_no_checks - "clean all static checks"; + "[semantics altering] clean all static checks"; unitCmd "-opt-fixed-arity" opt_fixed_arity - "disable variable function arity"; + "[semantics altering] disable variable function arity"; strCmd "-count-nodes" count_nodes "count the nodes of S5" ]