summaryrefslogtreecommitdiff
path: root/src
diff options
context:
space:
mode:
authorAlasdair Armstrong2018-06-13 21:26:35 +0100
committerAlasdair Armstrong2018-06-13 21:26:35 +0100
commit4b6732fdddebc07f072e012a52f7d9541e4d657c (patch)
treeea66e08af8607e64ac95f3631cfefc4e8bf577f8 /src
parentd96cd3e8d74b303ff89716294d173754c70cd6b7 (diff)
Tracing instrumentation for C backend
Diffstat (limited to 'src')
-rw-r--r--src/bitfield.ml18
-rw-r--r--src/c_backend.ml58
-rw-r--r--src/sail.ml3
-rw-r--r--src/sail_lib.ml4
-rw-r--r--src/value.ml3
5 files changed, 84 insertions, 2 deletions
diff --git a/src/bitfield.ml b/src/bitfield.ml
index 161908cd..afdd5baf 100644
--- a/src/bitfield.ml
+++ b/src/bitfield.ml
@@ -83,6 +83,22 @@ let rec translate_indices hi lo =
else
(hi / 64, hi mod 64, 0) :: translate_indices (hi - (hi mod 64 + 1)) lo
+let constructor name order start stop =
+ let indices = translate_indices start stop in
+ let size = if start > stop then start - (stop - 1) else stop - (start - 1) in
+ let constructor_val = Printf.sprintf "val Mk_%s : %s -> %s" name (bitvec size order) name in
+ let body (chunk, hi, lo) =
+ Printf.sprintf "%s_chunk_%i = v[%i .. %i]"
+ name chunk ((hi + chunk * 64) - stop) ((lo + chunk * 64) - stop)
+ in
+ let constructor_function = String.concat "\n"
+ [ Printf.sprintf "function Mk_%s v = struct {" name;
+ Printf.sprintf " %s" (Util.string_of_list ",\n " body indices);
+ "}"
+ ]
+ in
+ combine [ast_of_def_string order constructor_val; ast_of_def_string order constructor_function]
+
(* For every index range, create a getter and setter *)
let index_range_getter name field order start stop =
let indices = translate_indices start stop in
@@ -149,4 +165,4 @@ let field_accessor name order (id, ir) = index_range_accessor name (string_of_id
let macro id size order ranges =
let name = string_of_id id in
let ranges = (mk_id "bits", BF_aux (BF_range (Big_int.of_int (size - 1), Big_int.of_int 0), Parse_ast.Unknown)) :: ranges in
- combine ([newtype name size order] @ List.map (field_accessor name order) ranges)
+ combine ([newtype name size order; constructor name order (size - 1) 0] @ List.map (field_accessor name order) ranges)
diff --git a/src/c_backend.ml b/src/c_backend.ml
index e088b5e5..96cd9ed7 100644
--- a/src/c_backend.ml
+++ b/src/c_backend.ml
@@ -59,6 +59,7 @@ module Big_int = Nat_big_num
let c_verbosity = ref 1
let opt_ddump_flow_graphs = ref false
+let opt_trace = ref false
(* Optimization flags *)
let optimize_primops = ref false
@@ -990,8 +991,10 @@ let analyze_primop' ctx env l id args typ =
| "and_bits", [AV_C_fragment (v1, typ1); AV_C_fragment (v2, typ2)] ->
AE_val (AV_C_fragment (F_op (v1, "&", v2), typ))
+ (*
| "not_bits", [AV_C_fragment (v, _)] ->
AE_val (AV_C_fragment (F_unary ("~", v), typ))
+ *)
| "vector_subrange", [AV_C_fragment (vec, _); AV_C_fragment (f, _); AV_C_fragment (t, _)] ->
let len = F_op (f, "-", F_op (t, "-", v_one)) in
@@ -3231,6 +3234,59 @@ let sgen_finish = function
Printf.sprintf " finish_%s();" (sgen_id id)
| _ -> assert false
+let instrument_tracing ctx =
+ let module StringSet = Set.Make(String) in
+ let traceable = StringSet.of_list ["uint64_t"; "sail_string"; "bv_t"; "mpz_t"; "unit"; "bool"] in
+ let rec instrument = function
+ | (I_aux (I_funcall (clexp, _, id, args, ctyp), _) as instr) :: instrs ->
+ let trace_start =
+ iraw (Printf.sprintf "trace_start(\"%s\");" (String.escaped (string_of_id id)))
+ in
+ let trace_arg cval =
+ let ctyp_name = sgen_ctyp_name (cval_ctyp cval) in
+ if StringSet.mem ctyp_name traceable then
+ iraw (Printf.sprintf "trace_%s(%s);" ctyp_name (sgen_cval cval))
+ else
+ iraw "trace_unknown();"
+ in
+ let rec trace_args = function
+ | [] -> []
+ | [cval] -> [trace_arg cval]
+ | cval :: cvals ->
+ trace_arg cval :: iraw "trace_argsep();" :: trace_args cvals
+ in
+ let trace_end = iraw "trace_end();" in
+ let trace_ret =
+ let ctyp_name = sgen_ctyp_name ctyp in
+ if StringSet.mem ctyp_name traceable then
+ iraw (Printf.sprintf "trace_%s(%s);" (sgen_ctyp_name ctyp) (sgen_clexp_pure clexp))
+ else
+ iraw "trace_unknown();"
+ in
+ [trace_start;
+ iraw "g_trace_depth++;"]
+ @ trace_args args
+ @ [iraw "trace_argend();";
+ instr;
+ iraw "g_trace_depth--;";
+ trace_end;
+ trace_ret;
+ iraw "trace_retend();"]
+ @ instrument instrs
+
+ | I_aux (I_block block, aux) :: instrs -> I_aux (I_block (instrument block), aux) :: instrument instrs
+ | I_aux (I_try_block block, aux) :: instrs -> I_aux (I_try_block (instrument block), aux) :: instrument instrs
+ | I_aux (I_if (cval, then_instrs, else_instrs, ctyp), aux) :: instrs ->
+ I_aux (I_if (cval, instrument then_instrs, instrument else_instrs, ctyp), aux) :: instrument instrs
+
+ | instr :: instrs -> instr :: instrument instrs
+ | [] -> []
+ in
+ function
+ | CDEF_fundef (function_id, heap_return, args, body) ->
+ CDEF_fundef (function_id, heap_return, args, instrument body)
+ | cdef -> cdef
+
let bytecode_ast ctx rewrites (Defs defs) =
let assert_vs = Initial_check.extern_of_string dec_ord (mk_id "sail_assert") "(bool, string) -> unit effect {escape}" in
let exit_vs = Initial_check.extern_of_string dec_ord (mk_id "sail_exit") "unit -> unit effect {escape}" in
@@ -3258,7 +3314,7 @@ let compile_ast ctx (Defs defs) =
let ctx = { ctx with tc_env = snd (Type_error.check ctx.tc_env (Defs [assert_vs; exit_vs])) } in
let chunks, ctx = List.fold_left (fun (chunks, ctx) def -> let defs, ctx = compile_def ctx def in defs :: chunks, ctx) ([], ctx) defs in
let cdefs = List.concat (List.rev chunks) in
- let cdefs = optimize ctx cdefs in
+ let cdefs = List.map (instrument_tracing ctx) (optimize ctx cdefs) in
let docs = List.map (codegen_def ctx) cdefs in
let preamble = separate hardline
diff --git a/src/sail.ml b/src/sail.ml
index 36b4efd8..86c00254 100644
--- a/src/sail.ml
+++ b/src/sail.ml
@@ -119,6 +119,9 @@ let options = Arg.align ([
( "-Oconstant_fold",
Arg.Set Constant_fold.optimize_constant_fold,
" Apply constant folding optimizations");
+ ( "-c_trace",
+ Arg.Set C_backend.opt_trace,
+ " Instrument C ouput with tracing");
( "-lem_ast",
Arg.Set opt_print_lem_ast,
" output a Lem AST representation of the input");
diff --git a/src/sail_lib.ml b/src/sail_lib.ml
index 89056347..31b975df 100644
--- a/src/sail_lib.ml
+++ b/src/sail_lib.ml
@@ -575,6 +575,10 @@ let real_of_string str =
(* Not a very good sqrt implementation *)
let sqrt_real x = failwith "sqrt_real" (* real_of_string (string_of_float (sqrt (Num.float_of_num x))) *)
+let print str = Pervasives.print_string str
+
+let prerr str = Pervasives.prerr_string str
+
let print_int (str, x) =
print_endline (str ^ Big_int.to_string x)
diff --git a/src/value.ml b/src/value.ml
index 8ee219b7..41b52720 100644
--- a/src/value.ml
+++ b/src/value.ml
@@ -491,6 +491,9 @@ let primops =
StringMap.empty
[ ("and_bool", and_bool);
("or_bool", or_bool);
+ ("print", value_print);
+ ("prerr", fun vs -> (prerr_endline (string_of_value (List.hd vs)); V_unit));
+ ("dec_str", fun _ -> V_string "X");
("print_endline", value_print);
("prerr_endline", fun vs -> (prerr_endline (string_of_value (List.hd vs)); V_unit));
("putchar", value_putchar);