summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--src/c_backend.ml18
-rw-r--r--src/constant_fold.ml34
-rw-r--r--src/sail.ml3
3 files changed, 51 insertions, 4 deletions
diff --git a/src/c_backend.ml b/src/c_backend.ml
index d14b5391..925c7fd9 100644
--- a/src/c_backend.ml
+++ b/src/c_backend.ml
@@ -499,7 +499,7 @@ let analyze_primop' ctx id args typ =
AE_val (AV_C_fragment (F_call ("fast_zero_extend", [v1; v_int (Big_int.to_int n)]), typ, CT_fbits (Big_int.to_int n, true)))
| _ -> no_change
end
-
+
| "sign_extend", [AV_C_fragment (v1, _, CT_fbits (n, _)); _] ->
begin match destruct_vector ctx.tc_env typ with
| Some (Nexp_aux (Nexp_constant m, _), _, Typ_aux (Typ_id id, _))
@@ -515,9 +515,19 @@ let analyze_primop' ctx id args typ =
AE_val (AV_C_fragment (F_call ("fast_sign_extend2", [v1; v_int (Big_int.to_int m)]) , typ, CT_fbits (Big_int.to_int m, true)))
| _ -> no_change
end
-
+
+ | "add_bits", [AV_C_fragment (v1, _, CT_fbits (n, ord)); AV_C_fragment (v2, _, CT_fbits _)]
+ when n <= 63 ->
+ AE_val (AV_C_fragment (F_op (F_op (v1, "+", v2), "&", v_mask_lower n), typ, CT_fbits (n, ord)))
+
+ | "lteq", [AV_C_fragment (v1, _, _); AV_C_fragment (v2, _, _)] ->
+ AE_val (AV_C_fragment (F_op (v1, "<=", v2), typ, CT_bool))
| "gteq", [AV_C_fragment (v1, _, _); AV_C_fragment (v2, _, _)] ->
AE_val (AV_C_fragment (F_op (v1, ">=", v2), typ, CT_bool))
+ | "lt", [AV_C_fragment (v1, _, _); AV_C_fragment (v2, _, _)] ->
+ AE_val (AV_C_fragment (F_op (v1, "<", v2), typ, CT_bool))
+ | "gt", [AV_C_fragment (v1, _, _); AV_C_fragment (v2, _, _)] ->
+ AE_val (AV_C_fragment (F_op (v1, ">", v2), typ, CT_bool))
| "xor_bits", [AV_C_fragment (v1, _, (CT_fbits _ as ctyp)); AV_C_fragment (v2, _, CT_fbits _)] ->
AE_val (AV_C_fragment (F_op (v1, "^", v2), typ, ctyp))
@@ -608,7 +618,7 @@ let analyze_primop' ctx id args typ =
AE_val (AV_C_fragment (F_call ("fast_signed", [frag; v_int (Big_int.to_int n)]), typ, ctyp_of_typ ctx typ))
| _ -> no_change
end
-
+
| "add_int", [AV_C_fragment (op1, _, _); AV_C_fragment (op2, _, _)] ->
begin match destruct_range Env.empty typ with
| None -> no_change
@@ -638,7 +648,7 @@ let analyze_primop' ctx id args typ =
AV_C_fragment (lo, _, CT_fint 64);
AV_C_fragment (ys, _, CT_fbits (m, true))] ->
AE_val (AV_C_fragment (F_call ("fast_update_subrange", [xs; hi; lo; ys]), typ, CT_fbits (n, true)))
-
+
| "undefined_bool", _ ->
AE_val (AV_C_fragment (F_lit (V_bool false), typ, CT_bool))
diff --git a/src/constant_fold.ml b/src/constant_fold.ml
index 6ad1f663..0ede2401 100644
--- a/src/constant_fold.ml
+++ b/src/constant_fold.ml
@@ -62,6 +62,9 @@ let optimize_constant_fold = ref false
let rec fexp_of_ctor (field, value) =
FE_aux (FE_Fexp (mk_id field, exp_of_value value), no_annot)
+(* The interpreter will return a value for each folded expression, so
+ we must convert that back to expression to re-insert it in the AST
+ *)
and exp_of_value =
let open Value in
function
@@ -107,6 +110,32 @@ let safe_primops =
"Elf_loader.elf_tohost"
]
+(** We can specify a list of identifiers that we want to remove from
+ the final AST here. This is useful for removing tracing features in
+ optimized builds, e.g. for booting an OS as fast as possible.
+
+ Basically we just do this by mapping
+
+ f(x, y, z) -> ()
+
+ when f is in the list of identifiers to be mapped to unit. The
+ advantage of doing it like this is if x, y, and z are
+ computationally expensive then we remove them also. String
+ concatentation is very expensive at runtime so this is something we
+ really want when cutting out tracing features. Obviously it's
+ important that they don't have any meaningful side effects, and
+ that f does actually have type unit.
+*)
+let opt_fold_to_unit = ref []
+
+let fold_to_unit id =
+ let remove =
+ !opt_fold_to_unit
+ |> List.map mk_id
+ |> List.fold_left (fun m id -> IdSet.add id m) IdSet.empty
+ in
+ IdSet.mem id remove
+
let rec is_constant (E_aux (e_aux, _)) =
match e_aux with
| E_lit _ -> true
@@ -177,6 +206,11 @@ let rec rewrite_constant_function_calls' ast =
let rw_funcall e_aux annot =
match e_aux with
+ (*
+ | E_app (id, args) when fold_to_unit id ->
+ ok (); E_aux (E_lit (L_aux (L_unit, Parse_ast.Unknown)), annot)
+ *)
+
| E_app (id, args) when List.for_all is_constant args ->
evaluate e_aux annot
diff --git a/src/sail.ml b/src/sail.ml
index eb81a0ee..aad7097f 100644
--- a/src/sail.ml
+++ b/src/sail.ml
@@ -155,6 +155,9 @@ let options = Arg.align ([
( "-c_specialize",
Arg.Set opt_specialize_c,
" specialize integer arguments in C output");
+ ( "-c_fold_unit",
+ Arg.String (fun str -> Constant_fold.opt_fold_to_unit := Util.split_on_char ',' str),
+ " remove comma separated list of functions from C output, replacing them with unit");
( "-elf",
Arg.String (fun elf -> opt_process_elf := Some elf),
" process an ELF file so that it can be executed by compiled C code");