summaryrefslogtreecommitdiff
path: root/src/monomorphise.ml
diff options
context:
space:
mode:
Diffstat (limited to 'src/monomorphise.ml')
-rw-r--r--src/monomorphise.ml80
1 files changed, 54 insertions, 26 deletions
diff --git a/src/monomorphise.ml b/src/monomorphise.ml
index 4fa5d1d6..3ea156d0 100644
--- a/src/monomorphise.ml
+++ b/src/monomorphise.ml
@@ -54,8 +54,7 @@ open Ast_util
module Big_int = Nat_big_num
open Type_check
-let size_set_limit = 8
-let vector_split_limit = 4
+let size_set_limit = 16
let optmap v f =
match v with
@@ -1316,14 +1315,10 @@ let split_defs continue_anyway splits defs =
| Typ_app (Id_aux (Id "vector",_), [_;Typ_arg_aux (Typ_arg_nexp len,_);_;Typ_arg_aux (Typ_arg_typ (Typ_aux (Typ_id (Id_aux (Id "bit",_)),_)),_)]) ->
(match len with
| Nexp_aux (Nexp_constant sz,_) ->
- if Big_int.to_int sz <= vector_split_limit then
- let lits = make_vectors (Big_int.to_int sz) in
- List.map (fun lit ->
- P_aux (P_lit lit,(l,annot)),
- [var,E_aux (E_lit lit,(new_l,annot))]) lits
- else
- cannot ("Refusing to split vector type of length " ^ Big_int.to_string sz ^
- " (above limit " ^ string_of_int vector_split_limit ^ ")")
+ let lits = make_vectors (Big_int.to_int sz) in
+ List.map (fun lit ->
+ P_aux (P_lit lit,(l,annot)),
+ [var,E_aux (E_lit lit,(new_l,annot))]) lits
| _ ->
cannot ("length not constant, " ^ string_of_nexp len)
)
@@ -1494,6 +1489,19 @@ let split_defs continue_anyway splits defs =
in p
in
+ let check_split_size lst l =
+ let size = List.length lst in
+ if size > size_set_limit then
+ let open Reporting_basic in
+ let error =
+ Err_general (l, "Case split is too large (" ^ string_of_int size ^
+ " > limit " ^ string_of_int size_set_limit ^ ")")
+ in if continue_anyway
+ then (print_error error; false)
+ else raise (Fatal_error error)
+ else true
+ in
+
let rec map_exp ((E_aux (e,annot)) as ea) =
let re e = E_aux (e,annot) in
match e with
@@ -1556,13 +1564,16 @@ let split_defs continue_anyway splits defs =
FE_aux (FE_Fexp (id,map_exp e),annot)
and map_pexp = function
| Pat_aux (Pat_exp (p,e),l) ->
+ let nosplit = [Pat_aux (Pat_exp (p,map_exp e),l)] in
(match map_pat p with
- | NoSplit -> [Pat_aux (Pat_exp (p,map_exp e),l)]
+ | NoSplit -> nosplit
| VarSplit patsubsts ->
- List.map (fun (pat',substs) ->
- let exp' = subst_exp substs e in
- Pat_aux (Pat_exp (pat', map_exp exp'),l))
- patsubsts
+ if check_split_size patsubsts (pat_loc p) then
+ List.map (fun (pat',substs) ->
+ let exp' = subst_exp substs e in
+ Pat_aux (Pat_exp (pat', map_exp exp'),l))
+ patsubsts
+ else nosplit
| ConstrSplit patnsubsts ->
List.map (fun (pat',nsubst) ->
let pat' = nexp_subst_pat nsubst pat' in
@@ -1570,14 +1581,17 @@ let split_defs continue_anyway splits defs =
Pat_aux (Pat_exp (pat', map_exp exp'),l)
) patnsubsts)
| Pat_aux (Pat_when (p,e1,e2),l) ->
+ let nosplit = [Pat_aux (Pat_when (p,map_exp e1,map_exp e2),l)] in
(match map_pat p with
- | NoSplit -> [Pat_aux (Pat_when (p,map_exp e1,map_exp e2),l)]
+ | NoSplit -> nosplit
| VarSplit patsubsts ->
- List.map (fun (pat',substs) ->
- let exp1' = subst_exp substs e1 in
- let exp2' = subst_exp substs e2 in
- Pat_aux (Pat_when (pat', map_exp exp1', map_exp exp2'),l))
- patsubsts
+ if check_split_size patsubsts (pat_loc p) then
+ List.map (fun (pat',substs) ->
+ let exp1' = subst_exp substs e1 in
+ let exp2' = subst_exp substs e2 in
+ Pat_aux (Pat_when (pat', map_exp exp1', map_exp exp2'),l))
+ patsubsts
+ else nosplit
| ConstrSplit patnsubsts ->
List.map (fun (pat',nsubst) ->
let pat' = nexp_subst_pat nsubst pat' in
@@ -1770,6 +1784,10 @@ let rewrite_size_parameters env (Defs defs) =
{ (compute_exp_alg KidSet.empty KidSet.union) with
e_aux = (fun ((s,e),annot) -> KidSet.union s (sizes_of_annot annot), E_aux (e,annot));
e_let = (fun ((sl,lb),(s2,e2)) -> KidSet.union sl (KidSet.diff s2 (tyvars_bound_in_lb lb)), E_let (lb,e2));
+ e_for = (fun (id,(s1,e1),(s2,e2),(s3,e3),ord,(s4,e4)) ->
+ let kid = mk_kid ("loop_" ^ string_of_id id) in
+ KidSet.union s1 (KidSet.union s2 (KidSet.union s3 (KidSet.remove kid s4))),
+ E_for (id,e1,e2,e3,ord,e4));
pat_exp = (fun ((sp,pat),(s,e)) -> KidSet.diff s (tyvars_bound_in_pat pat), Pat_exp (pat,e))}
pexp)
in
@@ -1786,7 +1804,7 @@ let rewrite_size_parameters env (Defs defs) =
| P_aux (P_tup ps,_) -> ps
| _ -> [pat]
in
- let to_change = List.map
+ let to_change = Util.map_filter
(fun kid ->
let check (P_aux (_,(_,Some (env,typ,_)))) =
match Env.expand_synonyms env typ with
@@ -1799,9 +1817,10 @@ let rewrite_size_parameters env (Defs defs) =
if Kid.compare kid kid' = 0 then Some kid else None
| _ -> None
in match findi check parameters with
- | None -> raise (Reporting_basic.err_general l
- ("Unable to find an argument for " ^ string_of_kid kid))
- | Some i -> i)
+ | None -> (Reporting_basic.print_error (Reporting_basic.Err_general (l,
+ ("Unable to find an argument for " ^ string_of_kid kid)));
+ None)
+ | Some i -> Some i)
(KidSet.elements expose_tyvars)
in
let ik_compare (i,k) (i',k') =
@@ -1858,7 +1877,7 @@ let rewrite_size_parameters env (Defs defs) =
let body = List.fold_left add_var_rebind body vars in
let guard = match guard with
| None -> None
- | Some exp -> Some (List.fold_left add_var_rebind body vars)
+ | Some exp -> Some (List.fold_left add_var_rebind exp vars)
in
pat,guard,body
| exception Not_found -> pat,guard,body
@@ -2752,6 +2771,15 @@ let rewrite_app env typ (id,args) =
| _ -> E_app (id,args)
+ else if is_id env (Id "UInt") id then
+ let is_slice = is_id env (Id "slice") in
+ match args with
+ | [E_aux (E_app (slice1, [vector1; start1; length1]),_)]
+ when is_slice slice1 && not (is_constant length1) ->
+ E_app (mk_id "UInt_slice", [vector1; start1; length1])
+
+ | _ -> E_app (id,args)
+
else E_app (id,args)
let rewrite_aux = function