summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--language/jib.ott29
-rw-r--r--src/jib/anf.ml2
-rw-r--r--src/jib/c_backend.ml163
-rw-r--r--src/jib/jib_compile.ml118
-rw-r--r--src/jib/jib_compile.mli2
-rw-r--r--src/jib/jib_optimize.ml2
-rw-r--r--src/jib/jib_ssa.ml84
-rw-r--r--src/jib/jib_ssa.mli2
-rw-r--r--src/jib/jib_util.ml154
9 files changed, 273 insertions, 283 deletions
diff --git a/language/jib.ott b/language/jib.ott
index e54e2ea5..5a0e3eba 100644
--- a/language/jib.ott
+++ b/language/jib.ott
@@ -47,15 +47,19 @@ open import Value2
grammar
+name :: '' ::=
+ | id nat :: :: name
+ | have_exception nat :: :: have_exception
+ | current_exception nat :: :: current_exception
+ | return nat :: :: return
+
% Fragments are small pure snippets of (abstract) C code, mostly
-% expressions, used by the aval and cval types.
+% expressions, used by the aval (ANF) and cval (Jib) types.
fragment :: 'F_' ::=
- | id :: :: id
- | '&' id :: :: ref
+ | name :: :: id
+ | '&' name :: :: ref
| value :: :: lit
- | have_exception :: :: have_exception
- | current_exception :: :: current_exception
| fragment op fragment' :: :: op
| op fragment :: :: unary
| string ( fragment0 , ... , fragmentn ) :: :: call
@@ -129,13 +133,10 @@ cval :: 'CV_' ::=
{{ lem fragment * ctyp }}
clexp :: 'CL_' ::=
- | id : ctyp :: :: id
+ | name : ctyp :: :: id
| clexp . string :: :: field
| * clexp :: :: addr
| clexp . nat :: :: tuple
- | current_exception : ctyp :: :: current_exception
- | have_exception :: :: have_exception
- | return : ctyp :: :: return
| void :: :: void
ctype_def :: 'CTD_' ::=
@@ -152,14 +153,14 @@ instr :: 'I_' ::=
{{ aux _ iannot }}
% The following are the minimal set of instructions output by
% Jib_compile.ml.
- | ctyp id :: :: decl
- | ctyp id = cval :: :: init
+ | ctyp name :: :: decl
+ | ctyp name = cval :: :: init
| jump ( cval ) string :: :: jump
| goto string :: :: goto
| string : :: :: label
| clexp = bool id ( cval0 , ... , cvaln ) :: :: funcall
| clexp = cval :: :: copy
- | clear ctyp id :: :: clear
+ | clear ctyp name :: :: clear
| undefined ctyp :: :: undefined
| match_failure :: :: match_failure
| end :: :: end
@@ -187,8 +188,8 @@ instr :: 'I_' ::=
| return cval :: :: return
% For optimising away allocations and copying.
- | reset ctyp id :: :: reset
- | ctyp id = cval :: :: reinit
+ | reset ctyp name :: :: reset
+ | ctyp name = cval :: :: reinit
| alias clexp = cval :: :: alias
cdef :: 'CDEF_' ::=
diff --git a/src/jib/anf.ml b/src/jib/anf.ml
index 025138d0..c83fa8e2 100644
--- a/src/jib/anf.ml
+++ b/src/jib/anf.ml
@@ -158,7 +158,7 @@ let rec aval_rename from_id to_id = function
| AV_list (avals, typ) -> AV_list (List.map (aval_rename from_id to_id) avals, typ)
| AV_vector (avals, typ) -> AV_vector (List.map (aval_rename from_id to_id) avals, typ)
| AV_record (avals, typ) -> AV_record (Bindings.map (aval_rename from_id to_id) avals, typ)
- | AV_C_fragment (fragment, typ, ctyp) -> AV_C_fragment (frag_rename from_id to_id fragment, typ, ctyp)
+ | AV_C_fragment (fragment, typ, ctyp) -> AV_C_fragment (frag_rename (name from_id) (name to_id) fragment, typ, ctyp)
let rec aexp_rename from_id to_id (AE_aux (aexp, env, l)) =
let recur = aexp_rename from_id to_id in
diff --git a/src/jib/c_backend.ml b/src/jib/c_backend.ml
index 846b619f..301006d4 100644
--- a/src/jib/c_backend.ml
+++ b/src/jib/c_backend.ml
@@ -310,21 +310,21 @@ let rec c_aval ctx = function
(* We need to check that id's type hasn't changed due to flow typing *)
let _, ctyp' = Bindings.find id ctx.locals in
if ctyp_equal ctyp ctyp' then
- AV_C_fragment (F_id id, typ, ctyp)
+ AV_C_fragment (F_id (name id), typ, ctyp)
else
(* id's type changed due to flow
typing, so it's really still heap allocated! *)
v
with
(* Hack: Assuming global letbindings don't change from flow typing... *)
- Not_found -> AV_C_fragment (F_id id, typ, ctyp)
+ Not_found -> AV_C_fragment (F_id (name id), typ, ctyp)
end
else
v
| Register (_, _, typ) when is_stack_typ ctx typ ->
let ctyp = ctyp_of_typ ctx typ in
if is_stack_ctyp ctyp then
- AV_C_fragment (F_id id, typ, ctyp)
+ AV_C_fragment (F_id (name id), typ, ctyp)
else
v
| _ -> v
@@ -612,24 +612,6 @@ let analyze_primop ctx id args typ =
else
no_change
-let generate_cleanup instrs =
- let generate_cleanup' (I_aux (instr, _)) =
- match instr with
- | I_init (ctyp, id, cval) -> [(id, iclear ctyp id)]
- | I_decl (ctyp, id) -> [(id, iclear ctyp id)]
- | instr -> []
- in
- let is_clear ids = function
- | I_aux (I_clear (_, id), _) -> IdSet.add id ids
- | _ -> ids
- in
- let cleaned = List.fold_left is_clear IdSet.empty instrs in
- instrs
- |> List.map generate_cleanup'
- |> List.concat
- |> List.filter (fun (id, _) -> not (IdSet.mem id cleaned))
- |> List.map snd
-
(** Functions that have heap-allocated return types are implemented by
passing a pointer a location where the return value should be
stored. The ANF -> Sail IR pass for expressions simply outputs an
@@ -657,11 +639,11 @@ let fix_early_heap_return ret ret_ctyp instrs =
before
@ [iif cval (rewrite_return then_instrs) (rewrite_return else_instrs) ctyp]
@ rewrite_return after
- | before, I_aux (I_funcall (CL_return ctyp, extern, fid, args), aux) :: after ->
+ | before, I_aux (I_funcall (CL_id (Return _, ctyp), extern, fid, args), aux) :: after ->
before
@ [I_aux (I_funcall (CL_addr (CL_id (ret, CT_ref ctyp)), extern, fid, args), aux)]
@ rewrite_return after
- | before, I_aux (I_copy (CL_return ctyp, cval), aux) :: after ->
+ | before, I_aux (I_copy (CL_id (Return _, ctyp), cval), aux) :: after ->
before
@ [I_aux (I_copy (CL_addr (CL_id (ret, CT_ref ctyp)), cval), aux)]
@ rewrite_return after
@@ -694,11 +676,11 @@ let fix_early_stack_return ret ret_ctyp instrs =
before
@ [iif cval (rewrite_return then_instrs) (rewrite_return else_instrs) ctyp]
@ rewrite_return after
- | before, I_aux (I_funcall (CL_return ctyp, extern, fid, args), aux) :: after ->
+ | before, I_aux (I_funcall (CL_id (Return _, ctyp), extern, fid, args), aux) :: after ->
before
@ [I_aux (I_funcall (CL_id (ret, ctyp), extern, fid, args), aux)]
@ rewrite_return after
- | before, I_aux (I_copy (CL_return ctyp, cval), aux) :: after ->
+ | before, I_aux (I_copy (CL_id (Return _, ctyp), cval), aux) :: after ->
before
@ [I_aux (I_copy (CL_id (ret, ctyp), cval), aux)]
@ rewrite_return after
@@ -722,10 +704,10 @@ let rec insert_heap_returns ret_ctyps = function
| None ->
raise (Reporting.err_general (id_loc id) ("Cannot find return type for function " ^ string_of_id id))
| Some ret_ctyp when not (is_stack_ctyp ret_ctyp) ->
- CDEF_fundef (id, Some gs, args, fix_early_heap_return gs ret_ctyp body)
+ CDEF_fundef (id, Some gs, args, fix_early_heap_return (name gs) ret_ctyp body)
:: insert_heap_returns ret_ctyps cdefs
| Some ret_ctyp ->
- CDEF_fundef (id, None, args, fix_early_stack_return gs ret_ctyp (idecl ret_ctyp gs :: body))
+ CDEF_fundef (id, None, args, fix_early_stack_return (name gs) ret_ctyp (idecl ret_ctyp (name gs) :: body))
:: insert_heap_returns ret_ctyps cdefs
end
@@ -766,32 +748,6 @@ let add_local_labels instrs =
(* 5. Optimizations *)
(**************************************************************************)
-let rec instrs_rename from_id to_id =
- let rename id = if Id.compare id from_id = 0 then to_id else id in
- let crename = cval_rename from_id to_id in
- let irename instrs = instrs_rename from_id to_id instrs in
- let lrename = clexp_rename from_id to_id in
- function
- | (I_aux (I_decl (ctyp, new_id), _) :: _) as instrs when Id.compare from_id new_id = 0 -> instrs
- | I_aux (I_decl (ctyp, new_id), aux) :: instrs -> I_aux (I_decl (ctyp, new_id), aux) :: irename instrs
- | I_aux (I_reset (ctyp, id), aux) :: instrs -> I_aux (I_reset (ctyp, rename id), aux) :: irename instrs
- | I_aux (I_init (ctyp, id, cval), aux) :: instrs -> I_aux (I_init (ctyp, rename id, crename cval), aux) :: irename instrs
- | I_aux (I_reinit (ctyp, id, cval), aux) :: instrs -> I_aux (I_reinit (ctyp, rename id, crename cval), aux) :: irename instrs
- | I_aux (I_if (cval, then_instrs, else_instrs, ctyp), aux) :: instrs ->
- I_aux (I_if (crename cval, irename then_instrs, irename else_instrs, ctyp), aux) :: irename instrs
- | I_aux (I_jump (cval, label), aux) :: instrs -> I_aux (I_jump (crename cval, label), aux) :: irename instrs
- | I_aux (I_funcall (clexp, extern, id, cvals), aux) :: instrs ->
- I_aux (I_funcall (lrename clexp, extern, rename id, List.map crename cvals), aux) :: irename instrs
- | I_aux (I_copy (clexp, cval), aux) :: instrs -> I_aux (I_copy (lrename clexp, crename cval), aux) :: irename instrs
- | I_aux (I_alias (clexp, cval), aux) :: instrs -> I_aux (I_alias (lrename clexp, crename cval), aux) :: irename instrs
- | I_aux (I_clear (ctyp, id), aux) :: instrs -> I_aux (I_clear (ctyp, rename id), aux) :: irename instrs
- | I_aux (I_return cval, aux) :: instrs -> I_aux (I_return (crename cval), aux) :: irename instrs
- | I_aux (I_block block, aux) :: instrs -> I_aux (I_block (irename block), aux) :: irename instrs
- | I_aux (I_try_block block, aux) :: instrs -> I_aux (I_try_block (irename block), aux) :: irename instrs
- | I_aux (I_throw cval, aux) :: instrs -> I_aux (I_throw (crename cval), aux) :: irename instrs
- | (I_aux ((I_comment _ | I_raw _ | I_end | I_label _ | I_goto _ | I_match_failure | I_undefined _), _) as instr) :: instrs -> instr :: irename instrs
- | [] -> []
-
let hoist_ctyp = function
| CT_lint | CT_lbits _ | CT_struct _ -> true
| _ -> false
@@ -800,7 +756,7 @@ let hoist_counter = ref 0
let hoist_id () =
let id = mk_id ("gh#" ^ string_of_int !hoist_counter) in
incr hoist_counter;
- id
+ name id
let hoist_allocations recursive_functions = function
| CDEF_fundef (function_id, _, _, _) as cdef when IdSet.mem function_id recursive_functions ->
@@ -871,7 +827,7 @@ let rec specialize_variants ctx prior =
if ctyp_equal ctyp suprema then
[], (unpoly frag, ctyp), []
else
- let gs = gensym () in
+ let gs = ngensym () in
[idecl suprema gs;
icopy l (CL_id (gs, suprema)) (unpoly frag, ctyp)],
(F_id gs, suprema),
@@ -997,26 +953,26 @@ let remove_alias =
let rec scan ctyp id n instrs =
match n, !alias, instrs with
| 0, None, I_aux (I_copy (CL_id (id', ctyp'), (F_id a, ctyp'')), _) :: instrs
- when Id.compare id id' = 0 && ctyp_equal ctyp ctyp' && ctyp_equal ctyp' ctyp'' ->
+ when Name.compare id id' = 0 && ctyp_equal ctyp ctyp' && ctyp_equal ctyp' ctyp'' ->
alias := Some a;
scan ctyp id 1 instrs
| 1, Some a, I_aux (I_copy (CL_id (a', ctyp'), (F_id id', ctyp'')), _) :: instrs
- when Id.compare a a' = 0 && Id.compare id id' = 0 && ctyp_equal ctyp ctyp' && ctyp_equal ctyp' ctyp'' ->
+ when Name.compare a a' = 0 && Name.compare id id' = 0 && ctyp_equal ctyp ctyp' && ctyp_equal ctyp' ctyp'' ->
scan ctyp id 2 instrs
| 1, Some a, instr :: instrs ->
- if IdSet.mem a (instr_ids instr) then
+ if NameSet.mem a (instr_ids instr) then
None
else
scan ctyp id 1 instrs
| 2, Some a, I_aux (I_clear (ctyp', id'), _) :: instrs
- when Id.compare id id' = 0 && ctyp_equal ctyp ctyp' ->
+ when Name.compare id id' = 0 && ctyp_equal ctyp ctyp' ->
scan ctyp id 2 instrs
| 2, Some a, instr :: instrs ->
- if IdSet.mem id (instr_ids instr) then
+ if NameSet.mem id (instr_ids instr) then
None
else
scan ctyp id 2 instrs
@@ -1031,9 +987,9 @@ let remove_alias =
in
let remove_alias id alias = function
| I_aux (I_copy (CL_id (id', _), (F_id alias', _)), _)
- when Id.compare id id' = 0 && Id.compare alias alias' = 0 -> removed
+ when Name.compare id id' = 0 && Name.compare alias alias' = 0 -> removed
| I_aux (I_copy (CL_id (alias', _), (F_id id', _)), _)
- when Id.compare id id' = 0 && Id.compare alias alias' = 0 -> removed
+ when Name.compare id id' = 0 && Name.compare alias alias' = 0 -> removed
| I_aux (I_clear (_, id'), _) -> removed
| instr -> instr
in
@@ -1066,17 +1022,17 @@ let unique_names =
let unique_id () =
let id = mk_id ("u#" ^ string_of_int !unique_counter) in
incr unique_counter;
- id
+ name id
in
let rec opt seen = function
- | I_aux (I_decl (ctyp, id), aux) :: instrs when IdSet.mem id seen ->
+ | I_aux (I_decl (ctyp, id), aux) :: instrs when NameSet.mem id seen ->
let id' = unique_id () in
let instrs', seen = opt seen instrs in
I_aux (I_decl (ctyp, id'), aux) :: instrs_rename id id' instrs', seen
| I_aux (I_decl (ctyp, id), aux) :: instrs ->
- let instrs', seen = opt (IdSet.add id seen) instrs in
+ let instrs', seen = opt (NameSet.add id seen) instrs in
I_aux (I_decl (ctyp, id), aux) :: instrs', seen
| I_aux (I_block block, aux) :: instrs ->
@@ -1103,11 +1059,11 @@ let unique_names =
in
function
| CDEF_fundef (function_id, heap_return, args, body) ->
- [CDEF_fundef (function_id, heap_return, args, fst (opt IdSet.empty body))]
+ [CDEF_fundef (function_id, heap_return, args, fst (opt NameSet.empty body))]
| CDEF_reg_dec (id, ctyp, instrs) ->
- [CDEF_reg_dec (id, ctyp, fst (opt IdSet.empty instrs))]
+ [CDEF_reg_dec (id, ctyp, fst (opt NameSet.empty instrs))]
| CDEF_let (n, bindings, instrs) ->
- [CDEF_let (n, bindings, fst (opt IdSet.empty instrs))]
+ [CDEF_let (n, bindings, fst (opt NameSet.empty instrs))]
| cdef -> [cdef]
(** This optimization looks for patterns of the form
@@ -1135,26 +1091,26 @@ let combine_variables =
scan id 1 instrs
| 1, Some c, I_aux (I_copy (CL_id (id', ctyp'), (F_id c', ctyp'')), _) :: instrs
- when Id.compare c c' = 0 && Id.compare id id' = 0 && ctyp_equal ctyp ctyp' && ctyp_equal ctyp' ctyp'' ->
+ when Name.compare c c' = 0 && Name.compare id id' = 0 && ctyp_equal ctyp ctyp' && ctyp_equal ctyp' ctyp'' ->
scan id 2 instrs
(* Ignore seemingly early clears of x, as this can happen along exception paths *)
| 1, Some c, I_aux (I_clear (_, id'), _) :: instrs
- when Id.compare id id' = 0 ->
+ when Name.compare id id' = 0 ->
scan id 1 instrs
| 1, Some c, instr :: instrs ->
- if IdSet.mem id (instr_ids instr) then
+ if NameSet.mem id (instr_ids instr) then
None
else
scan id 1 instrs
| 2, Some c, I_aux (I_clear (ctyp', c'), _) :: instrs
- when Id.compare c c' = 0 && ctyp_equal ctyp ctyp' ->
+ when Name.compare c c' = 0 && ctyp_equal ctyp ctyp' ->
!combine
| 2, Some c, instr :: instrs ->
- if IdSet.mem c (instr_ids instr) then
+ if NameSet.mem c (instr_ids instr) then
None
else
scan id 2 instrs
@@ -1167,12 +1123,12 @@ let combine_variables =
scan id 0
in
let remove_variable id = function
- | I_aux (I_decl (_, id'), _) when Id.compare id id' = 0 -> removed
- | I_aux (I_clear (_, id'), _) when Id.compare id id' = 0 -> removed
+ | I_aux (I_decl (_, id'), _) when Name.compare id id' = 0 -> removed
+ | I_aux (I_clear (_, id'), _) when Name.compare id id' = 0 -> removed
| instr -> instr
in
let is_not_self_assignment = function
- | I_aux (I_copy (CL_id (id, _), (F_id id', _)), _) when Id.compare id id' = 0 -> false
+ | I_aux (I_copy (CL_id (id, _), (F_id id', _)), _) when Name.compare id id' = 0 -> false
| _ -> true
in
let rec opt = function
@@ -1224,9 +1180,9 @@ let hoist_alias =
function return, so we want to make sure we avoid that
case. *)
| (I_aux (I_copy (clexp, (F_id id', ctyp')), aux) as instr) :: instrs
- when not (IdSet.mem heap_return (instr_writes instr)) && Id.compare id id' = 0
+ when not (NameSet.mem heap_return (instr_writes instr)) && Name.compare id id' = 0
&& ctyp_equal (clexp_ctyp clexp) ctyp && ctyp_equal ctyp ctyp' ->
- if List.exists (IdSet.mem id) (List.map instr_ids instrs) then
+ if List.exists (NameSet.mem id) (List.map instr_ids instrs) then
instr :: scan instrs
else
I_aux (I_alias (clexp, (F_id id', ctyp')), aux) :: instrs
@@ -1254,7 +1210,7 @@ let hoist_alias =
in
function
| CDEF_fundef (function_id, Some heap_return, args, body) ->
- [CDEF_fundef (function_id, Some heap_return, args, optimize heap_return body)]
+ [CDEF_fundef (function_id, Some heap_return, args, optimize (name heap_return) body)]
| cdef -> [cdef]
let concatMap f xs = List.concat (List.map f xs)
@@ -1274,6 +1230,7 @@ let optimize recursive_functions cdefs =
(**************************************************************************)
let sgen_id id = Util.zencode_string (string_of_id id)
+let sgen_name id = string_of_name id
let codegen_id id = string (sgen_id id)
let sgen_function_id id =
@@ -1336,23 +1293,23 @@ let sgen_cval_param (frag, ctyp) =
let sgen_cval = function (frag, _) -> string_of_fragment frag
let rec sgen_clexp = function
- | CL_id (id, _) -> "&" ^ sgen_id id
+ | CL_id (Have_exception _, _) -> "have_exception"
+ | CL_id (Current_exception _, _) -> "current_exception"
+ | CL_id (Return _, _) -> assert false
+ | CL_id (Name (id, _), _) -> "&" ^ sgen_id id
| CL_field (clexp, field) -> "&((" ^ sgen_clexp clexp ^ ")->" ^ Util.zencode_string field ^ ")"
| CL_tuple (clexp, n) -> "&((" ^ sgen_clexp clexp ^ ")->ztup" ^ string_of_int n ^ ")"
| CL_addr clexp -> "(*(" ^ sgen_clexp clexp ^ "))"
- | CL_have_exception -> "have_exception"
- | CL_current_exception _ -> "current_exception"
- | CL_return _ -> assert false
| CL_void -> assert false
let rec sgen_clexp_pure = function
- | CL_id (id, _) -> sgen_id id
+ | CL_id (Have_exception _, _) -> "have_exception"
+ | CL_id (Current_exception _, _) -> "current_exception"
+ | CL_id (Return _, _) -> assert false
+ | CL_id (Name (id, _), _) -> sgen_id id
| CL_field (clexp, field) -> sgen_clexp_pure clexp ^ "." ^ Util.zencode_string field
| CL_tuple (clexp, n) -> sgen_clexp_pure clexp ^ ".ztup" ^ string_of_int n
| CL_addr clexp -> "(*(" ^ sgen_clexp_pure clexp ^ "))"
- | CL_have_exception -> "have_exception"
- | CL_current_exception _ -> "current_exception"
- | CL_return _ -> assert false
| CL_void -> assert false
(** Generate instructions to copy from a cval to a clexp. This will
@@ -1397,10 +1354,10 @@ let rec codegen_instr fid ctx (I_aux (instr, (_, l))) =
let open Printf in
match instr with
| I_decl (ctyp, id) when is_stack_ctyp ctyp ->
- ksprintf string " %s %s;" (sgen_ctyp ctyp) (sgen_id id)
+ ksprintf string " %s %s;" (sgen_ctyp ctyp) (sgen_name id)
| I_decl (ctyp, id) ->
- ksprintf string " %s %s;" (sgen_ctyp ctyp) (sgen_id id) ^^ hardline
- ^^ ksprintf string " CREATE(%s)(&%s);" (sgen_ctyp_name ctyp) (sgen_id id)
+ ksprintf string " %s %s;" (sgen_ctyp ctyp) (sgen_name id) ^^ hardline
+ ^^ ksprintf string " CREATE(%s)(&%s);" (sgen_ctyp_name ctyp) (sgen_name id)
| I_copy (clexp, cval) -> codegen_conversion l clexp cval
@@ -1504,7 +1461,7 @@ let rec codegen_instr fid ctx (I_aux (instr, (_, l))) =
| I_clear (ctyp, id) when is_stack_ctyp ctyp ->
empty
| I_clear (ctyp, id) ->
- string (Printf.sprintf " KILL(%s)(&%s);" (sgen_ctyp_name ctyp) (sgen_id id))
+ string (Printf.sprintf " KILL(%s)(&%s);" (sgen_ctyp_name ctyp) (sgen_name id))
| I_init (ctyp, id, cval) ->
codegen_instr fid ctx (idecl ctyp id) ^^ hardline
@@ -1515,9 +1472,9 @@ let rec codegen_instr fid ctx (I_aux (instr, (_, l))) =
^^ codegen_conversion Parse_ast.Unknown (CL_id (id, ctyp)) cval
| I_reset (ctyp, id) when is_stack_ctyp ctyp ->
- string (Printf.sprintf " %s %s;" (sgen_ctyp ctyp) (sgen_id id))
+ string (Printf.sprintf " %s %s;" (sgen_ctyp ctyp) (sgen_name id))
| I_reset (ctyp, id) ->
- string (Printf.sprintf " RECREATE(%s)(&%s);" (sgen_ctyp_name ctyp) (sgen_id id))
+ string (Printf.sprintf " RECREATE(%s)(&%s);" (sgen_ctyp_name ctyp) (sgen_name id))
| I_return cval ->
string (Printf.sprintf " return %s;" (sgen_cval cval))
@@ -1536,24 +1493,24 @@ let rec codegen_instr fid ctx (I_aux (instr, (_, l))) =
| CT_bool -> "false", []
| CT_enum (_, ctor :: _) -> sgen_id ctor, []
| CT_tup ctyps when is_stack_ctyp ctyp ->
- let gs = gensym () in
+ let gs = ngensym () in
let fold (inits, prev) (n, ctyp) =
let init, prev' = codegen_exn_return ctyp in
Printf.sprintf ".ztup%d = %s" n init :: inits, prev @ prev'
in
let inits, prev = List.fold_left fold ([], []) (List.mapi (fun i x -> (i, x)) ctyps) in
- sgen_id gs,
- [Printf.sprintf "struct %s %s = { " (sgen_ctyp_name ctyp) (sgen_id gs)
+ sgen_name gs,
+ [Printf.sprintf "struct %s %s = { " (sgen_ctyp_name ctyp) (sgen_name gs)
^ Util.string_of_list ", " (fun x -> x) inits ^ " };"] @ prev
| CT_struct (id, ctors) when is_stack_ctyp ctyp ->
- let gs = gensym () in
+ let gs = ngensym () in
let fold (inits, prev) (id, ctyp) =
let init, prev' = codegen_exn_return ctyp in
Printf.sprintf ".%s = %s" (sgen_id id) init :: inits, prev @ prev'
in
let inits, prev = List.fold_left fold ([], []) ctors in
- sgen_id gs,
- [Printf.sprintf "struct %s %s = { " (sgen_ctyp_name ctyp) (sgen_id gs)
+ sgen_name gs,
+ [Printf.sprintf "struct %s %s = { " (sgen_ctyp_name ctyp) (sgen_name gs)
^ Util.string_of_list ", " (fun x -> x) inits ^ " };"] @ prev
| ctyp -> c_error ("Cannot create undefined value for type: " ^ string_of_ctyp ctyp)
in
@@ -2014,13 +1971,13 @@ let is_decl = function
let codegen_decl = function
| I_aux (I_decl (ctyp, id), _) ->
- string (Printf.sprintf "%s %s;" (sgen_ctyp ctyp) (sgen_id id))
+ string (Printf.sprintf "%s %s;" (sgen_ctyp ctyp) (sgen_name id))
| _ -> assert false
let codegen_alloc = function
| I_aux (I_decl (ctyp, id), _) when is_stack_ctyp ctyp -> empty
| I_aux (I_decl (ctyp, id), _) ->
- string (Printf.sprintf " CREATE(%s)(&%s);" (sgen_ctyp_name ctyp) (sgen_id id))
+ string (Printf.sprintf " CREATE(%s)(&%s);" (sgen_ctyp_name ctyp) (sgen_name id))
| _ -> assert false
let codegen_def' ctx = function
@@ -2101,10 +2058,10 @@ let codegen_def' ctx = function
| CDEF_let (number, bindings, instrs) ->
let instrs = add_local_labels instrs in
let setup =
- List.concat (List.map (fun (id, ctyp) -> [idecl ctyp id]) bindings)
+ List.concat (List.map (fun (id, ctyp) -> [idecl ctyp (name id)]) bindings)
in
let cleanup =
- List.concat (List.map (fun (id, ctyp) -> [iclear ctyp id]) bindings)
+ List.concat (List.map (fun (id, ctyp) -> [iclear ctyp (name id)]) bindings)
in
separate_map hardline (fun (id, ctyp) -> string (Printf.sprintf "%s %s;" (sgen_ctyp ctyp) (sgen_id id))) bindings
^^ hardline ^^ string (Printf.sprintf "static void create_letbind_%d(void) " number)
diff --git a/src/jib/jib_compile.ml b/src/jib/jib_compile.ml
index facf64e9..85a77d2e 100644
--- a/src/jib/jib_compile.ml
+++ b/src/jib/jib_compile.ml
@@ -61,6 +61,8 @@ let opt_debug_function = ref ""
let opt_debug_flow_graphs = ref false
let opt_memo_cache = ref false
+let ngensym () = name (gensym ())
+
(**************************************************************************)
(* 4. Conversion to low-level AST *)
(**************************************************************************)
@@ -183,26 +185,26 @@ let rec compile_aval l ctx = function
begin
try
let _, ctyp = Bindings.find id ctx.locals in
- [], (F_id id, ctyp), []
+ [], (F_id (name id), ctyp), []
with
| Not_found ->
- [], (F_id id, ctyp_of_typ ctx (lvar_typ typ)), []
+ [], (F_id (name id), ctyp_of_typ ctx (lvar_typ typ)), []
end
| AV_ref (id, typ) ->
- [], (F_ref id, CT_ref (ctyp_of_typ ctx (lvar_typ typ))), []
+ [], (F_ref (name id), CT_ref (ctyp_of_typ ctx (lvar_typ typ))), []
| AV_lit (L_aux (L_string str, _), typ) ->
[], (F_lit (V_string (String.escaped str)), ctyp_of_typ ctx typ), []
| AV_lit (L_aux (L_num n, _), typ) when Big_int.less_equal (min_int 64) n && Big_int.less_equal n (max_int 64) ->
- let gs = gensym () in
+ let gs = ngensym () in
[iinit CT_lint gs (F_lit (V_int n), CT_fint 64)],
(F_id gs, CT_lint),
[iclear CT_lint gs]
| AV_lit (L_aux (L_num n, _), typ) ->
- let gs = gensym () in
+ let gs = ngensym () in
[iinit CT_lint gs (F_lit (V_string (Big_int.to_string n)), CT_string)],
(F_id gs, CT_lint),
[iclear CT_lint gs]
@@ -214,7 +216,7 @@ let rec compile_aval l ctx = function
| AV_lit (L_aux (L_false, _), _) -> [], (F_lit (V_bool false), CT_bool), []
| AV_lit (L_aux (L_real str, _), _) ->
- let gs = gensym () in
+ let gs = ngensym () in
[iinit CT_real gs (F_lit (V_string str), CT_string)],
(F_id gs, CT_real),
[iclear CT_real gs]
@@ -230,7 +232,7 @@ let rec compile_aval l ctx = function
let setup = List.concat (List.map (fun (setup, _, _) -> setup) elements) in
let cleanup = List.concat (List.rev (List.map (fun (_, _, cleanup) -> cleanup) elements)) in
let tup_ctyp = CT_tup (List.map cval_ctyp cvals) in
- let gs = gensym () in
+ let gs = ngensym () in
setup
@ [idecl tup_ctyp gs]
@ List.mapi (fun n cval -> icopy l (CL_tuple (CL_id (gs, tup_ctyp), n)) cval) cvals,
@@ -240,7 +242,7 @@ let rec compile_aval l ctx = function
| AV_record (fields, typ) ->
let ctyp = ctyp_of_typ ctx typ in
- let gs = gensym () in
+ let gs = ngensym () in
let compile_fields (id, aval) =
let field_setup, cval, field_cleanup = compile_aval l ctx aval in
field_setup
@@ -278,7 +280,7 @@ let rec compile_aval l ctx = function
let bitstring avals = F_lit (V_bits (List.map value_of_aval_bit avals)) in
let first_chunk = bitstring (Util.take (len mod 64) avals) in
let chunks = Util.drop (len mod 64) avals |> chunkify 64 |> List.map bitstring in
- let gs = gensym () in
+ let gs = ngensym () in
[iinit (CT_lbits true) gs (first_chunk, CT_fbits (len mod 64, true))]
@ List.map (fun chunk -> ifuncall (CL_id (gs, CT_lbits true))
(mk_id "append_64")
@@ -295,7 +297,7 @@ let rec compile_aval l ctx = function
| Ord_aux (Ord_dec, _) -> true
| Ord_aux (Ord_var _, _) -> raise (Reporting.err_general l "Polymorphic vector direction found")
in
- let gs = gensym () in
+ let gs = ngensym () in
let ctyp = CT_fbits (len, direction) in
let mask i = V_bits (Util.list_init (63 - i) (fun _ -> Sail2_values.B0) @ [Sail2_values.B1] @ Util.list_init i (fun _ -> Sail2_values.B0)) in
let aval_mask i aval =
@@ -323,7 +325,7 @@ let rec compile_aval l ctx = function
| Ord_aux (Ord_var _, _) -> raise (Reporting.err_general l "Polymorphic vector direction found")
in
let vector_ctyp = CT_vector (direction, ctyp_of_typ ctx typ) in
- let gs = gensym () in
+ let gs = ngensym () in
let aval_set i aval =
let setup, cval, cleanup = compile_aval l ctx aval in
setup
@@ -346,7 +348,7 @@ let rec compile_aval l ctx = function
| Typ_app (id, [A_aux (A_typ typ, _)]) when string_of_id id = "list" -> ctyp_of_typ ctx typ
| _ -> raise (Reporting.err_general l "Invalid list type")
in
- let gs = gensym () in
+ let gs = ngensym () in
let mk_cons aval =
let setup, cval, cleanup = compile_aval l ctx aval in
setup @ [ifuncall (CL_id (gs, CT_list ctyp)) (mk_id ("cons#" ^ string_of_ctyp ctyp)) [cval; (F_id gs, CT_list ctyp)]] @ cleanup
@@ -384,7 +386,7 @@ let compile_funcall l ctx id args typ =
else if ctyp_equal ctyp have_ctyp then
cval
else
- let gs = gensym () in
+ let gs = ngensym () in
setup := iinit ctyp gs cval :: !setup;
cleanup := iclear ctyp gs :: !cleanup;
(F_id gs, ctyp)
@@ -399,7 +401,7 @@ let compile_funcall l ctx id args typ =
if ctyp_equal (clexp_ctyp clexp) ret_ctyp then
ifuncall clexp id setup_args
else
- let gs = gensym () in
+ let gs = ngensym () in
iblock [idecl ret_ctyp gs;
ifuncall (CL_id (gs, ret_ctyp)) id setup_args;
icopy l clexp (F_id gs, ret_ctyp);
@@ -425,19 +427,19 @@ let rec compile_match ctx (AP_aux (apat_aux, env, l)) cval case_label =
| AP_global (pid, typ), (frag, ctyp) ->
let global_ctyp = ctyp_of_typ ctx typ in
- [icopy l (CL_id (pid, global_ctyp)) cval], [], ctx
+ [icopy l (CL_id (name pid, global_ctyp)) cval], [], ctx
| AP_id (pid, _), (frag, ctyp) when is_ct_enum ctyp ->
begin match Env.lookup_id pid ctx.tc_env with
- | Unbound -> [idecl ctyp pid; icopy l (CL_id (pid, ctyp)) (frag, ctyp)], [], ctx
- | _ -> [ijump (F_op (F_id pid, "!=", frag), CT_bool) case_label], [], ctx
+ | Unbound -> [idecl ctyp (name pid); icopy l (CL_id (name pid, ctyp)) (frag, ctyp)], [], ctx
+ | _ -> [ijump (F_op (F_id (name pid), "!=", frag), CT_bool) case_label], [], ctx
end
| AP_id (pid, typ), _ ->
let ctyp = cval_ctyp cval in
let id_ctyp = ctyp_of_typ ctx typ in
let ctx = { ctx with locals = Bindings.add pid (Immutable, id_ctyp) ctx.locals } in
- [idecl id_ctyp pid; icopy l (CL_id (pid, id_ctyp)) cval], [iclear id_ctyp pid], ctx
+ [idecl id_ctyp (name pid); icopy l (CL_id (name pid, id_ctyp)) cval], [iclear id_ctyp (name pid)], ctx
| AP_tup apats, (frag, ctyp) ->
begin
@@ -507,7 +509,9 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
let binding_ctyp = ctyp_of_typ { ctx with local_env = body_env } binding_typ in
let setup, call, cleanup = compile_aexp ctx binding in
let letb_setup, letb_cleanup =
- [idecl binding_ctyp id; iblock (setup @ [call (CL_id (id, binding_ctyp))] @ cleanup)], [iclear binding_ctyp id]
+ [idecl binding_ctyp (name id);
+ iblock (setup @ [call (CL_id (name id, binding_ctyp))] @ cleanup)],
+ [iclear binding_ctyp (name id)]
in
let ctx = { ctx with locals = Bindings.add id (mut, binding_ctyp) ctx.locals } in
let setup, call, cleanup = compile_aexp ctx body in
@@ -524,7 +528,7 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
| AE_case (aval, cases, typ) ->
let ctyp = ctyp_of_typ ctx typ in
let aval_setup, cval, aval_cleanup = compile_aval l ctx aval in
- let case_return_id = gensym () in
+ let case_return_id = ngensym () in
let finish_match_label = label "finish_match_" in
let compile_case (apat, guard, body) =
let trivial_guard = match guard with
@@ -536,7 +540,7 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
let destructure, destructure_cleanup, ctx = compile_match ctx apat cval case_label in
let guard_setup, guard_call, guard_cleanup = compile_aexp ctx guard in
let body_setup, body_call, body_cleanup = compile_aexp ctx body in
- let gs = gensym () in
+ let gs = ngensym () in
let case_instrs =
destructure @ [icomment "end destructuring"]
@ (if not trivial_guard then
@@ -566,7 +570,7 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
| AE_try (aexp, cases, typ) ->
let ctyp = ctyp_of_typ ctx typ in
let aexp_setup, aexp_call, aexp_cleanup = compile_aexp ctx aexp in
- let try_return_id = gensym () in
+ let try_return_id = ngensym () in
let handled_exception_label = label "handled_exception_" in
let fallthrough_label = label "fallthrough_exception_" in
let compile_case (apat, guard, body) =
@@ -576,11 +580,11 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
| _ -> false
in
let try_label = label "try_" in
- let exn_cval = (F_current_exception, ctyp_of_typ ctx (mk_typ (Typ_id (mk_id "exception")))) in
+ let exn_cval = (F_id current_exception, ctyp_of_typ ctx (mk_typ (Typ_id (mk_id "exception")))) in
let destructure, destructure_cleanup, ctx = compile_match ctx apat exn_cval try_label in
let guard_setup, guard_call, guard_cleanup = compile_aexp ctx guard in
let body_setup, body_call, body_cleanup = compile_aexp ctx body in
- let gs = gensym () in
+ let gs = ngensym () in
let case_instrs =
destructure @ [icomment "end destructuring"]
@ (if not trivial_guard then
@@ -596,11 +600,11 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
assert (ctyp_equal ctyp (ctyp_of_typ ctx typ));
[idecl ctyp try_return_id;
itry_block (aexp_setup @ [aexp_call (CL_id (try_return_id, ctyp))] @ aexp_cleanup);
- ijump (F_unary ("!", F_have_exception), CT_bool) handled_exception_label]
+ ijump (F_unary ("!", F_id have_exception), CT_bool) handled_exception_label]
@ List.concat (List.map compile_case cases)
@ [igoto fallthrough_label;
ilabel handled_exception_label;
- icopy l CL_have_exception (F_lit (V_bool false), CT_bool);
+ icopy l (CL_id (have_exception, CT_bool)) (F_lit (V_bool false), CT_bool);
ilabel fallthrough_label],
(fun clexp -> icopy l clexp (F_id try_return_id, ctyp)),
[]
@@ -631,7 +635,7 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
| CT_struct (_, ctors) -> List.fold_left (fun m (k, v) -> Bindings.add k v m) Bindings.empty ctors
| _ -> raise (Reporting.err_general l "Cannot perform record update for non-record type")
in
- let gs = gensym () in
+ let gs = ngensym () in
let compile_fields (id, aval) =
let field_setup, cval, field_cleanup = compile_aval l ctx aval in
field_setup
@@ -650,7 +654,7 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
| AE_short_circuit (SC_and, aval, aexp) ->
let left_setup, cval, left_cleanup = compile_aval l ctx aval in
let right_setup, call, right_cleanup = compile_aexp ctx aexp in
- let gs = gensym () in
+ let gs = ngensym () in
left_setup
@ [ idecl CT_bool gs;
iif cval
@@ -663,7 +667,7 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
| AE_short_circuit (SC_or, aval, aexp) ->
let left_setup, cval, left_cleanup = compile_aval l ctx aval in
let right_setup, call, right_cleanup = compile_aexp ctx aexp in
- let gs = gensym () in
+ let gs = ngensym () in
left_setup
@ [ idecl CT_bool gs;
iif cval
@@ -681,7 +685,7 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
let compile_fields (field_id, aval) =
let field_setup, cval, field_cleanup = compile_aval l ctx aval in
field_setup
- @ [icopy l (CL_field (CL_id (id, ctyp_of_typ ctx typ), string_of_id field_id)) cval]
+ @ [icopy l (CL_field (CL_id (name id, ctyp_of_typ ctx typ), string_of_id field_id)) cval]
@ field_cleanup
in
List.concat (List.map compile_fields (Bindings.bindings fields)),
@@ -695,7 +699,7 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
| None -> ctyp_of_typ ctx assign_typ
in
let setup, call, cleanup = compile_aexp ctx aexp in
- setup @ [call (CL_id (id, assign_ctyp))], (fun clexp -> icopy l clexp unit_fragment), cleanup
+ setup @ [call (CL_id (name id, assign_ctyp))], (fun clexp -> icopy l clexp unit_fragment), cleanup
| AE_block (aexps, aexp, _) ->
let block = compile_block ctx aexps in
@@ -707,8 +711,8 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
let loop_end_label = label "wend_" in
let cond_setup, cond_call, cond_cleanup = compile_aexp ctx cond in
let body_setup, body_call, body_cleanup = compile_aexp ctx body in
- let gs = gensym () in
- let unit_gs = gensym () in
+ let gs = ngensym () in
+ let unit_gs = ngensym () in
let loop_test = (F_unary ("!", F_id gs), CT_bool) in
[idecl CT_bool gs; idecl CT_unit unit_gs]
@ [ilabel loop_start_label]
@@ -729,8 +733,8 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
let loop_end_label = label "until_" in
let cond_setup, cond_call, cond_cleanup = compile_aexp ctx cond in
let body_setup, body_call, body_cleanup = compile_aexp ctx body in
- let gs = gensym () in
- let unit_gs = gensym () in
+ let gs = ngensym () in
+ let unit_gs = ngensym () in
let loop_test = (F_id gs, CT_bool) in
[idecl CT_bool gs; idecl CT_unit unit_gs]
@ [ilabel loop_start_label]
@@ -759,7 +763,7 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
if ctyp_equal fn_return_ctyp (cval_ctyp cval) then
[ireturn cval]
else
- let gs = gensym () in
+ let gs = ngensym () in
[idecl fn_return_ctyp gs;
icopy l (CL_id (gs, fn_return_ctyp)) cval;
ireturn (F_id gs, fn_return_ctyp)]
@@ -804,11 +808,11 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
(* Loop variables *)
let from_setup, from_call, from_cleanup = compile_aexp ctx loop_from in
- let from_gs = gensym () in
+ let from_gs = ngensym () in
let to_setup, to_call, to_cleanup = compile_aexp ctx loop_to in
- let to_gs = gensym () in
+ let to_gs = ngensym () in
let step_setup, step_call, step_cleanup = compile_aexp ctx loop_step in
- let step_gs = gensym () in
+ let step_gs = ngensym () in
let variable_init gs setup call cleanup =
[idecl (CT_fint 64) gs;
iblock (setup @ [call (CL_id (gs, CT_fint 64))] @ cleanup)]
@@ -817,8 +821,10 @@ let rec compile_aexp ctx (AE_aux (aexp_aux, env, l)) =
let loop_start_label = label "for_start_" in
let loop_end_label = label "for_end_" in
let body_setup, body_call, body_cleanup = compile_aexp ctx body in
- let body_gs = gensym () in
+ let body_gs = ngensym () in
+ let loop_var = name loop_var in
+
variable_init from_gs from_setup from_call from_cleanup
@ variable_init to_gs to_setup to_call to_cleanup
@ variable_init step_gs step_setup step_call step_cleanup
@@ -842,7 +848,7 @@ and compile_block ctx = function
| exp :: exps ->
let setup, call, cleanup = compile_aexp ctx exp in
let rest = compile_block ctx exps in
- let gs = gensym () in
+ let gs = ngensym () in
iblock (setup @ [idecl CT_unit gs; call (CL_id (gs, CT_unit))] @ cleanup) :: rest
(** Compile a sail type definition into a IR one. Most of the
@@ -892,14 +898,14 @@ let generate_cleanup instrs =
| instr -> []
in
let is_clear ids = function
- | I_aux (I_clear (_, id), _) -> IdSet.add id ids
+ | I_aux (I_clear (_, id), _) -> NameSet.add id ids
| _ -> ids
in
- let cleaned = List.fold_left is_clear IdSet.empty instrs in
+ let cleaned = List.fold_left is_clear NameSet.empty instrs in
instrs
|> List.map generate_cleanup'
|> List.concat
- |> List.filter (fun (id, _) -> not (IdSet.mem id cleaned))
+ |> List.filter (fun (id, _) -> not (NameSet.mem id cleaned))
|> List.map snd
let fix_exception_block ?return:(return=None) ctx instrs =
@@ -927,8 +933,8 @@ let fix_exception_block ?return:(return=None) ctx instrs =
@ rewrite_exception historic after
| before, I_aux (I_throw cval, (_, l)) :: after ->
before
- @ [icopy l (CL_current_exception (cval_ctyp cval)) cval;
- icopy l CL_have_exception (F_lit (V_bool true), CT_bool)]
+ @ [icopy l (CL_id (current_exception, cval_ctyp cval)) cval;
+ icopy l (CL_id (have_exception, CT_bool)) (F_lit (V_bool true), CT_bool)]
@ generate_cleanup (historic @ before)
@ [igoto end_block_label]
@ rewrite_exception (historic @ before) after
@@ -941,7 +947,7 @@ let fix_exception_block ?return:(return=None) ctx instrs =
if has_effect effects BE_escape then
before
@ [funcall;
- iif (F_have_exception, CT_bool) (generate_cleanup (historic @ before) @ [igoto end_block_label]) [] CT_unit]
+ iif (F_id have_exception, CT_bool) (generate_cleanup (historic @ before) @ [igoto end_block_label]) [] CT_unit]
@ rewrite_exception (historic @ before) after
else
before @ funcall :: rewrite_exception (historic @ before) after
@@ -979,7 +985,7 @@ let rec compile_arg_pat ctx label (P_aux (p_aux, (l, _)) as pat) ctyp =
| _ ->
let apat = anf_pat pat in
let gs = gensym () in
- let destructure, cleanup, _ = compile_match ctx apat (F_id gs, ctyp) label in
+ let destructure, cleanup, _ = compile_match ctx apat (F_id (name gs), ctyp) label in
(gs, (destructure, cleanup))
let rec compile_arg_pats ctx label (P_aux (p_aux, (l, _)) as pat) ctyps =
@@ -994,10 +1000,10 @@ let rec compile_arg_pats ctx label (P_aux (p_aux, (l, _)) as pat) ctyps =
let arg_id, (destructure, cleanup) = compile_arg_pat ctx label pat (CT_tup ctyps) in
let new_ids = List.map (fun ctyp -> gensym (), ctyp) ctyps in
destructure
- @ [idecl (CT_tup ctyps) arg_id]
- @ List.mapi (fun i (id, ctyp) -> icopy l (CL_tuple (CL_id (arg_id, CT_tup ctyps), i)) (F_id id, ctyp)) new_ids,
+ @ [idecl (CT_tup ctyps) (name arg_id)]
+ @ List.mapi (fun i (id, ctyp) -> icopy l (CL_tuple (CL_id (name arg_id, CT_tup ctyps), i)) (F_id (name id), ctyp)) new_ids,
List.map (fun (id, _) -> id, ([], [])) new_ids,
- [iclear (CT_tup ctyps) arg_id]
+ [iclear (CT_tup ctyps) (name arg_id)]
@ cleanup
let combine_destructure_cleanup xs = List.concat (List.map fst xs), List.concat (List.rev (List.map snd xs))
@@ -1108,7 +1114,7 @@ and compile_def' n total ctx = function
| DEF_reg_dec (DEC_aux (DEC_config (id, typ, exp), _)) ->
let aexp = ctx.optimize_anf ctx (no_shadow IdSet.empty (anf exp)) in
let setup, call, cleanup = compile_aexp ctx aexp in
- let instrs = setup @ [call (CL_id (id, ctyp_of_typ ctx typ))] @ cleanup in
+ let instrs = setup @ [call (CL_id (name id, ctyp_of_typ ctx typ))] @ cleanup in
[CDEF_reg_dec (id, ctyp_of_typ ctx typ, instrs)], ctx
| DEF_reg_dec (DEC_aux (_, (l, _))) ->
@@ -1161,8 +1167,8 @@ and compile_def' n total ctx = function
compiled_args |> List.map snd |> combine_destructure_cleanup |> fix_destructure fundef_label
in
- let instrs = arg_setup @ destructure @ setup @ [call (CL_return ret_ctyp)] @ cleanup @ destructure_cleanup @ arg_cleanup in
- let instrs = fix_early_return (CL_return ret_ctyp) instrs in
+ let instrs = arg_setup @ destructure @ setup @ [call (CL_id (return, ret_ctyp))] @ cleanup @ destructure_cleanup @ arg_cleanup in
+ let instrs = fix_early_return (CL_id (return, ret_ctyp)) instrs in
let instrs = fix_exception ~return:(Some ret_ctyp) ctx instrs in
if Id.compare (mk_id !opt_debug_function) id = 0 then
@@ -1211,7 +1217,7 @@ and compile_def' n total ctx = function
let aexp = ctx.optimize_anf ctx (no_shadow IdSet.empty (anf exp)) in
let setup, call, cleanup = compile_aexp ctx aexp in
let apat = anf_pat ~global:true pat in
- let gs = gensym () in
+ let gs = ngensym () in
let end_label = label "let_end_" in
let destructure, destructure_cleanup, _ = compile_match ctx apat (F_id gs, ctyp) end_label in
let gs_setup, gs_cleanup =
@@ -1278,7 +1284,7 @@ let rec specialize_variants ctx prior =
if ctyp_equal ctyp suprema then
[], (unpoly frag, ctyp), []
else
- let gs = gensym () in
+ let gs = ngensym () in
[idecl suprema gs;
icopy l (CL_id (gs, suprema)) (unpoly frag, ctyp)],
(F_id gs, suprema),
diff --git a/src/jib/jib_compile.mli b/src/jib/jib_compile.mli
index f3bd8c76..a0cacc3c 100644
--- a/src/jib/jib_compile.mli
+++ b/src/jib/jib_compile.mli
@@ -63,6 +63,8 @@ val opt_debug_flow_graphs : bool ref
(** Print the IR representation of a specific function. *)
val opt_debug_function : string ref
+val ngensym : unit -> name
+
(** {2 Jib context} *)
(** Context for compiling Sail to Jib. We need to pass a (global)
diff --git a/src/jib/jib_optimize.ml b/src/jib/jib_optimize.ml
index 889e650e..ea644bad 100644
--- a/src/jib/jib_optimize.ml
+++ b/src/jib/jib_optimize.ml
@@ -90,7 +90,7 @@ let flat_counter = ref 0
let flat_id () =
let id = mk_id ("local#" ^ string_of_int !flat_counter) in
incr flat_counter;
- id
+ name id
let rec flatten_instrs = function
| I_aux (I_decl (ctyp, decl_id), aux) :: instrs ->
diff --git a/src/jib/jib_ssa.ml b/src/jib/jib_ssa.ml
index 9ce3c3f0..470b646b 100644
--- a/src/jib/jib_ssa.ml
+++ b/src/jib/jib_ssa.ml
@@ -357,47 +357,47 @@ let dominance_frontiers graph root idom children =
(**************************************************************************)
type ssa_elem =
- | Phi of Ast.id * Ast.id list
+ | Phi of Jib.name * Jib.name list
| Pi of Jib.cval list
let place_phi_functions graph df =
- let defsites = ref Bindings.empty in
+ let defsites = ref NameMap.empty in
- let all_vars = ref IdSet.empty in
+ let all_vars = ref NameSet.empty in
let rec all_decls = function
| I_aux ((I_init (_, id, _) | I_decl (_, id)), _) :: instrs ->
- IdSet.add id (all_decls instrs)
+ NameSet.add id (all_decls instrs)
| _ :: instrs -> all_decls instrs
- | [] -> IdSet.empty
+ | [] -> NameSet.empty
in
let orig_A n =
match graph.nodes.(n) with
| Some ((_, CF_block instrs), _, _) ->
- let vars = List.fold_left IdSet.union IdSet.empty (List.map instr_writes instrs) in
- let vars = IdSet.diff vars (all_decls instrs) in
- all_vars := IdSet.union vars !all_vars;
+ let vars = List.fold_left NameSet.union NameSet.empty (List.map instr_writes instrs) in
+ let vars = NameSet.diff vars (all_decls instrs) in
+ all_vars := NameSet.union vars !all_vars;
vars
- | Some _ -> IdSet.empty
- | None -> IdSet.empty
+ | Some _ -> NameSet.empty
+ | None -> NameSet.empty
in
- let phi_A = ref Bindings.empty in
+ let phi_A = ref NameMap.empty in
for n = 0 to graph.next - 1 do
- IdSet.iter (fun a ->
- let ds = match Bindings.find_opt a !defsites with Some ds -> ds | None -> IntSet.empty in
- defsites := Bindings.add a (IntSet.add n ds) !defsites
+ NameSet.iter (fun a ->
+ let ds = match NameMap.find_opt a !defsites with Some ds -> ds | None -> IntSet.empty in
+ defsites := NameMap.add a (IntSet.add n ds) !defsites
) (orig_A n)
done;
- IdSet.iter (fun a ->
- let workset = ref (Bindings.find a !defsites) in
+ NameSet.iter (fun a ->
+ let workset = ref (NameMap.find a !defsites) in
while not (IntSet.is_empty !workset) do
let n = IntSet.choose !workset in
workset := IntSet.remove n !workset;
IntSet.iter (fun y ->
- let phi_A_a = match Bindings.find_opt a !phi_A with Some set -> set | None -> IntSet.empty in
+ let phi_A_a = match NameMap.find_opt a !phi_A with Some set -> set | None -> IntSet.empty in
if not (IntSet.mem y phi_A_a) then
begin
begin match graph.nodes.(y) with
@@ -405,8 +405,8 @@ let place_phi_functions graph df =
graph.nodes.(y) <- Some ((Phi (a, Util.list_init (IntSet.cardinal preds) (fun _ -> a)) :: phis, cfnode), preds, succs)
| None -> assert false
end;
- phi_A := Bindings.add a (IntSet.add y phi_A_a) !phi_A;
- if not (IdSet.mem a (orig_A y)) then
+ phi_A := NameMap.add a (IntSet.add y phi_A_a) !phi_A;
+ if not (NameSet.mem a (orig_A y)) then
workset := IntSet.add y !workset
end
) df.(n)
@@ -414,29 +414,34 @@ let place_phi_functions graph df =
) !all_vars
let rename_variables graph root children =
- let counts = ref Bindings.empty in
- let stacks = ref Bindings.empty in
+ let counts = ref NameMap.empty in
+ let stacks = ref NameMap.empty in
let get_count id =
- match Bindings.find_opt id !counts with Some n -> n | None -> 0
+ match NameMap.find_opt id !counts with Some n -> n | None -> 0
in
let top_stack id =
- match Bindings.find_opt id !stacks with Some (x :: _) -> x | (Some [] | None) -> 0
+ match NameMap.find_opt id !stacks with Some (x :: _) -> x | (Some [] | None) -> 0
in
let push_stack id n =
- stacks := Bindings.add id (n :: match Bindings.find_opt id !stacks with Some s -> s | None -> []) !stacks
+ stacks := NameMap.add id (n :: match NameMap.find_opt id !stacks with Some s -> s | None -> []) !stacks
in
+ let ssa_name i = function
+ | Name (id, _) -> Name (id, i)
+ | Have_exception _ -> Have_exception i
+ | Current_exception _ -> Current_exception i
+ | Return _ -> Return i
+ in
+
let rec fold_frag = function
| F_id id ->
let i = top_stack id in
- F_id (append_id id ("_" ^ string_of_int i))
+ F_id (ssa_name i id)
| F_ref id ->
let i = top_stack id in
- F_ref (append_id id ("_" ^ string_of_int i))
+ F_ref (ssa_name i id)
| F_lit vl -> F_lit vl
- | F_have_exception -> F_have_exception
- | F_current_exception -> F_current_exception
| F_op (f1, op, f2) -> F_op (fold_frag f1, op, fold_frag f2)
| F_unary (op, f) -> F_unary (op, fold_frag f)
| F_call (id, fs) -> F_call (id, List.map fold_frag fs)
@@ -448,15 +453,12 @@ let rename_variables graph root children =
let rec fold_clexp = function
| CL_id (id, ctyp) ->
let i = get_count id + 1 in
- counts := Bindings.add id i !counts;
+ counts := NameMap.add id i !counts;
push_stack id i;
- CL_id (append_id id ("_" ^ string_of_int i), ctyp)
+ CL_id (ssa_name i id, ctyp)
| CL_field (clexp, field) -> CL_field (fold_clexp clexp, field)
| CL_addr clexp -> CL_addr (fold_clexp clexp)
| CL_tuple (clexp, n) -> CL_tuple (fold_clexp clexp, n)
- | CL_current_exception ctyp -> CL_current_exception ctyp
- | CL_have_exception -> CL_have_exception
- | CL_return ctyp -> CL_return ctyp
| CL_void -> CL_void
in
@@ -472,15 +474,15 @@ let rename_variables graph root children =
I_copy (fold_clexp clexp, cval)
| I_decl (ctyp, id) ->
let i = get_count id + 1 in
- counts := Bindings.add id i !counts;
+ counts := NameMap.add id i !counts;
push_stack id i;
- I_decl (ctyp, append_id id ("_" ^ string_of_int i))
+ I_decl (ctyp, ssa_name i id)
| I_init (ctyp, id, cval) ->
let cval = fold_cval cval in
let i = get_count id + 1 in
- counts := Bindings.add id i !counts;
+ counts := NameMap.add id i !counts;
push_stack id i;
- I_init (ctyp, append_id id ("_" ^ string_of_int i), cval)
+ I_init (ctyp, ssa_name i id, cval)
| I_jump (cval, label) ->
I_jump (fold_cval cval, label)
| instr -> instr
@@ -498,9 +500,9 @@ let rename_variables graph root children =
let ssa_ssanode = function
| Phi (id, args) ->
let i = get_count id + 1 in
- counts := Bindings.add id i !counts;
+ counts := NameMap.add id i !counts;
push_stack id i;
- Phi (append_id id ("_" ^ string_of_int i), args)
+ Phi (ssa_name i id, args)
| Pi _ -> assert false (* Should not be introduced at this point *)
in
@@ -509,7 +511,7 @@ let rename_variables graph root children =
Phi (id, List.mapi (fun k a ->
if k = j then
let i = top_stack a in
- append_id a ("_" ^ string_of_int i)
+ ssa_name i a
else a)
ids)
| Pi _ -> assert false (* Should not be introduced at this point *)
@@ -603,7 +605,7 @@ let ssa instrs =
let string_of_ssainstr = function
| Phi (id, args) ->
- string_of_id id ^ " = &phi;(" ^ Util.string_of_list ", " string_of_id args ^ ")"
+ string_of_name id ^ " = &phi;(" ^ Util.string_of_list ", " string_of_name args ^ ")"
| Pi cvals ->
"&pi;(" ^ Util.string_of_list ", " (fun (f, _) -> String.escaped (string_of_fragment ~zencode:false f)) cvals ^ ")"
diff --git a/src/jib/jib_ssa.mli b/src/jib/jib_ssa.mli
index 75c130cf..8cfdb198 100644
--- a/src/jib/jib_ssa.mli
+++ b/src/jib/jib_ssa.mli
@@ -79,7 +79,7 @@ val control_flow_graph : Jib.instr list -> int * int list * ('a list * cf_node)
val immediate_dominators : 'a array_graph -> int -> int array
type ssa_elem =
- | Phi of Ast.id * Ast.id list
+ | Phi of Jib.name * Jib.name list
| Pi of Jib.cval list
(** Convert a list of instructions into SSA form *)
diff --git a/src/jib/jib_util.ml b/src/jib/jib_util.ml
index 81cd07ef..78eca13b 100644
--- a/src/jib/jib_util.ml
+++ b/src/jib/jib_util.ml
@@ -81,6 +81,9 @@ let ifuncall ?loc:(l=Parse_ast.Unknown) clexp id cvals =
let iextern ?loc:(l=Parse_ast.Unknown) clexp id cvals =
I_aux (I_funcall (clexp, true, id, cvals), (instr_number (), l))
+
+let icall ?loc:(l=Parse_ast.Unknown) clexp extern id cvals =
+ I_aux (I_funcall (clexp, extern, id, cvals), (instr_number (), l))
let icopy l clexp cval =
I_aux (I_copy (clexp, cval), (instr_number (), l))
@@ -125,14 +128,39 @@ let iraw ?loc:(l=Parse_ast.Unknown) str =
let ijump ?loc:(l=Parse_ast.Unknown) cval label =
I_aux (I_jump (cval, label), (instr_number (), l))
+module Name = struct
+ type t = name
+ let compare id1 id2 =
+ match id1, id2 with
+ | Name (x, n), Name (y, m) ->
+ let c1 = Id.compare x y in
+ if c1 = 0 then compare n m else c1
+ | Have_exception n, Have_exception m -> compare n m
+ | Current_exception n, Current_exception m -> compare n m
+ | Return n, Return m -> compare n m
+ | Name _, _ -> 1
+ | _, Name _ -> -1
+ | Have_exception _, _ -> 1
+ | _, Have_exception _ -> -1
+ | Current_exception _, _ -> 1
+ | _, Current_exception _ -> -1
+end
+
+module NameSet = Set.Make(Name)
+module NameMap = Map.Make(Name)
+
+let current_exception = Current_exception (-1)
+let have_exception = Have_exception (-1)
+let return = Return (-1)
+
+let name id = Name (id, -1)
+
let rec frag_rename from_id to_id = function
- | F_id id when Id.compare id from_id = 0 -> F_id to_id
+ | F_id id when Name.compare id from_id = 0 -> F_id to_id
| F_id id -> F_id id
- | F_ref id when Id.compare id from_id = 0 -> F_ref to_id
+ | F_ref id when Name.compare id from_id = 0 -> F_ref to_id
| F_ref id -> F_ref id
| F_lit v -> F_lit v
- | F_have_exception -> F_have_exception
- | F_current_exception -> F_current_exception
| F_call (call, frags) -> F_call (call, List.map (frag_rename from_id to_id) frags)
| F_op (f1, op, f2) -> F_op (frag_rename from_id to_id f1, op, frag_rename from_id to_id f2)
| F_unary (op, f) -> F_unary (op, frag_rename from_id to_id f)
@@ -143,7 +171,7 @@ let rec frag_rename from_id to_id = function
let cval_rename from_id to_id (frag, ctyp) = (frag_rename from_id to_id frag, ctyp)
let rec clexp_rename from_id to_id = function
- | CL_id (id, ctyp) when Id.compare id from_id = 0 -> CL_id (to_id, ctyp)
+ | CL_id (id, ctyp) when Name.compare id from_id = 0 -> CL_id (to_id, ctyp)
| CL_id (id, ctyp) -> CL_id (id, ctyp)
| CL_field (clexp, field) ->
CL_field (clexp_rename from_id to_id clexp, field)
@@ -151,17 +179,14 @@ let rec clexp_rename from_id to_id = function
CL_addr (clexp_rename from_id to_id clexp)
| CL_tuple (clexp, n) ->
CL_tuple (clexp_rename from_id to_id clexp, n)
- | CL_current_exception ctyp -> CL_current_exception ctyp
- | CL_have_exception -> CL_have_exception
- | CL_return ctyp -> CL_return ctyp
| CL_void -> CL_void
let rec instr_rename from_id to_id (I_aux (instr, aux)) =
let instr = match instr with
- | I_decl (ctyp, id) when Id.compare id from_id = 0 -> I_decl (ctyp, to_id)
+ | I_decl (ctyp, id) when Name.compare id from_id = 0 -> I_decl (ctyp, to_id)
| I_decl (ctyp, id) -> I_decl (ctyp, id)
- | I_init (ctyp, id, cval) when Id.compare id from_id = 0 ->
+ | I_init (ctyp, id, cval) when Name.compare id from_id = 0 ->
I_init (ctyp, to_id, cval_rename from_id to_id cval)
| I_init (ctyp, id, cval) ->
I_init (ctyp, id, cval_rename from_id to_id cval)
@@ -180,7 +205,7 @@ let rec instr_rename from_id to_id (I_aux (instr, aux)) =
| I_copy (clexp, cval) -> I_copy (clexp_rename from_id to_id clexp, cval_rename from_id to_id cval)
| I_alias (clexp, cval) -> I_alias (clexp_rename from_id to_id clexp, cval_rename from_id to_id cval)
- | I_clear (ctyp, id) when Id.compare id from_id = 0 -> I_clear (ctyp, to_id)
+ | I_clear (ctyp, id) when Name.compare id from_id = 0 -> I_clear (ctyp, to_id)
| I_clear (ctyp, id) -> I_clear (ctyp, id)
| I_return cval -> I_return (cval_rename from_id to_id cval)
@@ -205,10 +230,10 @@ let rec instr_rename from_id to_id (I_aux (instr, aux)) =
| I_end -> I_end
- | I_reset (ctyp, id) when Id.compare id from_id = 0 -> I_reset (ctyp, to_id)
+ | I_reset (ctyp, id) when Name.compare id from_id = 0 -> I_reset (ctyp, to_id)
| I_reset (ctyp, id) -> I_reset (ctyp, id)
- | I_reinit (ctyp, id, cval) when Id.compare id from_id = 0 ->
+ | I_reinit (ctyp, id, cval) when Name.compare id from_id = 0 ->
I_reinit (ctyp, to_id, cval_rename from_id to_id cval)
| I_reinit (ctyp, id, cval) ->
I_reinit (ctyp, id, cval_rename from_id to_id cval)
@@ -233,11 +258,21 @@ let string_of_value = function
| V_ctor_kind str -> "Kind_" ^ Util.zencode_string str
| _ -> failwith "Cannot convert value to string"
+let string_of_name ?zencode:(zencode=true) =
+ let ssa_num n = if n < 0 then "" else ("/" ^ string_of_int n) in
+ function
+ | Name (id, n) ->
+ (if zencode then Util.zencode_string (string_of_id id) else string_of_id id) ^ ssa_num n
+ | Have_exception n ->
+ "have_exception" ^ ssa_num n
+ | Return n ->
+ "return" ^ ssa_num n
+ | Current_exception n ->
+ "(*current_exception)" ^ ssa_num n
+
let rec string_of_fragment ?zencode:(zencode=true) = function
- | F_id id when zencode -> Util.zencode_string (string_of_id id)
- | F_id id -> string_of_id id
- | F_ref id when zencode -> "&" ^ Util.zencode_string (string_of_id id)
- | F_ref id -> "&" ^ string_of_id id
+ | F_id id -> string_of_name ~zencode:zencode id
+ | F_ref id -> "&" ^ string_of_name ~zencode:zencode id
| F_lit v -> string_of_value v
| F_call (str, frags) ->
Printf.sprintf "%s(%s)" str (Util.string_of_list ", " (string_of_fragment ~zencode:zencode) frags)
@@ -247,8 +282,6 @@ let rec string_of_fragment ?zencode:(zencode=true) = function
Printf.sprintf "%s %s %s" (string_of_fragment' ~zencode:zencode f1) op (string_of_fragment' ~zencode:zencode f2)
| F_unary (op, f) ->
op ^ string_of_fragment' ~zencode:zencode f
- | F_have_exception -> "have_exception"
- | F_current_exception -> "(*current_exception)"
| F_raw raw -> raw
| F_poly f -> string_of_fragment ~zencode:zencode f
and string_of_fragment' ?zencode:(zencode=true) f =
@@ -466,6 +499,9 @@ let rec is_polymorphic = function
let pp_id id =
string (string_of_id id)
+let pp_name id =
+ string (string_of_name ~zencode:false id)
+
let pp_ctyp ctyp =
string (full_string_of_ctyp ctyp |> Util.yellow |> Util.clear)
@@ -476,19 +512,16 @@ let pp_cval (frag, ctyp) =
string (string_of_fragment ~zencode:false frag) ^^ string " : " ^^ pp_ctyp ctyp
let rec pp_clexp = function
- | CL_id (id, ctyp) -> pp_id id ^^ string " : " ^^ pp_ctyp ctyp
+ | CL_id (id, ctyp) -> pp_name id ^^ string " : " ^^ pp_ctyp ctyp
| CL_field (clexp, field) -> parens (pp_clexp clexp) ^^ string "." ^^ string field
| CL_tuple (clexp, n) -> parens (pp_clexp clexp) ^^ string "." ^^ string (string_of_int n)
| CL_addr clexp -> string "*" ^^ pp_clexp clexp
- | CL_current_exception ctyp -> string "current_exception : " ^^ pp_ctyp ctyp
- | CL_have_exception -> string "have_exception"
- | CL_return ctyp -> string "return : " ^^ pp_ctyp ctyp
| CL_void -> string "void"
let rec pp_instr ?short:(short=false) (I_aux (instr, aux)) =
match instr with
| I_decl (ctyp, id) ->
- pp_keyword "var" ^^ pp_id id ^^ string " : " ^^ pp_ctyp ctyp
+ pp_keyword "var" ^^ pp_name id ^^ string " : " ^^ pp_ctyp ctyp
| I_if (cval, then_instrs, else_instrs, ctyp) ->
let pp_if_block = function
| [] -> string "{}"
@@ -508,11 +541,11 @@ let rec pp_instr ?short:(short=false) (I_aux (instr, aux)) =
| I_try_block instrs ->
pp_keyword "try" ^^ surround 2 0 lbrace (separate_map (semi ^^ hardline) pp_instr instrs) rbrace
| I_reset (ctyp, id) ->
- pp_keyword "recreate" ^^ pp_id id ^^ string " : " ^^ pp_ctyp ctyp
+ pp_keyword "recreate" ^^ pp_name id ^^ string " : " ^^ pp_ctyp ctyp
| I_init (ctyp, id, cval) ->
- pp_keyword "create" ^^ pp_id id ^^ string " : " ^^ pp_ctyp ctyp ^^ string " = " ^^ pp_cval cval
+ pp_keyword "create" ^^ pp_name id ^^ string " : " ^^ pp_ctyp ctyp ^^ string " = " ^^ pp_cval cval
| I_reinit (ctyp, id, cval) ->
- pp_keyword "recreate" ^^ pp_id id ^^ string " : " ^^ pp_ctyp ctyp ^^ string " = " ^^ pp_cval cval
+ pp_keyword "recreate" ^^ pp_name id ^^ string " : " ^^ pp_ctyp ctyp ^^ string " = " ^^ pp_cval cval
| I_funcall (x, _, f, args) ->
separate space [ pp_clexp x; string "=";
string (string_of_id f |> Util.green |> Util.clear) ^^ parens (separate_map (string ", ") pp_cval args) ]
@@ -521,7 +554,7 @@ let rec pp_instr ?short:(short=false) (I_aux (instr, aux)) =
| I_alias (clexp, cval) ->
pp_keyword "alias" ^^ separate space [pp_clexp clexp; string "="; pp_cval cval]
| I_clear (ctyp, id) ->
- pp_keyword "kill" ^^ pp_id id ^^ string " : " ^^ pp_ctyp ctyp
+ pp_keyword "kill" ^^ pp_name id ^^ string " : " ^^ pp_ctyp ctyp
| I_return cval ->
pp_keyword "return" ^^ pp_cval cval
| I_throw cval ->
@@ -584,55 +617,47 @@ let pp_cdef = function
^^ hardline
let rec fragment_deps = function
- | F_id id | F_ref id -> IdSet.singleton id
- | F_lit _ -> IdSet.empty
+ | F_id id | F_ref id -> NameSet.singleton id
+ | F_lit _ -> NameSet.empty
| F_field (frag, _) | F_unary (_, frag) | F_poly frag -> fragment_deps frag
- | F_call (_, frags) -> List.fold_left IdSet.union IdSet.empty (List.map fragment_deps frags)
- | F_op (frag1, _, frag2) -> IdSet.union (fragment_deps frag1) (fragment_deps frag2)
- | F_current_exception -> IdSet.empty
- | F_have_exception -> IdSet.empty
- | F_raw _ -> IdSet.empty
+ | F_call (_, frags) -> List.fold_left NameSet.union NameSet.empty (List.map fragment_deps frags)
+ | F_op (frag1, _, frag2) -> NameSet.union (fragment_deps frag1) (fragment_deps frag2)
+ | F_raw _ -> NameSet.empty
let cval_deps = function (frag, _) -> fragment_deps frag
let rec clexp_deps = function
- | CL_id (id, _) -> IdSet.singleton id
+ | CL_id (id, _) -> NameSet.singleton id
| CL_field (clexp, _) -> clexp_deps clexp
| CL_tuple (clexp, _) -> clexp_deps clexp
| CL_addr clexp -> clexp_deps clexp
- | CL_have_exception -> IdSet.empty
- | CL_current_exception _ -> IdSet.empty
- | CL_return _ -> IdSet.empty
- | CL_void -> IdSet.empty
+ | CL_void -> NameSet.empty
(* Return the direct, read/write dependencies of a single instruction *)
let instr_deps = function
- | I_decl (ctyp, id) -> IdSet.empty, IdSet.singleton id
- | I_reset (ctyp, id) -> IdSet.empty, IdSet.singleton id
- | I_init (ctyp, id, cval) | I_reinit (ctyp, id, cval) -> cval_deps cval, IdSet.singleton id
- | I_if (cval, _, _, _) -> cval_deps cval, IdSet.empty
- | I_jump (cval, label) -> cval_deps cval, IdSet.empty
- | I_funcall (clexp, _, _, cvals) -> List.fold_left IdSet.union IdSet.empty (List.map cval_deps cvals), clexp_deps clexp
+ | I_decl (ctyp, id) -> NameSet.empty, NameSet.singleton id
+ | I_reset (ctyp, id) -> NameSet.empty, NameSet.singleton id
+ | I_init (ctyp, id, cval) | I_reinit (ctyp, id, cval) -> cval_deps cval, NameSet.singleton id
+ | I_if (cval, _, _, _) -> cval_deps cval, NameSet.empty
+ | I_jump (cval, label) -> cval_deps cval, NameSet.empty
+ | I_funcall (clexp, _, _, cvals) -> List.fold_left NameSet.union NameSet.empty (List.map cval_deps cvals), clexp_deps clexp
| I_copy (clexp, cval) -> cval_deps cval, clexp_deps clexp
| I_alias (clexp, cval) -> cval_deps cval, clexp_deps clexp
- | I_clear (_, id) -> IdSet.singleton id, IdSet.empty
- | I_throw cval | I_return cval -> cval_deps cval, IdSet.empty
- | I_block _ | I_try_block _ -> IdSet.empty, IdSet.empty
- | I_comment _ | I_raw _ -> IdSet.empty, IdSet.empty
- | I_label label -> IdSet.empty, IdSet.empty
- | I_goto label -> IdSet.empty, IdSet.empty
- | I_undefined _ -> IdSet.empty, IdSet.empty
- | I_match_failure -> IdSet.empty, IdSet.empty
- | I_end -> IdSet.empty, IdSet.empty
+ | I_clear (_, id) -> NameSet.singleton id, NameSet.empty
+ | I_throw cval | I_return cval -> cval_deps cval, NameSet.empty
+ | I_block _ | I_try_block _ -> NameSet.empty, NameSet.empty
+ | I_comment _ | I_raw _ -> NameSet.empty, NameSet.empty
+ | I_label label -> NameSet.empty, NameSet.empty
+ | I_goto label -> NameSet.empty, NameSet.empty
+ | I_undefined _ -> NameSet.empty, NameSet.empty
+ | I_match_failure -> NameSet.empty, NameSet.empty
+ | I_end -> NameSet.empty, NameSet.empty
let rec map_clexp_ctyp f = function
| CL_id (id, ctyp) -> CL_id (id, f ctyp)
| CL_field (clexp, field) -> CL_field (map_clexp_ctyp f clexp, field)
| CL_tuple (clexp, n) -> CL_tuple (map_clexp_ctyp f clexp, n)
| CL_addr clexp -> CL_addr (map_clexp_ctyp f clexp)
- | CL_current_exception ctyp -> CL_current_exception (f ctyp)
- | CL_have_exception -> CL_have_exception
- | CL_return ctyp -> CL_return (f ctyp)
| CL_void -> CL_void
let rec map_instr_ctyp f (I_aux (instr, aux)) =
@@ -732,7 +757,7 @@ let map_instrs_list f instrs =
let rec instr_ids (I_aux (instr, _)) =
let reads, writes = instr_deps instr in
- IdSet.union reads writes
+ NameSet.union reads writes
let rec instr_reads (I_aux (instr, _)) =
fst (instr_deps instr)
@@ -764,7 +789,6 @@ let cval_ctyp = function (_, ctyp) -> ctyp
let rec clexp_ctyp = function
| CL_id (_, ctyp) -> ctyp
- | CL_return ctyp -> ctyp
| CL_field (clexp, field) ->
begin match clexp_ctyp clexp with
| CT_struct (id, ctors) ->
@@ -788,8 +812,6 @@ let rec clexp_ctyp = function
end
| ctyp -> failwith ("Bad ctyp for CL_addr " ^ string_of_ctyp ctyp)
end
- | CL_have_exception -> CT_bool
- | CL_current_exception ctyp -> ctyp
| CL_void -> CT_unit
let rec instr_ctyps (I_aux (instr, aux)) =
@@ -848,12 +870,12 @@ let instr_split_at f =
instr_split_at' f []
let rec instrs_rename from_id to_id =
- let rename id = if Id.compare id from_id = 0 then to_id else id in
+ let rename id = if Name.compare id from_id = 0 then to_id else id in
let crename = cval_rename from_id to_id in
let irename instrs = instrs_rename from_id to_id instrs in
let lrename = clexp_rename from_id to_id in
function
- | (I_aux (I_decl (ctyp, new_id), _) :: _) as instrs when Id.compare from_id new_id = 0 -> instrs
+ | (I_aux (I_decl (ctyp, new_id), _) :: _) as instrs when Name.compare from_id new_id = 0 -> instrs
| I_aux (I_decl (ctyp, new_id), aux) :: instrs -> I_aux (I_decl (ctyp, new_id), aux) :: irename instrs
| I_aux (I_reset (ctyp, id), aux) :: instrs -> I_aux (I_reset (ctyp, rename id), aux) :: irename instrs
| I_aux (I_init (ctyp, id, cval), aux) :: instrs -> I_aux (I_init (ctyp, rename id, crename cval), aux) :: irename instrs
@@ -861,8 +883,8 @@ let rec instrs_rename from_id to_id =
| I_aux (I_if (cval, then_instrs, else_instrs, ctyp), aux) :: instrs ->
I_aux (I_if (crename cval, irename then_instrs, irename else_instrs, ctyp), aux) :: irename instrs
| I_aux (I_jump (cval, label), aux) :: instrs -> I_aux (I_jump (crename cval, label), aux) :: irename instrs
- | I_aux (I_funcall (clexp, extern, id, cvals), aux) :: instrs ->
- I_aux (I_funcall (lrename clexp, extern, rename id, List.map crename cvals), aux) :: irename instrs
+ | I_aux (I_funcall (clexp, extern, function_id, cvals), aux) :: instrs ->
+ I_aux (I_funcall (lrename clexp, extern, function_id, List.map crename cvals), aux) :: irename instrs
| I_aux (I_copy (clexp, cval), aux) :: instrs -> I_aux (I_copy (lrename clexp, crename cval), aux) :: irename instrs
| I_aux (I_alias (clexp, cval), aux) :: instrs -> I_aux (I_alias (lrename clexp, crename cval), aux) :: irename instrs
| I_aux (I_clear (ctyp, id), aux) :: instrs -> I_aux (I_clear (ctyp, rename id), aux) :: irename instrs