summaryrefslogtreecommitdiff
path: root/minijazz/src/analysis/simplify.ml
diff options
context:
space:
mode:
Diffstat (limited to 'minijazz/src/analysis/simplify.ml')
-rw-r--r--minijazz/src/analysis/simplify.ml42
1 files changed, 42 insertions, 0 deletions
diff --git a/minijazz/src/analysis/simplify.ml b/minijazz/src/analysis/simplify.ml
new file mode 100644
index 0000000..f7cbb5c
--- /dev/null
+++ b/minijazz/src/analysis/simplify.ml
@@ -0,0 +1,42 @@
+open Ast
+open Static
+
+let is_not_zero ty = match ty with
+ | TBitArray { se_desc = SInt 0 } -> false
+ | _ -> true
+
+let rec simplify_exp e = match e.e_desc with
+ (* replace x[i..j] with [] if j < i *)
+ | Ecall("slice",
+ [{ se_desc = SInt min };
+ { se_desc = SInt max }; n], _) when max < min ->
+ { e with e_desc = Econst (VBitArray (Array.make 0 false)) }
+ (* replace x[i..i] with x[i] *)
+ | Ecall("slice", [min; max; n], args) when min = max ->
+ let new_e = { e with e_desc = Ecall("select", [min; n], args) } in
+ simplify_exp new_e
+ (* replace x.[] or [].x with x *)
+ | Ecall("concat", _, [{ e_ty = TBitArray { se_desc = SInt 0 } }; e1])
+ | Ecall("concat", _, [e1; { e_ty = TBitArray { se_desc = SInt 0 } }]) ->
+ e1
+ | Ecall(f, params, args) ->
+ { e with e_desc = Ecall(f, params, List.map simplify_exp args) }
+ | _ -> e
+
+let simplify_eq (pat,e) =
+ (pat, simplify_exp e)
+
+let rec block b = match b with
+ | BEqs(eqs, vds) ->
+ let eqs = List.map simplify_eq eqs in
+ (* remove variables with size 0 *)
+ let vds = List.filter (fun vd -> is_not_zero vd.v_ty) vds in
+ let eqs = List.filter (fun (_, e) -> is_not_zero e.e_ty) eqs in
+ BEqs(eqs, vds)
+ | BIf(se, trueb, elseb) -> BIf(se, block trueb, block elseb)
+
+let node n =
+ { n with n_body = block n.n_body }
+
+let program p =
+ { p with p_nodes = List.map node p.p_nodes }